2#include <test/jtx/TestHelpers.h> 
    3#include <test/jtx/utility.h> 
    5#include <xrpld/app/misc/HashRouter.h> 
    6#include <xrpld/app/misc/NetworkOPs.h> 
    7#include <xrpld/app/misc/Transaction.h> 
    8#include <xrpld/app/tx/apply.h> 
    9#include <xrpld/app/tx/detail/Batch.h> 
   11#include <xrpl/protocol/Batch.h> 
   12#include <xrpl/protocol/Feature.h> 
   13#include <xrpl/protocol/STParsedJSON.h> 
   14#include <xrpl/protocol/Sign.h> 
   15#include <xrpl/protocol/TxFlags.h> 
   16#include <xrpl/protocol/jss.h> 
   41        for (
auto const& txn : jrr[jss::result][jss::ledger][jss::transactions])
 
   43            if (txn[jss::metaData][sfTransactionIndex.jsonName] == index)
 
 
   53        params[jss::ledger_index] = env.
closed()->seq();
 
   54        params[jss::transactions] = 
true;
 
   55        params[jss::expand] = 
true;
 
 
   66        BEAST_EXPECT(jrr[sfTransactionType.jsonName] == ledgerResult.
txType);
 
   68            jrr[jss::meta][sfTransactionResult.jsonName] ==
 
   70        BEAST_EXPECT(jrr[jss::meta][sfParentBatchID.jsonName] == batchID);
 
 
   79        auto const transactions =
 
   80            jrr[jss::result][jss::ledger][jss::transactions];
 
   81        BEAST_EXPECT(transactions.size() == ledgerResults.
size());
 
   85            BEAST_EXPECT(txn[jss::hash].asString() == ledgerResult.txHash);
 
   86            BEAST_EXPECT(txn.isMember(jss::metaData));
 
   89                txn[sfTransactionType.jsonName] == ledgerResult.txType);
 
   91                meta[sfTransactionResult.jsonName] == ledgerResult.result);
 
   92            if (ledgerResult.batchID)
 
 
   97    template <
typename... Args>
 
  104        auto const ids = batchTxn.stx->getBatchTransactionIDs();
 
  106        for (
auto const& 
id : ids)
 
  108        TxID const batchID = batchTxn.stx->getTransactionID();
 
 
  124        auto& section = p->section(
"transaction_queue");
 
  125        section.set(
"ledgers_in_queue", 
"2");
 
  126        section.set(
"minimum_queue_size", 
"2");
 
  127        section.set(
"min_ledgers_to_compute_size_limit", 
"3");
 
  128        section.set(
"max_ledger_counts_to_store", 
"100");
 
  129        section.set(
"retry_sequence_percent", 
"25");
 
  130        section.set(
"normal_consensus_increase_percent", 
"0");
 
  132        for (
auto const& [k, v] : extraTxQ)
 
 
  143        auto const& view = *env.
current();
 
  145        return toDrops(metrics.openLedgerFeeLevel, batchFee) + 1;
 
 
  153        using namespace test::jtx;
 
  156        for (
bool const withBatch : {
true, 
false})
 
  158            auto const amend = withBatch ? features : features - featureBatch;
 
  161            auto const alice = 
Account(
"alice");
 
  162            auto const bob = 
Account(
"bob");
 
  163            auto const carol = 
Account(
"carol");
 
  164            env.fund(
XRP(10000), alice, bob, carol);
 
  169                auto const seq = env.
seq(alice);
 
  171                auto const txResult =
 
  185                auto const txResult =
 
  187                env(
pay(alice, bob, 
XRP(1)),
 
 
  202        using namespace test::jtx;
 
  210        auto const alice = 
Account(
"alice");
 
  211        auto const bob = 
Account(
"bob");
 
  212        auto const carol = 
Account(
"carol");
 
  213        env.fund(
XRP(10000), alice, bob, carol);
 
  226            auto const seq = env.
seq(alice);
 
  235            auto const seq = env.
seq(alice);
 
  244            auto const seq = env.
seq(alice);
 
  254            auto const seq = env.
seq(alice);
 
  263            auto const seq = env.
seq(alice);
 
  274            auto const seq = env.
seq(alice);
 
  293            auto const seq = env.
seq(alice);
 
  294            auto jt = env.jtnofill(
 
  306            auto const seq = env.
seq(alice);
 
  320            auto const seq = env.
seq(alice);
 
  323            auto jt = env.jtnofill(
 
  334            auto const seq = env.
seq(alice);
 
  336            auto jt = env.jt(
pay(alice, bob, 
XRP(1)));
 
  346            auto const seq = env.
seq(alice);
 
  348            auto tx1 = 
pay(alice, bob, 
XRP(1));
 
  351            tx1[sfSigners.jsonName][0U][sfSigner.jsonName][sfAccount.jsonName] =
 
  353            tx1[sfSigners.jsonName][0U][sfSigner.jsonName]
 
  354               [sfSigningPubKey.jsonName] = 
strHex(alice.pk());
 
  355            tx1[sfSigners.jsonName][0U][sfSigner.jsonName]
 
  356               [sfTxnSignature.jsonName] = 
"DEADBEEF";
 
  367            auto const seq = env.
seq(alice);
 
  370            tx1[jss::SigningPubKey] = 
strHex(alice.pk());
 
  371            auto jt = env.jtnofill(
 
  382            auto const seq = env.
seq(alice);
 
  394            auto const seq = env.
seq(alice);
 
  397            tx1[jss::Fee] = 
to_string(env.current()->fees().base);
 
  408            auto const seq = env.
seq(alice);
 
  411            tx1[jss::Sequence] = 
seq + 1;
 
  422            auto const seq = env.
seq(alice);
 
  433            auto const seq = env.
seq(alice);
 
  444            auto const seq = env.
seq(alice);
 
  455            auto const seq = env.
seq(alice);
 
  468            auto const seq = env.
seq(alice);
 
  490            auto const seq = env.
seq(alice);
 
  502            auto const seq = env.
seq(alice);
 
  515            auto const seq = env.
seq(alice);
 
  527            auto const seq = env.
seq(alice);
 
  539            auto const seq = env.
seq(alice);
 
  540            auto const bobSeq = env.seq(bob);
 
  542            auto jt = env.jtnofill(
 
  551            jt.jv[sfBatchSigners.jsonName][0u][sfBatchSigner.jsonName]
 
  552                 [sfAccount.jsonName] = bob.human();
 
  553            jt.jv[sfBatchSigners.jsonName][0u][sfBatchSigner.jsonName]
 
  554                 [sfSigningPubKey.jsonName] = 
strHex(alice.pk());
 
  555            jt.jv[sfBatchSigners.jsonName][0u][sfBatchSigner.jsonName]
 
  556                 [sfTxnSignature.jsonName] =
 
  565            auto const seq = env.
seq(alice);
 
 
  582        using namespace test::jtx;
 
  590        auto const alice = 
Account(
"alice");
 
  591        auto const bob = 
Account(
"bob");
 
  592        auto const carol = 
Account(
"carol");
 
  593        auto const dave = 
Account(
"dave");
 
  594        auto const elsa = 
Account(
"elsa");
 
  595        auto const frank = 
Account(
"frank");
 
  596        auto const phantom = 
Account(
"phantom");
 
  597        env.memoize(phantom);
 
  599        env.fund(
XRP(10000), alice, bob, carol, dave, elsa, frank);
 
  607            auto const seq = env.
seq(alice);
 
  622            auto const seq = env.
seq(alice);
 
  632        env(
signers(alice, 2, {{bob, 1}, {carol, 1}}));
 
  635        env(
signers(bob, 2, {{carol, 1}, {dave, 1}, {elsa, 1}}));
 
  640            auto const seq = env.
seq(alice);
 
  652            auto const seq = env.
seq(alice);
 
  657                batch::msig(bob, {carol, Account(
"dave", KeyType::ed25519)}),
 
  666            auto const seq = env.
seq(alice);
 
  678            auto const seq = env.
seq(alice);
 
  690            auto const seq = env.
seq(alice);
 
  704            auto const seq = env.
seq(alice);
 
  708                batch::inner(
pay(alice, bob, 
XRP(10)), seq + 1),
 
  709                batch::inner(
pay(bob, alice, 
XRP(5)), env.seq(bob)),
 
  710                batch::msig(bob, {carol, Reg{dave, davo}}),
 
  717            auto const seq = env.seq(alice);
 
  720                batch::inner(
pay(alice, bob, 
XRP(10)), seq + 1),
 
  721                batch::inner(
pay(bob, alice, 
XRP(5)), env.seq(bob)),
 
  722                batch::msig(bob, {carol}),
 
  729            auto const seq = env.seq(alice);
 
  732                batch::inner(
pay(alice, bob, 
XRP(10)), seq + 1),
 
  733                batch::inner(
pay(bob, alice, 
XRP(5)), env.seq(bob)),
 
  734                batch::msig(bob, {carol, dave}),
 
  741            auto const seq = env.seq(alice);
 
  744                batch::inner(
pay(alice, bob, 
XRP(10)), seq + 1),
 
  745                batch::inner(
pay(bob, alice, 
XRP(5)), env.seq(bob)),
 
  746                batch::msig(bob, {carol, dave}),
 
  757            auto const ledSeq = env.current()->seq();
 
  758            auto const seq = env.seq(alice);
 
  761                batch::inner(
pay(alice, phantom, 
XRP(1000)), seq + 1),
 
  762                batch::inner(
noop(phantom), ledSeq),
 
  763                batch::sig(Reg{phantom, carol}),
 
  770            auto const ledSeq = env.current()->seq();
 
  771            auto const seq = env.seq(alice);
 
  774                batch::inner(
pay(alice, bob, 
XRP(1000)), seq + 1),
 
  775                batch::inner(
noop(bob), ledSeq),
 
  776                batch::sig(Reg{bob, carol}),
 
  784            auto const seq = env.seq(alice);
 
  787                batch::inner(
pay(alice, bob, 
XRP(1)), seq + 1),
 
  788                batch::inner(
pay(bob, alice, 
XRP(2)), env.seq(bob)),
 
  789                batch::sig(Reg{bob, carol}),
 
  796            auto const seq = env.seq(alice);
 
  799                batch::inner(
pay(alice, bob, 
XRP(1)), seq + 1),
 
  800                batch::inner(
pay(bob, alice, 
XRP(2)), env.seq(bob)),
 
  810            auto const seq = env.seq(alice);
 
  813                batch::inner(
pay(alice, bob, 
XRP(1)), seq + 1),
 
  814                batch::inner(
pay(bob, alice, 
XRP(2)), env.seq(bob)),
 
 
  824        testcase(
"bad raw txn");
 
  826        using namespace test::jtx;
 
  831        auto const alice = 
Account(
"alice");
 
  832        auto const bob = 
Account(
"bob");
 
  834        env.fund(
XRP(10000), alice, bob);
 
  838            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
  839            auto const seq = env.
seq(alice);
 
  841            tx1.removeMember(jss::TransactionType);
 
  842            auto jt = env.jtnofill(
 
  853            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
  854            auto const seq = env.
seq(alice);
 
  856            tx1.removeMember(jss::Account);
 
  857            auto jt = env.jtnofill(
 
  868            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
  869            auto const seq = env.
seq(alice);
 
  871            tx1.removeMember(jss::Sequence);
 
  872            auto jt = env.jtnofill(
 
  883            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
  884            auto const seq = env.
seq(alice);
 
  886            tx1.removeMember(jss::Fee);
 
  887            auto jt = env.jtnofill(
 
  898            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
  899            auto const seq = env.
seq(alice);
 
  901            tx1.removeMember(jss::SigningPubKey);
 
  902            auto jt = env.jtnofill(
 
 
  915        testcase(
"bad sequence");
 
  917        using namespace test::jtx;
 
  922        auto const alice = 
Account(
"alice");
 
  923        auto const bob = 
Account(
"bob");
 
  925        auto const USD = gw[
"USD"];
 
  927        env.fund(
XRP(10000), alice, bob, gw);
 
  929        env.trust(USD(1000), alice, bob);
 
  930        env(pay(gw, alice, USD(100)));
 
  931        env(pay(gw, bob, USD(100)));
 
  939            auto const preAliceSeq = env.seq(alice);
 
  940            auto const preAlice = env.balance(alice);
 
  941            auto const preAliceUSD = env.balance(alice, USD.issue());
 
  942            auto const preBobSeq = env.seq(bob);
 
  943            auto const preBob = env.balance(bob);
 
  944            auto const preBobUSD = env.balance(bob, USD.issue());
 
  946            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
  947            auto const [txIDs, batchID] = submitBatch(
 
  960                validateClosedLedger(env, testCases);
 
  967                validateClosedLedger(env, testCases);
 
  971            BEAST_EXPECT(env.seq(alice) == preAliceSeq + 1);
 
  972            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
  973            BEAST_EXPECT(env.balance(alice, USD.issue()) == preAliceUSD);
 
  974            BEAST_EXPECT(env.seq(bob) == preBobSeq);
 
  975            BEAST_EXPECT(env.balance(bob) == preBob);
 
  976            BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD);
 
  981            auto const preAliceSeq = env.seq(alice);
 
  982            auto const preAlice = env.balance(alice);
 
  983            auto const preAliceUSD = env.balance(alice, USD.issue());
 
  984            auto const preBobSeq = env.seq(bob);
 
  985            auto const preBob = env.balance(bob);
 
  986            auto const preBobUSD = env.balance(bob, USD.issue());
 
  988            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
  989            auto const [txIDs, batchID] = submitBatch(
 
 1002                validateClosedLedger(env, testCases);
 
 1009                validateClosedLedger(env, testCases);
 
 1013            BEAST_EXPECT(env.seq(alice) == preAliceSeq + 1);
 
 1014            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1015            BEAST_EXPECT(env.balance(alice, USD.issue()) == preAliceUSD);
 
 1016            BEAST_EXPECT(env.seq(bob) == preBobSeq);
 
 1017            BEAST_EXPECT(env.balance(bob) == preBob);
 
 1018            BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD);
 
 1023            auto const preAliceSeq = env.seq(alice);
 
 1024            auto const preAlice = env.balance(alice);
 
 1025            auto const preAliceUSD = env.balance(alice, USD.issue());
 
 1026            auto const preBobSeq = env.seq(bob);
 
 1027            auto const preBob = env.balance(bob);
 
 1028            auto const preBobUSD = env.balance(bob, USD.issue());
 
 1030            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 1031            auto const [txIDs, batchID] = submitBatch(
 
 1044                validateClosedLedger(env, testCases);
 
 1051                validateClosedLedger(env, testCases);
 
 1055            BEAST_EXPECT(env.seq(alice) == preAliceSeq + 1);
 
 1056            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1057            BEAST_EXPECT(env.balance(alice, USD.issue()) == preAliceUSD);
 
 1058            BEAST_EXPECT(env.seq(bob) == preBobSeq);
 
 1059            BEAST_EXPECT(env.balance(bob) == preBob);
 
 1060            BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD);
 
 1065            auto const preAliceSeq = env.seq(alice);
 
 1066            auto const preAlice = env.balance(alice);
 
 1067            auto const preAliceUSD = env.balance(alice, USD.issue());
 
 1068            auto const preBobSeq = env.seq(bob);
 
 1069            auto const preBob = env.balance(bob);
 
 1070            auto const preBobUSD = env.balance(bob, USD.issue());
 
 1072            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 1073            auto const [txIDs, batchID] = submitBatch(
 
 1086                validateClosedLedger(env, testCases);
 
 1093                validateClosedLedger(env, testCases);
 
 1097            BEAST_EXPECT(env.seq(alice) == preAliceSeq + 1);
 
 1098            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1099            BEAST_EXPECT(env.balance(alice, USD.issue()) == preAliceUSD);
 
 1100            BEAST_EXPECT(env.seq(bob) == preBobSeq);
 
 1101            BEAST_EXPECT(env.balance(bob) == preBob);
 
 1102            BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD);
 
 1107            auto const preAliceSeq = env.seq(alice);
 
 1108            auto const preAlice = env.balance(alice);
 
 1109            auto const preAliceUSD = env.balance(alice, USD.issue());
 
 1110            auto const preBobSeq = env.seq(bob);
 
 1111            auto const preBob = env.balance(bob);
 
 1112            auto const preBobUSD = env.balance(bob, USD.issue());
 
 1114            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 1115            auto const [txIDs, batchID] = submitBatch(
 
 1128                validateClosedLedger(env, testCases);
 
 1135                validateClosedLedger(env, testCases);
 
 1139            BEAST_EXPECT(env.seq(alice) == preAliceSeq + 1);
 
 1140            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1141            BEAST_EXPECT(env.balance(alice, USD.issue()) == preAliceUSD);
 
 1142            BEAST_EXPECT(env.seq(bob) == preBobSeq);
 
 1143            BEAST_EXPECT(env.balance(bob) == preBob);
 
 1144            BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD);
 
 
 1151        testcase(
"bad outer fee");
 
 1153        using namespace test::jtx;
 
 1160            auto const alice = 
Account(
"alice");
 
 1161            auto const bob = 
Account(
"bob");
 
 1162            env.fund(
XRP(10000), alice, bob);
 
 1169            auto const batchFee = batch::calcBatchFee(env, 0, 1);
 
 1170            auto const aliceSeq = env.seq(alice);
 
 1182            auto const alice = 
Account(
"alice");
 
 1183            auto const bob = 
Account(
"bob");
 
 1184            auto const carol = 
Account(
"carol");
 
 1185            env.fund(
XRP(10000), alice, bob, carol);
 
 1191            env(signers(alice, 2, {{bob, 1}, {carol, 1}}));
 
 1195            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 1196            auto const aliceSeq = env.seq(alice);
 
 1209            auto const alice = 
Account(
"alice");
 
 1210            auto const bob = 
Account(
"bob");
 
 1211            auto const carol = 
Account(
"carol");
 
 1212            env.fund(
XRP(10000), alice, bob, carol);
 
 1218            env(signers(alice, 2, {{bob, 1}, {carol, 1}}));
 
 1222            auto const batchFee = batch::calcBatchFee(env, 2, 2);
 
 1223            auto const aliceSeq = env.seq(alice);
 
 1224            auto const bobSeq = env.seq(bob);
 
 1238            auto const alice = 
Account(
"alice");
 
 1239            auto const bob = 
Account(
"bob");
 
 1240            auto const carol = 
Account(
"carol");
 
 1241            env.fund(
XRP(10000), alice, bob, carol);
 
 1247            env(signers(alice, 2, {{bob, 1}, {carol, 1}}));
 
 1250            env(signers(bob, 2, {{alice, 1}, {carol, 1}}));
 
 1254            auto const batchFee = batch::calcBatchFee(env, 3, 2);
 
 1255            auto const aliceSeq = env.seq(alice);
 
 1256            auto const bobSeq = env.seq(bob);
 
 1270            auto const alice = 
Account(
"alice");
 
 1271            auto const bob = 
Account(
"bob");
 
 1272            env.fund(
XRP(10000), alice, bob);
 
 1279            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 1280            auto const aliceSeq = env.seq(alice);
 
 1281            auto const bobSeq = env.seq(bob);
 
 1294            auto const alice = 
Account(
"alice");
 
 1295            auto const bob = 
Account(
"bob");
 
 1296            auto const gw = 
Account(
"gw");
 
 1297            auto const USD = gw[
"USD"];
 
 1299            env.fund(
XRP(10000), alice, bob, gw);
 
 1301            auto const ammCreate =
 
 1304                    jv[jss::Account] = alice.human();
 
 1307                    jv[jss::TradingFee] = 0;
 
 1308                    jv[jss::TransactionType] = jss::AMMCreate;
 
 1312            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 1313            auto const seq = env.
seq(alice);
 
 
 1325        testcase(
"calculate base fee");
 
 1327        using namespace test::jtx;
 
 1334            auto const alice = 
Account(
"alice");
 
 1335            auto const bob = 
Account(
"bob");
 
 1336            env.fund(
XRP(10000), alice, bob);
 
 1339            auto const batchFee = batch::calcBatchFee(env, 0, 9);
 
 1340            auto const aliceSeq = env.seq(alice);
 
 1359            auto const alice = 
Account(
"alice");
 
 1360            auto const bob = 
Account(
"bob");
 
 1361            env.fund(
XRP(10000), alice, bob);
 
 1364            auto const batchFee = batch::calcBatchFee(env, 0, 9);
 
 1365            auto const aliceSeq = env.seq(alice);
 
 1366            auto jt = env.jtnofill(
 
 1378            env.app().openLedger().modify(
 
 1384                    return result.applied;
 
 1392            auto const alice = 
Account(
"alice");
 
 1393            auto const bob = 
Account(
"bob");
 
 1394            env.fund(
XRP(10000), alice, bob);
 
 1397            auto const aliceSeq = env.seq(alice);
 
 1398            auto const batchFee = batch::calcBatchFee(env, 9, 2);
 
 1402                batch::sig(bob, bob, bob, bob, bob, bob, bob, bob, bob, bob),
 
 1411            auto const alice = 
Account(
"alice");
 
 1412            auto const bob = 
Account(
"bob");
 
 1413            env.fund(
XRP(10000), alice, bob);
 
 1416            auto const batchFee = batch::calcBatchFee(env, 0, 9);
 
 1417            auto const aliceSeq = env.seq(alice);
 
 1418            auto jt = env.jtnofill(
 
 1422                batch::sig(bob, bob, bob, bob, bob, bob, bob, bob, bob, bob));
 
 1424            env.app().openLedger().modify(
 
 1430                    return result.applied;
 
 
 1438        testcase(
"all or nothing");
 
 1440        using namespace test::jtx;
 
 1445        auto const alice = 
Account(
"alice");
 
 1446        auto const bob = 
Account(
"bob");
 
 1447        auto const gw = 
Account(
"gw");
 
 1448        auto const USD = gw[
"USD"];
 
 1449        env.fund(
XRP(10000), alice, bob, gw);
 
 1454            auto const preAlice = env.balance(alice);
 
 1455            auto const preBob = env.balance(bob);
 
 1457            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 1458            auto const seq = env.
seq(alice);
 
 1459            auto const [txIDs, batchID] = submitBatch(
 
 1469                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 1470                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 1472            validateClosedLedger(env, testCases);
 
 1475            BEAST_EXPECT(env.seq(alice) == 
seq + 3);
 
 1478            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(3) - batchFee);
 
 1479            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 1484            auto const preAlice = env.balance(alice);
 
 1485            auto const preBob = env.balance(bob);
 
 1487            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 1488            auto const seq = env.
seq(alice);
 
 1490            auto const [txIDs, batchID] = submitBatch(
 
 1502            validateClosedLedger(env, testCases);
 
 1505            BEAST_EXPECT(env.seq(alice) == 
seq + 1);
 
 1508            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1509            BEAST_EXPECT(env.balance(bob) == preBob);
 
 1514            auto const preAlice = env.balance(alice);
 
 1515            auto const preBob = env.balance(bob);
 
 1517            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 1518            auto const seq = env.
seq(alice);
 
 1519            auto const [txIDs, batchID] = submitBatch(
 
 1531            validateClosedLedger(env, testCases);
 
 1534            BEAST_EXPECT(env.seq(alice) == 
seq + 1);
 
 1537            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1538            BEAST_EXPECT(env.balance(bob) == preBob);
 
 1543            auto const preAlice = env.balance(alice);
 
 1544            auto const preBob = env.balance(bob);
 
 1546            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 1547            auto const seq = env.
seq(alice);
 
 1548            auto const [txIDs, batchID] = submitBatch(
 
 1560            validateClosedLedger(env, testCases);
 
 1563            BEAST_EXPECT(env.seq(alice) == 
seq + 1);
 
 1566            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1567            BEAST_EXPECT(env.balance(bob) == preBob);
 
 
 1574        testcase(
"only one");
 
 1576        using namespace test::jtx;
 
 1581        auto const alice = 
Account(
"alice");
 
 1582        auto const bob = 
Account(
"bob");
 
 1583        auto const carol = 
Account(
"carol");
 
 1584        auto const dave = 
Account(
"dave");
 
 1585        auto const gw = 
Account(
"gw");
 
 1586        auto const USD = gw[
"USD"];
 
 1587        env.fund(
XRP(10000), alice, bob, carol, dave, gw);
 
 1592            auto const preAlice = env.balance(alice);
 
 1593            auto const preBob = env.balance(bob);
 
 1595            auto const batchFee = batch::calcBatchFee(env, 0, 3);
 
 1596            auto const seq = env.
seq(alice);
 
 1597            auto const [txIDs, batchID] = submitBatch(
 
 1611                {1, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[0], batchID},
 
 1612                {2, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[1], batchID},
 
 1613                {3, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[2], batchID},
 
 1615            validateClosedLedger(env, testCases);
 
 1618            BEAST_EXPECT(env.seq(alice) == 
seq + 4);
 
 1621            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1622            BEAST_EXPECT(env.balance(bob) == preBob);
 
 1627            auto const preAlice = env.balance(alice);
 
 1628            auto const preBob = env.balance(bob);
 
 1630            auto const batchFee = batch::calcBatchFee(env, 0, 3);
 
 1631            auto const seq = env.
seq(alice);
 
 1632            auto const [txIDs, batchID] = submitBatch(
 
 1644                {1, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[0], batchID},
 
 1645                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 1647            validateClosedLedger(env, testCases);
 
 1650            BEAST_EXPECT(env.seq(alice) == 
seq + 3);
 
 1653            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(1) - batchFee);
 
 1654            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(1));
 
 1659            auto const preAlice = env.balance(alice);
 
 1660            auto const preBob = env.balance(bob);
 
 1662            auto const batchFee = batch::calcBatchFee(env, 0, 3);
 
 1663            auto const seq = env.
seq(alice);
 
 1664            auto const [txIDs, batchID] = submitBatch(
 
 1676                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 1678            validateClosedLedger(env, testCases);
 
 1681            BEAST_EXPECT(env.seq(alice) == 
seq + 2);
 
 1684            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(1) - batchFee);
 
 1685            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(1));
 
 1690            auto const preAlice = env.balance(alice);
 
 1691            auto const preBob = env.balance(bob);
 
 1693            auto const batchFee = batch::calcBatchFee(env, 0, 3);
 
 1694            auto const seq = env.
seq(alice);
 
 1695            auto const [txIDs, batchID] = submitBatch(
 
 1707                {1, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 1709            validateClosedLedger(env, testCases);
 
 1712            BEAST_EXPECT(env.seq(alice) == 
seq + 2);
 
 1715            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee - 
XRP(1));
 
 1716            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(1));
 
 1721            auto const preAlice = env.balance(alice);
 
 1722            auto const preBob = env.balance(bob);
 
 1724            auto const batchFee = batch::calcBatchFee(env, 0, 3);
 
 1725            auto const seq = env.
seq(alice);
 
 1726            auto const [txIDs, batchID] = submitBatch(
 
 1738                {1, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 1740            validateClosedLedger(env, testCases);
 
 1743            BEAST_EXPECT(env.seq(alice) == 
seq + 2);
 
 1746            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee - 
XRP(1));
 
 1747            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(1));
 
 1752            auto const preAlice = env.balance(alice);
 
 1753            auto const preBob = env.balance(bob);
 
 1754            auto const preCarol = env.balance(carol);
 
 1755            auto const seq = env.
seq(alice);
 
 1756            auto const batchFee = batch::calcBatchFee(env, 0, 6);
 
 1758            auto const [txIDs, batchID] = submitBatch(
 
 1790                {1, 
"OfferCreate", 
"tecKILLED", txIDs[0], batchID},
 
 1791                {2, 
"OfferCreate", 
"tecKILLED", txIDs[1], batchID},
 
 1792                {3, 
"OfferCreate", 
"tecKILLED", txIDs[2], batchID},
 
 1793                {4, 
"Payment", 
"tesSUCCESS", txIDs[3], batchID},
 
 1795            validateClosedLedger(env, testCases);
 
 1797            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(100) - batchFee);
 
 1798            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(100));
 
 1799            BEAST_EXPECT(env.balance(carol) == preCarol);
 
 
 1806        testcase(
"until failure");
 
 1808        using namespace test::jtx;
 
 1813        auto const alice = 
Account(
"alice");
 
 1814        auto const bob = 
Account(
"bob");
 
 1815        auto const carol = 
Account(
"carol");
 
 1816        auto const dave = 
Account(
"dave");
 
 1817        auto const gw = 
Account(
"gw");
 
 1818        auto const USD = gw[
"USD"];
 
 1819        env.fund(
XRP(10000), alice, bob, carol, dave, gw);
 
 1824            auto const preAlice = env.balance(alice);
 
 1825            auto const preBob = env.balance(bob);
 
 1827            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 1828            auto const seq = env.
seq(alice);
 
 1829            auto const [txIDs, batchID] = submitBatch(
 
 1842                {1, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[0], batchID},
 
 1844            validateClosedLedger(env, testCases);
 
 1847            BEAST_EXPECT(env.seq(alice) == 
seq + 2);
 
 1850            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 1851            BEAST_EXPECT(env.balance(bob) == preBob);
 
 1856            auto const preAlice = env.balance(alice);
 
 1857            auto const preBob = env.balance(bob);
 
 1859            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 1860            auto const seq = env.
seq(alice);
 
 1861            auto const [txIDs, batchID] = submitBatch(
 
 1873                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 1874                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 1875                {3, 
"Payment", 
"tesSUCCESS", txIDs[2], batchID},
 
 1876                {4, 
"Payment", 
"tesSUCCESS", txIDs[3], batchID},
 
 1878            validateClosedLedger(env, testCases);
 
 1881            BEAST_EXPECT(env.seq(alice) == 
seq + 5);
 
 1884            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(10) - batchFee);
 
 1885            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(10));
 
 1890            auto const preAlice = env.balance(alice);
 
 1891            auto const preBob = env.balance(bob);
 
 1893            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 1894            auto const seq = env.
seq(alice);
 
 1895            auto const [txIDs, batchID] = submitBatch(
 
 1908                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 1909                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 1910                {3, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[2], batchID},
 
 1912            validateClosedLedger(env, testCases);
 
 1915            BEAST_EXPECT(env.seq(alice) == 
seq + 4);
 
 1918            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(3) - batchFee);
 
 1919            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 1924            auto const preAlice = env.balance(alice);
 
 1925            auto const preBob = env.balance(bob);
 
 1927            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 1928            auto const seq = env.
seq(alice);
 
 1929            auto const [txIDs, batchID] = submitBatch(
 
 1942                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 1943                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 1945            validateClosedLedger(env, testCases);
 
 1948            BEAST_EXPECT(env.seq(alice) == 
seq + 3);
 
 1951            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(3) - batchFee);
 
 1952            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 1957            auto const preAlice = env.balance(alice);
 
 1958            auto const preBob = env.balance(bob);
 
 1960            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 1961            auto const seq = env.
seq(alice);
 
 1962            auto const [txIDs, batchID] = submitBatch(
 
 1975                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 1976                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 1978            validateClosedLedger(env, testCases);
 
 1981            BEAST_EXPECT(env.seq(alice) == 
seq + 3);
 
 1984            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(3) - batchFee);
 
 1985            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 1990            auto const preAlice = env.balance(alice);
 
 1991            auto const preBob = env.balance(bob);
 
 1992            auto const preCarol = env.balance(carol);
 
 1993            auto const seq = env.
seq(alice);
 
 1994            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 1995            auto const [txIDs, batchID] = submitBatch(
 
 2013                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2014                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2015                {3, 
"OfferCreate", 
"tecKILLED", txIDs[2], batchID},
 
 2017            validateClosedLedger(env, testCases);
 
 2019            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(200) - batchFee);
 
 2020            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(100));
 
 2021            BEAST_EXPECT(env.balance(carol) == preCarol + 
XRP(100));
 
 
 2028        testcase(
"independent");
 
 2030        using namespace test::jtx;
 
 2035        auto const alice = 
Account(
"alice");
 
 2036        auto const bob = 
Account(
"bob");
 
 2037        auto const carol = 
Account(
"carol");
 
 2038        auto const gw = 
Account(
"gw");
 
 2039        auto const USD = gw[
"USD"];
 
 2040        env.fund(
XRP(10000), alice, bob, carol, gw);
 
 2045            auto const preAlice = env.balance(alice);
 
 2046            auto const preBob = env.balance(bob);
 
 2048            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 2049            auto const seq = env.
seq(alice);
 
 2050            auto const [txIDs, batchID] = submitBatch(
 
 2064                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2065                {2, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[1], batchID},
 
 2066                {3, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[2], batchID},
 
 2067                {4, 
"Payment", 
"tesSUCCESS", txIDs[3], batchID},
 
 2069            validateClosedLedger(env, testCases);
 
 2072            BEAST_EXPECT(env.seq(alice) == 
seq + 5);
 
 2075            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(4) - batchFee);
 
 2076            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(4));
 
 2081            auto const preAlice = env.balance(alice);
 
 2082            auto const preBob = env.balance(bob);
 
 2084            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 2085            auto const seq = env.
seq(alice);
 
 2086            auto const [txIDs, batchID] = submitBatch(
 
 2099                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2100                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2101                {3, 
"Payment", 
"tecUNFUNDED_PAYMENT", txIDs[2], batchID},
 
 2102                {4, 
"Payment", 
"tesSUCCESS", txIDs[3], batchID},
 
 2104            validateClosedLedger(env, testCases);
 
 2107            BEAST_EXPECT(env.seq(alice) == 
seq + 5);
 
 2110            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(6) - batchFee);
 
 2111            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(6));
 
 2116            auto const preAlice = env.balance(alice);
 
 2117            auto const preBob = env.balance(bob);
 
 2119            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 2120            auto const seq = env.
seq(alice);
 
 2121            auto const [txIDs, batchID] = submitBatch(
 
 2134                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2135                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2136                {3, 
"Payment", 
"tesSUCCESS", txIDs[3], batchID},
 
 2138            validateClosedLedger(env, testCases);
 
 2141            BEAST_EXPECT(env.seq(alice) == 
seq + 4);
 
 2144            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee - 
XRP(6));
 
 2145            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(6));
 
 2150            auto const preAlice = env.balance(alice);
 
 2151            auto const preBob = env.balance(bob);
 
 2153            auto const batchFee = batch::calcBatchFee(env, 0, 4);
 
 2154            auto const seq = env.
seq(alice);
 
 2155            auto const [txIDs, batchID] = submitBatch(
 
 2168                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2169                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2170                {3, 
"Payment", 
"tesSUCCESS", txIDs[3], batchID},
 
 2172            validateClosedLedger(env, testCases);
 
 2175            BEAST_EXPECT(env.seq(alice) == 
seq + 4);
 
 2178            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee - 
XRP(6));
 
 2179            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(6));
 
 2184            auto const preAlice = env.balance(alice);
 
 2185            auto const preBob = env.balance(bob);
 
 2186            auto const preCarol = env.balance(carol);
 
 2187            auto const seq = env.
seq(alice);
 
 2188            auto const batchFee = batch::calcBatchFee(env, 0, 3);
 
 2189            auto const [txIDs, batchID] = submitBatch(
 
 2206                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2207                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2208                {3, 
"OfferCreate", 
"tecKILLED", txIDs[2], batchID},
 
 2210            validateClosedLedger(env, testCases);
 
 2212            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(200) - batchFee);
 
 2213            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(100));
 
 2214            BEAST_EXPECT(env.balance(carol) == preCarol + 
XRP(100));
 
 
 2221        testcase(
"inner submit rpc");
 
 2223        using namespace test::jtx;
 
 2228        auto const alice = 
Account(
"alice");
 
 2229        auto const bob = 
Account(
"bob");
 
 2231        env.fund(
XRP(10000), alice, bob);
 
 2234        auto submitAndValidate = [&](
Slice const& 
slice) {
 
 2235            auto const jrr = env.rpc(
"submit", 
strHex(
slice))[jss::result];
 
 2237                jrr[jss::status] == 
"error" &&
 
 2238                jrr[jss::error] == 
"invalidTransaction" &&
 
 2239                jrr[jss::error_exception] ==
 
 2240                    "fails local checks: Malformed: Invalid inner batch " 
 2252            txn[sfTxnSignature] = 
"DEADBEEF";
 
 2256            submitAndValidate(s.
slice());
 
 2266            txn[sfSigningPubKey] = 
strHex(alice.pk());
 
 2270            submitAndValidate(s.
slice());
 
 2284            submitAndValidate(s.
slice());
 
 2297            auto const jrr = env.rpc(
"submit", 
strHex(s.
slice()))[jss::result];
 
 2299                jrr[jss::status] == 
"success" &&
 
 2300                jrr[jss::engine_result] == 
"temINVALID_FLAG");
 
 
 2309        testcase(
"account activation");
 
 2311        using namespace test::jtx;
 
 2316        auto const alice = 
Account(
"alice");
 
 2317        auto const bob = 
Account(
"bob");
 
 2318        env.fund(
XRP(10000), alice);
 
 2322        auto const preAlice = env.balance(alice);
 
 2323        auto const ledSeq = env.current()->seq();
 
 2324        auto const seq = env.
seq(alice);
 
 2325        auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 2326        auto const [txIDs, batchID] = submitBatch(
 
 2337            {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2338            {2, 
"AccountSet", 
"tesSUCCESS", txIDs[1], batchID},
 
 2340        validateClosedLedger(env, testCases);
 
 2343        BEAST_EXPECT(env.seq(alice) == 
seq + 2);
 
 2346        BEAST_EXPECT(env.seq(bob) == ledSeq + 1);
 
 2349        BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(1000) - batchFee);
 
 2350        BEAST_EXPECT(env.balance(bob) == 
XRP(1000));
 
 
 2356        testcase(
"account set");
 
 2358        using namespace test::jtx;
 
 2363        auto const alice = 
Account(
"alice");
 
 2364        auto const bob = 
Account(
"bob");
 
 2365        env.fund(
XRP(10000), alice, bob);
 
 2368        auto const preAlice = env.balance(alice);
 
 2369        auto const preBob = env.balance(bob);
 
 2371        auto const seq = env.
seq(alice);
 
 2372        auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 2376        auto const [txIDs, batchID] = submitBatch(
 
 2386            {1, 
"AccountSet", 
"tesSUCCESS", txIDs[0], batchID},
 
 2387            {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2389        validateClosedLedger(env, testCases);
 
 2397        BEAST_EXPECT(env.seq(alice) == 
seq + 3);
 
 2400        BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(1) - batchFee);
 
 2401        BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(1));
 
 
 2407        testcase(
"account delete");
 
 2409        using namespace test::jtx;
 
 2416            auto const alice = 
Account(
"alice");
 
 2417            auto const bob = 
Account(
"bob");
 
 2418            env.fund(
XRP(10000), alice, bob);
 
 2422            for (
int i = 0; i < 5; ++i)
 
 2425            auto const preAlice = env.balance(alice);
 
 2426            auto const preBob = env.balance(bob);
 
 2428            auto const seq = env.
seq(alice);
 
 2429            auto const batchFee = batch::calcBatchFee(env, 0, 2) +
 
 2430                env.current()->fees().increment;
 
 2431            auto const [txIDs, batchID] = submitBatch(
 
 2443                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2444                {2, 
"AccountDelete", 
"tesSUCCESS", txIDs[1], batchID},
 
 2446            validateClosedLedger(env, testCases);
 
 2450            BEAST_EXPECT(env.balance(bob) == preBob + (preAlice - batchFee));
 
 2457            auto const alice = 
Account(
"alice");
 
 2458            auto const bob = 
Account(
"bob");
 
 2459            env.fund(
XRP(10000), alice, bob);
 
 2463            for (
int i = 0; i < 5; ++i)
 
 2466            auto const preAlice = env.balance(alice);
 
 2467            auto const preBob = env.balance(bob);
 
 2469            env.trust(bob[
"USD"](1000), alice);
 
 2472            auto const seq = env.
seq(alice);
 
 2473            auto const batchFee = batch::calcBatchFee(env, 0, 2) +
 
 2474                env.current()->fees().increment;
 
 2475            auto const [txIDs, batchID] = submitBatch(
 
 2487                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2488                {2, 
"AccountDelete", 
"tecHAS_OBLIGATIONS", txIDs[1], batchID},
 
 2489                {3, 
"Payment", 
"tesSUCCESS", txIDs[2], batchID},
 
 2491            validateClosedLedger(env, testCases);
 
 2495            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 2502            auto const alice = 
Account(
"alice");
 
 2503            auto const bob = 
Account(
"bob");
 
 2504            env.fund(
XRP(10000), alice, bob);
 
 2508            for (
int i = 0; i < 5; ++i)
 
 2511            auto const preAlice = env.balance(alice);
 
 2512            auto const preBob = env.balance(bob);
 
 2514            auto const seq = env.
seq(alice);
 
 2515            auto const batchFee = batch::calcBatchFee(env, 0, 2) +
 
 2516                env.current()->fees().increment;
 
 2517            auto const [txIDs, batchID] = submitBatch(
 
 2530            validateClosedLedger(env, testCases);
 
 2534            BEAST_EXPECT(env.balance(bob) == preBob);
 
 
 2541        testcase(
"object create w/ sequence");
 
 2543        using namespace test::jtx;
 
 2548        auto const alice = 
Account(
"alice");
 
 2549        auto const bob = 
Account(
"bob");
 
 2550        auto const gw = 
Account(
"gw");
 
 2551        auto const USD = gw[
"USD"];
 
 2553        env.fund(
XRP(10000), alice, bob, gw);
 
 2556        env.trust(USD(1000), alice, bob);
 
 2557        env(pay(gw, alice, USD(100)));
 
 2558        env(pay(gw, bob, USD(100)));
 
 2563            auto const aliceSeq = env.seq(alice);
 
 2564            auto const bobSeq = env.seq(bob);
 
 2565            auto const preAlice = env.balance(alice);
 
 2566            auto const preBob = env.balance(bob);
 
 2567            auto const preAliceUSD = env.balance(alice, USD.issue());
 
 2568            auto const preBobUSD = env.balance(bob, USD.issue());
 
 2570            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 2571            uint256 const chkID{getCheckIndex(bob, env.seq(bob))};
 
 2572            auto const [txIDs, batchID] = submitBatch(
 
 2576                batch::inner(check::create(bob, alice, USD(10)), bobSeq),
 
 2577                batch::inner(check::cash(alice, chkID, USD(10)), aliceSeq + 1),
 
 2583                {1, 
"CheckCreate", 
"tesSUCCESS", txIDs[0], batchID},
 
 2584                {2, 
"CheckCash", 
"tesSUCCESS", txIDs[1], batchID},
 
 2586            validateClosedLedger(env, testCases);
 
 2589            BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
 
 2592            BEAST_EXPECT(env.seq(bob) == bobSeq + 1);
 
 2595            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 2596            BEAST_EXPECT(env.balance(bob) == preBob);
 
 2600                env.balance(alice, USD.issue()) == preAliceUSD + USD(10));
 
 2601            BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD - USD(10));
 
 2609            auto const aliceSeq = env.seq(alice);
 
 2610            auto const bobSeq = env.seq(bob);
 
 2611            auto const preAlice = env.balance(alice);
 
 2612            auto const preBob = env.balance(bob);
 
 2613            auto const preAliceUSD = env.balance(alice, USD.issue());
 
 2614            auto const preBobUSD = env.balance(bob, USD.issue());
 
 2616            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 2617            uint256 const chkID{getCheckIndex(bob, env.seq(bob))};
 
 2618            auto const [txIDs, batchID] = submitBatch(
 
 2623                batch::inner(check::create(bob, alice, USD(10)), bobSeq),
 
 2624                batch::inner(check::cash(alice, chkID, USD(10)), aliceSeq + 1),
 
 2630                {1, 
"CheckCreate", 
"tecDST_TAG_NEEDED", txIDs[0], batchID},
 
 2631                {2, 
"CheckCash", 
"tecNO_ENTRY", txIDs[1], batchID},
 
 2633            validateClosedLedger(env, testCases);
 
 2636            BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
 
 2639            BEAST_EXPECT(env.seq(bob) == bobSeq + 1);
 
 2642            BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 2643            BEAST_EXPECT(env.balance(bob) == preBob);
 
 2646            BEAST_EXPECT(env.balance(alice, USD.issue()) == preAliceUSD);
 
 2647            BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD);
 
 
 2654        testcase(
"object create w/ ticket");
 
 2656        using namespace test::jtx;
 
 2661        auto const alice = 
Account(
"alice");
 
 2662        auto const bob = 
Account(
"bob");
 
 2663        auto const gw = 
Account(
"gw");
 
 2664        auto const USD = gw[
"USD"];
 
 2666        env.fund(
XRP(10000), alice, bob, gw);
 
 2669        env.trust(USD(1000), alice, bob);
 
 2670        env(pay(gw, alice, USD(100)));
 
 2671        env(pay(gw, bob, USD(100)));
 
 2674        auto const aliceSeq = env.seq(alice);
 
 2675        auto const bobSeq = env.seq(bob);
 
 2676        auto const preAlice = env.balance(alice);
 
 2677        auto const preBob = env.balance(bob);
 
 2678        auto const preAliceUSD = env.balance(alice, USD.issue());
 
 2679        auto const preBobUSD = env.balance(bob, USD.issue());
 
 2681        auto const batchFee = batch::calcBatchFee(env, 1, 3);
 
 2682        uint256 const chkID{getCheckIndex(bob, bobSeq + 1)};
 
 2683        auto const [txIDs, batchID] = submitBatch(
 
 2688            batch::inner(check::create(bob, alice, USD(10)), 0, bobSeq + 1),
 
 2689            batch::inner(check::cash(alice, chkID, USD(10)), aliceSeq + 1),
 
 2695            {1, 
"TicketCreate", 
"tesSUCCESS", txIDs[0], batchID},
 
 2696            {2, 
"CheckCreate", 
"tesSUCCESS", txIDs[1], batchID},
 
 2697            {3, 
"CheckCash", 
"tesSUCCESS", txIDs[2], batchID},
 
 2699        validateClosedLedger(env, testCases);
 
 2701        BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
 
 2702        BEAST_EXPECT(env.seq(bob) == bobSeq + 10 + 1);
 
 2703        BEAST_EXPECT(env.balance(alice) == preAlice - batchFee);
 
 2704        BEAST_EXPECT(env.balance(bob) == preBob);
 
 2705        BEAST_EXPECT(env.balance(alice, USD.issue()) == preAliceUSD + USD(10));
 
 2706        BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD - USD(10));
 
 
 2712        testcase(
"object create w/ 3rd party");
 
 2714        using namespace test::jtx;
 
 2719        auto const alice = 
Account(
"alice");
 
 2720        auto const bob = 
Account(
"bob");
 
 2721        auto const carol = 
Account(
"carol");
 
 2722        auto const gw = 
Account(
"gw");
 
 2723        auto const USD = gw[
"USD"];
 
 2725        env.fund(
XRP(10000), alice, bob, carol, gw);
 
 2728        env.trust(USD(1000), alice, bob);
 
 2729        env(pay(gw, alice, USD(100)));
 
 2730        env(pay(gw, bob, USD(100)));
 
 2733        auto const aliceSeq = env.seq(alice);
 
 2734        auto const bobSeq = env.seq(bob);
 
 2735        auto const carolSeq = env.seq(carol);
 
 2736        auto const preAlice = env.balance(alice);
 
 2737        auto const preBob = env.balance(bob);
 
 2738        auto const preCarol = env.balance(carol);
 
 2739        auto const preAliceUSD = env.balance(alice, USD.issue());
 
 2740        auto const preBobUSD = env.balance(bob, USD.issue());
 
 2742        auto const batchFee = batch::calcBatchFee(env, 2, 2);
 
 2743        uint256 const chkID{getCheckIndex(bob, env.seq(bob))};
 
 2744        auto const [txIDs, batchID] = submitBatch(
 
 2748            batch::inner(check::create(bob, alice, USD(10)), bobSeq),
 
 2749            batch::inner(check::cash(alice, chkID, USD(10)), aliceSeq),
 
 2755            {1, 
"CheckCreate", 
"tesSUCCESS", txIDs[0], batchID},
 
 2756            {2, 
"CheckCash", 
"tesSUCCESS", txIDs[1], batchID},
 
 2758        validateClosedLedger(env, testCases);
 
 2760        BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
 
 2761        BEAST_EXPECT(env.seq(bob) == bobSeq + 1);
 
 2762        BEAST_EXPECT(env.seq(carol) == carolSeq + 1);
 
 2763        BEAST_EXPECT(env.balance(alice) == preAlice);
 
 2764        BEAST_EXPECT(env.balance(bob) == preBob);
 
 2765        BEAST_EXPECT(env.balance(carol) == preCarol - batchFee);
 
 2766        BEAST_EXPECT(env.balance(alice, USD.issue()) == preAliceUSD + USD(10));
 
 2767        BEAST_EXPECT(env.balance(bob, USD.issue()) == preBobUSD - USD(10));
 
 
 2774            testcase(
"tickets outer");
 
 2776            using namespace test::jtx;
 
 2781            auto const alice = 
Account(
"alice");
 
 2782            auto const bob = 
Account(
"bob");
 
 2784            env.fund(
XRP(10000), alice, bob);
 
 2788            env(ticket::create(alice, 10));
 
 2791            auto const aliceSeq = env.seq(alice);
 
 2792            auto const preAlice = env.balance(alice);
 
 2793            auto const preBob = env.balance(bob);
 
 2795            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 2796            auto const [txIDs, batchID] = submitBatch(
 
 2807                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2808                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2810            validateClosedLedger(env, testCases);
 
 2814            BEAST_EXPECT(sle->getFieldU32(sfOwnerCount) == 9);
 
 2815            BEAST_EXPECT(sle->getFieldU32(sfTicketCount) == 9);
 
 2817            BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
 
 2818            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(3) - batchFee);
 
 2819            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 2823            testcase(
"tickets inner");
 
 2825            using namespace test::jtx;
 
 2830            auto const alice = 
Account(
"alice");
 
 2831            auto const bob = 
Account(
"bob");
 
 2833            env.fund(
XRP(10000), alice, bob);
 
 2837            env(ticket::create(alice, 10));
 
 2840            auto const aliceSeq = env.seq(alice);
 
 2841            auto const preAlice = env.balance(alice);
 
 2842            auto const preBob = env.balance(bob);
 
 2844            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 2845            auto const [txIDs, batchID] = submitBatch(
 
 2855                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2856                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2858            validateClosedLedger(env, testCases);
 
 2862            BEAST_EXPECT(sle->getFieldU32(sfOwnerCount) == 8);
 
 2863            BEAST_EXPECT(sle->getFieldU32(sfTicketCount) == 8);
 
 2865            BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
 
 2866            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(3) - batchFee);
 
 2867            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 2871            testcase(
"tickets outer inner");
 
 2873            using namespace test::jtx;
 
 2878            auto const alice = 
Account(
"alice");
 
 2879            auto const bob = 
Account(
"bob");
 
 2881            env.fund(
XRP(10000), alice, bob);
 
 2885            env(ticket::create(alice, 10));
 
 2888            auto const aliceSeq = env.seq(alice);
 
 2889            auto const preAlice = env.balance(alice);
 
 2890            auto const preBob = env.balance(bob);
 
 2892            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 2893            auto const [txIDs, batchID] = submitBatch(
 
 2904                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2905                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2907            validateClosedLedger(env, testCases);
 
 2911            BEAST_EXPECT(sle->getFieldU32(sfOwnerCount) == 8);
 
 2912            BEAST_EXPECT(sle->getFieldU32(sfTicketCount) == 8);
 
 2914            BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
 
 2915            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(3) - batchFee);
 
 2916            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 
 2923        testcase(
"sequence open ledger");
 
 2925        using namespace test::jtx;
 
 2928        auto const alice = 
Account(
"alice");
 
 2929        auto const bob = 
Account(
"bob");
 
 2930        auto const carol = 
Account(
"carol");
 
 2940            env.fund(
XRP(10000), alice, bob, carol);
 
 2943            auto const aliceSeq = env.seq(alice);
 
 2944            auto const carolSeq = env.seq(carol);
 
 2947            auto const noopTxn = env.jt(
noop(alice), 
seq(aliceSeq + 2));
 
 2948            auto const noopTxnID = 
to_string(noopTxn.stx->getTransactionID());
 
 2952            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 2953            auto const [txIDs, batchID] = submitBatch(
 
 2965                    {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 2966                    {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 2968                validateClosedLedger(env, testCases);
 
 2975                    {0, 
"AccountSet", 
"tesSUCCESS", noopTxnID, 
std::nullopt},
 
 2977                validateClosedLedger(env, testCases);
 
 2987            env.fund(
XRP(10000), alice, bob);
 
 2990            auto const aliceSeq = env.seq(alice);
 
 2993            auto const noopTxn = env.jt(
noop(alice), 
seq(aliceSeq + 1));
 
 2997            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 2998            auto const [txIDs, batchID] = submitBatch(
 
 3009                    {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 3010                    {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3012                validateClosedLedger(env, testCases);
 
 3019                validateClosedLedger(env, testCases);
 
 3029            env.fund(
XRP(10000), alice, bob);
 
 3032            auto const aliceSeq = env.seq(alice);
 
 3033            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3034            auto const [txIDs, batchID] = submitBatch(
 
 3041            auto const noopTxn = env.jt(
noop(alice), 
seq(aliceSeq + 1));
 
 3042            auto const noopTxnID = 
to_string(noopTxn.stx->getTransactionID());
 
 3049                    {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 3050                    {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3052                validateClosedLedger(env, testCases);
 
 3059                validateClosedLedger(env, testCases);
 
 3066            env.fund(
XRP(10000), alice, bob, carol);
 
 3069            auto const aliceSeq = env.seq(alice);
 
 3070            auto const carolSeq = env.seq(carol);
 
 3073            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 3074            auto const [txIDs, batchID] = submitBatch(
 
 3083            auto const noopTxn = env.jt(
noop(carol), 
seq(carolSeq));
 
 3084            auto const noopTxnID = 
to_string(noopTxn.stx->getTransactionID());
 
 3090                    {0, 
"AccountSet", 
"tesSUCCESS", noopTxnID, 
std::nullopt},
 
 3092                    {2, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 3093                    {3, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3095                validateClosedLedger(env, testCases);
 
 3102                validateClosedLedger(env, testCases);
 
 
 3110        testcase(
"tickets open ledger");
 
 3112        using namespace test::jtx;
 
 3115        auto const alice = 
Account(
"alice");
 
 3116        auto const bob = 
Account(
"bob");
 
 3124            env.fund(
XRP(10000), alice, bob);
 
 3128            env(ticket::create(alice, 10));
 
 3131            auto const aliceSeq = env.seq(alice);
 
 3134            auto const noopTxn =
 
 3136            auto const noopTxnID = 
to_string(noopTxn.stx->getTransactionID());
 
 3140            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3141            auto const [txIDs, batchID] = submitBatch(
 
 3153                    {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 3154                    {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3156                validateClosedLedger(env, testCases);
 
 3163                validateClosedLedger(env, testCases);
 
 3173            env.fund(
XRP(10000), alice, bob);
 
 3177            env(ticket::create(alice, 10));
 
 3180            auto const aliceSeq = env.seq(alice);
 
 3183            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3184            auto const [txIDs, batchID] = submitBatch(
 
 3193            auto const noopTxn =
 
 3201                    {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 3202                    {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3204                validateClosedLedger(env, testCases);
 
 3211                validateClosedLedger(env, testCases);
 
 
 3219        testcase(
"objects open ledger");
 
 3221        using namespace test::jtx;
 
 3224        auto const alice = 
Account(
"alice");
 
 3225        auto const bob = 
Account(
"bob");
 
 3235            env.fund(
XRP(10000), alice, bob);
 
 3239            env(ticket::create(alice, 10));
 
 3242            auto const aliceSeq = env.seq(alice);
 
 3245            uint256 const chkID{getCheckIndex(alice, aliceSeq)};
 
 3246            auto const objTxn = env.jt(check::cash(bob, chkID, 
XRP(10)));
 
 3247            auto const objTxnID = 
to_string(objTxn.stx->getTransactionID());
 
 3251            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3252            auto const [txIDs, batchID] = submitBatch(
 
 3264                    {1, 
"CheckCreate", 
"tesSUCCESS", txIDs[0], batchID},
 
 3265                    {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3266                    {3, 
"CheckCash", 
"tesSUCCESS", objTxnID, 
std::nullopt},
 
 3268                validateClosedLedger(env, testCases);
 
 3275                validateClosedLedger(env, testCases);
 
 3282            env.fund(
XRP(10000), alice, bob);
 
 3286            env(ticket::create(alice, 10));
 
 3289            auto const aliceSeq = env.seq(alice);
 
 3290            auto const bobSeq = env.seq(bob);
 
 3293            uint256 const chkID{getCheckIndex(alice, aliceSeq)};
 
 3294            auto const objTxn = env.jt(check::create(alice, bob, 
XRP(10)));
 
 3295            auto const objTxnID = 
to_string(objTxn.stx->getTransactionID());
 
 3299            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 3300            auto const [txIDs, batchID] = submitBatch(
 
 3312                    {0, 
"CheckCreate", 
"tesSUCCESS", objTxnID, 
std::nullopt},
 
 3314                    {2, 
"CheckCash", 
"tesSUCCESS", txIDs[0], batchID},
 
 3315                    {3, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3317                validateClosedLedger(env, testCases);
 
 3329            env.fund(
XRP(10000), alice, bob);
 
 3333            env(ticket::create(alice, 10));
 
 3336            auto const aliceSeq = env.seq(alice);
 
 3339            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3340            uint256 const chkID{getCheckIndex(alice, aliceSeq)};
 
 3341            auto const [txIDs, batchID] = submitBatch(
 
 3350            auto const objTxn = env.jt(check::cash(bob, chkID, 
XRP(10)));
 
 3351            auto const objTxnID = 
to_string(objTxn.stx->getTransactionID());
 
 3358                    {1, 
"CheckCreate", 
"tesSUCCESS", txIDs[0], batchID},
 
 3359                    {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3360                    {3, 
"CheckCash", 
"tesSUCCESS", objTxnID, 
std::nullopt},
 
 3362                validateClosedLedger(env, testCases);
 
 
 3370        testcase(
"pseudo txn with tfInnerBatchTxn");
 
 3372        using namespace test::jtx;
 
 3377        auto const alice = 
Account(
"alice");
 
 3378        auto const bob = 
Account(
"bob");
 
 3379        env.fund(
XRP(10000), alice, bob);
 
 3382        STTx const stx = 
STTx(ttAMENDMENT, [&](
auto& obj) {
 
 3383            obj.setAccountID(sfAccount, 
AccountID());
 
 3384            obj.setFieldH256(sfAmendment, 
uint256(2));
 
 3385            obj.setFieldU32(sfLedgerSequence, env.seq(alice));
 
 3392        BEAST_EXPECT(reason == 
"Cannot submit pseudo transactions.");
 
 3396            return result.applied;
 
 
 3403        testcase(
"batch open ledger");
 
 3411        using namespace test::jtx;
 
 3415        XRPAmount const baseFee = env.current()->fees().base;
 
 3417        auto const alice = 
Account(
"alice");
 
 3418        auto const bob = 
Account(
"bob");
 
 3420        env.fund(
XRP(10000), alice, bob);
 
 3426        auto const aliceSeq = env.seq(alice);
 
 3427        auto const preAlice = env.balance(alice);
 
 3428        auto const preBob = env.balance(bob);
 
 3429        auto const bobSeq = env.seq(bob);
 
 3432        auto const payTxn1 = env.jt(pay(alice, bob, 
XRP(10)), 
seq(aliceSeq));
 
 3433        auto const payTxn1ID = 
to_string(payTxn1.stx->getTransactionID());
 
 3437        auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 3438        auto const [txIDs, batchID] = submitBatch(
 
 3447        auto const payTxn2 = env.jt(pay(bob, alice, 
XRP(5)), 
seq(bobSeq + 1));
 
 3448        auto const payTxn2ID = 
to_string(payTxn2.stx->getTransactionID());
 
 3455            {2, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 3456            {3, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3458        validateClosedLedger(env, testCases);
 
 3466            validateClosedLedger(env, testCases);
 
 3470        BEAST_EXPECT(env.seq(alice) == aliceSeq + 3);
 
 3473        BEAST_EXPECT(env.seq(bob) == bobSeq + 2);
 
 3477            env.balance(alice) == preAlice - 
XRP(10) - batchFee - baseFee);
 
 3478        BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(10) - baseFee);
 
 
 3484        testcase(
"batch tx queue");
 
 3486        using namespace test::jtx;
 
 3493                makeSmallQueueConfig(
 
 3494                    {{
"minimum_txn_in_ledger_standalone", 
"2"}}),
 
 3498            auto alice = 
Account(
"alice");
 
 3500            auto carol = 
Account(
"carol");
 
 3504            env.close(env.now() + 5s, 10000ms);
 
 3506            env.close(env.now() + 5s, 10000ms);
 
 3517            auto const aliceSeq = env.seq(alice);
 
 3518            auto const bobSeq = env.seq(bob);
 
 3519            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 3537                        openLedgerFee(env, batchFee),
 
 3553                makeSmallQueueConfig(
 
 3554                    {{
"minimum_txn_in_ledger_standalone", 
"2"}}),
 
 3558            auto alice = 
Account(
"alice");
 
 3560            auto carol = 
Account(
"carol");
 
 3564            env.close(env.now() + 5s, 10000ms);
 
 3566            env.close(env.now() + 5s, 10000ms);
 
 3573            auto const aliceSeq = env.seq(alice);
 
 3574            auto const bobSeq = env.seq(bob);
 
 3575            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 
 3596        testcase(
"batch network ops");
 
 3598        using namespace test::jtx;
 
 3608        auto alice = 
Account(
"alice");
 
 3610        env.
fund(
XRP(10000), alice, bob);
 
 3618            return jt.stx->getTransactionID();
 
 3630            return transaction->getID();
 
 
 3655        testcase(
"batch delegate");
 
 3657        using namespace test::jtx;
 
 3664            auto const alice = 
Account(
"alice");
 
 3665            auto const bob = 
Account(
"bob");
 
 3666            auto const gw = 
Account(
"gw");
 
 3667            auto const USD = gw[
"USD"];
 
 3668            env.fund(
XRP(10000), alice, bob, gw);
 
 3671            env(delegate::set(alice, bob, {
"Payment"}));
 
 3674            auto const preAlice = env.balance(alice);
 
 3675            auto const preBob = env.balance(bob);
 
 3677            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3678            auto const seq = env.
seq(alice);
 
 3681            tx[jss::Delegate] = bob.human();
 
 3682            auto const [txIDs, batchID] = submitBatch(
 
 3692                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 3693                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3695            validateClosedLedger(env, testCases);
 
 3698            BEAST_EXPECT(env.seq(alice) == 
seq + 3);
 
 3701            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(3) - batchFee);
 
 3702            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(3));
 
 3709            auto const alice = 
Account(
"alice");
 
 3710            auto const bob = 
Account(
"bob");
 
 3711            auto const carol = 
Account(
"carol");
 
 3712            auto const gw = 
Account(
"gw");
 
 3713            auto const USD = gw[
"USD"];
 
 3714            env.fund(
XRP(10000), alice, bob, carol, gw);
 
 3717            env(delegate::set(bob, carol, {
"Payment"}));
 
 3720            auto const preAlice = env.balance(alice);
 
 3721            auto const preBob = env.balance(bob);
 
 3722            auto const preCarol = env.balance(carol);
 
 3724            auto const batchFee = batch::calcBatchFee(env, 1, 2);
 
 3725            auto const aliceSeq = env.seq(alice);
 
 3726            auto const bobSeq = env.seq(bob);
 
 3729            tx[jss::Delegate] = carol.human();
 
 3730            auto const [txIDs, batchID] = submitBatch(
 
 3741                {1, 
"Payment", 
"tesSUCCESS", txIDs[0], batchID},
 
 3742                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3744            validateClosedLedger(env, testCases);
 
 3746            BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
 
 3747            BEAST_EXPECT(env.seq(bob) == bobSeq + 1);
 
 3748            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(1) - batchFee);
 
 3749            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(1));
 
 3752            BEAST_EXPECT(env.balance(carol) == preCarol);
 
 3761            auto const alice = 
Account(
"alice");
 
 3762            auto const bob = 
Account(
"bob");
 
 3763            auto const gw = 
Account(
"gw");
 
 3764            auto const USD = gw[
"USD"];
 
 3765            env.fund(
XRP(10000), alice, bob, gw);
 
 3768            env(delegate::set(alice, bob, {
"AccountDomainSet"}));
 
 3771            auto const preAlice = env.balance(alice);
 
 3772            auto const preBob = env.balance(bob);
 
 3774            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3775            auto const seq = env.
seq(alice);
 
 3780            tx[jss::Delegate] = bob.human();
 
 3781            auto const [txIDs, batchID] = submitBatch(
 
 3791                {1, 
"AccountSet", 
"tesSUCCESS", txIDs[0], batchID},
 
 3792                {2, 
"Payment", 
"tesSUCCESS", txIDs[1], batchID},
 
 3794            validateClosedLedger(env, testCases);
 
 3797            BEAST_EXPECT(env.seq(alice) == 
seq + 3);
 
 3800            BEAST_EXPECT(env.balance(alice) == preAlice - 
XRP(2) - batchFee);
 
 3801            BEAST_EXPECT(env.balance(bob) == preBob + 
XRP(2));
 
 3811            env.fund(
XRP(100000), alice, bob);
 
 3814            auto const mptID = 
makeMptID(env.seq(alice), alice);
 
 3815            MPTTester mpt(env, alice, {.fund = 
false});
 
 3822                alice, bob, {
"MPTokenIssuanceLock", 
"MPTokenIssuanceUnlock"}));
 
 3825            auto const seq = env.
seq(alice);
 
 3826            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3829            jv1[sfTransactionType] = jss::MPTokenIssuanceSet;
 
 3830            jv1[sfAccount] = alice.human();
 
 3831            jv1[sfDelegate] = bob.human();
 
 3832            jv1[sfSequence] = 
seq + 1;
 
 3833            jv1[sfMPTokenIssuanceID] = 
to_string(mptID);
 
 3837            jv2[sfTransactionType] = jss::MPTokenIssuanceSet;
 
 3838            jv2[sfAccount] = alice.human();
 
 3839            jv2[sfDelegate] = bob.human();
 
 3840            jv2[sfSequence] = 
seq + 2;
 
 3841            jv2[sfMPTokenIssuanceID] = 
to_string(mptID);
 
 3844            auto const [txIDs, batchID] = submitBatch(
 
 3854                {1, 
"MPTokenIssuanceSet", 
"tesSUCCESS", txIDs[0], batchID},
 
 3855                {2, 
"MPTokenIssuanceSet", 
"tesSUCCESS", txIDs[1], batchID},
 
 3857            validateClosedLedger(env, testCases);
 
 3868            env.fund(
XRP(10000), gw, alice, bob);
 
 3871            env(trust(alice, gw[
"USD"](50)));
 
 3875                gw, bob, {
"TrustlineAuthorize", 
"TrustlineFreeze"}));
 
 3878            auto const seq = env.
seq(gw);
 
 3879            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3881            auto jv1 = trust(gw, gw[
"USD"](0), alice, 
tfSetfAuth);
 
 3882            jv1[sfDelegate] = bob.human();
 
 3883            auto jv2 = trust(gw, gw[
"USD"](0), alice, 
tfSetFreeze);
 
 3884            jv2[sfDelegate] = bob.human();
 
 3886            auto const [txIDs, batchID] = submitBatch(
 
 3896                {1, 
"TrustSet", 
"tesSUCCESS", txIDs[0], batchID},
 
 3897                {2, 
"TrustSet", 
"tesSUCCESS", txIDs[1], batchID},
 
 3899            validateClosedLedger(env, testCases);
 
 3908            env.fund(
XRP(10000), gw, alice, bob);
 
 3911            env(trust(alice, gw[
"USD"](50)));
 
 3915                gw, bob, {
"TrustlineAuthorize", 
"TrustlineFreeze"}));
 
 3918            auto const seq = env.
seq(gw);
 
 3919            auto const batchFee = batch::calcBatchFee(env, 0, 2);
 
 3921            auto jv1 = trust(gw, gw[
"USD"](0), alice, 
tfSetFreeze);
 
 3922            jv1[sfDelegate] = bob.human();
 
 3924            jv2[sfDelegate] = bob.human();
 
 3926            auto const [txIDs, batchID] = submitBatch(
 
 3937                {1, 
"TrustSet", 
"tesSUCCESS", txIDs[0], batchID},
 
 3939            validateClosedLedger(env, testCases);
 
 
 3949        testcase(
"Validate RPC response");
 
 3951        using namespace jtx;
 
 3955        env.
fund(
XRP(10000), alice, bob);
 
 3960            auto const baseFee = env.
current()->fees().base;
 
 3961            auto const aliceSeq = env.
seq(alice);
 
 3962            auto jtx = env.
jt(pay(alice, bob, 
XRP(1)));
 
 3966            auto const jr = env.
rpc(
"submit", 
strHex(s.
slice()))[jss::result];
 
 3969            BEAST_EXPECT(jr.isMember(jss::account_sequence_available));
 
 3971                jr[jss::account_sequence_available].asUInt() == aliceSeq + 1);
 
 3972            BEAST_EXPECT(jr.isMember(jss::account_sequence_next));
 
 3974                jr[jss::account_sequence_next].asUInt() == aliceSeq + 1);
 
 3975            BEAST_EXPECT(jr.isMember(jss::open_ledger_cost));
 
 3976            BEAST_EXPECT(jr[jss::open_ledger_cost] == 
to_string(baseFee));
 
 3977            BEAST_EXPECT(jr.isMember(jss::validated_ledger_index));
 
 3982            auto const baseFee = env.
current()->fees().base;
 
 3983            auto const aliceSeq = env.
seq(alice);
 
 3985            auto jtx = env.
jt(pay(alice, bob, 
XRP(1)), 
seq(aliceSeq));
 
 3989            auto const jr = env.
rpc(
"submit", 
strHex(s.
slice()))[jss::result];
 
 3992            BEAST_EXPECT(jr.isMember(jss::account_sequence_available));
 
 3994                jr[jss::account_sequence_available].asUInt() == aliceSeq + 1);
 
 3995            BEAST_EXPECT(jr.isMember(jss::account_sequence_next));
 
 3997                jr[jss::account_sequence_next].asUInt() == aliceSeq + 1);
 
 3998            BEAST_EXPECT(jr.isMember(jss::open_ledger_cost));
 
 3999            BEAST_EXPECT(jr[jss::open_ledger_cost] == 
to_string(baseFee));
 
 4000            BEAST_EXPECT(jr.isMember(jss::validated_ledger_index));
 
 4005            auto const baseFee = env.
current()->fees().base;
 
 4006            auto const aliceSeq = env.
seq(alice);
 
 4007            auto jtx = env.
jt(pay(alice, bob, 
XRP(1)), 
seq(aliceSeq + 1));
 
 4011            auto const jr = env.
rpc(
"submit", 
strHex(s.
slice()))[jss::result];
 
 4014            BEAST_EXPECT(jr.isMember(jss::account_sequence_available));
 
 4016                jr[jss::account_sequence_available].asUInt() == aliceSeq);
 
 4017            BEAST_EXPECT(jr.isMember(jss::account_sequence_next));
 
 4018            BEAST_EXPECT(jr[jss::account_sequence_next].asUInt() == aliceSeq);
 
 4019            BEAST_EXPECT(jr.isMember(jss::open_ledger_cost));
 
 4020            BEAST_EXPECT(jr[jss::open_ledger_cost] == 
to_string(baseFee));
 
 4021            BEAST_EXPECT(jr.isMember(jss::validated_ledger_index));
 
 
 4028        using namespace jtx;
 
 4033        env.
fund(
XRP(10000), alice, bob, carol);
 
 4044            auto const seq = env.
seq(alice);
 
 4045            XRPAmount const batchFee = batch::calcBatchFee(env, 0, 2);
 
 4051            XRPAmount const txBaseFee = getBaseFee(jtx);
 
 4057            auto const seq = env.
seq(alice);
 
 4058            XRPAmount const batchFee = batch::calcBatchFee(env, 0, 2);
 
 4072            XRPAmount const txBaseFee = getBaseFee(jtx);
 
 4078            auto const seq = env.
seq(alice);
 
 4079            XRPAmount const batchFee = batch::calcBatchFee(env, 0, 2);
 
 4096            XRPAmount const txBaseFee = getBaseFee(jtx);
 
 4102            auto const seq = env.
seq(alice);
 
 4103            XRPAmount const batchFee = batch::calcBatchFee(env, 0, 2);
 
 4108            XRPAmount const txBaseFee = getBaseFee(jtx);
 
 4109            BEAST_EXPECT(txBaseFee == batchFee);
 
 
 4116        testEnable(features);
 
 4117        testPreflight(features);
 
 4118        testPreclaim(features);
 
 4119        testBadRawTxn(features);
 
 4120        testBadSequence(features);
 
 4121        testBadOuterFee(features);
 
 4122        testCalculateBaseFee(features);
 
 4123        testAllOrNothing(features);
 
 4124        testOnlyOne(features);
 
 4125        testUntilFailure(features);
 
 4126        testIndependent(features);
 
 4127        testInnerSubmitRPC(features);
 
 4128        testAccountActivation(features);
 
 4129        testAccountSet(features);
 
 4130        testAccountDelete(features);
 
 4131        testObjectCreateSequence(features);
 
 4132        testObjectCreateTicket(features);
 
 4133        testObjectCreate3rdParty(features);
 
 4134        testTickets(features);
 
 4135        testSequenceOpenLedger(features);
 
 4136        testTicketsOpenLedger(features);
 
 4137        testObjectsOpenLedger(features);
 
 4138        testPseudoTxn(features);
 
 4139        testOpenLedger(features);
 
 4140        testBatchTxQueue(features);
 
 4141        testBatchNetworkOps(features);
 
 4142        testBatchDelegate(features);
 
 4143        testValidateRPCResponse(features);
 
 4144        testBatchCalculateBaseFee(features);
 
 
 4151        using namespace test::jtx;
 
 
 
A generic endpoint for log messages.
 
testcase_t testcase
Memberspace for declaring test cases.
 
virtual NetworkOPs & getOPs()=0
 
virtual HashRouter & getHashRouter()=0
 
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Calculates the total base fee for a batch transaction.
 
HashRouterFlags getFlags(uint256 const &key)
 
virtual void submitTransaction(std::shared_ptr< STTx const > const &)=0
 
virtual void processTransaction(std::shared_ptr< Transaction > &transaction, bool bUnlimited, bool bLocal, FailHard failType)=0
Process transactions as they arrive from the network or which are submitted by clients.
 
Writable ledger view that accumulates state and tx changes.
 
Json::Value getJson(JsonOptions=JsonOptions::none) const override
 
Holds the serialized result of parsing an input JSON object.
 
std::optional< STObject > object
The STObject if the parse was successful.
 
Slice slice() const noexcept
 
An immutable linear range of bytes.
 
Metrics getMetrics(OpenView const &view) const
Returns fee metrics in reference fee level units.
 
void testBatchNetworkOps(FeatureBitset features)
 
void validateInnerTxn(jtx::Env &env, std::string const &batchID, TestLedgerData const &ledgerResult)
 
void testAccountSet(FeatureBitset features)
 
void testTickets(FeatureBitset features)
 
void run() override
Runs the suite.
 
void testAllOrNothing(FeatureBitset features)
 
void testBatchCalculateBaseFee(FeatureBitset features)
 
void testObjectCreate3rdParty(FeatureBitset features)
 
void testAccountActivation(FeatureBitset features)
 
Json::Value getLastLedger(jtx::Env &env)
 
void testValidateRPCResponse(FeatureBitset features)
 
void testObjectCreateTicket(FeatureBitset features)
 
void testBadRawTxn(FeatureBitset features)
 
void testPreclaim(FeatureBitset features)
 
std::pair< std::vector< std::string >, std::string > submitBatch(jtx::Env &env, TER const &result, Args &&... args)
 
void testBatchTxQueue(FeatureBitset features)
 
void testBadSequence(FeatureBitset features)
 
static uint256 getCheckIndex(AccountID const &account, std::uint32_t uSequence)
 
Json::Value getTxByIndex(Json::Value const &jrr, int const index)
 
void validateClosedLedger(jtx::Env &env, std::vector< TestLedgerData > const &ledgerResults)
 
void testObjectCreateSequence(FeatureBitset features)
 
void testBatchDelegate(FeatureBitset features)
 
void testOpenLedger(FeatureBitset features)
 
auto openLedgerFee(jtx::Env &env, XRPAmount const &batchFee)
 
void testPreflight(FeatureBitset features)
 
void testUntilFailure(FeatureBitset features)
 
void testWithFeats(FeatureBitset features)
 
void testSequenceOpenLedger(FeatureBitset features)
 
void testTicketsOpenLedger(FeatureBitset features)
 
void testIndependent(FeatureBitset features)
 
static std::unique_ptr< Config > makeSmallQueueConfig(std::map< std::string, std::string > extraTxQ={}, std::map< std::string, std::string > extraVoting={})
 
void testOnlyOne(FeatureBitset features)
 
void testPseudoTxn(FeatureBitset features)
 
void testInnerSubmitRPC(FeatureBitset features)
 
void testEnable(FeatureBitset features)
 
void testBadOuterFee(FeatureBitset features)
 
void testObjectsOpenLedger(FeatureBitset features)
 
void testCalculateBaseFee(FeatureBitset features)
 
void testAccountDelete(FeatureBitset features)
 
Immutable cryptographic account descriptor.
 
A transaction testing environment.
 
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
 
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
 
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
 
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
 
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
 
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 fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
 
void create(MPTCreate const &arg=MPTCreate{})
 
Adds a new Batch Txn on a JTx and autofills.
 
Set a batch nested multi-signature on a JTx.
 
Set a batch signature on a JTx.
 
Set a multisignature on a JTx.
 
Set the regular signature on a JTx.
 
Set the expected result code for a JTx The test will fail if the code doesn't match.
 
Set a ticket sequence on a JTx.
 
@ arrayValue
array value (ordered list)
 
@ objectValue
object value (collection of name/value pairs).
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
 
Json::Value outer(jtx::Account const &account, uint32_t seq, STAmount const &fee, std::uint32_t flags)
Batch.
 
XRPAmount calcBatchFee(jtx::Env const &env, uint32_t const &numSigners, uint32_t const &txns=0)
Calculate Batch Fee.
 
Json::Value regkey(Account const &account, disabled_t)
Disable the regular key.
 
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
 
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
 
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
 
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
 
FeatureBitset testable_amendments()
 
std::array< Account, 1+sizeof...(Args)> noripple(Account const &account, Args const &... args)
Designate accounts as no-ripple in Env::fund.
 
void checkMetrics(Suite &test, jtx::Env &env, std::size_t expectedCount, std::optional< std::size_t > expectedMaxCount, std::size_t expectedInLedger, std::size_t expectedPerLedger, std::uint64_t expectedMinFeeLevel=baseFeeLevel.fee(), std::uint64_t expectedMedFeeLevel=minEscalationFeeLevel.fee(), source_location const location=source_location::current())
 
void incLgrSeqForAccDel(jtx::Env &env, jtx::Account const &acc, std::uint32_t margin=0)
 
Json::Value acctdelete(Account const &account, Account const &dest)
Delete account.
 
XRP_t const XRP
Converts to XRP Issue or STAmount.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
 
constexpr std::uint32_t tfAllOrNothing
 
constexpr std::uint32_t tfOnlyOne
 
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
 
constexpr std::uint32_t asfRequireDest
 
constexpr std::uint32_t tfIndependent
 
void serializeBatch(Serializer &msg, std::uint32_t const &flags, std::vector< uint256 > const &txids)
 
constexpr std::uint32_t const tfMPTUnlock
 
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
 
constexpr XRPAmount INITIAL_XRP
Configure the native currency.
 
constexpr std::uint32_t tfImmediateOrCancel
 
constexpr std::uint32_t asfDisableMaster
 
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &message)
Generate a signature for a message.
 
constexpr std::uint32_t tfUntilFailure
 
std::string strHex(FwdIt begin, FwdIt end)
 
constexpr std::uint32_t tfSetfAuth
 
constexpr std::uint32_t tfClearFreeze
 
constexpr std::uint32_t const tfMPTLock
 
constexpr std::uint32_t tfDisallowXRP
 
ApplyResult apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
 
bool passesLocalChecks(STObject const &st, std::string &)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
constexpr std::uint32_t asfAllowTrustLineClawback
 
XRPAmount toDrops(FeeLevel< T > const &level, XRPAmount baseFee)
 
constexpr std::uint32_t asfRequireAuth
 
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
 
constexpr std::uint32_t tfSetFreeze
 
constexpr std::uint32_t const tfMPTCanLock
 
constexpr std::uint32_t tfInnerBatchTxn
 
std::optional< std::string > batchID
 
Execution context for applying a JSON transaction.
 
Set the sequence number on a JTx.