2#include <test/jtx/WSClient.h>
4#include <xrpl/beast/unit_test.h>
5#include <xrpl/beast/unit_test/suite.h>
6#include <xrpl/protocol/jss.h>
90 if (t[jss::TransactionType].asString() != jss::Payment)
93 bool const isSet = metaData.
isMember(jss::delivered_amount);
94 bool isSetUnavailable =
false;
95 bool isSetAvailable =
false;
98 if (metaData[jss::delivered_amount] !=
"unavailable")
100 isSetAvailable =
true;
104 isSetUnavailable =
true;
111 else if (isSetUnavailable)
122 if (metaData.
isMember(sfDeliveredAmount.jsonName))
124 if (metaData[jss::delivered_amount] != metaData[sfDeliveredAmount.jsonName])
131 if (metaData[jss::delivered_amount] != t[jss::Amount])
136 if (metaData[jss::delivered_amount] !=
"unavailable")
142 if (metaData[sfTransactionResult.jsonName] !=
"tesSUCCESS")
156 if (metaData.
isMember(sfDeliveredAmount.jsonName))
163 if (!isSetUnavailable)
177 testcase(
"Ledger Request Subscribe DeliveredAmount");
179 using namespace test::jtx;
180 using namespace std::chrono_literals;
185 auto const gw =
Account(
"gateway");
186 auto const USD = gw[
"USD"];
188 for (
bool const afterSwitchTime : {
true,
false})
191 cfg->FEES.reference_fee = 10;
192 Env env(*
this, std::move(cfg));
193 env.
fund(
XRP(10000), alice, bob, carol, gw);
194 env.
trust(USD(1000), alice, bob, carol);
209 env(
pay(gw, alice, USD(50)));
210 checkDeliveredAmount.adjCountersSuccess();
211 env(
pay(gw, alice,
XRP(50)));
212 checkDeliveredAmount.adjCountersSuccess();
215 env(
pay(gw, bob, USD(9999999)),
txflags(tfPartialPayment));
216 checkDeliveredAmount.adjCountersPartialPayment();
221 checkDeliveredAmount.adjCountersFail();
231 stream[jss::streams].append(
"ledger");
233 stream[jss::accounts].append(
toBase58(alice.
id()));
234 stream[jss::accounts].append(
toBase58(bob.
id()));
235 stream[jss::accounts].append(
toBase58(carol.
id()));
236 auto jv = wsc->invoke(
"subscribe", stream);
237 if (wsc->version() == 2)
239 BEAST_EXPECT(jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] ==
"2.0");
240 BEAST_EXPECT(jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] ==
"2.0");
241 BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
243 BEAST_EXPECT(jv[jss::result][jss::ledger_index] == 3);
250 auto const r = wsc->findMsg(
251 1s, [&](
auto const& jv) {
return jv[jss::ledger_index] == 4; });
255 if (!r->isMember(jss::transaction))
259 checkDeliveredAmount.checkTxn((*r)[jss::transaction], (*r)[jss::meta]));
262 BEAST_EXPECT(checkDeliveredAmount.checkExpectedCounters());
268 testcase(
"Ledger Request RPC DeliveredAmount");
270 using namespace test::jtx;
271 using namespace std::chrono_literals;
276 auto const gw =
Account(
"gateway");
277 auto const USD = gw[
"USD"];
279 for (
bool const afterSwitchTime : {
true,
false})
282 cfg->FEES.reference_fee = 10;
283 Env env(*
this, std::move(cfg));
284 env.
fund(
XRP(10000), alice, bob, carol, gw);
285 env.
trust(USD(1000), alice, bob, carol);
297 env(
pay(gw, alice, USD(50)));
298 checkDeliveredAmount.adjCountersSuccess();
299 env(
pay(gw, alice,
XRP(50)));
300 checkDeliveredAmount.adjCountersSuccess();
303 env(
pay(gw, bob, USD(9999999)),
txflags(tfPartialPayment));
304 checkDeliveredAmount.adjCountersPartialPayment();
309 checkDeliveredAmount.adjCountersFail();
314 jvParams[jss::ledger_index] = 4u;
315 jvParams[jss::transactions] =
true;
316 jvParams[jss::expand] =
true;
317 auto const jtxn = env.
rpc(
318 "json",
"ledger",
to_string(jvParams))[jss::result][jss::ledger][jss::transactions];
319 for (
auto const& t : jtxn)
320 BEAST_EXPECT(checkDeliveredAmount.checkTxn(t, t[jss::metaData]));
321 BEAST_EXPECT(checkDeliveredAmount.checkExpectedCounters());
334 Env env{*
this, features};
336 MPTTester mptAlice(env, alice, {.holders = {bob, carol}, .close =
false});
339 {.transferFee = 25000, .ownerCount = 1, .holderCount = 0, .flags = tfMPTCanTransfer});
340 auto const MPT = mptAlice[
"MPT"];
342 mptAlice.authorize({.account = bob});
343 mptAlice.authorize({.account = carol});
346 mptAlice.pay(alice, bob, 10000);
349 env(
pay(bob, carol, mptAlice.mpt(1000)),
txflags(tfPartialPayment));
354 Json::Value meta = env.rpc(
"tx", txHash)[jss::result][jss::meta];
356 if (features[fixMPTDeliveredAmount])
365 BEAST_EXPECT(!meta.
isMember(sfDeliveredAmount.jsonName));
366 BEAST_EXPECT(meta[jss::delivered_amount] =
Json::Value(
"unavailable"));
373 meta = env.rpc(
"tx", txHash)[jss::result][jss::meta];
375 if (features[fixMPTDeliveredAmount])
384 BEAST_EXPECT(!meta.
isMember(sfDeliveredAmount.jsonName));
385 BEAST_EXPECT(meta[jss::delivered_amount] =
Json::Value(
"unavailable"));
393 using namespace test::jtx;
404BEAST_DEFINE_TESTSUITE(DeliveredAmount,
rpc,
xrpl);
bool isMember(char const *key) const
Return true if the object has a member named key.
testcase_t testcase
Memberspace for declaring test cases.
virtual Config & config()=0
Json::Value getJson(JsonOptions=JsonOptions::none) const override
bool checkTxn(Json::Value const &t, Json::Value const &metaData)
void adjCountersSuccess()
CheckDeliveredAmount(bool afterSwitchTime)
bool checkExpectedCounters() const
int numExpectedSetUnavailable_
int numExpectedAvailable_
void adjCountersPartialPayment()
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)
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
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 require(Args const &... args)
Check a set of requirements.
void create(MPTCreate const &arg=MPTCreate{})
Converts to MPT Issue or STAmount.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Sets the SendMax on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
@ arrayValue
array value (ordered list)
XRP_t const XRP
Converts to XRP Issue or STAmount.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
FeatureBitset testable_amendments()
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
std::unique_ptr< WSClient > makeWSClient(Config const &cfg, bool v2, unsigned rpc_version, 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 to_string(base_uint< Bits, Tag > const &a)
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.