20 #include <ripple/beast/unit_test.h> 
   21 #include <ripple/protocol/ErrorCodes.h> 
   22 #include <ripple/protocol/jss.h> 
   23 #include <ripple/rpc/impl/RPCHelpers.h> 
   26 #include <boost/container/flat_set.hpp> 
   40         boost::container::flat_set<std::string> 
created;
 
   41         boost::container::flat_set<std::string> 
deleted;
 
   42         boost::container::flat_set<std::string> 
modified;
 
   52             auto buildSet = [](
auto&& init) {
 
   53                 boost::container::flat_set<std::string> r;
 
   54                 r.reserve(init.size());
 
   70         BEAST_EXPECT(
txNode[jss::validated].asBool() == 
true);
 
   76         boost::container::flat_set<std::string> createdNodes;
 
   77         boost::container::flat_set<std::string> deletedNodes;
 
   78         boost::container::flat_set<std::string> modifiedNodes;
 
  100                     "Unexpected or unlabeled node type in metadata.",
 
  105         BEAST_EXPECT(createdNodes == sane.
created);
 
  106         BEAST_EXPECT(deletedNodes == sane.
deleted);
 
  107         BEAST_EXPECT(modifiedNodes == sane.
modified);
 
  113         using namespace test::jtx;
 
  124             return j.isMember(jss::result) &&
 
  125                 (j[jss::result][jss::status] == 
"success") &&
 
  126                 (j[jss::result][jss::transactions].size() == 2) &&
 
  127                 (j[jss::result][jss::transactions][0u][jss::tx]
 
  128                   [jss::TransactionType] == jss::AccountSet) &&
 
  129                 (j[jss::result][jss::transactions][1u][jss::tx]
 
  130                   [jss::TransactionType] == jss::Payment);
 
  134             return j.isMember(jss::result) &&
 
  135                 (j[jss::result][jss::status] == 
"success") &&
 
  136                 (j[jss::result][jss::transactions].size() == 0);
 
  141                 j[jss::result].
isMember(jss::error) &&
 
  151         jParms[jss::account] = 
"0xDEADBEEF";
 
  157         jParms[jss::account] = A1.human();
 
  158         BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(jParms))));
 
  163             p[jss::ledger_index_min] = -1;
 
  164             p[jss::ledger_index_max] = -1;
 
  165             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  167             p[jss::ledger_index_min] = 0;
 
  168             p[jss::ledger_index_max] = 100;
 
  169             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  171             p[jss::ledger_index_min] = 1;
 
  172             p[jss::ledger_index_max] = 2;
 
  173             BEAST_EXPECT(noTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  175             p[jss::ledger_index_min] = 2;
 
  176             p[jss::ledger_index_max] = 1;
 
  186             p[jss::ledger_index_min] = -1;
 
  187             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  189             p[jss::ledger_index_min] = 1;
 
  190             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  192             p[jss::ledger_index_min] = env.
current()->info().seq;
 
  202             p[jss::ledger_index_max] = -1;
 
  203             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  205             p[jss::ledger_index_max] = env.
current()->info().seq;
 
  206             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  208             p[jss::ledger_index_max] = env.
closed()->info().seq;
 
  209             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  211             p[jss::ledger_index_max] = env.
closed()->info().seq - 1;
 
  212             BEAST_EXPECT(noTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  219             p[jss::ledger_index] = env.
closed()->info().seq;
 
  220             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  222             p[jss::ledger_index] = env.
closed()->info().seq - 1;
 
  223             BEAST_EXPECT(noTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  225             p[jss::ledger_index] = env.
current()->info().seq;
 
  230             p[jss::ledger_index] = env.
current()->info().seq + 1;
 
  240             BEAST_EXPECT(hasTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  243             BEAST_EXPECT(noTxs(env.
rpc(
"json", 
"account_tx", 
to_string(p))));
 
  252         using namespace test::jtx;
 
  253         using namespace std::chrono_literals;
 
  259         auto const USD{gw[
"USD"]};
 
  261         env.
fund(
XRP(1000000), alice, gw);
 
  268         env(
pay(alice, gw, 
XRP(100)));
 
  275         env(
trust(alice, USD(200)), 
sig(alie));
 
  277         env(offer(alice, USD(50), 
XRP(150)), 
sig(alie));
 
  284         env(signers(alice, 1, {{
"bogie", 1}, {
"demon", 1}}), 
sig(alie));
 
  289             auto escrow = [](
Account const& account,
 
  293                 escro[jss::TransactionType] = jss::EscrowCreate;
 
  295                 escro[jss::Account] = account.human();
 
  296                 escro[jss::Destination] = to.human();
 
  305                 nextTime.time_since_epoch().count();
 
  308             env(escrowWithFinish, 
sig(alie));
 
  312                 nextTime.time_since_epoch().count();
 
  314                 nextTime.time_since_epoch().count() + 1;
 
  317             env(escrowWithCancel, 
sig(alie));
 
  322                 escrowFinish[jss::TransactionType] = jss::EscrowFinish;
 
  324                 escrowFinish[jss::Account] = alice.human();
 
  327                 env(escrowFinish, 
sig(alie));
 
  331                 escrowCancel[jss::TransactionType] = jss::EscrowCancel;
 
  333                 escrowCancel[jss::Account] = alice.human();
 
  336                 env(escrowCancel, 
sig(alie));
 
  345             payChanCreate[jss::TransactionType] = jss::PaymentChannelCreate;
 
  347             payChanCreate[jss::Account] = alice.human();
 
  348             payChanCreate[jss::Destination] = gw.human();
 
  349             payChanCreate[jss::Amount] =
 
  354             env(payChanCreate, 
sig(alie));
 
  362                 payChanFund[jss::TransactionType] = jss::PaymentChannelFund;
 
  364                 payChanFund[jss::Account] = alice.human();
 
  366                 payChanFund[jss::Amount] =
 
  368                 env(payChanFund, 
sig(alie));
 
  373                 payChanClaim[jss::TransactionType] = jss::PaymentChannelClaim;
 
  374                 payChanClaim[jss::Flags] = 
tfClose;
 
  375                 payChanClaim[jss::Account] = gw.human();
 
  386             env(check::create(alice, gw, 
XRP(300)), 
sig(alie));
 
  389             env(check::create(gw, alice, 
XRP(200)));
 
  392             env(check::cash(alice, gwCheckId, 
XRP(200)), 
sig(alie));
 
  393             env(check::cancel(alice, aliceCheckId), 
sig(alie));
 
  399             env(ticket::create(alice, 1), 
sig(alie));
 
  408         params[jss::account] = alice.human();
 
  409         params[jss::ledger_index_min] = -1;
 
  410         params[jss::ledger_index_max] = -1;
 
  415         BEAST_EXPECT(result[jss::result][jss::status] == 
"success");
 
  416         BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
 
  418         Json::Value const& txs{result[jss::result][jss::transactions]};
 
  425             {0,  jss::DepositPreauth,         {jss::DepositPreauth},                                      {jss::Ticket},                    {jss::AccountRoot, jss::DirectoryNode}},
 
  426             {1,  jss::TicketCreate,           {jss::Ticket},                                              {},                               {jss::AccountRoot, jss::DirectoryNode}},
 
  427             {2,  jss::CheckCancel,            {},                                                         {jss::Check},                     {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
 
  428             {3,  jss::CheckCash,              {},                                                         {jss::Check},                     {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
 
  429             {4,  jss::CheckCreate,            {jss::Check},                                               {},                               {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
 
  430             {5,  jss::CheckCreate,            {jss::Check},                                               {},                               {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
 
  431             {6,  jss::PaymentChannelClaim,    {},                                                         {jss::PayChannel},                {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
 
  432             {7,  jss::PaymentChannelFund,     {},                                                         {},                               {jss::AccountRoot, jss::PayChannel}},
 
  433             {8,  jss::PaymentChannelCreate,   {jss::PayChannel},                                          {},                               {jss::AccountRoot, jss::AccountRoot, jss::DirectoryNode, jss::DirectoryNode}},
 
  434             {9,  jss::EscrowCancel,           {},                                                         {jss::Escrow},                    {jss::AccountRoot, jss::DirectoryNode}},
 
  435             {10, jss::EscrowFinish,           {},                                                         {jss::Escrow},                    {jss::AccountRoot, jss::DirectoryNode}},
 
  436             {11, jss::EscrowCreate,           {jss::Escrow},                                              {},                               {jss::AccountRoot, jss::DirectoryNode}},
 
  437             {12, jss::EscrowCreate,           {jss::Escrow},                                              {},                               {jss::AccountRoot, jss::DirectoryNode}},
 
  438             {13, jss::SignerListSet,          {jss::SignerList},                                          {},                               {jss::AccountRoot, jss::DirectoryNode}},
 
  439             {14, jss::OfferCancel,            {},                                                         {jss::Offer, jss::DirectoryNode}, {jss::AccountRoot, jss::DirectoryNode}},
 
  440             {15, jss::OfferCreate,            {jss::Offer, jss::DirectoryNode},                           {},                               {jss::AccountRoot, jss::DirectoryNode}},
 
  441             {16, jss::TrustSet,               {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode}, {},                               {jss::AccountRoot, jss::AccountRoot}},
 
  442             {17, jss::SetRegularKey,          {},                                                         {},                               {jss::AccountRoot}},
 
  443             {18, jss::Payment,                {},                                                         {},                               {jss::AccountRoot, jss::AccountRoot}},
 
  444             {19, jss::AccountSet,             {},                                                         {},                               {jss::AccountRoot}},
 
  445             {20, jss::AccountSet,             {},                                                         {},                               {jss::AccountRoot}},
 
  446             {21, jss::Payment,                {jss::AccountRoot},                                         {},                               {jss::AccountRoot}},
 
  451             std::size(sanity) == result[jss::result][jss::transactions].size());
 
  453         for (
unsigned int index{0}; index < 
std::size(sanity); ++index)
 
  465         using namespace test::jtx;
 
  466         using namespace std::chrono_literals;
 
  472         env.
fund(
XRP(10000), alice, becky);
 
  477         BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
 
  489         auto const beckyPreDelBalance{env.
balance(becky)};
 
  491         auto const acctDelFee{
drops(env.
current()->fees().increment)};
 
  496         BEAST_EXPECT(!env.
closed()->exists(beckyAcctKey));
 
  508  { 0, jss::Payment,              {},                 {},                 {jss::AccountRoot, jss::AccountRoot}},
 
  509  { 1, jss::Payment,              {jss::AccountRoot}, {},                 {jss::AccountRoot}},
 
  510  { 2, jss::AccountDelete,        {},                 {jss::AccountRoot}, {jss::AccountRoot}},
 
  511  { 3, jss::AccountSet,           {},                 {},                 {jss::AccountRoot}},
 
  512  { 4, jss::AccountSet,           {},                 {},                 {jss::AccountRoot}},
 
  513  { 5, jss::Payment,              {jss::AccountRoot}, {},                 {jss::AccountRoot}}
 
  521             params[jss::account] = becky.human();
 
  522             params[jss::ledger_index_min] = -1;
 
  523             params[jss::ledger_index_max] = -1;
 
  528             BEAST_EXPECT(result[jss::result][jss::status] == 
"success");
 
  529             BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
 
  532             constexpr 
unsigned int beckyDeletedOffest = 2;
 
  535                 result[jss::result][jss::transactions].size() +
 
  538             Json::Value const& txs{result[jss::result][jss::transactions]};
 
  540             for (
unsigned int index = beckyDeletedOffest;
 
  544                 checkSanity(txs[index - beckyDeletedOffest], sanity[index]);
 
  557         env(
pay(alice, becky, 
XRP(45)));
 
  561         BEAST_EXPECT(env.
closed()->exists(beckyAcctKey));
 
  565         env(
pay(becky, alice, 
XRP(20)));
 
  571         params[jss::account] = becky.human();
 
  572         params[jss::ledger_index_min] = -1;
 
  573         params[jss::ledger_index_max] = -1;
 
  578         BEAST_EXPECT(result[jss::result][jss::status] == 
"success");
 
  579         BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
 
  582             std::size(sanity) == result[jss::result][jss::transactions].size());
 
  584         Json::Value const& txs{result[jss::result][jss::transactions]};
 
  586         for (
unsigned int index = 0; index < 
std::size(sanity); ++index)