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"));
1731 using namespace jtx;
1738 testAll(
all - featureMultiSignReserve - featureExpandedSignerList);
1749BEAST_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 test_masterSigners(FeatureBitset features)
void test_phantomSigners(FeatureBitset features)
void test_fee(FeatureBitset features)
void test_signerListSet(FeatureBitset features)
void run() override
Runs the suite.
void test_misorderedSigners(FeatureBitset features)
void test_txTypes(FeatureBitset features)
void test_regKey(FeatureBitset features)
void test_signersWithTickets(FeatureBitset features)
void testAll(FeatureBitset features)
void test_signerListSetFlags(FeatureBitset features)
void test_signForHash(FeatureBitset features)
void test_noMultiSigners(FeatureBitset features)
void test_regularSignersUsingSubmitMulti(FeatureBitset features)
void test_keyDisable(FeatureBitset features)
void test_regularSigners(FeatureBitset features)
void test_signersWithTags(FeatureBitset features)
void test_amendmentTransition()
void test_noReserve(FeatureBitset features)
void test_heterogeneousSigners(FeatureBitset features)
void test_multisigningMultisigner(FeatureBitset features)
void test_badSignatureText(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)
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.