19#include <xrpld/core/ConfigSections.h>
20#include <xrpl/protocol/Feature.h>
21#include <xrpl/protocol/jss.h>
69 Env env{*
this, features};
74 bool const reserve1{features[featureMultiSignReserve]};
78 auto const fee = env.current()->fees().base;
79 auto const smallSignersReserve = reserve1 ?
XRP(250) :
XRP(350);
80 env.fund(smallSignersReserve -
drops(1), alice);
82 env.require(
owners(alice, 0));
89 env.require(
owners(alice, 0));
96 env.require(
owners(alice, reserve1 ? 1 : 3));
101 auto const addReserveBigSigners = reserve1 ?
XRP(0) :
XRP(350);
102 env(
pay(env.master, alice, addReserveBigSigners +
fee -
drops(1)));
118 env.require(
owners(alice, reserve1 ? 1 : 3));
125 env.require(
owners(alice, reserve1 ? 1 : 10));
130 env.require(
owners(alice, 0));
139 Env env{*
this, features};
141 env.fund(
XRP(1000), alice);
193 features[featureExpandedSignerList]
211 env.require(
owners(alice, 0));
220 Env env{*
this, features};
222 env.fund(
XRP(1000), alice);
228 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
231 auto const baseFee = env.current()->fees().base;
235 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
238 aliceSeq = env.seq(alice);
241 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
243 aliceSeq = env.seq(alice);
246 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
249 aliceSeq = env.seq(alice);
253 rpc(
"invalidTransaction",
254 "fails local checks: Duplicate Signers not allowed."));
256 BEAST_EXPECT(env.seq(alice) == aliceSeq);
259 aliceSeq = env.seq(alice);
265 BEAST_EXPECT(env.seq(alice) == aliceSeq);
269 aliceSeq = env.seq(alice);
272 BEAST_EXPECT(env.seq(alice) == aliceSeq);
275 aliceSeq = env.seq(alice);
278 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
287 Env env{*
this, features};
289 env.fund(
XRP(1000), alice);
305 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 10));
308 auto const baseFee = env.current()->fees().base;
313 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
316 aliceSeq = env.seq(alice);
319 fee((2 * baseFee) - 1),
323 BEAST_EXPECT(env.seq(alice) == aliceSeq);
326 aliceSeq = env.seq(alice);
332 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
335 aliceSeq = env.seq(alice);
338 fee((9 * baseFee) - 1),
342 BEAST_EXPECT(env.seq(alice) == aliceSeq);
351 Env env{*
this, features};
353 env.fund(
XRP(1000), alice);
360 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
363 std::reverse(phantoms.signers.begin(), phantoms.signers.end());
367 rpc(
"invalidTransaction",
368 "fails local checks: Unsorted Signers array."));
370 BEAST_EXPECT(env.seq(alice) == aliceSeq);
379 Env env{*
this, features};
383 env.fund(
XRP(1000), alice, becky, cheri);
394 BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
397 env(
signers(alice, 4, {{becky, 3}, {cheri, 4}}),
sig(alice));
399 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
402 auto const baseFee = env.current()->fees().base;
403 aliceSeq = env.seq(alice);
406 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
409 aliceSeq = env.seq(alice);
412 BEAST_EXPECT(env.seq(alice) == aliceSeq);
422 aliceSeq = env.seq(alice);
423 env(
noop(alice),
msig(becky, cheri),
fee(3 * baseFee));
425 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
434 Env env{*
this, features};
438 env.fund(
XRP(1000), alice, becky, cheri);
442 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}}),
sig(alice));
458 auto const baseFee = env.current()->fees().base;
462 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
465 aliceSeq = env.seq(alice);
471 BEAST_EXPECT(env.seq(alice) == aliceSeq);
474 aliceSeq = env.seq(alice);
477 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
479 aliceSeq = env.seq(alice);
482 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
485 aliceSeq = env.seq(alice);
490 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
496 testcase(
"Regular Signers Using submit_multisigned");
502 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
509 env.
fund(
XRP(1000), alice, becky, cheri);
513 env(
signers(alice, 2, {{becky, 1}, {cheri, 1}}),
sig(alice));
526 auto const baseFee = env.
current()->fees().base;
532 jv[jss::tx_json][jss::Account] = alice.human();
533 jv[jss::tx_json][jss::TransactionType] = jss::AccountSet;
534 jv[jss::tx_json][jss::Fee] = (8 * baseFee).jsonClipped();
535 jv[jss::tx_json][jss::Sequence] = env.
seq(alice);
536 jv[jss::tx_json][jss::SigningPubKey] =
"";
540 jv[jss::account] = cheri.human();
541 jv[jss::key_type] =
"ed25519";
542 jv[jss::passphrase] = cher.name();
545 jv[jss::account] = becky.human();
546 jv[jss::secret] = beck.name();
552 aliceSeq = env.
seq(alice);
556 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
557 BEAST_EXPECT(jrr[jss::status] ==
"success");
562 jv_two[jss::tx_json] = jrr[jss::tx_json];
564 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
565 BEAST_EXPECT(jrr[jss::status] ==
"success");
568 jv_submit[jss::tx_json] = jrr[jss::tx_json];
571 "submit_multisigned",
573 BEAST_EXPECT(jrr[jss::status] ==
"success");
575 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
580 aliceSeq = env.
seq(alice);
582 jv_one[jss::tx_json][jss::SigningPubKey] =
583 strHex(alice.pk().slice());
586 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
587 BEAST_EXPECT(jrr[jss::status] ==
"error");
588 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
590 jrr[jss::error_message] ==
591 "When multi-signing 'tx_json.SigningPubKey' must be empty.");
596 aliceSeq = env.
seq(alice);
598 jv_one[jss::tx_json][jss::Fee] = -1;
601 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
602 BEAST_EXPECT(jrr[jss::status] ==
"success");
607 jv_two[jss::tx_json] = jrr[jss::tx_json];
609 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
610 BEAST_EXPECT(jrr[jss::status] ==
"success");
613 jv_submit[jss::tx_json] = jrr[jss::tx_json];
616 "submit_multisigned",
618 BEAST_EXPECT(jrr[jss::status] ==
"error");
619 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
621 jrr[jss::error_message] ==
622 "Invalid Fee field. Fees must be greater than zero.");
627 aliceSeq = env.
seq(alice);
629 jv_one[jss::tx_json][jss::Fee] =
630 alice[
"USD"](10).value().getFullText();
633 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
634 BEAST_EXPECT(jrr[jss::status] ==
"success");
639 jv_two[jss::tx_json] = jrr[jss::tx_json];
641 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
642 BEAST_EXPECT(jrr[jss::status] ==
"success");
645 jv_submit[jss::tx_json] = jrr[jss::tx_json];
648 "submit_multisigned",
650 BEAST_EXPECT(jrr[jss::status] ==
"error");
651 BEAST_EXPECT(jrr[jss::error] ==
"internal");
652 BEAST_EXPECT(jrr[jss::error_message] ==
"Internal error.");
657 aliceSeq = env.
seq(alice);
659 jv[jss::account] = cheri.human();
660 jv[jss::secret] = cheri.name();
661 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
662 BEAST_EXPECT(jrr[jss::status] ==
"error");
663 BEAST_EXPECT(jrr[jss::error] ==
"masterDisabled");
665 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
671 aliceSeq = env.
seq(alice);
675 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
676 BEAST_EXPECT(jrr[jss::status] ==
"success");
681 jv_two[jss::tx_json] = jrr[jss::tx_json];
682 jv_two[jss::account] = becky.human();
683 jv_two[jss::key_type] =
"ed25519";
684 jv_two[jss::passphrase] = becky.name();
685 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
686 BEAST_EXPECT(jrr[jss::status] ==
"success");
689 jv_submit[jss::tx_json] = jrr[jss::tx_json];
692 "submit_multisigned",
694 BEAST_EXPECT(jrr[jss::status] ==
"success");
696 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
702 jv[jss::tx_json][jss::Account] =
"DEADBEEF";
704 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
705 BEAST_EXPECT(jrr[jss::status] ==
"error");
706 BEAST_EXPECT(jrr[jss::error] ==
"srcActMalformed");
709 jv[jss::tx_json][jss::Account] = jimmy.human();
710 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
711 BEAST_EXPECT(jrr[jss::status] ==
"error");
712 BEAST_EXPECT(jrr[jss::error] ==
"srcActNotFound");
716 aliceSeq = env.
seq(alice);
718 jv[jss::tx_json][sfSigners.fieldName] =
722 "json",
"submit_multisigned",
to_string(jv))[jss::result];
723 BEAST_EXPECT(jrr[jss::status] ==
"error");
724 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
726 jrr[jss::error_message] ==
727 "tx_json.Signers array may not be empty.");
729 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
739 Env env{*
this, features};
744 env.fund(
XRP(1000), alice, becky, cheri, daria);
765 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}, {daria, 1}, {
jinni, 1}}),
768 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 6));
771 auto const baseFee = env.current()->fees().base;
775 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
777 aliceSeq = env.seq(alice);
780 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
782 aliceSeq = env.seq(alice);
785 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
787 aliceSeq = env.seq(alice);
790 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
792 aliceSeq = env.seq(alice);
795 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
798 aliceSeq = env.seq(alice);
803 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
815 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 6));
817 aliceSeq = env.seq(alice);
822 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
825 aliceSeq = env.seq(alice);
830 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
846 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 10));
848 aliceSeq = env.seq(alice);
861 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
864 aliceSeq = env.seq(alice);
870 BEAST_EXPECT(env.seq(alice) == aliceSeq);
875 env.require(
owners(alice, 0));
886 Env env{*
this, features};
888 env.fund(
XRP(1000), alice);
928 auto const baseFee = env.current()->fees().base;
967 Env env{*
this, features};
969 env.fund(
XRP(1000), alice);
985 env.fund(
XRP(1000), becky);
987 env(
signers(becky, 1, {{alice, 1}}),
sig(becky));
1001 using namespace jtx;
1002 Env env{*
this, features};
1007 auto const USD = gw[
"USD"];
1008 env.fund(
XRP(1000), alice, becky, zelda, gw);
1013 env(
regkey(alice, alie));
1019 int const signerListOwners{features[featureMultiSignReserve] ? 1 : 4};
1020 env.require(
owners(alice, signerListOwners + 0));
1023 auto const baseFee = env.current()->fees().base;
1025 env(
pay(alice, env.master,
XRP(1)),
1029 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1032 aliceSeq = env.seq(alice);
1035 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1038 aliceSeq = env.seq(alice);
1042 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1045 env(
trust(
"alice", USD(100)),
1050 env.require(
owners(alice, signerListOwners + 1));
1053 env(
pay(gw, alice, USD(50)));
1055 env.require(
balance(alice, USD(50)));
1056 env.require(
balance(gw, alice[
"USD"](-50)));
1059 env(
offer(alice,
XRP(50), USD(50)),
1063 env.require(
owners(alice, signerListOwners + 2));
1067 aliceSeq = env.seq(alice);
1073 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1074 env.require(
owners(alice, signerListOwners + 1));
1082 env.require(
owners(alice, features[featureMultiSignReserve] ? 2 : 6));
1091 using namespace jtx;
1093 Env env{*
this, features};
1096 auto submitSTTx = [&env](
STTx const& stx) {
1098 jvResult[jss::tx_blob] =
strHex(stx.getSerializer().slice());
1099 return env.rpc(
"json",
"submit",
to_string(jvResult));
1103 env.fund(
XRP(1000), alice);
1106 auto const baseFee = env.current()->fees().base;
1112 auto const info = submitSTTx(local);
1114 info[jss::result][jss::error_exception] ==
1115 "fails local checks: Empty SigningPubKey.");
1122 auto badSig = local.
getFieldVL(sfTxnSignature);
1126 auto const info = submitSTTx(local);
1128 info[jss::result][jss::error_exception] ==
1129 "fails local checks: Invalid signature.");
1139 auto const info = submitSTTx(local);
1141 info[jss::result][jss::error_exception] ==
1142 "fails local checks: Invalid signature.");
1148 local[sfSigningPubKey] = alice.pk();
1149 auto const info = submitSTTx(local);
1151 info[jss::result][jss::error_exception] ==
1152 "fails local checks: Cannot both single- and multi-sign.");
1158 local.
sign(alice.pk(), alice.sk());
1160 auto const info = submitSTTx(local);
1162 info[jss::result][jss::error_exception] ==
1163 "fails local checks: Cannot both single- and multi-sign.");
1171 auto badSig =
signer.getFieldVL(sfTxnSignature);
1173 signer.setFieldVL(sfTxnSignature, badSig);
1175 auto const info = submitSTTx(local);
1177 info[jss::result][jss::error_exception].asString().find(
1178 "Invalid signature on account r") != std::string::npos);
1185 auto const info = submitSTTx(local);
1187 info[jss::result][jss::error_exception] ==
1188 "fails local checks: Invalid Signers array size.");
1197 features[featureExpandedSignerList] ?
msig(
1242 auto const info = submitSTTx(local);
1244 info[jss::result][jss::error_exception] ==
1245 "fails local checks: Invalid Signers array size.");
1251 auto const info = submitSTTx(local);
1253 info[jss::result][jss::error_exception] ==
1254 "fails local checks: Invalid multisigner.");
1260 auto const info = submitSTTx(local);
1262 info[jss::result][jss::error_exception] ==
1263 "fails local checks: Duplicate Signers not allowed.");
1273 auto const info = submitSTTx(local);
1275 info[jss::result][jss::error_exception] ==
1276 "fails local checks: Unsorted Signers array.");
1285 using namespace jtx;
1286 Env env{*
this, features};
1289 env.fund(
XRP(1000), alice, becky);
1292 auto const baseFee = env.current()->fees().base;
1302 testcase(
"Multisigning multisigner");
1309 using namespace jtx;
1310 Env env{*
this, features};
1313 env.fund(
XRP(1000), alice, becky);
1317 env(
signers(alice, 1, {{becky, 1}}));
1326 auto const baseFee = env.current()->fees().base;
1385 using namespace jtx;
1391 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
1403 auto const baseFee = env.
current()->fees().base;
1407 jvSig1[jss::tx_json][jss::Account] = alice.human();
1408 jvSig1[jss::tx_json][jss::Amount] = 10000000;
1409 jvSig1[jss::tx_json][jss::Destination] = env.
master.
human();
1410 jvSig1[jss::tx_json][jss::Fee] = (3 * baseFee).jsonClipped();
1411 jvSig1[jss::tx_json][jss::Sequence] = env.
seq(alice);
1412 jvSig1[jss::tx_json][jss::TransactionType] = jss::Payment;
1415 BEAST_EXPECT(jvSig2[jss::result][jss::status].asString() ==
"success");
1419 jvSig2[jss::result][jss::tx_json][jss::hash].
asString();
1422 jvSig2[jss::result][jss::account] =
ghost.
human();
1423 jvSig2[jss::result][jss::secret] =
ghost.
name();
1425 env.
rpc(
"json",
"sign_for",
to_string(jvSig2[jss::result]));
1427 jvSubmit[jss::result][jss::status].asString() ==
"success");
1431 jvSubmit[jss::result][jss::tx_json][jss::hash].
asString();
1432 BEAST_EXPECT(hash1 != hash2);
1436 "json",
"submit_multisigned",
to_string(jvSubmit[jss::result]));
1438 jvResult[jss::result][jss::status].asString() ==
"success");
1440 jvResult[jss::result][jss::engine_result].asString() ==
1446 hash2 == jvResult[jss::result][jss::tx_json][jss::hash].asString());
1452 BEAST_EXPECT(jvTx[jss::result][jss::status].asString() ==
"success");
1453 BEAST_EXPECT(jvTx[jss::result][jss::validated].asString() ==
"true");
1455 jvTx[jss::result][jss::meta][sfTransactionResult.jsonName]
1468 using namespace jtx;
1475 env.fund(
XRP(1000), alice, becky, cheri, daria);
1493 env.require(
owners(alice, 3));
1494 env.require(
owners(becky, 10));
1497 env.enableFeature(featureMultiSignReserve);
1515 env.require(
owners(alice, 3));
1516 env.require(
owners(becky, 10));
1517 env.require(
owners(cheri, 1));
1518 env.require(
owners(daria, 1));
1536 env.require(
owners(alice, 1));
1537 env.require(
owners(becky, 0));
1538 env.require(
owners(cheri, 1));
1539 env.require(
owners(daria, 1));
1548 env.require(
owners(alice, 0));
1549 env.require(
owners(becky, 0));
1550 env.require(
owners(cheri, 0));
1551 env.require(
owners(daria, 0));
1559 using namespace jtx;
1560 Env env{*
this, features};
1562 env.fund(
XRP(2000), alice);
1575 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1576 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1579 auto const baseFee = env.current()->fees().base;
1585 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1586 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1591 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1592 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1598 if (!features[featureExpandedSignerList])
1603 using namespace jtx;
1604 Env env{*
this, features};
1606 env.fund(
XRP(1000), alice);
1608 uint8_t tag1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1609 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1610 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1611 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1614 "hello world some ascii 32b long";
1622 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
1625 auto const baseFee = env.current()->fees().base;
1629 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1632 aliceSeq = env.seq(alice);
1635 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1637 aliceSeq = env.seq(alice);
1640 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1643 aliceSeq = env.seq(alice);
1647 rpc(
"invalidTransaction",
1648 "fails local checks: Duplicate Signers not allowed."));
1650 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1653 aliceSeq = env.seq(alice);
1659 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1663 aliceSeq = env.seq(alice);
1666 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1669 aliceSeq = env.seq(alice);
1672 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1678 using namespace test::jtx;
1680 Env env{*
this, features};
1683 env.fund(
XRP(1000), alice);
1686 bool const enabled = features[fixInvalidTxFlags];
1689 (enabled ?
"enabled" :
"disabled"));
1724 using namespace jtx;
1731 testAll(
all - featureMultiSignReserve - featureExpandedSignerList);
1742BEAST_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
Json::Value noop(Account const &account)
The null transaction.
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.
FeatureBitset supported_amendments()
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.