20 #include <ripple/beast/unit_test.h>
21 #include <ripple/protocol/ErrorCodes.h>
22 #include <ripple/protocol/jss.h>
25 #include <boost/container/flat_set.hpp>
39 boost::container::flat_set<std::string>
created;
40 boost::container::flat_set<std::string>
deleted;
41 boost::container::flat_set<std::string>
modified;
51 auto buildSet = [](
auto&& init){
52 boost::container::flat_set<std::string> r;
53 r.reserve(init.size());
69 BEAST_EXPECT(
txNode[jss::validated].asBool() ==
true);
75 boost::container::flat_set<std::string> createdNodes;
76 boost::container::flat_set<std::string> deletedNodes;
77 boost::container::flat_set<std::string> modifiedNodes;
93 modifiedNodes.insert (
98 fail (
"Unexpected or unlabeled node type in metadata.",
102 BEAST_EXPECT(createdNodes == sane.
created);
103 BEAST_EXPECT(deletedNodes == sane.
deleted);
104 BEAST_EXPECT(modifiedNodes == sane.
modified);
110 using namespace test::jtx;
121 return j.isMember(jss::result) &&
122 (j[jss::result][jss::status] ==
"success") &&
123 (j[jss::result][jss::transactions].size() == 2) &&
124 (j[jss::result][jss::transactions][0u][jss::tx]
125 [jss::TransactionType] == jss::AccountSet) &&
126 (j[jss::result][jss::transactions][1u][jss::tx]
127 [jss::TransactionType] == jss::Payment);
131 return j.isMember(jss::result) &&
132 (j[jss::result][jss::status] ==
"success") &&
133 (j[jss::result][jss::transactions].size() == 0);
138 j[jss::result].
isMember(jss::error) &&
148 jParms[jss::account] =
"0xDEADBEEF";
154 jParms[jss::account] = A1.human();
155 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(jParms))));
160 p[jss::ledger_index_min] = -1;
161 p[jss::ledger_index_max] = -1;
162 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
164 p[jss::ledger_index_min] = 0;
165 p[jss::ledger_index_max] = 100;
166 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
168 p[jss::ledger_index_min] = 1;
169 p[jss::ledger_index_max] = 2;
170 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
172 p[jss::ledger_index_min] = 2;
173 p[jss::ledger_index_max] = 1;
182 p[jss::ledger_index_min] = -1;
183 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
185 p[jss::ledger_index_min] = 1;
186 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
188 p[jss::ledger_index_min] = env.
current()->info().seq;
197 p[jss::ledger_index_max] = -1;
198 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
200 p[jss::ledger_index_max] = env.
current()->info().seq;
201 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
203 p[jss::ledger_index_max] = env.
closed()->info().seq;
204 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
206 p[jss::ledger_index_max] = env.
closed()->info().seq - 1 ;
207 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
214 p[jss::ledger_index] = env.
closed()->info().seq;
215 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
217 p[jss::ledger_index] = env.
closed()->info().seq - 1;
218 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
220 p[jss::ledger_index] = env.
current()->info().seq;
225 p[jss::ledger_index] = env.
current()->info().seq + 1;
236 BEAST_EXPECT(hasTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
239 BEAST_EXPECT(noTxs(env.
rpc(
"json",
"account_tx",
to_string(p))));
248 using namespace test::jtx;
249 using namespace std::chrono_literals;
255 auto const USD {gw[
"USD"]};
257 env.
fund(
XRP(1000000), alice, gw);
264 env (
pay (alice, gw,
XRP (100)));
267 env (
regkey(alice, alie));
271 env (
trust (alice, USD (200)),
sig (alie));
273 env (
offer (alice, USD (50),
XRP (150)),
sig (alie));
278 cancelOffer[jss::Account] = alice.human();
279 cancelOffer[jss::OfferSequence] = offerSeq;
280 cancelOffer[jss::TransactionType] = jss::OfferCancel;
281 env (cancelOffer,
sig (alie));
286 env (
signers (alice, 1, {{
"bogie", 1}, {
"demon", 1}}),
sig (alie));
291 auto escrow = [] (
Account const& account,
295 escro[jss::TransactionType] = jss::EscrowCreate;
297 escro[jss::Account] = account.human();
298 escro[jss::Destination] = to.human();
307 nextTime.time_since_epoch().count();
310 env (escrowWithFinish,
sig (alie));
314 nextTime.time_since_epoch().count();
316 nextTime.time_since_epoch().count() + 1;
319 env (escrowWithCancel,
sig (alie));
324 escrowFinish[jss::TransactionType] = jss::EscrowFinish;
326 escrowFinish[jss::Account] = alice.human();
329 env (escrowFinish,
sig (alie));
333 escrowCancel[jss::TransactionType] = jss::EscrowCancel;
335 escrowCancel[jss::Account] = alice.human();
338 env (escrowCancel,
sig (alie));
347 payChanCreate[jss::TransactionType] = jss::PaymentChannelCreate;
349 payChanCreate[jss::Account] = alice.human();
350 payChanCreate[jss::Destination] = gw.human();
351 payChanCreate[jss::Amount] =
356 env (payChanCreate,
sig (alie));
364 payChanFund[jss::TransactionType] = jss::PaymentChannelFund;
366 payChanFund[jss::Account] = alice.human();
368 payChanFund[jss::Amount] =
370 env (payChanFund,
sig (alie));
375 payChanClaim[jss::TransactionType] = jss::PaymentChannelClaim;
376 payChanClaim[jss::Flags] =
tfClose;
377 payChanClaim[jss::Account] = gw.human();
389 env (check::create (alice, gw,
XRP (300)),
sig (alie));
393 env (check::create (gw, alice,
XRP (200)));
396 env (check::cash (alice, gwCheckId,
XRP (200)),
sig (alie));
397 env (check::cancel (alice, aliceCheckId),
sig (alie));
402 env (deposit::auth (alice, gw),
sig (alie));
407 params[jss::account] = alice.human();
408 params[jss::ledger_index_min] = -1;
409 params[jss::ledger_index_max] = -1;
414 BEAST_EXPECT (result[jss::result][jss::status] ==
"success");
415 BEAST_EXPECT (result[jss::result][jss::transactions].isArray());
417 Json::Value const& txs {result[jss::result][jss::transactions]};
424 { 0, jss::DepositPreauth, {jss::DepositPreauth}, {}, {jss::AccountRoot, jss::DirectoryNode}},
425 { 1, jss::CheckCancel, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
426 { 2, jss::CheckCash, {}, {jss::Check}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
427 { 3, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
428 { 4, jss::CheckCreate, {jss::Check}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
429 { 5, jss::PaymentChannelClaim, {}, {jss::PayChannel}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
430 { 6, jss::PaymentChannelFund, {}, {}, {jss::AccountRoot, jss::PayChannel }},
431 { 7, jss::PaymentChannelCreate, {jss::PayChannel}, {}, {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
432 { 8, jss::EscrowCancel, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
433 { 9, jss::EscrowFinish, {}, {jss::Escrow}, {jss::AccountRoot, jss::DirectoryNode}},
434 { 10, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
435 { 11, jss::EscrowCreate, {jss::Escrow}, {}, {jss::AccountRoot, jss::DirectoryNode}},
436 { 12, jss::SignerListSet, {jss::SignerList}, {}, {jss::AccountRoot, jss::DirectoryNode}},
437 { 13, jss::OfferCancel, {}, {jss::Offer, jss::DirectoryNode}, {jss::AccountRoot, jss::DirectoryNode}},
438 { 14, jss::OfferCreate, {jss::Offer, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::DirectoryNode}},
439 { 15, jss::TrustSet, {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode}, {}, {jss::AccountRoot, jss::AccountRoot}},
440 { 16, jss::SetRegularKey, {}, {}, {jss::AccountRoot}},
441 { 17, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
442 { 18, jss::AccountSet, {}, {}, {jss::AccountRoot}},
443 { 19, jss::AccountSet, {}, {}, {jss::AccountRoot}},
444 { 20, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
447 BEAST_EXPECT (
std::extent<decltype (sanity)>::value ==
448 result[jss::result][jss::transactions].size());
450 for (
unsigned int index {0};
451 index <
std::extent<decltype (sanity)>::value; ++index)
463 using namespace test::jtx;
464 using namespace std::chrono_literals;
470 env.
fund(
XRP(10000), alice, becky);
475 BEAST_EXPECT (env.
closed()->exists (beckyAcctKey));
482 env.
current()->seq() + 257 - env.
seq (becky)};
487 auto const beckyPreDelBalance {env.
balance (becky)};
489 auto const acctDelFee {
drops (env.
current()->fees().increment)};
494 BEAST_EXPECT (! env.
closed()->exists (beckyAcctKey));
502 env (
pay (alice, becky,
XRP (45)));
506 BEAST_EXPECT (env.
closed()->exists (beckyAcctKey));
507 BEAST_EXPECT (env.
balance (becky) ==
XRP (45));
510 env (
pay (becky, alice,
XRP(20)));
516 params[jss::account] = becky.human();
517 params[jss::ledger_index_min] = -1;
518 params[jss::ledger_index_max] = -1;
523 BEAST_EXPECT (result[jss::result][jss::status] ==
"success");
524 BEAST_EXPECT (result[jss::result][jss::transactions].isArray());
526 Json::Value const& txs {result[jss::result][jss::transactions]};
533 { 0, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
534 { 1, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
535 { 2, jss::AccountDelete, {}, {jss::AccountRoot}, {jss::AccountRoot}},
536 { 3, jss::AccountSet, {}, {}, {jss::AccountRoot}},
537 { 4, jss::AccountSet, {}, {}, {jss::AccountRoot}},
538 { 5, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}}
541 BEAST_EXPECT (
std::extent<decltype (sanity)>::value ==
542 result[jss::result][jss::transactions].size());
544 for (
unsigned int index {0};
545 index <
std::extent<decltype (sanity)>::value; ++index)