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);
195 features[featureExpandedSignerList]
213 env.require(
owners(alice, 0));
222 Env env{*
this, features};
224 env.fund(
XRP(1000), alice);
230 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
233 auto const baseFee = env.current()->fees().base;
237 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
240 aliceSeq = env.seq(alice);
243 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
245 aliceSeq = env.seq(alice);
248 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
251 aliceSeq = env.seq(alice);
255 rpc(
"invalidTransaction",
256 "fails local checks: Duplicate Signers not allowed."));
258 BEAST_EXPECT(env.seq(alice) == aliceSeq);
261 aliceSeq = env.seq(alice);
267 BEAST_EXPECT(env.seq(alice) == aliceSeq);
271 aliceSeq = env.seq(alice);
274 BEAST_EXPECT(env.seq(alice) == aliceSeq);
277 aliceSeq = env.seq(alice);
280 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
289 Env env{*
this, features};
291 env.fund(
XRP(1000), alice);
307 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 10));
310 auto const baseFee = env.current()->fees().base;
315 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
318 aliceSeq = env.seq(alice);
321 fee((2 * baseFee) - 1),
325 BEAST_EXPECT(env.seq(alice) == aliceSeq);
328 aliceSeq = env.seq(alice);
334 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
337 aliceSeq = env.seq(alice);
340 fee((9 * baseFee) - 1),
344 BEAST_EXPECT(env.seq(alice) == aliceSeq);
353 Env env{*
this, features};
355 env.fund(
XRP(1000), alice);
362 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
365 std::reverse(phantoms.signers.begin(), phantoms.signers.end());
369 rpc(
"invalidTransaction",
370 "fails local checks: Unsorted Signers array."));
372 BEAST_EXPECT(env.seq(alice) == aliceSeq);
381 Env env{*
this, features};
385 env.fund(
XRP(1000), alice, becky, cheri);
396 BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
399 env(
signers(alice, 4, {{becky, 3}, {cheri, 4}}),
sig(alice));
401 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
404 auto const baseFee = env.current()->fees().base;
405 aliceSeq = env.seq(alice);
408 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
411 aliceSeq = env.seq(alice);
414 BEAST_EXPECT(env.seq(alice) == aliceSeq);
424 aliceSeq = env.seq(alice);
425 env(
noop(alice),
msig(becky, cheri),
fee(3 * baseFee));
427 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
436 Env env{*
this, features};
440 env.fund(
XRP(1000), alice, becky, cheri);
444 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}}),
sig(alice));
460 auto const baseFee = env.current()->fees().base;
464 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
467 aliceSeq = env.seq(alice);
473 BEAST_EXPECT(env.seq(alice) == aliceSeq);
476 aliceSeq = env.seq(alice);
479 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
481 aliceSeq = env.seq(alice);
484 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
487 aliceSeq = env.seq(alice);
492 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
498 testcase(
"Regular Signers Using submit_multisigned");
504 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
511 env.
fund(
XRP(1000), alice, becky, cheri);
515 env(
signers(alice, 2, {{becky, 1}, {cheri, 1}}),
sig(alice));
528 auto const baseFee = env.
current()->fees().base;
534 jv[jss::tx_json][jss::Account] = alice.human();
535 jv[jss::tx_json][jss::TransactionType] = jss::AccountSet;
536 jv[jss::tx_json][jss::Fee] = (8 * baseFee).jsonClipped();
537 jv[jss::tx_json][jss::Sequence] = env.
seq(alice);
538 jv[jss::tx_json][jss::SigningPubKey] =
"";
542 jv[jss::account] = cheri.human();
543 jv[jss::key_type] =
"ed25519";
544 jv[jss::passphrase] = cher.name();
547 jv[jss::account] = becky.human();
548 jv[jss::secret] = beck.name();
554 aliceSeq = env.
seq(alice);
558 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
559 BEAST_EXPECT(jrr[jss::status] ==
"success");
564 jv_two[jss::tx_json] = jrr[jss::tx_json];
566 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
567 BEAST_EXPECT(jrr[jss::status] ==
"success");
570 jv_submit[jss::tx_json] = jrr[jss::tx_json];
573 "submit_multisigned",
575 BEAST_EXPECT(jrr[jss::status] ==
"success");
577 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
582 aliceSeq = env.
seq(alice);
584 jv_one[jss::tx_json][jss::SigningPubKey] =
585 strHex(alice.pk().slice());
588 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
589 BEAST_EXPECT(jrr[jss::status] ==
"error");
590 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
592 jrr[jss::error_message] ==
593 "When multi-signing 'tx_json.SigningPubKey' must be empty.");
598 aliceSeq = env.
seq(alice);
600 jv_one[jss::tx_json][jss::Fee] = -1;
603 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
604 BEAST_EXPECT(jrr[jss::status] ==
"success");
609 jv_two[jss::tx_json] = jrr[jss::tx_json];
611 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
612 BEAST_EXPECT(jrr[jss::status] ==
"success");
615 jv_submit[jss::tx_json] = jrr[jss::tx_json];
618 "submit_multisigned",
620 BEAST_EXPECT(jrr[jss::status] ==
"error");
621 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
623 jrr[jss::error_message] ==
624 "Invalid Fee field. Fees must be greater than zero.");
629 aliceSeq = env.
seq(alice);
631 jv_one[jss::tx_json][jss::Fee] =
632 alice[
"USD"](10).value().getFullText();
635 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
636 BEAST_EXPECT(jrr[jss::status] ==
"success");
641 jv_two[jss::tx_json] = jrr[jss::tx_json];
643 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
644 BEAST_EXPECT(jrr[jss::status] ==
"success");
647 jv_submit[jss::tx_json] = jrr[jss::tx_json];
650 "submit_multisigned",
652 BEAST_EXPECT(jrr[jss::status] ==
"error");
653 BEAST_EXPECT(jrr[jss::error] ==
"internal");
654 BEAST_EXPECT(jrr[jss::error_message] ==
"Internal error.");
659 aliceSeq = env.
seq(alice);
661 jv[jss::account] = cheri.human();
662 jv[jss::secret] = cheri.name();
663 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
664 BEAST_EXPECT(jrr[jss::status] ==
"error");
665 BEAST_EXPECT(jrr[jss::error] ==
"masterDisabled");
667 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
673 aliceSeq = env.
seq(alice);
677 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
678 BEAST_EXPECT(jrr[jss::status] ==
"success");
683 jv_two[jss::tx_json] = jrr[jss::tx_json];
684 jv_two[jss::account] = becky.human();
685 jv_two[jss::key_type] =
"ed25519";
686 jv_two[jss::passphrase] = becky.name();
687 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
688 BEAST_EXPECT(jrr[jss::status] ==
"success");
691 jv_submit[jss::tx_json] = jrr[jss::tx_json];
694 "submit_multisigned",
696 BEAST_EXPECT(jrr[jss::status] ==
"success");
698 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
704 jv[jss::tx_json][jss::Account] =
"DEADBEEF";
706 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
707 BEAST_EXPECT(jrr[jss::status] ==
"error");
708 BEAST_EXPECT(jrr[jss::error] ==
"srcActMalformed");
711 jv[jss::tx_json][jss::Account] = jimmy.human();
712 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
713 BEAST_EXPECT(jrr[jss::status] ==
"error");
714 BEAST_EXPECT(jrr[jss::error] ==
"srcActNotFound");
718 aliceSeq = env.
seq(alice);
720 jv[jss::tx_json][sfSigners.fieldName] =
724 "json",
"submit_multisigned",
to_string(jv))[jss::result];
725 BEAST_EXPECT(jrr[jss::status] ==
"error");
726 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
728 jrr[jss::error_message] ==
729 "tx_json.Signers array may not be empty.");
731 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
741 Env env{*
this, features};
746 env.fund(
XRP(1000), alice, becky, cheri, daria);
767 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}, {daria, 1}, {
jinni, 1}}),
770 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 6));
773 auto const baseFee = env.current()->fees().base;
777 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
779 aliceSeq = env.seq(alice);
782 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
784 aliceSeq = env.seq(alice);
787 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
789 aliceSeq = env.seq(alice);
792 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
794 aliceSeq = env.seq(alice);
797 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
800 aliceSeq = env.seq(alice);
805 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
817 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 6));
819 aliceSeq = env.seq(alice);
824 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
827 aliceSeq = env.seq(alice);
832 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
848 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 10));
850 aliceSeq = env.seq(alice);
863 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
866 aliceSeq = env.seq(alice);
872 BEAST_EXPECT(env.seq(alice) == aliceSeq);
877 env.require(
owners(alice, 0));
888 Env env{*
this, features};
890 env.fund(
XRP(1000), alice);
930 auto const baseFee = env.current()->fees().base;
969 Env env{*
this, features};
971 env.fund(
XRP(1000), alice);
987 env.fund(
XRP(1000), becky);
989 env(
signers(becky, 1, {{alice, 1}}),
sig(becky));
1003 using namespace jtx;
1004 Env env{*
this, features};
1009 auto const USD = gw[
"USD"];
1010 env.fund(
XRP(1000), alice, becky, zelda, gw);
1015 env(
regkey(alice, alie));
1021 int const signerListOwners{features[featureMultiSignReserve] ? 1 : 4};
1022 env.require(
owners(alice, signerListOwners + 0));
1025 auto const baseFee = env.current()->fees().base;
1027 env(
pay(alice, env.master,
XRP(1)),
1031 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1034 aliceSeq = env.seq(alice);
1037 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1040 aliceSeq = env.seq(alice);
1044 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1047 env(
trust(
"alice", USD(100)),
1052 env.require(
owners(alice, signerListOwners + 1));
1055 env(
pay(gw, alice, USD(50)));
1057 env.require(
balance(alice, USD(50)));
1058 env.require(
balance(gw, alice[
"USD"](-50)));
1061 env(
offer(alice,
XRP(50), USD(50)),
1065 env.require(
owners(alice, signerListOwners + 2));
1069 aliceSeq = env.seq(alice);
1075 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1076 env.require(
owners(alice, signerListOwners + 1));
1084 env.require(
owners(alice, features[featureMultiSignReserve] ? 2 : 6));
1093 using namespace jtx;
1095 Env env{*
this, features};
1098 auto submitSTTx = [&env](
STTx const& stx) {
1100 jvResult[jss::tx_blob] =
strHex(stx.getSerializer().slice());
1101 return env.rpc(
"json",
"submit",
to_string(jvResult));
1105 env.fund(
XRP(1000), alice);
1108 auto const baseFee = env.current()->fees().base;
1114 auto const info = submitSTTx(local);
1116 info[jss::result][jss::error_exception] ==
1117 "fails local checks: Empty SigningPubKey.");
1124 auto badSig = local.
getFieldVL(sfTxnSignature);
1128 auto const info = submitSTTx(local);
1130 info[jss::result][jss::error_exception] ==
1131 "fails local checks: Invalid signature.");
1141 auto const info = submitSTTx(local);
1143 info[jss::result][jss::error_exception] ==
1144 "fails local checks: Invalid signature.");
1150 local[sfSigningPubKey] = alice.pk();
1151 auto const info = submitSTTx(local);
1153 info[jss::result][jss::error_exception] ==
1154 "fails local checks: Cannot both single- and multi-sign.");
1160 local.
sign(alice.pk(), alice.sk());
1162 auto const info = submitSTTx(local);
1164 info[jss::result][jss::error_exception] ==
1165 "fails local checks: Cannot both single- and multi-sign.");
1173 auto badSig =
signer.getFieldVL(sfTxnSignature);
1175 signer.setFieldVL(sfTxnSignature, badSig);
1177 auto const info = submitSTTx(local);
1179 info[jss::result][jss::error_exception].asString().find(
1180 "Invalid signature on account r") != std::string::npos);
1187 auto const info = submitSTTx(local);
1189 info[jss::result][jss::error_exception] ==
1190 "fails local checks: Invalid Signers array size.");
1199 features[featureExpandedSignerList] ?
msig(
1244 auto const info = submitSTTx(local);
1246 info[jss::result][jss::error_exception] ==
1247 "fails local checks: Invalid Signers array size.");
1253 auto const info = submitSTTx(local);
1255 info[jss::result][jss::error_exception] ==
1256 "fails local checks: Invalid multisigner.");
1262 auto const info = submitSTTx(local);
1264 info[jss::result][jss::error_exception] ==
1265 "fails local checks: Duplicate Signers not allowed.");
1275 auto const info = submitSTTx(local);
1277 info[jss::result][jss::error_exception] ==
1278 "fails local checks: Unsorted Signers array.");
1287 using namespace jtx;
1288 Env env{*
this, features};
1291 env.fund(
XRP(1000), alice, becky);
1294 auto const baseFee = env.current()->fees().base;
1304 testcase(
"Multisigning multisigner");
1311 using namespace jtx;
1312 Env env{*
this, features};
1315 env.fund(
XRP(1000), alice, becky);
1319 env(
signers(alice, 1, {{becky, 1}}));
1328 auto const baseFee = env.current()->fees().base;
1387 using namespace jtx;
1393 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
1405 auto const baseFee = env.
current()->fees().base;
1409 jvSig1[jss::tx_json][jss::Account] = alice.human();
1410 jvSig1[jss::tx_json][jss::Amount] = 10000000;
1411 jvSig1[jss::tx_json][jss::Destination] = env.
master.
human();
1412 jvSig1[jss::tx_json][jss::Fee] = (3 * baseFee).jsonClipped();
1413 jvSig1[jss::tx_json][jss::Sequence] = env.
seq(alice);
1414 jvSig1[jss::tx_json][jss::TransactionType] = jss::Payment;
1417 BEAST_EXPECT(jvSig2[jss::result][jss::status].asString() ==
"success");
1421 jvSig2[jss::result][jss::tx_json][jss::hash].
asString();
1424 jvSig2[jss::result][jss::account] =
ghost.
human();
1425 jvSig2[jss::result][jss::secret] =
ghost.
name();
1427 env.
rpc(
"json",
"sign_for",
to_string(jvSig2[jss::result]));
1429 jvSubmit[jss::result][jss::status].asString() ==
"success");
1433 jvSubmit[jss::result][jss::tx_json][jss::hash].
asString();
1434 BEAST_EXPECT(hash1 != hash2);
1438 "json",
"submit_multisigned",
to_string(jvSubmit[jss::result]));
1440 jvResult[jss::result][jss::status].asString() ==
"success");
1442 jvResult[jss::result][jss::engine_result].asString() ==
1448 hash2 == jvResult[jss::result][jss::tx_json][jss::hash].asString());
1454 BEAST_EXPECT(jvTx[jss::result][jss::status].asString() ==
"success");
1455 BEAST_EXPECT(jvTx[jss::result][jss::validated].asString() ==
"true");
1457 jvTx[jss::result][jss::meta][sfTransactionResult.jsonName]
1470 using namespace jtx;
1477 env.fund(
XRP(1000), alice, becky, cheri, daria);
1495 env.require(
owners(alice, 3));
1496 env.require(
owners(becky, 10));
1499 env.enableFeature(featureMultiSignReserve);
1517 env.require(
owners(alice, 3));
1518 env.require(
owners(becky, 10));
1519 env.require(
owners(cheri, 1));
1520 env.require(
owners(daria, 1));
1538 env.require(
owners(alice, 1));
1539 env.require(
owners(becky, 0));
1540 env.require(
owners(cheri, 1));
1541 env.require(
owners(daria, 1));
1550 env.require(
owners(alice, 0));
1551 env.require(
owners(becky, 0));
1552 env.require(
owners(cheri, 0));
1553 env.require(
owners(daria, 0));
1561 using namespace jtx;
1562 Env env{*
this, features};
1564 env.fund(
XRP(2000), alice);
1577 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1578 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1581 auto const baseFee = env.current()->fees().base;
1587 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1588 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1593 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1594 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1600 if (!features[featureExpandedSignerList])
1605 using namespace jtx;
1606 Env env{*
this, features};
1608 env.fund(
XRP(1000), alice);
1610 uint8_t tag1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1611 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1612 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1613 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1616 "hello world some ascii 32b long";
1624 env.require(
owners(alice, features[featureMultiSignReserve] ? 1 : 4));
1627 auto const baseFee = env.current()->fees().base;
1631 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1634 aliceSeq = env.seq(alice);
1637 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1639 aliceSeq = env.seq(alice);
1642 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1645 aliceSeq = env.seq(alice);
1649 rpc(
"invalidTransaction",
1650 "fails local checks: Duplicate Signers not allowed."));
1652 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1655 aliceSeq = env.seq(alice);
1661 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1665 aliceSeq = env.seq(alice);
1668 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1671 aliceSeq = env.seq(alice);
1674 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1680 using namespace test::jtx;
1682 Env env{*
this, features};
1685 env.fund(
XRP(1000), alice);
1688 bool const enabled = features[fixInvalidTxFlags];
1691 (enabled ?
"enabled" :
"disabled"));
1726 using namespace jtx;
1733 testAll(
all - featureMultiSignReserve - featureExpandedSignerList);
1744BEAST_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.