21#include <test/jtx/Env.h>
22#include <test/jtx/attester.h>
23#include <test/jtx/multisign.h>
24#include <test/jtx/xchain_bridge.h>
25#include <xrpl/beast/unit_test/suite.h>
26#include <xrpl/protocol/Feature.h>
27#include <xrpl/protocol/Indexes.h>
28#include <xrpl/protocol/Issue.h>
29#include <xrpl/protocol/SField.h>
30#include <xrpl/protocol/STXChainBridge.h>
31#include <xrpl/protocol/Serializer.h>
32#include <xrpl/protocol/TER.h>
33#include <xrpl/protocol/XChainAttestations.h>
62 :
env_(s,
std::move(config), features,
std::move(logs), thresh)
87 template <
class Arg,
class... Args>
95 template <
class JsonValue,
class... FN>
97 tx(JsonValue&& jv, FN
const&... fN)
99 env_(std::forward<JsonValue>(jv), fN...);
103 template <
class... FN>
107 for (
auto const& jv : jvv)
133 return env_.
current()->fees().accountReserve(count);
157 if ((*r)[sfXChainBridge] == b)
170 return (*
bridge(jvb))[sfXChainAccountClaimCount];
176 return (*
bridge(jvb))[sfXChainClaimID];
212 this->
fund(xrp_funds, s.account);
227 this->
fund(xrp_funds, ra);
230 this->
fund(xrp_funds, s.account);
280 :
from_(env, from_acct)
286 for (
size_t i = 0; i < num_payees; ++i)
318 [&](
const balance& b) { return b.diff() == reward; });
332 bool check_payer =
true)
400 bool exceptionPresent =
false;
403 exceptionPresent =
false;
408 exceptionPresent =
true;
411 BEAST_EXPECT(!exceptionPresent);
415 exceptionPresent =
false;
416 jBridge[
"Extra"] = 1;
421 exceptionPresent =
true;
424 BEAST_EXPECT(exceptionPresent);
599 testcase(
"Bridge create constraints");
600 XEnv env(*
this,
true);
604 auto AUSD = A[
"USD"];
605 auto BUSD = B[
"USD"];
606 auto CUSD = C[
"USD"];
607 auto GUSD =
scGw[
"USD"];
608 auto AEUR = A[
"EUR"];
609 auto BEUR = B[
"EUR"];
610 auto CEUR = C[
"EUR"];
611 auto GEUR =
scGw[
"EUR"];
621 env.
fund(
XRP(10000), a1, a2, a3, a4, a5, a6);
644 auto const goodBridge1 =
bridge(A, GUSD, B, BUSD);
645 auto const goodBridge2 =
bridge(A, BUSD, C, CUSD);
663 .
tx(
pay(B, C, BUSD(1000)))
665 auto const aBalanceStart = env.
balance(A, BUSD);
666 auto const cBalanceStart = env.
balance(C, BUSD);
668 BEAST_EXPECT(env.
balance(A, BUSD) - aBalanceStart == BUSD(0));
669 BEAST_EXPECT(env.
balance(C, BUSD) - cBalanceStart == BUSD(-50));
671 BEAST_EXPECT(env.
balance(A, BUSD) - aBalanceStart == BUSD(60));
672 BEAST_EXPECT(env.
balance(C, BUSD) - cBalanceStart == BUSD(-50 - 60));
676 BEAST_EXPECT((*env.
bridge(goodBridge1))[sfSignatureReward] ==
XRP(33));
678 BEAST_EXPECT((*env.
bridge(goodBridge2))[sfSignatureReward] ==
XRP(44));
728 "Locking chain is IOU(locking chain door)",
729 [&](
auto& env,
bool) {
734 "Locking chain is IOU(issuing chain door funded on locking "
736 [&](
auto& env,
bool shouldFund) {
743 "Locking chain is IOU(issuing chain door account unfunded "
745 [&](
auto& env,
bool) {
750 "Locking chain is IOU(bob funded on locking chain)",
751 [&](
auto& env,
bool) {
756 "Locking chain is IOU(bob unfunded on locking chain)",
757 [&](
auto& env,
bool) {
768 "Issuing chain is IOU(issuing chain door account)",
769 [&](
auto& env,
bool) {
774 "Issuing chain is IOU(locking chain door funded on issuing "
776 [&](
auto& env,
bool shouldFund) {
783 "Issuing chain is IOU(locking chain door unfunded on "
785 [&](
auto& env,
bool) {
790 "Issuing chain is IOU(bob funded on issuing chain)",
791 [&](
auto& env,
bool) {
796 "Issuing chain is IOU(bob unfunded on issuing chain)",
797 [&](
auto& env,
bool) {
802 "Issuing chain is XRP and issuing chain door account is "
803 "not the root account",
804 [&](
auto& env,
bool) {
809 "Issuing chain is XRP and issuing chain door account is "
811 [&](
auto& env,
bool) {
862 auto testcase = [&](
auto const& lc,
auto const& ic) {
864 XEnv scEnv(*
this,
true);
866 lc.second(mcEnv,
true);
867 lc.second(scEnv,
false);
869 ic.second(mcEnv,
false);
870 ic.second(scEnv,
true);
872 auto const& expected = expected_result[test_result.
size()];
889 auto apply_ics = [&](
auto const& lc,
auto const& ics) {
891 [&](
auto const&... ic) { (
testcase(lc, ic), ...); }, ics);
894 std::apply([&](
auto const&... lc) { (apply_ics(lc, ics), ...); }, lcs);
896#if GENERATE_MTX_OUTPUT
901 std::cout <<
"Markdown output for matrix test: " << fname <<
"\n";
907 if (std::get<2>(tup))
916 auto output_table = [&](
auto print_res) {
922 res +=
"| `issuing ->` | ";
924 [&](
auto const&... ic) {
925 ((res += ic.first, res +=
" | "), ...);
932 [&](
auto const&... ic) {
933 (((void)ic.first, res +=
":---: | "), ...);
938 auto output = [&](
auto const& lc,
auto const& ic) {
939 res += print_res(test_result[test_idx]);
944 auto output_ics = [&](
auto const& lc,
auto const& ics) {
949 [&](
auto const&... ic) { (output(lc, ic), ...); }, ics);
954 [&](
auto const&... lc) { (output_ics(lc, ics), ...); }, lcs);
962 std::cout <<
"ter output for matrix test: " << ter_fname <<
"\n";
965 for (
auto& t : test_result)
1026 for (
auto withClaim : {
false,
true})
1029 XEnv scEnv(*
this,
true);
1040 auto const amt =
XRP(1000);
1081 for (
auto withClaim : {
false,
true})
1084 XEnv scEnv(*
this,
true);
1095 auto const amt =
XRP(1000);
1144 for (
auto withClaim : {
false,
true})
1147 XEnv scEnv(*
this,
true);
1158 auto const amt =
XRP(1000);
1283 using namespace jtx;
1300 XEnv xenv(*
this,
true);
1308 BEAST_EXPECT(scAlice_bal.
diff() == -tx_fee);
1373 using namespace jtx;
1388 auto const amt =
XRP(1000);
1396 BEAST_EXPECT(alice_bal.
diff() == -(claim_cost + tx_fee));
1509 using namespace jtx;
1525 for (
auto withClaim : {
true})
1528 XEnv scEnv(*
this,
true);
1542 auto const amt =
XRP(1000);
1594 for (
auto withClaim : {
false,
true})
1597 XEnv scEnv(*
this,
true);
1601 constexpr int numSigners = 4;
1606 for (
int i = 0; i < numSigners; ++i)
1608 using namespace std::literals;
1626 auto const amt =
XRP(1000);
1669 for (
auto withClaim : {
false,
true})
1672 XEnv scEnv(*
this,
true);
1676 constexpr int numSigners = 4;
1681 for (
int i = 0; i < numSigners; ++i)
1683 using namespace std::literals;
1703 auto const amt =
XRP(1000);
1747 for (
auto withClaim : {
false,
true})
1750 XEnv scEnv(*
this,
true);
1754 constexpr int numSigners = 4;
1759 for (
int i = 0; i < numSigners; ++i)
1761 using namespace std::literals;
1780 auto const amt =
XRP(1000);
1822 for (
auto withClaim : {
false,
true})
1825 XEnv scEnv(*
this,
true);
1829 constexpr int numSigners = 4;
1834 for (
int i = 0; i < numSigners; ++i)
1836 using namespace std::literals;
1855 auto const amt =
XRP(1000);
1905 XEnv scEnv(*
this,
true);
1906 auto const amt =
XRP(1000);
1907 auto const amt_plus_reward = amt +
reward;
1927 BEAST_EXPECT(carol.
diff() == -(amt +
reward + tx_fee));
1947 BEAST_EXPECT(attester.
diff() == -multiTtxFee(6));
1967 BEAST_EXPECT(attester.
diff() == -multiTtxFee(3));
1985 BEAST_EXPECT(attester.
diff() == -multiTtxFee(3));
2001 BEAST_EXPECT(door.
diff() == -amt_plus_reward);
2003 BEAST_EXPECT(attester.
diff() == -multiTtxFee(3));
2023 BEAST_EXPECT(attester.
diff() == -multiTtxFee(3));
2039 BEAST_EXPECT(door.
diff() == -amt_plus_reward);
2040 BEAST_EXPECT(attester.
diff() == -tx_fee);
2055 BEAST_EXPECT(door.
diff() == -amt_plus_reward);
2056 BEAST_EXPECT(attester.
diff() == -tx_fee);
2068 XEnv scEnv(*
this,
true);
2070 auto const amt = res0 -
XRP(1);
2071 auto const amt_plus_reward = amt +
reward;
2084 BEAST_EXPECT(door.
diff() == amt_plus_reward);
2085 BEAST_EXPECT(carol.
diff() == -(amt_plus_reward + tx_fee));
2105 BEAST_EXPECT(attester.
diff() == -multiTtxFee(4));
2114 XEnv scEnv(*
this,
true);
2116 auto const amt =
XRP(111);
2117 auto const amt_plus_reward = amt +
reward;
2130 BEAST_EXPECT(door.
diff() == amt_plus_reward);
2131 BEAST_EXPECT(carol.
diff() == -(amt_plus_reward + tx_fee));
2152 BEAST_EXPECT(door.
diff() == -amt_plus_reward);
2153 BEAST_EXPECT(attester.
diff() == -multiTtxFee(4));
2154 BEAST_EXPECT(alice.
diff() == amt);
2161 XEnv scEnv(*
this,
true);
2163 auto const amt =
XRP(1000);
2164 auto const amt_plus_reward = amt +
reward;
2177 BEAST_EXPECT(door.
diff() == amt_plus_reward);
2178 BEAST_EXPECT(carol.
diff() == -(amt_plus_reward + tx_fee));
2201 BEAST_EXPECT(attester.
diff() == -multiTtxFee(4));
2212 XEnv scEnv(*
this,
true);
2213 auto const amt =
XRP(1000);
2214 auto const amt_plus_reward = amt +
reward;
2236 BEAST_EXPECT(carol.
diff() == -(amt +
reward + tx_fee));
2247 auto const bad_amt =
XRP(10);
2258 BEAST_EXPECTS(!!scEnv.
caClaimID(
jvb, 1),
"claim id 1 created");
2259 BEAST_EXPECTS(!!scEnv.
caClaimID(
jvb, 2),
"claim id 2 created");
2260 BEAST_EXPECTS(!!scEnv.
caClaimID(
jvb, 3),
"claim id 3 created");
2294 BEAST_EXPECTS(!scEnv.
caClaimID(
jvb, 1),
"claim id 1 deleted");
2295 BEAST_EXPECTS(scEnv.
claimCount(
jvb) == 1,
"scuAlice created");
2304 BEAST_EXPECTS(!scEnv.
caClaimID(
jvb, 2),
"claim id 2 deleted");
2305 BEAST_EXPECTS(!scEnv.
caClaimID(
jvb, 1),
"claim id 1 not added");
2313 BEAST_EXPECTS(!scEnv.
caClaimID(
jvb, 3),
"claim id 3 deleted");
2324 BEAST_EXPECT(attester.
diff() == -multiTtxFee(txCount));
2337 XEnv scEnv(*
this,
true);
2359 XEnv scEnv(*
this,
true);
2382 using namespace jtx;
2384 testcase(
"Add Non Batch Claim Attestation");
2388 XEnv scEnv(*
this,
true);
2402 auto const amt =
XRP(1000);
2405 auto const dstStartBalance = scEnv.
env_.
balance(dst);
2407 for (
int i = 0; i <
signers.size(); ++i)
2420 TER const expectedTER =
2428 BEAST_EXPECT(dstStartBalance == scEnv.
env_.
balance(dst));
2431 dstStartBalance + amt == scEnv.
env_.
balance(dst));
2433 BEAST_EXPECT(dstStartBalance + amt == scEnv.
env_.
balance(dst));
2454 XEnv scEnv(*
this,
true);
2455 auto const amt =
XRP(1000);
2471 auto const dstStartBalance = scEnv.
env_.
balance(dst);
2505 att[sfAttestationSignerAccount.getJsonName()] =
2512 auto const unfundedSigner1 =
2514 auto const unfundedSigner2 =
2526 att[sfAttestationSignerAccount.getJsonName()] =
2527 unfundedSigner2.account.human();
2530 att[sfAttestationSignerAccount.getJsonName()] =
2531 unfundedSigner1.
account.human();
2548 tempSignerList.
front());
2549 att[sfAttestationSignerAccount.getJsonName()] =
2597 att.removeMember(sfAttestationSignerAccount.getJsonName());
2599 BEAST_EXPECT(dstStartBalance == scEnv.
env_.
balance(dst));
2600 att[sfAttestationSignerAccount.getJsonName()] =
2603 BEAST_EXPECT(dstStartBalance + amt == scEnv.
env_.
balance(dst));
2611 using namespace jtx;
2613 testcase(
"Add Non Batch Account Create Attestation");
2616 XEnv scEnv(*
this,
true);
2624 mcEnv.
fund(funds, a);
2625 mcEnv.
fund(funds, doorA);
2640 xrp_b.initBridge(mcEnv, scEnv);
2642 auto const amt =
XRP(777);
2643 auto const amt_plus_reward = amt + xrp_b.reward;
2645 Balance bal_doorA(mcEnv, doorA);
2650 a, xrp_b.jvb, ua, amt, xrp_b.reward))
2653 BEAST_EXPECT(bal_doorA.
diff() == amt_plus_reward);
2654 BEAST_EXPECT(bal_a.
diff() == -(amt_plus_reward + tx_fee));
2657 for (
int i = 0; i <
signers.size(); ++i)
2670 TER const expectedTER = i < xrp_b.quorum
2675 if (i + 1 < xrp_b.quorum)
2676 BEAST_EXPECT(!scEnv.
env_.
le(ua));
2678 BEAST_EXPECT(scEnv.
env_.
le(ua));
2680 BEAST_EXPECT(scEnv.
env_.
le(ua));
2686 using namespace jtx;
2697 for (
auto withClaim : {
false,
true})
2700 XEnv scEnv(*
this,
true);
2711 auto const amt =
XRP(1000);
2751 for (
auto withClaim : {
false,
true})
2754 XEnv scEnv(*
this,
true);
2766 auto const amt =
XRP(1000);
2801 for (
auto withClaim : {
false,
true})
2804 XEnv scEnv(*
this,
true);
2817 auto const amt =
XRP(1000);
2850 for (
auto withClaim : {
false,
true})
2853 XEnv scEnv(*
this,
true);
2869 auto const amt =
XRP(1000);
2908 for (
auto withClaim : {
false,
true})
2911 XEnv scEnv(*
this,
true);
2922 auto const amt =
XRP(1000);
2959 for (
auto withClaim : {
false,
true})
2962 XEnv scEnv(*
this,
true);
2973 auto const amt =
XRP(1000);
3018 for (
auto withClaim : {
false,
true})
3021 XEnv scEnv(*
this,
true);
3032 auto const amt =
XRP(1000);
3058 for (
auto withClaim : {
false,
true})
3061 XEnv scEnv(*
this,
true);
3072 auto const amt =
XRP(1000);
3079 auto tooFew =
quorum - 1;
3109 for (
auto withClaim : {
false,
true})
3112 XEnv scEnv(*
this,
true);
3123 auto const amt =
XRP(1000);
3163 for (
auto withClaim : {
true})
3166 XEnv scEnv(*
this,
true);
3177 auto const amt =
XRP(1000);
3219 for (
auto withClaim : {
true})
3222 XEnv scEnv(*
this,
true);
3233 auto const amt =
XRP(1000);
3275 for (
auto withClaim : {
false,
true})
3278 XEnv scEnv(*
this,
true);
3291 auto const amt =
XRP(1000);
3342 scEnv.
tx(txns.back());
3359 for (
auto withClaim : {
false,
true})
3362 XEnv scEnv(*
this,
true);
3377 auto const amt =
XRP(1000);
3413 for (
auto withClaim : {
false,
true})
3416 XEnv scEnv(*
this,
true);
3428 auto const amt =
XRP(1000);
3456 scEnv.
tx(txns.back()).
close();
3472 BEAST_EXPECT(scCarol_bal.
diff() == amt);
3476 scEnv.
tx(txns.back()).
close();
3489 scEnv.
tx(txns.back()).
close();
3490 BEAST_EXPECT(scBob_bal.
diff() == amt);
3496 for (
auto withClaim : {
false,
true})
3499 XEnv scEnv(*
this,
true);
3511 auto const amt =
XRP(1000);
3539 scEnv.
tx(txns.back()).
close();
3554 BEAST_EXPECT(scCarol_bal.
diff() == amt);
3558 scEnv.
tx(txns.back()).
close();
3572 scEnv.
tx(txns.back()).
close();
3573 BEAST_EXPECT(scBob_bal.
diff() == amt);
3583 XEnv scEnv(*
this,
true);
3595 auto const amt =
XRP(1000);
3620 BEAST_EXPECT(scCarol_bal.
diff() == amt);
3625 for (
auto withClaim : {
true})
3628 XEnv scEnv(*
this,
true);
3639 auto const amt =
XRP(1000);
3678 for (
auto withClaim : {
false,
true})
3681 XEnv scEnv(*
this,
true);
3692 auto const amt =
XRP(1000);
3725 claim_cost += tx_fee;
3730 scAlice_bal.
diff() == -claim_cost);
3736 for (
auto withClaim : {
false,
true})
3739 XEnv scEnv(*
this,
true);
3750 auto const amt =
XRP(1000);
3782 claim_cost += tx_fee;
3795 for (
auto withClaim : {
false,
true})
3798 XEnv scEnv(*
this,
true);
3803 alt_payees.back() =
Account(
"inexistent");
3812 auto const amt =
XRP(1000);
3850 for (
auto withClaim : {
false,
true})
3853 XEnv scEnv(*
this,
true);
3865 auto const amt =
XRP(1000);
3870 Balance last_signer(scEnv, unpaid);
3942 using namespace jtx;
3949 XEnv scEnv(*
this,
true);
3951 auto const amt =
XRP(111);
3952 auto const amt_plus_reward = amt +
reward;
3996 BEAST_EXPECT(carol.
diff() == -tx_fee);
4083 BEAST_EXPECT(door.
diff() == -tx_fee);
4107 using namespace jtx;
4130 auto const minAccountCreate =
XRP(20);
4157 using namespace jtx;
4159 testcase(
"Bridge Delete Door Account");
4161 auto const acctDelFee{
4172 for (
size_t i = 0; i < 256; ++i)
4184 XEnv scEnv(*
this,
true);
4193 for (
size_t i = 0; i < 256; ++i)
4207 using namespace jtx;
4212 XEnv scEnv(*
this,
true);
4215 auto const amt =
XRP(1000);
4233 auto k = jvAtt[
"PublicKey"].asString();
4235 jvAtt[
"PublicKey"] = k;
4242 XEnv scEnv(*
this,
true);
4245 auto const amt =
XRP(1000);
4246 auto const rewardAmt =
XRP(1);
4263 auto k = jvAtt[
"PublicKey"].asString();
4265 jvAtt[
"PublicKey"] = k;
4366 for (
auto const& c : claims)
4380 size_t num_successful = 0;
4381 for (
auto const& c : claims)
4392 return num_successful;
4398 bool callback_called;
4405 callback_called =
false;
4413 auto& create_claims =
4414 claims.create_claims[c.claim_count];
4415 auto num_attns = create_claims.size();
4419 i,
bridge, create_claims);
4421 assert(claims.create_claims[c.claim_count].empty());
4426 if (c.num_create_attn_sent >=
bridge->quorum)
4428 callback_called =
true;
4429 c.create_callbacks[c.claim_count](c.signers);
4431 c.num_create_attn_sent = 0;
4435 }
while (callback_called);
4460 it->second.expectedDiff +=
4498 for (
auto const& [acct, state] :
accounts)
4499 if (!state.verify(
env, acct))
4592 return static_cast<T&
>(*this).a2b() ?
st_->a_ :
st_->b_;
4598 return static_cast<T&
>(*this).a2b() ?
st_->b_ :
st_->a_;
4694 if (counters.create_callbacks.size() <
cr.
claim_id)
4695 counters.create_callbacks.resize(
cr.
claim_id);
4698 auto num_attestors =
signers.size();
4704 assert(
cr.
claim_id - 1 == counters.claim_count);
4718 counters.create_callbacks[
cr.
claim_id - 1] = std::move(complete_cb);
4949 bool verify_balances =
true)
4951 using namespace jtx;
4961 auto vis = [&](
auto& sm) {
4962 uint32_t rnd = distrib(gen);
4963 return sm.advance(time, rnd);
4965 auto& [t, sm] = *it;
4973 st->sendAttestations();
4979 if (verify_balances)
4981 BEAST_EXPECT(st->verify());
4989 using namespace jtx;
4991 testcase(
"Bridge usage simulation");
4994 XEnv scEnv(*
this,
true);
4996 auto st = std::make_shared<ChainStateTracker>(mcEnv, scEnv);
5000 Account doorXRPLocking(
"doorXRPLocking"),
5001 doorUSDLocking(
"doorUSDLocking"), doorUSDIssuing(
"doorUSDIssuing");
5003 constexpr size_t num_acct = 10;
5004 auto a = [&doorXRPLocking, &doorUSDLocking, &doorUSDIssuing]() {
5005 using namespace std::literals;
5008 for (
int i = 0; i < num_acct; ++i)
5013 doorXRPLocking = result.
back();
5015 doorUSDLocking = result.
back();
5017 doorUSDIssuing = result.
back();
5021 for (
auto& acct : a)
5025 mcEnv.
fund(amt, acct);
5026 scEnv.
fund(amt, acct);
5028 Account USDLocking{
"USDLocking"};
5029 IOU usdLocking{USDLocking[
"USD"]};
5030 IOU usdIssuing{doorUSDIssuing[
"USD"]};
5032 mcEnv.
fund(
XRP(100000), USDLocking);
5034 mcEnv.
tx(
trust(doorUSDLocking, usdLocking(100000)));
5036 mcEnv.
tx(
pay(USDLocking, doorUSDLocking, usdLocking(50000)));
5038 for (
int i = 0; i < a.size(); ++i)
5043 mcEnv.
tx(
trust(acct, usdLocking(100000)));
5044 scEnv.
tx(
trust(acct, usdIssuing(100000)));
5049 st->init(s.account);
5054 constexpr size_t num_ua = 20;
5056 using namespace std::literals;
5059 for (
int i = 0; i < num_ua; ++i)
5067 auto initBridge = [&mcEnv, &scEnv, &st](
BridgeDef& bd) {
5068 bd.initBridge(mcEnv, scEnv);
5069 st->a_.spendFee(bd.doorA, 2);
5070 st->b_.spendFee(bd.doorB, 2);
5108 ac(0, st, xrp_b, {a[0], ua[0],
XRP(777), xrp_b.reward,
true});
5109 xfer(8, st, xrp_b, {a[0], ua[0], a[2],
XRP(3),
true});
5114 ac(0, st, xrp_b, {a[0], ua[0],
XRP(777), xrp_b.reward,
false});
5115 xfer(8, st, xrp_b, {a[0], ua[0], a[2],
XRP(3),
false});
5122 xfer(1, st, xrp_b, {a[1], a[1], a[1],
XRP(1),
true});
5123 xfer(2, st, xrp_b, {a[0], a[0], a[1],
XRP(3),
false});
5124 xfer(2, st, xrp_b, {a[1], a[1], a[1],
XRP(5),
false});
5126 xfer(2, st, xrp_b, {a[1], a[1], a[1],
XRP(9),
true});
5131 xfer(0, st, usd_b, {a[0], a[1], a[2], usdLocking(3),
true});
5136 xfer(0, st, usd_b, {a[0], a[0], a[1], usdLocking(6),
true});
5137 xfer(1, st, usd_b, {a[0], a[0], a[1], usdIssuing(8),
false});
5138 xfer(1, st, usd_b, {a[1], a[1], a[1], usdLocking(1),
true});
5139 xfer(2, st, usd_b, {a[0], a[0], a[1], usdIssuing(3),
false});
5140 xfer(2, st, usd_b, {a[1], a[1], a[1], usdIssuing(5),
false});
5141 xfer(2, st, usd_b, {a[0], a[0], a[1], usdIssuing(7),
false});
5142 xfer(2, st, usd_b, {a[1], a[1], a[1], usdLocking(9),
true});
5147 xfer(0, st, xrp_b, {a[0], a[0], a[0],
XRP(1),
true});
5148 xfer(0, st, usd_b, {a[1], a[3], a[3], usdIssuing(3),
false});
5149 xfer(0, st, usd_b, {a[3], a[2], a[1], usdIssuing(5),
false});
5151 xfer(1, st, xrp_b, {a[0], a[0], a[0],
XRP(4),
false});
5152 xfer(1, st, xrp_b, {a[1], a[1], a[0],
XRP(8),
true});
5153 xfer(1, st, usd_b, {a[4], a[1], a[1], usdLocking(7),
true});
5155 xfer(3, st, xrp_b, {a[1], a[1], a[0],
XRP(7),
true});
5156 xfer(3, st, xrp_b, {a[0], a[4], a[3],
XRP(2),
false});
5157 xfer(3, st, xrp_b, {a[1], a[1], a[0],
XRP(9),
true});
5158 xfer(3, st, usd_b, {a[3], a[1], a[1], usdIssuing(11),
false});
5163 ac(0, st, xrp_b, {a[0], ua[1],
XRP(301), xrp_b.reward,
true});
5164 ac(0, st, xrp_b, {a[1], ua[2],
XRP(302), xrp_b.reward,
true});
5165 ac(1, st, xrp_b, {a[0], ua[3],
XRP(303), xrp_b.reward,
true});
5166 ac(2, st, xrp_b, {a[1], ua[4],
XRP(304), xrp_b.reward,
true});
5167 ac(3, st, xrp_b, {a[0], ua[5],
XRP(305), xrp_b.reward,
true});
5168 ac(4, st, xrp_b, {a[1], ua[6],
XRP(306), xrp_b.reward,
true});
5169 ac(6, st, xrp_b, {a[0], ua[7],
XRP(307), xrp_b.reward,
true});
5170 ac(7, st, xrp_b, {a[2], ua[8],
XRP(308), xrp_b.reward,
true});
5171 ac(9, st, xrp_b, {a[0], ua[9],
XRP(309), xrp_b.reward,
true});
5172 ac(9, st, xrp_b, {a[0], ua[9],
XRP(309), xrp_b.reward,
true});
5173 ac(10, st, xrp_b, {a[0], ua[10],
XRP(310), xrp_b.reward,
true});
5174 ac(12, st, xrp_b, {a[0], ua[11],
XRP(311), xrp_b.reward,
true});
5175 ac(12, st, xrp_b, {a[3], ua[12],
XRP(312), xrp_b.reward,
true});
5176 ac(12, st, xrp_b, {a[4], ua[13],
XRP(313), xrp_b.reward,
true});
5177 ac(12, st, xrp_b, {a[3], ua[14],
XRP(314), xrp_b.reward,
true});
5178 ac(12, st, xrp_b, {a[6], ua[15],
XRP(315), xrp_b.reward,
true});
5179 ac(13, st, xrp_b, {a[7], ua[16],
XRP(316), xrp_b.reward,
true});
5180 ac(15, st, xrp_b, {a[3], ua[17],
XRP(317), xrp_b.reward,
true});
5192BEAST_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_
const BridgeDef & bridge_
ChainStateTrack & srcState()
jtx::Account const & srcDoor()
SmBase(const std::shared_ptr< ChainStateTracker > &chainstate, const BridgeDef &bridge)
jtx::Account const & dstDoor()
ChainStateTrack & destState()
SmCreateAccount(const std::shared_ptr< ChainStateTracker > &chainstate, const BridgeDef &bridge, AccountCreate create)
uint32_t issue_account_create()
SmState advance(uint64_t time, uint32_t rnd)
void attest(uint64_t time, uint32_t rnd)
void distribute_reward(ChainStateTrack &st)
SmState advance(uint64_t time, uint32_t rnd)
SmTransfer(const std::shared_ptr< ChainStateTracker > &chainstate, const BridgeDef &bridge, Transfer xfer)
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)
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
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 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)
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.
FeatureBitset supported_amendments()
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, const std::shared_ptr< ChainStateTracker > &chainstate, BridgeDef const &bridge, AccountCreate ac)
void xfer(uint64_t time, const std::shared_ptr< ChainStateTracker > &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
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)
std::uint32_t const quorum
const STAmount tiny_reward_remainder
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)
const STAmount tiny_reward
const STAmount tiny_reward_split
STAmount const split_reward_everyone
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.