3#include <xrpld/core/ConfigSections.h>
5#include <xrpl/protocol/Feature.h>
6#include <xrpl/protocol/jss.h>
54 Env env{*
this, features};
59 auto const fee = env.current()->fees().base;
60 env.fund(
XRP(250) -
drops(1), alice);
62 env.require(
owners(alice, 0));
69 env.require(
owners(alice, 0));
76 env.require(
owners(alice, 1));
87 {{
bogie, 1}, {
demon, 1}, {
ghost, 1}, {
haunt, 1}, {
jinni, 1}, {
phase, 1}, {
shade, 1}, {
spook, 1}});
90 env.require(
owners(alice, 1));
97 env.require(
owners(alice, 1));
102 env.require(
owners(alice, 0));
111 Env env{*
this, features};
113 env.fund(
XRP(1000), alice);
132 {{
bogie, 1}, {
demon, 1}, {
ghost, 1}, {
haunt, 1}, {
jinni, 1}, {
phase, 1}, {
demon, 1}, {
spook, 1}}),
142 {{
bogie, 1}, {
demon, 1}, {
ghost, 1}, {
haunt, 1}, {
jinni, 1}, {
phase, 1}, {
shade, 1}, {
spook, 1}}),
165 env.require(
owners(alice, 0));
174 Env env{*
this, features};
176 env.fund(
XRP(1000), alice);
182 env.require(
owners(alice, 1));
185 auto const baseFee = env.current()->fees().base;
189 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
192 aliceSeq = env.seq(alice);
195 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
197 aliceSeq = env.seq(alice);
200 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
203 aliceSeq = env.seq(alice);
207 rpc(
"invalidTransaction",
"fails local checks: Duplicate Signers not allowed."));
209 BEAST_EXPECT(env.seq(alice) == aliceSeq);
212 aliceSeq = env.seq(alice);
215 BEAST_EXPECT(env.seq(alice) == aliceSeq);
219 aliceSeq = env.seq(alice);
222 BEAST_EXPECT(env.seq(alice) == aliceSeq);
225 aliceSeq = env.seq(alice);
228 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
237 Env env{*
this, features};
239 env.fund(
XRP(1000), alice);
246 {{
bogie, 1}, {
demon, 1}, {
ghost, 1}, {
haunt, 1}, {
jinni, 1}, {
phase, 1}, {
shade, 1}, {
spook, 1}}));
248 env.require(
owners(alice, 1));
251 auto const baseFee = env.current()->fees().base;
256 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
259 aliceSeq = env.seq(alice);
263 BEAST_EXPECT(env.seq(alice) == aliceSeq);
266 aliceSeq = env.seq(alice);
270 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
273 aliceSeq = env.seq(alice);
276 fee((9 * baseFee) - 1),
280 BEAST_EXPECT(env.seq(alice) == aliceSeq);
289 Env env{*
this, features};
291 env.fund(
XRP(1000), alice);
298 env.require(
owners(alice, 1));
301 std::reverse(phantoms.signers.begin(), phantoms.signers.end());
303 env(
noop(alice), phantoms,
rpc(
"invalidTransaction",
"fails local checks: Unsorted Signers array."));
305 BEAST_EXPECT(env.seq(alice) == aliceSeq);
314 Env env{*
this, features};
318 env.fund(
XRP(1000), alice, becky, cheri);
329 BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
332 env(
signers(alice, 4, {{becky, 3}, {cheri, 4}}),
sig(alice));
334 env.require(
owners(alice, 1));
337 auto const baseFee = env.current()->fees().base;
338 aliceSeq = env.seq(alice);
341 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
344 aliceSeq = env.seq(alice);
347 BEAST_EXPECT(env.seq(alice) == aliceSeq);
357 aliceSeq = env.seq(alice);
358 env(
noop(alice),
msig(becky, cheri),
fee(3 * baseFee));
360 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
369 Env env{*
this, features};
373 env.fund(
XRP(1000), alice, becky, cheri);
377 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}}),
sig(alice));
393 auto const baseFee = env.current()->fees().base;
397 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
400 aliceSeq = env.seq(alice);
403 BEAST_EXPECT(env.seq(alice) == aliceSeq);
406 aliceSeq = env.seq(alice);
409 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
411 aliceSeq = env.seq(alice);
414 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
417 aliceSeq = env.seq(alice);
420 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
426 testcase(
"Regular Signers Using submit_multisigned");
432 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
439 env.
fund(
XRP(1000), alice, becky, cheri);
443 env(
signers(alice, 2, {{becky, 1}, {cheri, 1}}),
sig(alice));
456 auto const baseFee = env.
current()->fees().base;
462 jv[jss::tx_json][jss::Account] = alice.human();
463 jv[jss::tx_json][jss::TransactionType] = jss::AccountSet;
464 jv[jss::tx_json][jss::Fee] = (8 * baseFee).jsonClipped();
465 jv[jss::tx_json][jss::Sequence] = env.
seq(alice);
466 jv[jss::tx_json][jss::SigningPubKey] =
"";
470 jv[jss::account] = cheri.human();
471 jv[jss::key_type] =
"ed25519";
472 jv[jss::passphrase] = cher.name();
475 jv[jss::account] = becky.human();
476 jv[jss::secret] = beck.name();
482 aliceSeq = env.
seq(alice);
485 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
486 BEAST_EXPECT(jrr[jss::status] ==
"success");
491 jv_two[jss::tx_json] = jrr[jss::tx_json];
493 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
494 BEAST_EXPECT(jrr[jss::status] ==
"success");
497 jv_submit[jss::tx_json] = jrr[jss::tx_json];
498 jrr = env.
rpc(
"json",
"submit_multisigned",
to_string(jv_submit))[jss::result];
499 BEAST_EXPECT(jrr[jss::status] ==
"success");
501 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
506 aliceSeq = env.
seq(alice);
508 jv_one[jss::tx_json][jss::SigningPubKey] =
strHex(alice.pk().slice());
510 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
511 BEAST_EXPECT(jrr[jss::status] ==
"error");
512 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
513 BEAST_EXPECT(jrr[jss::error_message] ==
"When multi-signing 'tx_json.SigningPubKey' must be empty.");
518 aliceSeq = env.
seq(alice);
520 jv_one[jss::tx_json][jss::Fee] = -1;
522 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
523 BEAST_EXPECT(jrr[jss::status] ==
"success");
528 jv_two[jss::tx_json] = jrr[jss::tx_json];
530 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
531 BEAST_EXPECT(jrr[jss::status] ==
"success");
534 jv_submit[jss::tx_json] = jrr[jss::tx_json];
535 jrr = env.
rpc(
"json",
"submit_multisigned",
to_string(jv_submit))[jss::result];
536 BEAST_EXPECT(jrr[jss::status] ==
"error");
537 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
538 BEAST_EXPECT(jrr[jss::error_message] ==
"Invalid Fee field. Fees must be greater than zero.");
543 aliceSeq = env.
seq(alice);
545 jv_one[jss::tx_json][jss::Fee] = alice[
"USD"](10).value().getFullText();
547 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
548 BEAST_EXPECT(jrr[jss::status] ==
"success");
553 jv_two[jss::tx_json] = jrr[jss::tx_json];
555 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
556 BEAST_EXPECT(jrr[jss::status] ==
"success");
559 jv_submit[jss::tx_json] = jrr[jss::tx_json];
560 jrr = env.
rpc(
"json",
"submit_multisigned",
to_string(jv_submit))[jss::result];
561 BEAST_EXPECT(jrr[jss::status] ==
"error");
562 BEAST_EXPECT(jrr[jss::error] ==
"internal");
563 BEAST_EXPECT(jrr[jss::error_message] ==
"Internal error.");
568 aliceSeq = env.
seq(alice);
570 jv[jss::account] = cheri.human();
571 jv[jss::secret] = cheri.name();
572 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
573 BEAST_EXPECT(jrr[jss::status] ==
"error");
574 BEAST_EXPECT(jrr[jss::error] ==
"masterDisabled");
576 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
582 aliceSeq = env.
seq(alice);
585 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
586 BEAST_EXPECT(jrr[jss::status] ==
"success");
591 jv_two[jss::tx_json] = jrr[jss::tx_json];
592 jv_two[jss::account] = becky.human();
593 jv_two[jss::key_type] =
"ed25519";
594 jv_two[jss::passphrase] = becky.name();
595 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
596 BEAST_EXPECT(jrr[jss::status] ==
"success");
599 jv_submit[jss::tx_json] = jrr[jss::tx_json];
600 jrr = env.
rpc(
"json",
"submit_multisigned",
to_string(jv_submit))[jss::result];
601 BEAST_EXPECT(jrr[jss::status] ==
"success");
603 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
609 jv[jss::tx_json][jss::Account] =
"DEADBEEF";
611 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
612 BEAST_EXPECT(jrr[jss::status] ==
"error");
613 BEAST_EXPECT(jrr[jss::error] ==
"srcActMalformed");
616 jv[jss::tx_json][jss::Account] = jimmy.human();
617 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
618 BEAST_EXPECT(jrr[jss::status] ==
"error");
619 BEAST_EXPECT(jrr[jss::error] ==
"srcActNotFound");
623 aliceSeq = env.
seq(alice);
627 auto jrr = env.
rpc(
"json",
"submit_multisigned",
to_string(jv))[jss::result];
628 BEAST_EXPECT(jrr[jss::status] ==
"error");
629 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
630 BEAST_EXPECT(jrr[jss::error_message] ==
"tx_json.Signers array may not be empty.");
632 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
642 Env env{*
this, features};
647 env.fund(
XRP(1000), alice, becky, cheri, daria);
668 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}, {daria, 1}, {
jinni, 1}}),
sig(alie));
670 env.require(
owners(alice, 1));
673 auto const baseFee = env.current()->fees().base;
677 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
679 aliceSeq = env.seq(alice);
682 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
684 aliceSeq = env.seq(alice);
687 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
689 aliceSeq = env.seq(alice);
692 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
694 aliceSeq = env.seq(alice);
697 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
700 aliceSeq = env.seq(alice);
703 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
706 env(
signers(alice, 0x3FFFC, {{becky, 0xFFFF}, {cheri, 0xFFFF}, {daria, 0xFFFF}, {
jinni, 0xFFFF}}),
sig(alie));
708 env.require(
owners(alice, 1));
710 aliceSeq = env.seq(alice);
713 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
716 aliceSeq = env.seq(alice);
719 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
735 env.require(
owners(alice, 1));
737 aliceSeq = env.seq(alice);
742 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
745 aliceSeq = env.seq(alice);
748 BEAST_EXPECT(env.seq(alice) == aliceSeq);
753 env.require(
owners(alice, 0));
764 Env env{*
this, features};
766 env.fund(
XRP(1000), alice);
805 auto const baseFee = env.current()->fees().base;
841 Env env{*
this, features};
843 env.fund(
XRP(1000), alice);
860 env.fund(
XRP(1000), becky);
863 env(
signers(becky, 1, {{alice, 1}}),
sig(becky));
878 Env env{*
this, features};
883 auto const USD = gw[
"USD"];
884 env.fund(
XRP(1000), alice, becky, zelda, gw);
895 env.require(
owners(alice, 1));
898 auto const baseFee = env.current()->fees().base;
902 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
905 aliceSeq = env.seq(alice);
908 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
911 aliceSeq = env.seq(alice);
915 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
920 env.require(
owners(alice, 2));
923 env(
pay(gw, alice, USD(50)));
925 env.require(
balance(alice, USD(50)));
926 env.require(
balance(gw, alice[
"USD"](-50)));
931 env.require(
owners(alice, 3));
935 aliceSeq = env.seq(alice);
938 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
939 env.require(
owners(alice, 2));
943 env(
signers(alice, 3, {{becky, 1}, {
bogie, 1}, {
demon, 1}}),
msig(becky,
bogie),
fee(3 * baseFee));
945 env.require(
owners(alice, 2));
956 Env env{*
this, features};
959 auto submitSTTx = [&env](
STTx const& stx) {
961 jvResult[jss::tx_blob] =
strHex(stx.getSerializer().slice());
962 return env.rpc(
"json",
"submit",
to_string(jvResult));
966 env.fund(
XRP(1000), alice);
970 auto const baseFee = env.current()->fees().base;
976 auto const info = submitSTTx(local);
977 BEAST_EXPECT(info[jss::result][jss::error_exception] ==
"fails local checks: Empty SigningPubKey.");
984 auto badSig = local.
getFieldVL(sfTxnSignature);
988 auto const info = submitSTTx(local);
989 BEAST_EXPECT(info[jss::result][jss::error_exception] ==
"fails local checks: Invalid signature.");
999 auto const info = submitSTTx(local);
1000 BEAST_EXPECT(info[jss::result][jss::error_exception] ==
"fails local checks: Invalid signature.");
1006 local[sfSigningPubKey] = alice.pk();
1007 auto const info = submitSTTx(local);
1009 info[jss::result][jss::error_exception] ==
"fails local checks: Cannot both single- and multi-sign.");
1015 local.
sign(alice.pk(), alice.sk());
1017 auto const info = submitSTTx(local);
1019 info[jss::result][jss::error_exception] ==
"fails local checks: Cannot both single- and multi-sign.");
1027 auto badSig =
signer.getFieldVL(sfTxnSignature);
1029 signer.setFieldVL(sfTxnSignature, badSig);
1031 auto const info = submitSTTx(local);
1033 info[jss::result][jss::error_exception].asString().find(
"Invalid signature on account r") !=
1041 auto const info = submitSTTx(local);
1042 BEAST_EXPECT(info[jss::result][jss::error_exception] ==
"fails local checks: Invalid Signers array size.");
1084 auto const info = submitSTTx(local);
1085 BEAST_EXPECT(info[jss::result][jss::error_exception] ==
"fails local checks: Invalid Signers array size.");
1091 auto const info = submitSTTx(local);
1092 BEAST_EXPECT(info[jss::result][jss::error_exception] ==
"fails local checks: Invalid multisigner.");
1098 auto const info = submitSTTx(local);
1100 info[jss::result][jss::error_exception] ==
"fails local checks: Duplicate Signers not allowed.");
1110 auto const info = submitSTTx(local);
1111 BEAST_EXPECT(info[jss::result][jss::error_exception] ==
"fails local checks: Unsorted Signers array.");
1120 using namespace jtx;
1121 Env env{*
this, features};
1124 env.fund(
XRP(1000), alice, becky);
1127 auto const baseFee = env.current()->fees().base;
1134 testcase(
"Multisigning multisigner");
1141 using namespace jtx;
1142 Env env{*
this, features};
1145 env.fund(
XRP(1000), alice, becky);
1149 env(
signers(alice, 1, {{becky, 1}}));
1158 auto const baseFee = env.current()->fees().base;
1205 using namespace jtx;
1211 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
1223 auto const baseFee = env.
current()->fees().base;
1227 jvSig1[jss::tx_json][jss::Account] = alice.human();
1228 jvSig1[jss::tx_json][jss::Amount] = 10000000;
1229 jvSig1[jss::tx_json][jss::Destination] = env.
master.
human();
1230 jvSig1[jss::tx_json][jss::Fee] = (3 * baseFee).jsonClipped();
1231 jvSig1[jss::tx_json][jss::Sequence] = env.
seq(alice);
1232 jvSig1[jss::tx_json][jss::TransactionType] = jss::Payment;
1235 BEAST_EXPECT(jvSig2[jss::result][jss::status].asString() ==
"success");
1241 jvSig2[jss::result][jss::account] =
ghost.
human();
1242 jvSig2[jss::result][jss::secret] =
ghost.
name();
1244 BEAST_EXPECT(jvSubmit[jss::result][jss::status].asString() ==
"success");
1248 BEAST_EXPECT(hash1 != hash2);
1252 BEAST_EXPECT(jvResult[jss::result][jss::status].asString() ==
"success");
1253 BEAST_EXPECT(jvResult[jss::result][jss::engine_result].asString() ==
"tesSUCCESS");
1257 BEAST_EXPECT(hash2 == jvResult[jss::result][jss::tx_json][jss::hash].asString());
1263 BEAST_EXPECT(jvTx[jss::result][jss::status].asString() ==
"success");
1264 BEAST_EXPECT(jvTx[jss::result][jss::validated].asString() ==
"true");
1265 BEAST_EXPECT(jvTx[jss::result][jss::meta][sfTransactionResult.jsonName].
asString() ==
"tesSUCCESS");
1273 using namespace jtx;
1274 Env env{*
this, features};
1276 env.fund(
XRP(2000), alice);
1288 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1289 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1292 auto const baseFee = env.current()->fees().base;
1295 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1296 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1301 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1302 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1310 using namespace jtx;
1311 Env env{*
this, features};
1313 env.fund(
XRP(1000), alice);
1315 uint8_t tag1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03,
1316 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
1317 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1319 uint8_t tag2[] =
"hello world some ascii 32b long";
1327 env.require(
owners(alice, 1));
1330 auto const baseFee = env.current()->fees().base;
1334 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1337 aliceSeq = env.seq(alice);
1340 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1342 aliceSeq = env.seq(alice);
1345 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1348 aliceSeq = env.seq(alice);
1352 rpc(
"invalidTransaction",
"fails local checks: Duplicate Signers not allowed."));
1354 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1357 aliceSeq = env.seq(alice);
1360 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1364 aliceSeq = env.seq(alice);
1367 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1370 aliceSeq = env.seq(alice);
1373 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1379 using namespace test::jtx;
1381 Env env{*
this, features};
1384 env.fund(
XRP(1000), alice);
1387 bool const enabled = features[fixInvalidTxFlags];
1401 using namespace jtx;
1402 Env env{*
this, features};
1404 env.fund(
XRP(1000), alice);
1414 BEAST_EXPECT(sle->getFieldArray(sfSignerEntries).size() == 2);
1415 if (features[fixIncludeKeyletFields])
1417 BEAST_EXPECT((*sle)[sfOwner] == alice.id());
1421 BEAST_EXPECT(!sle->isFieldPresent(sfOwner));
1451 using namespace jtx;
1464BEAST_DEFINE_TESTSUITE(MultiSign, app,
xrpl);
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 setFieldVL(SField const &field, Blob const &)
void setFieldU32(SField const &field, std::uint32_t)
STArray & peekFieldArray(SField const &field)
void sign(PublicKey const &publicKey, SecretKey const &secretKey, std::optional< std::reference_wrapper< SField const > > signatureTarget={})
static base_uint fromVoid(void const *data)
void testMultisigningMultisigner(FeatureBitset features)
void testRegKey(FeatureBitset features)
void testAll(FeatureBitset features)
void testPhantomSigners(FeatureBitset features)
void testBadSignatureText(FeatureBitset features)
void testSignForHash(FeatureBitset features)
void testTxTypes(FeatureBitset features)
void testRegularSigners(FeatureBitset features)
void testKeyDisable(FeatureBitset features)
void testMisorderedSigners(FeatureBitset features)
void testSignersWithTags(FeatureBitset features)
void testSignerListSet(FeatureBitset features)
void testSignerListSetFlags(FeatureBitset features)
void testRegularSignersUsingSubmitMulti(FeatureBitset features)
void testSignerListObject(FeatureBitset features)
void testHeterogeneousSigners(FeatureBitset features)
void testMasterSigners(FeatureBitset features)
void testFee(FeatureBitset features)
void run() override
Runs the suite.
void testNoMultiSigners(FeatureBitset features)
void testNoReserve(FeatureBitset features)
void testSignersWithTickets(FeatureBitset features)
Immutable cryptographic account descriptor.
std::string const & human() const
Returns the human readable public key.
std::string const & name() const
Return the name.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
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.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
XRP_t const XRP
Converts to XRP Issue or STAmount.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
Json::Value offer_cancel(Account const &account, std::uint32_t offerSeq)
Cancel an offer.
FeatureBitset testable_amendments()
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Json::Value regkey(Account const &account, disabled_t)
Disable the regular key.
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
owner_count< ltTICKET > tickets
Match the number of tickets on the account.
owner_count< ltRIPPLE_STATE > lines
Match the number of trust lines in the account's owner directory.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
static disabled_t const disabled
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create 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 to_string(base_uint< Bits, Tag > const &a)
std::string strHex(FwdIt begin, FwdIt end)
TERSubset< CanCvtToTER > TER
std::vector< unsigned char > Blob
Storage for linear binary data.
@ tecINSUFFICIENT_RESERVE
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.