2#include <test/jtx/Env.h> 
    3#include <test/jtx/attester.h> 
    4#include <test/jtx/multisign.h> 
    5#include <test/jtx/xchain_bridge.h> 
    7#include <xrpl/beast/unit_test/suite.h> 
    8#include <xrpl/protocol/Feature.h> 
    9#include <xrpl/protocol/Indexes.h> 
   10#include <xrpl/protocol/Issue.h> 
   11#include <xrpl/protocol/SField.h> 
   12#include <xrpl/protocol/STXChainBridge.h> 
   13#include <xrpl/protocol/Serializer.h> 
   14#include <xrpl/protocol/TER.h> 
   15#include <xrpl/protocol/XChainAttestations.h> 
   44        : 
env_(s, 
std::move(config), features, 
std::move(logs), thresh)
 
 
   69    template <
class Arg, 
class... Args>
 
   77    template <
class JsonValue, 
class... FN>
 
   79    tx(JsonValue&& jv, FN 
const&... fN)
 
 
   85    template <
class... FN>
 
   89        for (
auto const& jv : jvv)
 
 
  115        return env_.
current()->fees().accountReserve(count);
 
 
  139                if ((*r)[sfXChainBridge] == b)
 
 
  152        return (*
bridge(jvb))[sfXChainAccountClaimCount];
 
 
  158        return (*
bridge(jvb))[sfXChainClaimID];
 
 
 
  194                this->
fund(xrp_funds, s.account);
 
  209                this->
fund(xrp_funds, ra);
 
  212                this->
fund(xrp_funds, s.account);
 
 
 
  262        : 
from_(env, from_acct)
 
  268            for (
size_t i = 0; i < num_payees; ++i)
 
 
  300            [&](
balance const& b) { return b.diff() == reward; });
 
 
  314        bool check_payer = 
true)
 
 
 
  382        bool exceptionPresent = 
false;
 
  385            exceptionPresent = 
false;
 
  390            exceptionPresent = 
true;
 
  393        BEAST_EXPECT(!exceptionPresent);
 
  397            exceptionPresent = 
false;
 
  398            jBridge[
"Extra"] = 1;
 
  403            exceptionPresent = 
true;
 
  406        BEAST_EXPECT(exceptionPresent);
 
 
  581        testcase(
"Bridge create constraints");
 
  582        XEnv env(*
this, 
true);
 
  586        auto AUSD = A[
"USD"];
 
  587        auto BUSD = B[
"USD"];
 
  588        auto CUSD = C[
"USD"];
 
  589        auto GUSD = 
scGw[
"USD"];
 
  590        auto AEUR = A[
"EUR"];
 
  591        auto BEUR = B[
"EUR"];
 
  592        auto CEUR = C[
"EUR"];
 
  593        auto GEUR = 
scGw[
"EUR"];
 
  603        env.
fund(
XRP(10000), a1, a2, a3, a4, a5, a6);
 
  626        auto const goodBridge1 = 
bridge(A, GUSD, B, BUSD);
 
  627        auto const goodBridge2 = 
bridge(A, BUSD, C, CUSD);
 
  645            .
tx(
pay(B, C, BUSD(1000)))
 
  647        auto const aBalanceStart = env.
balance(A, BUSD);
 
  648        auto const cBalanceStart = env.
balance(C, BUSD);
 
  650        BEAST_EXPECT(env.
balance(A, BUSD) - aBalanceStart == BUSD(0));
 
  651        BEAST_EXPECT(env.
balance(C, BUSD) - cBalanceStart == BUSD(-50));
 
  653        BEAST_EXPECT(env.
balance(A, BUSD) - aBalanceStart == BUSD(60));
 
  654        BEAST_EXPECT(env.
balance(C, BUSD) - cBalanceStart == BUSD(-50 - 60));
 
  658        BEAST_EXPECT((*env.
bridge(goodBridge1))[sfSignatureReward] == 
XRP(33));
 
  660        BEAST_EXPECT((*env.
bridge(goodBridge2))[sfSignatureReward] == 
XRP(44));
 
 
  710                "Locking chain is IOU(locking chain door)",
 
  711                [&](
auto& env, 
bool) {
 
  716                "Locking chain is IOU(issuing chain door funded on locking " 
  718                [&](
auto& env, 
bool shouldFund) {
 
  725                "Locking chain is IOU(issuing chain door account unfunded " 
  727                [&](
auto& env, 
bool) {
 
  732                "Locking chain is IOU(bob funded on locking chain)",
 
  733                [&](
auto& env, 
bool) {
 
  738                "Locking chain is IOU(bob unfunded on locking chain)",
 
  739                [&](
auto& env, 
bool) {
 
  750                "Issuing chain is IOU(issuing chain door account)",
 
  751                [&](
auto& env, 
bool) {
 
  756                "Issuing chain is IOU(locking chain door funded on issuing " 
  758                [&](
auto& env, 
bool shouldFund) {
 
  765                "Issuing chain is IOU(locking chain door unfunded on " 
  767                [&](
auto& env, 
bool) {
 
  772                "Issuing chain is IOU(bob funded on issuing chain)",
 
  773                [&](
auto& env, 
bool) {
 
  778                "Issuing chain is IOU(bob unfunded on issuing chain)",
 
  779                [&](
auto& env, 
bool) {
 
  784                "Issuing chain is XRP and issuing chain door account is " 
  785                "not the root account",
 
  786                [&](
auto& env, 
bool) {
 
  791                "Issuing chain is XRP and issuing chain door account is " 
  793                [&](
auto& env, 
bool) {
 
  844        auto testcase = [&](
auto const& lc, 
auto const& ic) {
 
  846            XEnv scEnv(*
this, 
true);
 
  848            lc.second(mcEnv, 
true);
 
  849            lc.second(scEnv, 
false);
 
  851            ic.second(mcEnv, 
false);
 
  852            ic.second(scEnv, 
true);
 
  854            auto const& expected = expected_result[test_result.
size()];
 
  871        auto apply_ics = [&](
auto const& lc, 
auto const& ics) {
 
  873                [&](
auto const&... ic) { (
testcase(lc, ic), ...); }, ics);
 
  876        std::apply([&](
auto const&... lc) { (apply_ics(lc, ics), ...); }, lcs);
 
  878#if GENERATE_MTX_OUTPUT 
  883        std::cout << 
"Markdown output for matrix test: " << fname << 
"\n";
 
  898        auto output_table = [&](
auto print_res) {
 
  904            res += 
"|  `issuing ->` | ";
 
  906                [&](
auto const&... ic) {
 
  907                    ((res += ic.first, res += 
" | "), ...);
 
  914                [&](
auto const&... ic) {
 
  915                    (((void)ic.first, res += 
":---: |  "), ...);
 
  920            auto output = [&](
auto const& lc, 
auto const& ic) {
 
  921                res += print_res(test_result[test_idx]);
 
  926            auto output_ics = [&](
auto const& lc, 
auto const& ics) {
 
  931                    [&](
auto const&... ic) { (output(lc, ic), ...); }, ics);
 
  936                [&](
auto const&... lc) { (output_ics(lc, ics), ...); }, lcs);
 
  944        std::cout << 
"ter output for matrix test: " << ter_fname << 
"\n";
 
  947        for (
auto& t : test_result)
 
 
 1008        for (
auto withClaim : {
false, 
true})
 
 1011            XEnv scEnv(*
this, 
true);
 
 1022            auto const amt = 
XRP(1000);
 
 1063        for (
auto withClaim : {
false, 
true})
 
 1066            XEnv scEnv(*
this, 
true);
 
 1077            auto const amt = 
XRP(1000);
 
 1126        for (
auto withClaim : {
false, 
true})
 
 1129            XEnv scEnv(*
this, 
true);
 
 1140            auto const amt = 
XRP(1000);
 
 
 1265        using namespace jtx;
 
 1282            XEnv xenv(*
this, 
true);
 
 1290            BEAST_EXPECT(scAlice_bal.
diff() == -tx_fee);
 
 
 1355        using namespace jtx;
 
 1370            auto const amt = 
XRP(1000);
 
 1378            BEAST_EXPECT(alice_bal.
diff() == -(claim_cost + tx_fee));
 
 
 1491        using namespace jtx;
 
 1507        for (
auto withClaim : {
true})
 
 1510            XEnv scEnv(*
this, 
true);
 
 1524            auto const amt = 
XRP(1000);
 
 1576        for (
auto withClaim : {
false, 
true})
 
 1579            XEnv scEnv(*
this, 
true);
 
 1583                constexpr int numSigners = 4;
 
 1588                for (
int i = 0; i < numSigners; ++i)
 
 1608            auto const amt = 
XRP(1000);
 
 1651        for (
auto withClaim : {
false, 
true})
 
 1654            XEnv scEnv(*
this, 
true);
 
 1658                constexpr int numSigners = 4;
 
 1663                for (
int i = 0; i < numSigners; ++i)
 
 1685            auto const amt = 
XRP(1000);
 
 1729        for (
auto withClaim : {
false, 
true})
 
 1732            XEnv scEnv(*
this, 
true);
 
 1736                constexpr int numSigners = 4;
 
 1741                for (
int i = 0; i < numSigners; ++i)
 
 1762            auto const amt = 
XRP(1000);
 
 1804        for (
auto withClaim : {
false, 
true})
 
 1807            XEnv scEnv(*
this, 
true);
 
 1811                constexpr int numSigners = 4;
 
 1816                for (
int i = 0; i < numSigners; ++i)
 
 1837            auto const amt = 
XRP(1000);
 
 1887            XEnv scEnv(*
this, 
true);
 
 1888            auto const amt = 
XRP(1000);
 
 1889            auto const amt_plus_reward = amt + 
reward;
 
 1909                BEAST_EXPECT(carol.
diff() == -(amt + 
reward + tx_fee));
 
 1929                BEAST_EXPECT(attester.
diff() == -multiTtxFee(6));
 
 1949                BEAST_EXPECT(attester.
diff() == -multiTtxFee(3));
 
 1967                BEAST_EXPECT(attester.
diff() == -multiTtxFee(3));
 
 1983                BEAST_EXPECT(door.
diff() == -amt_plus_reward);
 
 1985                BEAST_EXPECT(attester.
diff() == -multiTtxFee(3));
 
 2005                BEAST_EXPECT(attester.
diff() == -multiTtxFee(3));
 
 2021                BEAST_EXPECT(door.
diff() == -amt_plus_reward);
 
 2022                BEAST_EXPECT(attester.
diff() == -tx_fee);
 
 2037                BEAST_EXPECT(door.
diff() == -amt_plus_reward);
 
 2038                BEAST_EXPECT(attester.
diff() == -tx_fee);
 
 2050            XEnv scEnv(*
this, 
true);
 
 2052            auto const amt = res0 - 
XRP(1);
 
 2053            auto const amt_plus_reward = amt + 
reward;
 
 2066                BEAST_EXPECT(door.
diff() == amt_plus_reward);
 
 2067                BEAST_EXPECT(carol.
diff() == -(amt_plus_reward + tx_fee));
 
 2087            BEAST_EXPECT(attester.
diff() == -multiTtxFee(4));
 
 2096            XEnv scEnv(*
this, 
true);
 
 2098            auto const amt = 
XRP(111);
 
 2099            auto const amt_plus_reward = amt + 
reward;
 
 2112                BEAST_EXPECT(door.
diff() == amt_plus_reward);
 
 2113                BEAST_EXPECT(carol.
diff() == -(amt_plus_reward + tx_fee));
 
 2134            BEAST_EXPECT(door.
diff() == -amt_plus_reward);
 
 2135            BEAST_EXPECT(attester.
diff() == -multiTtxFee(4));
 
 2136            BEAST_EXPECT(alice.
diff() == amt);
 
 2143            XEnv scEnv(*
this, 
true);
 
 2145            auto const amt = 
XRP(1000);
 
 2146            auto const amt_plus_reward = amt + 
reward;
 
 2159                BEAST_EXPECT(door.
diff() == amt_plus_reward);
 
 2160                BEAST_EXPECT(carol.
diff() == -(amt_plus_reward + tx_fee));
 
 2183            BEAST_EXPECT(attester.
diff() == -multiTtxFee(4));
 
 2194            XEnv scEnv(*
this, 
true);
 
 2195            auto const amt = 
XRP(1000);
 
 2196            auto const amt_plus_reward = amt + 
reward;
 
 2218                BEAST_EXPECT(carol.
diff() == -(amt + 
reward + tx_fee));
 
 2229                auto const bad_amt = 
XRP(10);
 
 2240                BEAST_EXPECTS(!!scEnv.
caClaimID(
jvb, 1), 
"claim id 1 created");
 
 2241                BEAST_EXPECTS(!!scEnv.
caClaimID(
jvb, 2), 
"claim id 2 created");
 
 2242                BEAST_EXPECTS(!!scEnv.
caClaimID(
jvb, 3), 
"claim id 3 created");
 
 2276                BEAST_EXPECTS(!scEnv.
caClaimID(
jvb, 1), 
"claim id 1 deleted");
 
 2277                BEAST_EXPECTS(scEnv.
claimCount(
jvb) == 1, 
"scuAlice created");
 
 2286                BEAST_EXPECTS(!scEnv.
caClaimID(
jvb, 2), 
"claim id 2 deleted");
 
 2287                BEAST_EXPECTS(!scEnv.
caClaimID(
jvb, 1), 
"claim id 1 not added");
 
 2295                BEAST_EXPECTS(!scEnv.
caClaimID(
jvb, 3), 
"claim id 3 deleted");
 
 2306                BEAST_EXPECT(attester.
diff() == -multiTtxFee(txCount));
 
 2319            XEnv scEnv(*
this, 
true);
 
 2341            XEnv scEnv(*
this, 
true);
 
 
 2364        using namespace jtx;
 
 2366        testcase(
"Add Non Batch Claim Attestation");
 
 2370            XEnv scEnv(*
this, 
true);
 
 2384            auto const amt = 
XRP(1000);
 
 2387            auto const dstStartBalance = scEnv.
env_.
balance(dst);
 
 2389            for (
int i = 0; i < 
signers.size(); ++i)
 
 2402                TER const expectedTER =
 
 2410                    BEAST_EXPECT(dstStartBalance == scEnv.
env_.
balance(dst));
 
 2413                        dstStartBalance + amt == scEnv.
env_.
balance(dst));
 
 2415            BEAST_EXPECT(dstStartBalance + amt == scEnv.
env_.
balance(dst));
 
 2436            XEnv scEnv(*
this, 
true);
 
 2437            auto const amt = 
XRP(1000);
 
 2453            auto const dstStartBalance = scEnv.
env_.
balance(dst);
 
 2487                att[sfAttestationSignerAccount.getJsonName()] =
 
 2494                auto const unfundedSigner1 =
 
 2496                auto const unfundedSigner2 =
 
 2508                att[sfAttestationSignerAccount.getJsonName()] =
 
 2509                    unfundedSigner2.account.human();
 
 2512                att[sfAttestationSignerAccount.getJsonName()] =
 
 2513                    unfundedSigner1.
account.human();
 
 2530                    tempSignerList.
front());
 
 2531                att[sfAttestationSignerAccount.getJsonName()] =
 
 2580                att.removeMember(sfAttestationSignerAccount.getJsonName());
 
 2582                BEAST_EXPECT(dstStartBalance == scEnv.
env_.
balance(dst));
 
 2583                att[sfAttestationSignerAccount.getJsonName()] =
 
 2586                BEAST_EXPECT(dstStartBalance + amt == scEnv.
env_.
balance(dst));
 
 
 2594        using namespace jtx;
 
 2596        testcase(
"Add Non Batch Account Create Attestation");
 
 2599        XEnv scEnv(*
this, 
true);
 
 2607        mcEnv.
fund(funds, a);
 
 2608        mcEnv.
fund(funds, doorA);
 
 2623        xrp_b.initBridge(mcEnv, scEnv);
 
 2625        auto const amt = 
XRP(777);
 
 2626        auto const amt_plus_reward = amt + xrp_b.reward;
 
 2628            Balance bal_doorA(mcEnv, doorA);
 
 2633                    a, xrp_b.jvb, ua, amt, xrp_b.reward))
 
 2636            BEAST_EXPECT(bal_doorA.
diff() == amt_plus_reward);
 
 2637            BEAST_EXPECT(bal_a.
diff() == -(amt_plus_reward + tx_fee));
 
 2640        for (
int i = 0; i < 
signers.size(); ++i)
 
 2653            TER const expectedTER = i < xrp_b.quorum
 
 2658            if (i + 1 < xrp_b.quorum)
 
 2659                BEAST_EXPECT(!scEnv.
env_.
le(ua));
 
 2661                BEAST_EXPECT(scEnv.
env_.
le(ua));
 
 2663        BEAST_EXPECT(scEnv.
env_.
le(ua));
 
 
 2669        using namespace jtx;
 
 2680        for (
auto withClaim : {
false, 
true})
 
 2683            XEnv scEnv(*
this, 
true);
 
 2694            auto const amt = 
XRP(1000);
 
 2734        for (
auto withClaim : {
false, 
true})
 
 2737            XEnv scEnv(*
this, 
true);
 
 2749            auto const amt = 
XRP(1000);
 
 2784        for (
auto withClaim : {
false, 
true})
 
 2787            XEnv scEnv(*
this, 
true);
 
 2800            auto const amt = 
XRP(1000);
 
 2833        for (
auto withClaim : {
false, 
true})
 
 2836            XEnv scEnv(*
this, 
true);
 
 2852            auto const amt = 
XRP(1000);
 
 2891        for (
auto withClaim : {
false, 
true})
 
 2894            XEnv scEnv(*
this, 
true);
 
 2905            auto const amt = 
XRP(1000);
 
 2942        for (
auto withClaim : {
false, 
true})
 
 2945            XEnv scEnv(*
this, 
true);
 
 2956            auto const amt = 
XRP(1000);
 
 3001        for (
auto withClaim : {
false, 
true})
 
 3004            XEnv scEnv(*
this, 
true);
 
 3015            auto const amt = 
XRP(1000);
 
 3041        for (
auto withClaim : {
false, 
true})
 
 3044            XEnv scEnv(*
this, 
true);
 
 3055            auto const amt = 
XRP(1000);
 
 3062            auto tooFew = 
quorum - 1;
 
 3092        for (
auto withClaim : {
false, 
true})
 
 3095            XEnv scEnv(*
this, 
true);
 
 3106            auto const amt = 
XRP(1000);
 
 3146        for (
auto withClaim : {
true})
 
 3149            XEnv scEnv(*
this, 
true);
 
 3160            auto const amt = 
XRP(1000);
 
 3202        for (
auto withClaim : {
true})
 
 3205            XEnv scEnv(*
this, 
true);
 
 3216            auto const amt = 
XRP(1000);
 
 3258        for (
auto withClaim : {
false, 
true})
 
 3261            XEnv scEnv(*
this, 
true);
 
 3274            auto const amt = 
XRP(1000);
 
 3325                scEnv.
tx(txns.back());
 
 3342        for (
auto withClaim : {
false, 
true})
 
 3345            XEnv scEnv(*
this, 
true);
 
 3360            auto const amt = 
XRP(1000);
 
 3396        for (
auto withClaim : {
false, 
true})
 
 3399            XEnv scEnv(*
this, 
true);
 
 3411            auto const amt = 
XRP(1000);
 
 3439                scEnv.
tx(txns.back()).
close();
 
 3455                BEAST_EXPECT(scCarol_bal.
diff() == amt);
 
 3459                scEnv.
tx(txns.back()).
close();
 
 3472                scEnv.
tx(txns.back()).
close();
 
 3473                BEAST_EXPECT(scBob_bal.
diff() == amt);
 
 3479        for (
auto withClaim : {
false, 
true})
 
 3482            XEnv scEnv(*
this, 
true);
 
 3494            auto const amt = 
XRP(1000);
 
 3522                scEnv.
tx(txns.back()).
close();
 
 3537                BEAST_EXPECT(scCarol_bal.
diff() == amt);
 
 3541                scEnv.
tx(txns.back()).
close();
 
 3555                scEnv.
tx(txns.back()).
close();
 
 3556                BEAST_EXPECT(scBob_bal.
diff() == amt);
 
 3566            XEnv scEnv(*
this, 
true);
 
 3578            auto const amt = 
XRP(1000);
 
 3603            BEAST_EXPECT(scCarol_bal.
diff() == amt);
 
 3608        for (
auto withClaim : {
true})
 
 3611            XEnv scEnv(*
this, 
true);
 
 3622            auto const amt = 
XRP(1000);
 
 3661        for (
auto withClaim : {
false, 
true})
 
 3664            XEnv scEnv(*
this, 
true);
 
 3675            auto const amt = 
XRP(1000);
 
 3708                claim_cost += tx_fee;
 
 3713                scAlice_bal.
diff() == -claim_cost);  
 
 3719        for (
auto withClaim : {
false, 
true})
 
 3722            XEnv scEnv(*
this, 
true);
 
 3733            auto const amt = 
XRP(1000);
 
 3765                claim_cost += tx_fee;
 
 3778        for (
auto withClaim : {
false, 
true})
 
 3781            XEnv scEnv(*
this, 
true);
 
 3786            alt_payees.back() = 
Account(
"inexistent");
 
 3795            auto const amt = 
XRP(1000);
 
 3833        for (
auto withClaim : {
false, 
true})
 
 3836            XEnv scEnv(*
this, 
true);
 
 3848            auto const amt = 
XRP(1000);
 
 3853            Balance last_signer(scEnv, unpaid);
 
 
 3925        using namespace jtx;
 
 3932            XEnv scEnv(*
this, 
true);
 
 3934            auto const amt = 
XRP(111);
 
 3935            auto const amt_plus_reward = amt + 
reward;
 
 3979            BEAST_EXPECT(carol.
diff() == -tx_fee);
 
 4066            BEAST_EXPECT(door.
diff() == -tx_fee);
 
 
 4090        using namespace jtx;
 
 4113        auto const minAccountCreate = 
XRP(20);
 
 
 4140        using namespace jtx;
 
 4142        testcase(
"Bridge Delete Door Account");
 
 4144        auto const acctDelFee{
 
 4155            for (
size_t i = 0; i < 256; ++i)
 
 4167            XEnv scEnv(*
this, 
true);
 
 4176            for (
size_t i = 0; i < 256; ++i)
 
 
 4190        using namespace jtx;
 
 4195            XEnv scEnv(*
this, 
true);
 
 4198            auto const amt = 
XRP(1000);
 
 4216                auto k = jvAtt[
"PublicKey"].asString();
 
 4218                jvAtt[
"PublicKey"] = k;
 
 4225            XEnv scEnv(*
this, 
true);
 
 4228            auto const amt = 
XRP(1000);
 
 4229            auto const rewardAmt = 
XRP(1);
 
 4246                auto k = jvAtt[
"PublicKey"].asString();
 
 4248                jvAtt[
"PublicKey"] = k;
 
 
 
 4349            for (
auto const& c : claims)
 
 
 4363            size_t num_successful = 0;
 
 4364            for (
auto const& c : claims)
 
 4375            return num_successful;
 
 
 4381            bool callback_called;
 
 4388                callback_called = 
false;
 
 4396                        auto& create_claims =
 
 4397                            claims.create_claims[c.claim_count];
 
 4398                        auto num_attns = create_claims.size();
 
 4402                                i, 
bridge, create_claims);
 
 4404                        assert(claims.create_claims[c.claim_count].empty());
 
 4409                    if (c.num_create_attn_sent >= 
bridge->quorum)
 
 4411                        callback_called = 
true;
 
 4412                        c.create_callbacks[c.claim_count](c.signers);
 
 4414                        c.num_create_attn_sent = 0;
 
 4418            } 
while (callback_called);
 
 
 4443                it->second.expectedDiff +=
 
 
 4481            for (
auto const& [acct, state] : 
accounts)
 
 4482                if (!state.verify(
env, acct))
 
 
 
 4575            return static_cast<T&
>(*this).a2b() ? 
st_->a_ : 
st_->b_;
 
 
 4581            return static_cast<T&
>(*this).a2b() ? 
st_->b_ : 
st_->a_;
 
 
 
 4677            if (counters.create_callbacks.size() < 
cr.
claim_id)
 
 4678                counters.create_callbacks.resize(
cr.
claim_id);
 
 4681                auto num_attestors = 
signers.size();
 
 4687                assert(
cr.
claim_id - 1 == counters.claim_count);
 
 4701            counters.create_callbacks[
cr.
claim_id - 1] = std::move(complete_cb);
 
 
 
 4932        bool verify_balances = 
true)
 
 4934        using namespace jtx;
 
 4944                auto vis = [&](
auto& sm) {
 
 4946                    return sm.advance(time, rnd);
 
 4948                auto& [t, sm] = *it;
 
 4956            st->sendAttestations();
 
 4962            if (verify_balances)
 
 4964                BEAST_EXPECT(st->verify());
 
 
 4972        using namespace jtx;
 
 4974        testcase(
"Bridge usage simulation");
 
 4977        XEnv scEnv(*
this, 
true);
 
 4983        Account doorXRPLocking(
"doorXRPLocking"),
 
 4984            doorUSDLocking(
"doorUSDLocking"), doorUSDIssuing(
"doorUSDIssuing");
 
 4986        constexpr size_t num_acct = 10;
 
 4987        auto a = [&doorXRPLocking, &doorUSDLocking, &doorUSDIssuing]() {
 
 4991            for (
int i = 0; i < num_acct; ++i)
 
 4996            doorXRPLocking = result.
back();
 
 4998            doorUSDLocking = result.
back();
 
 5000            doorUSDIssuing = result.
back();
 
 5004        for (
auto& acct : a)
 
 5008            mcEnv.
fund(amt, acct);
 
 5009            scEnv.
fund(amt, acct);
 
 5011        Account USDLocking{
"USDLocking"};
 
 5012        IOU usdLocking{USDLocking[
"USD"]};
 
 5013        IOU usdIssuing{doorUSDIssuing[
"USD"]};
 
 5015        mcEnv.
fund(
XRP(100000), USDLocking);
 
 5017        mcEnv.
tx(
trust(doorUSDLocking, usdLocking(100000)));
 
 5019        mcEnv.
tx(
pay(USDLocking, doorUSDLocking, usdLocking(50000)));
 
 5021        for (
int i = 0; i < a.size(); ++i)
 
 5026                mcEnv.
tx(
trust(acct, usdLocking(100000)));
 
 5027                scEnv.
tx(
trust(acct, usdIssuing(100000)));
 
 5032            st->init(s.account);
 
 5037        constexpr size_t num_ua = 20;
 
 5042            for (
int i = 0; i < num_ua; ++i)
 
 5050        auto initBridge = [&mcEnv, &scEnv, &st](
BridgeDef& bd) {
 
 5051            bd.initBridge(mcEnv, scEnv);
 
 5052            st->a_.spendFee(bd.doorA, 2);
 
 5053            st->b_.spendFee(bd.doorB, 2);
 
 5091        ac(0, st, xrp_b, {a[0], ua[0], 
XRP(777), xrp_b.reward, 
true});
 
 5092        xfer(8, st, xrp_b, {a[0], ua[0], a[2], 
XRP(3), 
true});
 
 5097        ac(0, st, xrp_b, {a[0], ua[0], 
XRP(777), xrp_b.reward, 
false});
 
 5098        xfer(8, st, xrp_b, {a[0], ua[0], a[2], 
XRP(3), 
false});
 
 5105        xfer(1, st, xrp_b, {a[1], a[1], a[1], 
XRP(1), 
true});
 
 5106        xfer(2, st, xrp_b, {a[0], a[0], a[1], 
XRP(3), 
false});
 
 5107        xfer(2, st, xrp_b, {a[1], a[1], a[1], 
XRP(5), 
false});
 
 5109        xfer(2, st, xrp_b, {a[1], a[1], a[1], 
XRP(9), 
true});
 
 5114        xfer(0, st, usd_b, {a[0], a[1], a[2], usdLocking(3), 
true});
 
 5119        xfer(0, st, usd_b, {a[0], a[0], a[1], usdLocking(6), 
true});
 
 5120        xfer(1, st, usd_b, {a[0], a[0], a[1], usdIssuing(8), 
false});
 
 5121        xfer(1, st, usd_b, {a[1], a[1], a[1], usdLocking(1), 
true});
 
 5122        xfer(2, st, usd_b, {a[0], a[0], a[1], usdIssuing(3), 
false});
 
 5123        xfer(2, st, usd_b, {a[1], a[1], a[1], usdIssuing(5), 
false});
 
 5124        xfer(2, st, usd_b, {a[0], a[0], a[1], usdIssuing(7), 
false});
 
 5125        xfer(2, st, usd_b, {a[1], a[1], a[1], usdLocking(9), 
true});
 
 5130        xfer(0, st, xrp_b, {a[0], a[0], a[0], 
XRP(1), 
true});
 
 5131        xfer(0, st, usd_b, {a[1], a[3], a[3], usdIssuing(3), 
false});
 
 5132        xfer(0, st, usd_b, {a[3], a[2], a[1], usdIssuing(5), 
false});
 
 5134        xfer(1, st, xrp_b, {a[0], a[0], a[0], 
XRP(4), 
false});
 
 5135        xfer(1, st, xrp_b, {a[1], a[1], a[0], 
XRP(8), 
true});
 
 5136        xfer(1, st, usd_b, {a[4], a[1], a[1], usdLocking(7), 
true});
 
 5138        xfer(3, st, xrp_b, {a[1], a[1], a[0], 
XRP(7), 
true});
 
 5139        xfer(3, st, xrp_b, {a[0], a[4], a[3], 
XRP(2), 
false});
 
 5140        xfer(3, st, xrp_b, {a[1], a[1], a[0], 
XRP(9), 
true});
 
 5141        xfer(3, st, usd_b, {a[3], a[1], a[1], usdIssuing(11), 
false});
 
 5146        ac(0, st, xrp_b, {a[0], ua[1], 
XRP(301), xrp_b.reward, 
true});
 
 5147        ac(0, st, xrp_b, {a[1], ua[2], 
XRP(302), xrp_b.reward, 
true});
 
 5148        ac(1, st, xrp_b, {a[0], ua[3], 
XRP(303), xrp_b.reward, 
true});
 
 5149        ac(2, st, xrp_b, {a[1], ua[4], 
XRP(304), xrp_b.reward, 
true});
 
 5150        ac(3, st, xrp_b, {a[0], ua[5], 
XRP(305), xrp_b.reward, 
true});
 
 5151        ac(4, st, xrp_b, {a[1], ua[6], 
XRP(306), xrp_b.reward, 
true});
 
 5152        ac(6, st, xrp_b, {a[0], ua[7], 
XRP(307), xrp_b.reward, 
true});
 
 5153        ac(7, st, xrp_b, {a[2], ua[8], 
XRP(308), xrp_b.reward, 
true});
 
 5154        ac(9, st, xrp_b, {a[0], ua[9], 
XRP(309), xrp_b.reward, 
true});
 
 5155        ac(9, st, xrp_b, {a[0], ua[9], 
XRP(309), xrp_b.reward, 
true});
 
 5156        ac(10, st, xrp_b, {a[0], ua[10], 
XRP(310), xrp_b.reward, 
true});
 
 5157        ac(12, st, xrp_b, {a[0], ua[11], 
XRP(311), xrp_b.reward, 
true});
 
 5158        ac(12, st, xrp_b, {a[3], ua[12], 
XRP(312), xrp_b.reward, 
true});
 
 5159        ac(12, st, xrp_b, {a[4], ua[13], 
XRP(313), xrp_b.reward, 
true});
 
 5160        ac(12, st, xrp_b, {a[3], ua[14], 
XRP(314), xrp_b.reward, 
true});
 
 5161        ac(12, st, xrp_b, {a[6], ua[15], 
XRP(315), xrp_b.reward, 
true});
 
 5162        ac(13, st, xrp_b, {a[7], ua[16], 
XRP(316), xrp_b.reward, 
true});
 
 5163        ac(15, st, xrp_b, {a[3], ua[17], 
XRP(317), xrp_b.reward, 
true});
 
 
 
 5175BEAST_DEFINE_TESTSUITE(XChainSim, app, 
ripple);
 
void pass()
Record a successful test condition.
 
testcase_t testcase
Memberspace for declaring test cases.
 
virtual Config & config()=0
 
std::unordered_set< uint256, beast::uhash<> > features
 
A currency issued by an account.
 
Issue const & issue() const
 
static constexpr TERSubset fromInt(int from)
 
std::shared_ptr< ChainStateTracker > st_
 
SmBase(std::shared_ptr< ChainStateTracker > const &chainstate, BridgeDef const &bridge)
 
BridgeDef const  & bridge_
 
ChainStateTrack & srcState()
 
jtx::Account const & srcDoor()
 
jtx::Account const & dstDoor()
 
ChainStateTrack & destState()
 
uint32_t issue_account_create()
 
SmCreateAccount(std::shared_ptr< ChainStateTracker > const &chainstate, BridgeDef const &bridge, AccountCreate create)
 
SmState advance(uint64_t time, uint32_t rnd)
 
void attest(uint64_t time, uint32_t rnd)
 
void distribute_reward(ChainStateTrack &st)
 
SmTransfer(std::shared_ptr< ChainStateTracker > const &chainstate, BridgeDef const &bridge, Transfer xfer)
 
SmState advance(uint64_t time, uint32_t rnd)
 
bool attest(uint64_t time, uint32_t rnd)
 
uint32_t create_claim_id()
 
Immutable cryptographic account descriptor.
 
static Account const master
The master account.
 
A transaction testing environment.
 
TER ter() const
Return the TER for the last JTx.
 
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.
 
void enableFeature(uint256 const feature)
 
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
 
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
 
void memoize(Account const &account)
Associate AccountID with account.
 
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
 
Converts to IOU Issue or STAmount.
 
Set the expected result code for a JTx The test will fail if the code doesn't match.
 
T emplace_back(T... args)
 
Severity
Severity level / threshold of a Journal message.
 
Keylet xChainClaimID(STXChainBridge const &bridge, std::uint64_t seq)
 
Keylet bridge(STXChainBridge const &bridge, STXChainBridge::ChainType chainType)
 
Keylet xChainCreateAccountClaimID(STXChainBridge const &bridge, std::uint64_t seq)
 
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount, NetClock::duration const &settleDelay, PublicKey const &pk, std::optional< NetClock::time_point > const &cancelAfter, std::optional< std::uint32_t > const &dstTag)
 
constexpr std::size_t UT_XCHAIN_DEFAULT_QUORUM
 
Json::Value create_account_attestation(jtx::Account const &submittingAccount, Json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, jtx::AnyAmount const &rewardAmount, jtx::Account const &rewardAccount, bool wasLockingChainSend, std::uint64_t createCount, jtx::Account const &dst, jtx::signer const &signer)
 
JValueVec claim_attestations(jtx::Account const &submittingAccount, Json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, std::vector< jtx::Account > const &rewardAccounts, bool wasLockingChainSend, std::uint64_t claimID, std::optional< jtx::Account > const &dst, std::vector< jtx::signer > const &signers, std::size_t const numAtts, std::size_t const fromIdx)
 
Json::Value bridge_create(Account const &acc, Json::Value const &bridge, STAmount const &reward, std::optional< STAmount > const &minAccountCreate)
 
Json::Value claim_attestation(jtx::Account const &submittingAccount, Json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, jtx::Account const &rewardAccount, bool wasLockingChainSend, std::uint64_t claimID, std::optional< jtx::Account > const &dst, jtx::signer const &signer)
 
Json::Value bridge(Account const &lockingChainDoor, Issue const &lockingChainIssue, Account const &issuingChainDoor, Issue const &issuingChainIssue)
 
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)
 
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
 
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
 
std::vector< Json::Value > JValueVec
 
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
 
Json::Value sidechain_xchain_account_create(Account const &acc, Json::Value const &bridge, Account const &dst, AnyAmount const &amt, AnyAmount const &reward)
 
Json::Value xchain_claim(Account const &acc, Json::Value const &bridge, std::uint32_t claimID, AnyAmount const &amt, Account const &dst)
 
constexpr std::size_t UT_XCHAIN_DEFAULT_NUM_SIGNERS
 
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()
 
Json::Value xchain_create_claim_id(Account const &acc, Json::Value const &bridge, STAmount const &reward, Account const &otherChainSource)
 
Json::Value bridge_modify(Account const &acc, Json::Value const &bridge, std::optional< STAmount > const &reward, std::optional< STAmount > const &minAccountCreate)
 
Json::Value acctdelete(Account const &account, Account const &dest)
Delete account.
 
Json::Value xchain_commit(Account const &acc, Json::Value const &bridge, std::uint32_t claimID, AnyAmount const &amt, std::optional< Account > const &dst)
 
XRP_t const XRP
Converts to XRP Issue or STAmount.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
 
STAmount divide(STAmount const &amount, Rate const &rate)
 
constexpr std::uint32_t asfDepositAuth
 
constexpr std::uint32_t asfRequireDest
 
STAmount multiply(STAmount const &amount, Rate const &rate)
 
constexpr std::uint32_t tfFillOrKill
 
@ current
This was a new validation and was added.
 
constexpr std::uint32_t asfDisableMaster
 
std::string transToken(TER code)
 
constexpr std::uint32_t tfClearAccountCreateAmount
 
@ tecXCHAIN_INSUFF_CREATE_AMOUNT
 
@ tecXCHAIN_CREATE_ACCOUNT_DISABLED
 
@ tecXCHAIN_CLAIM_NO_QUORUM
 
@ tecXCHAIN_ACCOUNT_CREATE_PAST
 
@ tecXCHAIN_REWARD_MISMATCH
 
@ tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR
 
@ tecXCHAIN_NO_SIGNERS_LIST
 
@ tecINSUFFICIENT_RESERVE
 
@ temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT
 
@ temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT
 
@ temXCHAIN_EQUAL_DOOR_ACCOUNTS
 
@ temXCHAIN_BRIDGE_NONDOOR_OWNER
 
@ temXCHAIN_BRIDGE_BAD_ISSUES
 
bool payees_received(STAmount const &reward) const
 
std::vector< balance > reward_accounts
 
BalanceTransfer(T &env, jtx::Account const &from_acct, jtx::Account const &to_acct, jtx::Account const &payor, jtx::Account const *payees, size_t num_payees, bool withClaim)
 
bool check_most_balances(STAmount const &amt, STAmount const &reward)
 
BalanceTransfer(T &env, jtx::Account const &from_acct, jtx::Account const &to_acct, jtx::Account const &payor, std::vector< jtx::Account > const &payees, bool withClaim)
 
bool has_happened(STAmount const &amt, STAmount const &reward, bool check_payer=true)
 
Balance(T &env, jtx::Account const &account)
 
jtx::Account const  & account_
 
STAmount minAccountCreate
 
void initBridge(ENV &mcEnv, ENV &scEnv)
 
std::vector< jtx::signer > const  & signers
 
std::shared_ptr< SLE const > bridge(Json::Value const &jvb)
 
SEnv(T &s, std::unique_ptr< Config > config, FeatureBitset features, std::unique_ptr< Logs > logs=nullptr, beast::severities::Severity thresh=beast::severities::kError)
 
SEnv & enableFeature(uint256 const feature)
 
std::uint64_t claimCount(Json::Value const &jvb)
 
std::shared_ptr< SLE const > account(jtx::Account const &account)
 
SEnv & multiTx(jtx::JValueVec &&jvv, FN const &... fN)
 
std::shared_ptr< SLE const > caClaimID(Json::Value const &jvb, std::uint64_t seq)
 
std::uint64_t claimID(Json::Value const &jvb)
 
std::shared_ptr< SLE const > claimID(Json::Value const &jvb, std::uint64_t seq)
 
SEnv & tx(JsonValue &&jv, FN const &... fN)
 
XRPAmount reserve(std::uint32_t count)
 
STAmount balance(jtx::Account const &account) const
 
SEnv & disableFeature(uint256 const feature)
 
STAmount balance(jtx::Account const &account, Issue const &issue) const
 
SEnv & fund(STAmount const &amount, Arg const &arg, Args const &... args)
 
std::array< bool, num_signers > attested
 
void init(ENV &env, jtx::Account const &acct)
 
bool verify(ENV &env, jtx::Account const &acct) const
 
std::vector< complete_cb > create_callbacks
 
std::vector< size_t > signers
 
uint32_t num_create_attn_sent
 
CreateClaimMap create_claims
 
SignersAttns signers_attns
 
void spend(jtx::Account const &acct, STAmount amt, std::uint64_t times=1)
 
void transfer(jtx::Account const &from, jtx::Account const &to, STAmount amt)
 
ChainStateTrack(ENV &env)
 
uint32_t sendCreateAttestations(size_t signer_idx, BridgeID bridge, CreateClaimVec &claims)
 
void spendFee(jtx::Account const &acct, size_t times=1)
 
std::map< BridgeID, BridgeCounters > counters
 
void init(jtx::Account const &acct)
 
void sendAttestations(size_t signer_idx, BridgeID bridge, ClaimVec &claims)
 
void receive(jtx::Account const &acct, STAmount amt, std::uint64_t divisor=1)
 
std::map< jtx::Account, AccountStateTrack > accounts
 
void init(jtx::Account const &acct)
 
ChainStateTracker(ENV &a_env, ENV &b_env)
 
std::array< bool, num_signers > attested
 
BridgeDef const  * BridgeID
 
void testXChainSimulation()
 
void ac(uint64_t time, std::shared_ptr< ChainStateTracker > const &chainstate, BridgeDef const &bridge, AccountCreate ac)
 
void xfer(uint64_t time, std::shared_ptr< ChainStateTracker > const &chainstate, BridgeDef const &bridge, Transfer transfer)
 
void run() override
Runs the suite.
 
static constexpr size_t num_signers
 
void runSimulation(std::shared_ptr< ChainStateTracker > const &st, bool verify_balances=true)
 
void testXChainDeleteDoor()
 
void run() override
Runs the suite.
 
void testXChainBridgeExtraFields()
 
void testXChainAddAccountCreateNonBatchAttestation()
 
XRPAmount reserve(std::uint32_t count)
 
void testXChainBridgeCreateConstraints()
 
void testXChainAddAttestation()
 
void testXChainAddClaimNonBatchAttestation()
 
void testXChainModifyBridge()
 
void testXChainCreateAccount()
 
void testXChainCreateClaimID()
 
void testXChainCreateBridgeMatrix()
 
void testXChainCreateBridge()
 
void testFeeDipsIntoReserve()
 
XEnv(T &s, bool side=false)
 
STAmount const & value() const
 
STAmount const tiny_reward_split
 
JValueVec att_create_acct_vec(std::uint64_t createCount, jtx::AnyAmount const &amt, jtx::Account const &dst, std::size_t const numAtts, std::size_t const fromIdx=0)
 
STAmount const tiny_reward
 
std::uint32_t const quorum
 
std::vector< signer > const alt_signers
 
Json::Value create_bridge(Account const &acc, Json::Value const &bridge=Json::nullValue, STAmount const &_reward=XRP(1), std::optional< STAmount > const &minAccountCreate=std::nullopt)
 
STAmount const split_reward_everyone
 
STAmount const tiny_reward_remainder
 
std::vector< Account > const payees
 
FeatureBitset const features
 
std::vector< signer > const signers
 
STAmount const split_reward_quorum
 
Set the sequence number on a JTx.
 
A signer in a SignerList.