1#include <test/jtx/Account.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/WSClient.h>
4#include <test/jtx/amount.h>
5#include <test/jtx/balance.h>
6#include <test/jtx/envconfig.h>
7#include <test/jtx/mpt.h>
8#include <test/jtx/pay.h>
9#include <test/jtx/sendmax.h>
10#include <test/jtx/ter.h>
11#include <test/jtx/txflags.h>
13#include <xrpl/basics/chrono.h>
14#include <xrpl/beast/unit_test/suite.h>
15#include <xrpl/json/json_value.h>
16#include <xrpl/json/to_string.h>
17#include <xrpl/protocol/AccountID.h>
18#include <xrpl/protocol/Feature.h>
19#include <xrpl/protocol/SField.h>
20#include <xrpl/protocol/TER.h>
21#include <xrpl/protocol/TxFlags.h>
22#include <xrpl/protocol/jss.h>
108 if (t[jss::TransactionType].asString() != jss::Payment)
111 bool const isSet = metaData.
isMember(jss::delivered_amount);
112 bool isSetUnavailable =
false;
113 bool isSetAvailable =
false;
116 if (metaData[jss::delivered_amount] !=
"unavailable")
118 isSetAvailable =
true;
122 isSetUnavailable =
true;
129 else if (isSetUnavailable)
140 if (metaData.
isMember(sfDeliveredAmount.jsonName))
142 if (metaData[jss::delivered_amount] != metaData[sfDeliveredAmount.jsonName])
149 if (metaData[jss::delivered_amount] != t[jss::Amount])
154 if (metaData[jss::delivered_amount] !=
"unavailable")
160 if (metaData[sfTransactionResult.jsonName] !=
"tesSUCCESS")
174 if (metaData.
isMember(sfDeliveredAmount.jsonName))
181 if (!isSetUnavailable)
195 testcase(
"Ledger Request Subscribe DeliveredAmount");
198 using namespace std::chrono_literals;
203 auto const gw =
Account(
"gateway");
204 auto const usd = gw[
"USD"];
206 for (
bool const afterSwitchTime : {
true,
false})
209 cfg->fees.referenceFee = 10;
210 Env env(*
this, std::move(cfg));
211 env.
fund(
XRP(10000), alice, bob, carol, gw);
212 env.
trust(usd(1000), alice, bob, carol);
227 env(
pay(gw, alice, usd(50)));
229 env(
pay(gw, alice,
XRP(50)));
233 env(
pay(gw, bob, usd(9999999)),
Txflags(tfPartialPayment));
249 stream[jss::streams].append(
"ledger");
251 stream[jss::accounts].append(
toBase58(alice.
id()));
252 stream[jss::accounts].append(
toBase58(bob.
id()));
253 stream[jss::accounts].append(
toBase58(carol.
id()));
254 auto jv = wsc->invoke(
"subscribe", stream);
255 if (wsc->version() == 2)
257 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
258 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
259 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
261 BEAST_EXPECT(jv[jss::result][jss::ledger_index] == 3);
268 auto const r = wsc->findMsg(
269 1s, [&](
auto const& jv) {
return jv[jss::ledger_index] == 4; });
273 if (!r->isMember(jss::transaction))
277 checkDeliveredAmount.
checkTxn((*r)[jss::transaction], (*r)[jss::meta]));
286 testcase(
"Ledger Request RPC DeliveredAmount");
289 using namespace std::chrono_literals;
294 auto const gw =
Account(
"gateway");
295 auto const usd = gw[
"USD"];
297 for (
bool const afterSwitchTime : {
true,
false})
300 cfg->fees.referenceFee = 10;
301 Env env(*
this, std::move(cfg));
302 env.
fund(
XRP(10000), alice, bob, carol, gw);
303 env.
trust(usd(1000), alice, bob, carol);
315 env(
pay(gw, alice, usd(50)));
317 env(
pay(gw, alice,
XRP(50)));
321 env(
pay(gw, bob, usd(9999999)),
Txflags(tfPartialPayment));
332 jvParams[jss::ledger_index] = 4u;
333 jvParams[jss::transactions] =
true;
334 jvParams[jss::expand] =
true;
335 auto const jtxn = env.
rpc(
336 "json",
"ledger",
to_string(jvParams))[jss::result][jss::ledger][jss::transactions];
337 for (
auto const& t : jtxn)
338 BEAST_EXPECT(checkDeliveredAmount.
checkTxn(t, t[jss::metaData]));
352 Env env{*
this, features};
354 MPTTester mptAlice(env, alice, {.holders = {bob, carol}, .close =
false});
357 {.transferFee = 25000, .ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer});
358 auto const mpt = mptAlice[
"MPT"];
360 mptAlice.authorize({.account = bob});
361 mptAlice.authorize({.account = carol});
364 mptAlice.pay(alice, bob, 10000);
367 env(
pay(bob, carol, mptAlice.mpt(1000)),
Txflags(tfPartialPayment));
374 if (features[fixMPTDeliveredAmount])
377 meta[sfDeliveredAmount.jsonName] ==
380 meta[jss::delivered_amount] ==
385 BEAST_EXPECT(!meta.
isMember(sfDeliveredAmount.jsonName));
386 BEAST_EXPECT(meta[jss::delivered_amount] =
json::Value(
"unavailable"));
393 meta = env.
rpc(
"tx", txHash)[jss::result][jss::meta];
395 if (features[fixMPTDeliveredAmount])
398 meta[sfDeliveredAmount.jsonName] ==
401 meta[jss::delivered_amount] ==
406 BEAST_EXPECT(!meta.
isMember(sfDeliveredAmount.jsonName));
407 BEAST_EXPECT(meta[jss::delivered_amount] =
json::Value(
"unavailable"));
TestcaseT testcase
Memberspace for declaring test cases.
bool isMember(char const *key) const
Return true if the object has a member named key.
virtual Config & config()=0
std::chrono::time_point< NetClock > time_point
json::Value getJson(JsonOptions=JsonOptions::Values::None) const override
void adjCountersSuccess()
CheckDeliveredAmount(bool afterSwitchTime)
bool checkExpectedCounters() const
int numExpectedSetUnavailable_
int numExpectedAvailable_
void adjCountersPartialPayment()
bool checkTxn(json::Value const &t, json::Value const &metaData)
void adjCounters(bool success, bool partial)
void run() override
Runs the suite.
void testAccountDeliveredAmountSubscribe()
void testMPTDeliveredAmountRPC(FeatureBitset features)
void testTxDeliveredAmountRPC()
Immutable cryptographic account descriptor.
AccountID id() const
Returns the Account ID.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
void require(Args const &... args)
Check a set of requirements.
Test helper for creating, mutating, and asserting MPT and confidential MPT ledger state.
void create(MPTCreate const &arg=MPTCreate{})
Sets the SendMax on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
@ Array
array value (ordered list)
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
XrpT const XRP
Converts to XRP Issue or STAmount.
FeatureBitset testableAmendments()
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
std::unique_ptr< WSClient > makeWSClient(Config const &cfg, bool v2, unsigned rpcVersion, std::unordered_map< std::string, std::string > const &headers)
Returns a client operating through WebSockets/S.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
std::string to_string(BaseUInt< Bits, Tag > const &a)