20#include <xrpld/core/ConfigSections.h>
22#include <xrpl/protocol/Feature.h>
23#include <xrpl/protocol/jss.h>
71 Env env{*
this, features};
76 bool const reserve1{features[featureMultiSignReserve]};
80 auto const fee = env.current()->fees().base;
81 auto const smallSignersReserve = reserve1 ?
XRP(250) :
XRP(350);
82 env.fund(smallSignersReserve -
drops(1), alice);
84 env.require(
owners(alice, 0));
91 env.require(
owners(alice, 0));
98 env.require(
owners(alice, reserve1 ? 1 : 3));
103 auto const addReserveBigSigners = reserve1 ?
XRP(0) :
XRP(350);
104 env(
pay(env.master, alice, addReserveBigSigners +
fee -
drops(1)));
120 env.require(
owners(alice, reserve1 ? 1 : 3));
127 env.require(
owners(alice, reserve1 ? 1 : 10));
132 env.require(
owners(alice, 0));
141 Env env{*
this, features};
143 env.fund(
XRP(1000), alice);
196 features[featureExpandedSignerList]
214 env.require(
owners(alice, 0));
223 Env env{*
this, features};
225 env.fund(
XRP(1000), alice);
231 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
234 auto const baseFee = env.current()->fees().base;
238 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
241 aliceSeq = env.seq(alice);
244 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
246 aliceSeq = env.seq(alice);
249 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
252 aliceSeq = env.seq(alice);
256 rpc(
"invalidTransaction",
257 "fails local checks: Duplicate Signers not allowed."));
259 BEAST_EXPECT(env.seq(alice) == aliceSeq);
262 aliceSeq = env.seq(alice);
268 BEAST_EXPECT(env.seq(alice) == aliceSeq);
272 aliceSeq = env.seq(alice);
275 BEAST_EXPECT(env.seq(alice) == aliceSeq);
278 aliceSeq = env.seq(alice);
281 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
290 Env env{*
this, features};
292 env.fund(
XRP(1000), alice);
308 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 10));
311 auto const baseFee = env.current()->fees().base;
316 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
319 aliceSeq = env.seq(alice);
322 fee((2 * baseFee) - 1),
326 BEAST_EXPECT(env.seq(alice) == aliceSeq);
329 aliceSeq = env.seq(alice);
335 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
338 aliceSeq = env.seq(alice);
341 fee((9 * baseFee) - 1),
345 BEAST_EXPECT(env.seq(alice) == aliceSeq);
354 Env env{*
this, features};
356 env.fund(
XRP(1000), alice);
363 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
366 std::reverse(phantoms.signers.begin(), phantoms.signers.end());
370 rpc(
"invalidTransaction",
371 "fails local checks: Unsorted Signers array."));
373 BEAST_EXPECT(env.seq(alice) == aliceSeq);
382 Env env{*
this, features};
386 env.fund(
XRP(1000), alice, becky, cheri);
397 BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
400 env(
signers(alice, 4, {{becky, 3}, {cheri, 4}}),
sig(alice));
402 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
405 auto const baseFee = env.current()->fees().base;
406 aliceSeq = env.seq(alice);
409 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
412 aliceSeq = env.seq(alice);
415 BEAST_EXPECT(env.seq(alice) == aliceSeq);
425 aliceSeq = env.seq(alice);
426 env(
noop(alice),
msig(becky, cheri),
fee(3 * baseFee));
428 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
437 Env env{*
this, features};
441 env.fund(
XRP(1000), alice, becky, cheri);
445 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}}),
sig(alice));
461 auto const baseFee = env.current()->fees().base;
465 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
468 aliceSeq = env.seq(alice);
474 BEAST_EXPECT(env.seq(alice) == aliceSeq);
477 aliceSeq = env.seq(alice);
480 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
482 aliceSeq = env.seq(alice);
485 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
488 aliceSeq = env.seq(alice);
493 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
499 testcase(
"Regular Signers Using submit_multisigned");
505 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
512 env.
fund(
XRP(1000), alice, becky, cheri);
516 env(
signers(alice, 2, {{becky, 1}, {cheri, 1}}),
sig(alice));
529 auto const baseFee = env.
current()->fees().base;
535 jv[jss::tx_json][jss::Account] = alice.human();
536 jv[jss::tx_json][jss::TransactionType] = jss::AccountSet;
537 jv[jss::tx_json][jss::Fee] = (8 * baseFee).jsonClipped();
538 jv[jss::tx_json][jss::Sequence] = env.
seq(alice);
539 jv[jss::tx_json][jss::SigningPubKey] =
"";
543 jv[jss::account] = cheri.human();
544 jv[jss::key_type] =
"ed25519";
545 jv[jss::passphrase] = cher.name();
548 jv[jss::account] = becky.human();
549 jv[jss::secret] = beck.name();
555 aliceSeq = env.
seq(alice);
559 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
560 BEAST_EXPECT(jrr[jss::status] ==
"success");
565 jv_two[jss::tx_json] = jrr[jss::tx_json];
567 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
568 BEAST_EXPECT(jrr[jss::status] ==
"success");
571 jv_submit[jss::tx_json] = jrr[jss::tx_json];
574 "submit_multisigned",
576 BEAST_EXPECT(jrr[jss::status] ==
"success");
578 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
583 aliceSeq = env.
seq(alice);
585 jv_one[jss::tx_json][jss::SigningPubKey] =
586 strHex(alice.pk().slice());
589 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
590 BEAST_EXPECT(jrr[jss::status] ==
"error");
591 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
593 jrr[jss::error_message] ==
594 "When multi-signing 'tx_json.SigningPubKey' must be empty.");
599 aliceSeq = env.
seq(alice);
601 jv_one[jss::tx_json][jss::Fee] = -1;
604 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
605 BEAST_EXPECT(jrr[jss::status] ==
"success");
610 jv_two[jss::tx_json] = jrr[jss::tx_json];
612 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
613 BEAST_EXPECT(jrr[jss::status] ==
"success");
616 jv_submit[jss::tx_json] = jrr[jss::tx_json];
619 "submit_multisigned",
621 BEAST_EXPECT(jrr[jss::status] ==
"error");
622 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
624 jrr[jss::error_message] ==
625 "Invalid Fee field. Fees must be greater than zero.");
630 aliceSeq = env.
seq(alice);
632 jv_one[jss::tx_json][jss::Fee] =
633 alice[
"USD"](10).value().getFullText();
636 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
637 BEAST_EXPECT(jrr[jss::status] ==
"success");
642 jv_two[jss::tx_json] = jrr[jss::tx_json];
644 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
645 BEAST_EXPECT(jrr[jss::status] ==
"success");
648 jv_submit[jss::tx_json] = jrr[jss::tx_json];
651 "submit_multisigned",
653 BEAST_EXPECT(jrr[jss::status] ==
"error");
654 BEAST_EXPECT(jrr[jss::error] ==
"internal");
655 BEAST_EXPECT(jrr[jss::error_message] ==
"Internal error.");
660 aliceSeq = env.
seq(alice);
662 jv[jss::account] = cheri.human();
663 jv[jss::secret] = cheri.name();
664 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
665 BEAST_EXPECT(jrr[jss::status] ==
"error");
666 BEAST_EXPECT(jrr[jss::error] ==
"masterDisabled");
668 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
674 aliceSeq = env.
seq(alice);
678 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
679 BEAST_EXPECT(jrr[jss::status] ==
"success");
684 jv_two[jss::tx_json] = jrr[jss::tx_json];
685 jv_two[jss::account] = becky.human();
686 jv_two[jss::key_type] =
"ed25519";
687 jv_two[jss::passphrase] = becky.name();
688 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
689 BEAST_EXPECT(jrr[jss::status] ==
"success");
692 jv_submit[jss::tx_json] = jrr[jss::tx_json];
695 "submit_multisigned",
697 BEAST_EXPECT(jrr[jss::status] ==
"success");
699 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
705 jv[jss::tx_json][jss::Account] =
"DEADBEEF";
707 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
708 BEAST_EXPECT(jrr[jss::status] ==
"error");
709 BEAST_EXPECT(jrr[jss::error] ==
"srcActMalformed");
712 jv[jss::tx_json][jss::Account] = jimmy.human();
713 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
714 BEAST_EXPECT(jrr[jss::status] ==
"error");
715 BEAST_EXPECT(jrr[jss::error] ==
"srcActNotFound");
719 aliceSeq = env.
seq(alice);
721 jv[jss::tx_json][sfSigners.fieldName] =
725 "json",
"submit_multisigned",
to_string(jv))[jss::result];
726 BEAST_EXPECT(jrr[jss::status] ==
"error");
727 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
729 jrr[jss::error_message] ==
730 "tx_json.Signers array may not be empty.");
732 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
742 Env env{*
this, features};
747 env.fund(
XRP(1000), alice, becky, cheri, daria);
768 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}, {daria, 1}, {
jinni, 1}}),
771 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 6));
774 auto const baseFee = env.current()->fees().base;
778 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
780 aliceSeq = env.seq(alice);
783 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
785 aliceSeq = env.seq(alice);
788 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
790 aliceSeq = env.seq(alice);
793 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
795 aliceSeq = env.seq(alice);
798 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
801 aliceSeq = env.seq(alice);
806 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
818 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 6));
820 aliceSeq = env.seq(alice);
825 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
828 aliceSeq = env.seq(alice);
833 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
849 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 10));
851 aliceSeq = env.seq(alice);
864 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
867 aliceSeq = env.seq(alice);
873 BEAST_EXPECT(env.seq(alice) == aliceSeq);
878 env.require(
owners(alice, 0));
889 Env env{*
this, features};
891 env.fund(
XRP(1000), alice);
932 auto const baseFee = env.current()->fees().base;
971 Env env{*
this, features};
973 env.fund(
XRP(1000), alice);
990 env.fund(
XRP(1000), becky);
993 env(
signers(becky, 1, {{alice, 1}}),
sig(becky));
1007 using namespace jtx;
1008 Env env{*
this, features};
1013 auto const USD = gw[
"USD"];
1014 env.fund(
XRP(1000), alice, becky, zelda, gw);
1019 env(
regkey(alice, alie));
1025 int const signerListOwners{features[featureMultiSignReserve] ? 1 : 4};
1026 env.require(
owners(alice, signerListOwners + 0));
1029 auto const baseFee = env.current()->fees().base;
1031 env(
pay(alice, env.master,
XRP(1)),
1035 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1038 aliceSeq = env.seq(alice);
1041 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1044 aliceSeq = env.seq(alice);
1048 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1051 env(
trust(
"alice", USD(100)),
1056 env.require(
owners(alice, signerListOwners + 1));
1059 env(
pay(gw, alice, USD(50)));
1061 env.require(
balance(alice, USD(50)));
1062 env.require(
balance(gw, alice[
"USD"](-50)));
1065 env(
offer(alice,
XRP(50), USD(50)),
1069 env.require(
owners(alice, signerListOwners + 2));
1073 aliceSeq = env.seq(alice);
1079 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1080 env.require(
owners(alice, signerListOwners + 1));
1088 env.require(
owners(alice, features[featureMultiSignReserve] ? 2 : 6));
1097 using namespace jtx;
1099 Env env{*
this, features};
1102 auto submitSTTx = [&env](
STTx const& stx) {
1104 jvResult[jss::tx_blob] =
strHex(stx.getSerializer().slice());
1105 return env.rpc(
"json",
"submit",
to_string(jvResult));
1109 env.fund(
XRP(1000), alice);
1113 auto const baseFee = env.current()->fees().base;
1119 auto const info = submitSTTx(local);
1121 info[jss::result][jss::error_exception] ==
1122 "fails local checks: Empty SigningPubKey.");
1129 auto badSig = local.
getFieldVL(sfTxnSignature);
1133 auto const info = submitSTTx(local);
1135 info[jss::result][jss::error_exception] ==
1136 "fails local checks: Invalid signature.");
1146 auto const info = submitSTTx(local);
1148 info[jss::result][jss::error_exception] ==
1149 "fails local checks: Invalid signature.");
1155 local[sfSigningPubKey] = alice.pk();
1156 auto const info = submitSTTx(local);
1158 info[jss::result][jss::error_exception] ==
1159 "fails local checks: Cannot both single- and multi-sign.");
1165 local.
sign(alice.pk(), alice.sk());
1167 auto const info = submitSTTx(local);
1169 info[jss::result][jss::error_exception] ==
1170 "fails local checks: Cannot both single- and multi-sign.");
1178 auto badSig =
signer.getFieldVL(sfTxnSignature);
1180 signer.setFieldVL(sfTxnSignature, badSig);
1182 auto const info = submitSTTx(local);
1184 info[jss::result][jss::error_exception].asString().find(
1185 "Invalid signature on account r") != std::string::npos);
1192 auto const info = submitSTTx(local);
1194 info[jss::result][jss::error_exception] ==
1195 "fails local checks: Invalid Signers array size.");
1204 features[featureExpandedSignerList] ?
msig(
1249 auto const info = submitSTTx(local);
1251 info[jss::result][jss::error_exception] ==
1252 "fails local checks: Invalid Signers array size.");
1258 auto const info = submitSTTx(local);
1260 info[jss::result][jss::error_exception] ==
1261 "fails local checks: Invalid multisigner.");
1267 auto const info = submitSTTx(local);
1269 info[jss::result][jss::error_exception] ==
1270 "fails local checks: Duplicate Signers not allowed.");
1280 auto const info = submitSTTx(local);
1282 info[jss::result][jss::error_exception] ==
1283 "fails local checks: Unsorted Signers array.");
1292 using namespace jtx;
1293 Env env{*
this, features};
1296 env.fund(
XRP(1000), alice, becky);
1299 auto const baseFee = env.current()->fees().base;
1309 testcase(
"Multisigning multisigner");
1316 using namespace jtx;
1317 Env env{*
this, features};
1320 env.fund(
XRP(1000), alice, becky);
1324 env(
signers(alice, 1, {{becky, 1}}));
1333 auto const baseFee = env.current()->fees().base;
1392 using namespace jtx;
1398 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
1410 auto const baseFee = env.
current()->fees().base;
1414 jvSig1[jss::tx_json][jss::Account] = alice.human();
1415 jvSig1[jss::tx_json][jss::Amount] = 10000000;
1416 jvSig1[jss::tx_json][jss::Destination] = env.
master.
human();
1417 jvSig1[jss::tx_json][jss::Fee] = (3 * baseFee).jsonClipped();
1418 jvSig1[jss::tx_json][jss::Sequence] = env.
seq(alice);
1419 jvSig1[jss::tx_json][jss::TransactionType] = jss::Payment;
1422 BEAST_EXPECT(jvSig2[jss::result][jss::status].asString() ==
"success");
1426 jvSig2[jss::result][jss::tx_json][jss::hash].
asString();
1429 jvSig2[jss::result][jss::account] =
ghost.
human();
1430 jvSig2[jss::result][jss::secret] =
ghost.
name();
1432 env.
rpc(
"json",
"sign_for",
to_string(jvSig2[jss::result]));
1434 jvSubmit[jss::result][jss::status].asString() ==
"success");
1438 jvSubmit[jss::result][jss::tx_json][jss::hash].
asString();
1439 BEAST_EXPECT(hash1 != hash2);
1443 "json",
"submit_multisigned",
to_string(jvSubmit[jss::result]));
1445 jvResult[jss::result][jss::status].asString() ==
"success");
1447 jvResult[jss::result][jss::engine_result].asString() ==
1453 hash2 == jvResult[jss::result][jss::tx_json][jss::hash].asString());
1459 BEAST_EXPECT(jvTx[jss::result][jss::status].asString() ==
"success");
1460 BEAST_EXPECT(jvTx[jss::result][jss::validated].asString() ==
"true");
1462 jvTx[jss::result][jss::meta][sfTransactionResult.jsonName]
1475 using namespace jtx;
1482 env.fund(
XRP(1000), alice, becky, cheri, daria);
1500 env.require(
owners(alice, 3));
1501 env.require(
owners(becky, 10));
1504 env.enableFeature(featureMultiSignReserve);
1522 env.require(
owners(alice, 3));
1523 env.require(
owners(becky, 10));
1524 env.require(
owners(cheri, 1));
1525 env.require(
owners(daria, 1));
1543 env.require(
owners(alice, 1));
1544 env.require(
owners(becky, 0));
1545 env.require(
owners(cheri, 1));
1546 env.require(
owners(daria, 1));
1555 env.require(
owners(alice, 0));
1556 env.require(
owners(becky, 0));
1557 env.require(
owners(cheri, 0));
1558 env.require(
owners(daria, 0));
1566 using namespace jtx;
1567 Env env{*
this, features};
1569 env.fund(
XRP(2000), alice);
1582 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1583 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1586 auto const baseFee = env.current()->fees().base;
1592 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1593 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1598 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1599 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1605 if (!features[featureExpandedSignerList])
1610 using namespace jtx;
1611 Env env{*
this, features};
1613 env.fund(
XRP(1000), alice);
1615 uint8_t tag1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1616 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1617 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1618 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1621 "hello world some ascii 32b long";
1629 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
1632 auto const baseFee = env.current()->fees().base;
1636 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1639 aliceSeq = env.seq(alice);
1642 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1644 aliceSeq = env.seq(alice);
1647 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1650 aliceSeq = env.seq(alice);
1654 rpc(
"invalidTransaction",
1655 "fails local checks: Duplicate Signers not allowed."));
1657 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1660 aliceSeq = env.seq(alice);
1666 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1670 aliceSeq = env.seq(alice);
1673 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1676 aliceSeq = env.seq(alice);
1679 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1685 using namespace test::jtx;
1687 Env env{*
this, features};
1690 env.fund(
XRP(1000), alice);
1693 bool const enabled = features[fixInvalidTxFlags];
1696 (enabled ?
"enabled" :
"disabled"));
1711 using namespace jtx;
1712 Env env{*
this, features};
1714 env.fund(
XRP(1000), alice);
1724 BEAST_EXPECT(sle->getFieldArray(sfSignerEntries).size() == 2);
1725 if (features[fixIncludeKeyletFields])
1727 BEAST_EXPECT((*sle)[sfOwner] == alice.id());
1731 BEAST_EXPECT(!sle->isFieldPresent(sfOwner));
1761 using namespace jtx;
1768 testAll(
all - featureMultiSignReserve - featureExpandedSignerList);
1782BEAST_DEFINE_TESTSUITE(MultiSign, app,
ripple);
const_iterator begin() const
const_iterator end() const
std::string asString() const
Returns the unquoted string value.
testcase_t testcase
Memberspace for declaring test cases.
Blob getFieldVL(SField const &field) const
std::uint32_t getFieldU32(SField const &field) const
void setFieldU32(SField const &field, std::uint32_t)
STArray & peekFieldArray(SField const &field)
void setFieldVL(SField const &field, Blob const &)
void sign(PublicKey const &publicKey, SecretKey const &secretKey)
static base_uint fromVoid(void const *data)
void testSignersWithTickets(FeatureBitset features)
void testSignersWithTags(FeatureBitset features)
void testAmendmentTransition()
void testSignForHash(FeatureBitset features)
void run() override
Runs the suite.
void testPhantomSigners(FeatureBitset features)
void testHeterogeneousSigners(FeatureBitset features)
void testMisorderedSigners(FeatureBitset features)
void testSignerListObject(FeatureBitset features)
void testAll(FeatureBitset features)
void testMasterSigners(FeatureBitset features)
void testKeyDisable(FeatureBitset features)
void testRegularSignersUsingSubmitMulti(FeatureBitset features)
void testBadSignatureText(FeatureBitset features)
void testSignerListSetFlags(FeatureBitset features)
void testFee(FeatureBitset features)
void testMultisigningMultisigner(FeatureBitset features)
void testSignerListSet(FeatureBitset features)
void testNoMultiSigners(FeatureBitset features)
void testNoReserve(FeatureBitset features)
void testRegularSigners(FeatureBitset features)
void testRegKey(FeatureBitset features)
void testTxTypes(FeatureBitset features)
Immutable cryptographic account descriptor.
std::string const & name() const
Return the name.
std::string const & human() const
Returns the human readable public key.
A transaction testing environment.
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.
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)
Set a multisignature on a JTx.
Match the number of items in the account's owner directory.
Check a set of conditions.
Set the expected result code for a JTx The test will fail if the code doesn't match.
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)
Keylet signers(AccountID const &account) noexcept
A SignerList.
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
owner_count< ltRIPPLE_STATE > lines
Match the number of trust lines in the account's owner directory.
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
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.
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()
static disabled_t const disabled
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
owner_count< ltTICKET > tickets
Match the number of tickets on the account.
XRP_t const XRP
Converts to XRP Issue or STAmount.
Json::Value offer_cancel(Account const &account, std::uint32_t offerSeq)
Cancel an offer.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t tfPassive
constexpr std::uint32_t asfDisableMaster
std::string strHex(FwdIt begin, FwdIt end)
@ tecINSUFFICIENT_RESERVE
std::vector< unsigned char > Blob
Storage for linear binary data.
std::string to_string(base_uint< Bits, Tag > const &a)
TERSubset< CanCvtToTER > TER
Execution context for applying a JSON transaction.
std::shared_ptr< STTx const > stx
Set the sequence number on a JTx.
A signer in a SignerList.