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));
97 env.require(
owners(alice, 1));
104 env.require(
owners(alice, 1));
109 env.require(
owners(alice, 0));
118 Env env{*
this, features};
120 env.fund(
XRP(1000), alice);
186 env.require(
owners(alice, 0));
195 Env env{*
this, features};
197 env.fund(
XRP(1000), alice);
203 env.require(
owners(alice, 1));
206 auto const baseFee = env.current()->fees().base;
210 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
213 aliceSeq = env.seq(alice);
216 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
218 aliceSeq = env.seq(alice);
221 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
224 aliceSeq = env.seq(alice);
228 rpc(
"invalidTransaction",
229 "fails local checks: Duplicate Signers not allowed."));
231 BEAST_EXPECT(env.seq(alice) == aliceSeq);
234 aliceSeq = env.seq(alice);
240 BEAST_EXPECT(env.seq(alice) == aliceSeq);
244 aliceSeq = env.seq(alice);
247 BEAST_EXPECT(env.seq(alice) == aliceSeq);
250 aliceSeq = env.seq(alice);
253 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
262 Env env{*
this, features};
264 env.fund(
XRP(1000), alice);
280 env.require(
owners(alice, 1));
283 auto const baseFee = env.current()->fees().base;
288 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
291 aliceSeq = env.seq(alice);
294 fee((2 * baseFee) - 1),
298 BEAST_EXPECT(env.seq(alice) == aliceSeq);
301 aliceSeq = env.seq(alice);
307 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
310 aliceSeq = env.seq(alice);
313 fee((9 * baseFee) - 1),
317 BEAST_EXPECT(env.seq(alice) == aliceSeq);
326 Env env{*
this, features};
328 env.fund(
XRP(1000), alice);
335 env.require(
owners(alice, 1));
338 std::reverse(phantoms.signers.begin(), phantoms.signers.end());
342 rpc(
"invalidTransaction",
343 "fails local checks: Unsorted Signers array."));
345 BEAST_EXPECT(env.seq(alice) == aliceSeq);
354 Env env{*
this, features};
358 env.fund(
XRP(1000), alice, becky, cheri);
369 BEAST_EXPECT(env.seq(alice) == aliceSeq + 2);
372 env(
signers(alice, 4, {{becky, 3}, {cheri, 4}}),
sig(alice));
374 env.require(
owners(alice, 1));
377 auto const baseFee = env.current()->fees().base;
378 aliceSeq = env.seq(alice);
381 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
384 aliceSeq = env.seq(alice);
387 BEAST_EXPECT(env.seq(alice) == aliceSeq);
397 aliceSeq = env.seq(alice);
398 env(
noop(alice),
msig(becky, cheri),
fee(3 * baseFee));
400 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
409 Env env{*
this, features};
413 env.fund(
XRP(1000), alice, becky, cheri);
417 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}}),
sig(alice));
433 auto const baseFee = env.current()->fees().base;
437 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
440 aliceSeq = env.seq(alice);
446 BEAST_EXPECT(env.seq(alice) == aliceSeq);
449 aliceSeq = env.seq(alice);
452 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
454 aliceSeq = env.seq(alice);
457 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
460 aliceSeq = env.seq(alice);
465 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
471 testcase(
"Regular Signers Using submit_multisigned");
477 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
484 env.
fund(
XRP(1000), alice, becky, cheri);
488 env(
signers(alice, 2, {{becky, 1}, {cheri, 1}}),
sig(alice));
501 auto const baseFee = env.
current()->fees().base;
507 jv[jss::tx_json][jss::Account] = alice.human();
508 jv[jss::tx_json][jss::TransactionType] = jss::AccountSet;
509 jv[jss::tx_json][jss::Fee] = (8 * baseFee).jsonClipped();
510 jv[jss::tx_json][jss::Sequence] = env.
seq(alice);
511 jv[jss::tx_json][jss::SigningPubKey] =
"";
515 jv[jss::account] = cheri.human();
516 jv[jss::key_type] =
"ed25519";
517 jv[jss::passphrase] = cher.name();
520 jv[jss::account] = becky.human();
521 jv[jss::secret] = beck.name();
527 aliceSeq = env.
seq(alice);
531 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
532 BEAST_EXPECT(jrr[jss::status] ==
"success");
537 jv_two[jss::tx_json] = jrr[jss::tx_json];
539 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
540 BEAST_EXPECT(jrr[jss::status] ==
"success");
543 jv_submit[jss::tx_json] = jrr[jss::tx_json];
546 "submit_multisigned",
548 BEAST_EXPECT(jrr[jss::status] ==
"success");
550 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
555 aliceSeq = env.
seq(alice);
557 jv_one[jss::tx_json][jss::SigningPubKey] =
558 strHex(alice.pk().slice());
561 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
562 BEAST_EXPECT(jrr[jss::status] ==
"error");
563 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
565 jrr[jss::error_message] ==
566 "When multi-signing 'tx_json.SigningPubKey' must be empty.");
571 aliceSeq = env.
seq(alice);
573 jv_one[jss::tx_json][jss::Fee] = -1;
576 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
577 BEAST_EXPECT(jrr[jss::status] ==
"success");
582 jv_two[jss::tx_json] = jrr[jss::tx_json];
584 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
585 BEAST_EXPECT(jrr[jss::status] ==
"success");
588 jv_submit[jss::tx_json] = jrr[jss::tx_json];
591 "submit_multisigned",
593 BEAST_EXPECT(jrr[jss::status] ==
"error");
594 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
596 jrr[jss::error_message] ==
597 "Invalid Fee field. Fees must be greater than zero.");
602 aliceSeq = env.
seq(alice);
604 jv_one[jss::tx_json][jss::Fee] =
605 alice[
"USD"](10).value().getFullText();
608 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
609 BEAST_EXPECT(jrr[jss::status] ==
"success");
614 jv_two[jss::tx_json] = jrr[jss::tx_json];
616 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
617 BEAST_EXPECT(jrr[jss::status] ==
"success");
620 jv_submit[jss::tx_json] = jrr[jss::tx_json];
623 "submit_multisigned",
625 BEAST_EXPECT(jrr[jss::status] ==
"error");
626 BEAST_EXPECT(jrr[jss::error] ==
"internal");
627 BEAST_EXPECT(jrr[jss::error_message] ==
"Internal error.");
632 aliceSeq = env.
seq(alice);
634 jv[jss::account] = cheri.human();
635 jv[jss::secret] = cheri.name();
636 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
637 BEAST_EXPECT(jrr[jss::status] ==
"error");
638 BEAST_EXPECT(jrr[jss::error] ==
"masterDisabled");
640 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
646 aliceSeq = env.
seq(alice);
650 env.
rpc(
"json",
"sign_for",
to_string(jv_one))[jss::result];
651 BEAST_EXPECT(jrr[jss::status] ==
"success");
656 jv_two[jss::tx_json] = jrr[jss::tx_json];
657 jv_two[jss::account] = becky.human();
658 jv_two[jss::key_type] =
"ed25519";
659 jv_two[jss::passphrase] = becky.name();
660 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv_two))[jss::result];
661 BEAST_EXPECT(jrr[jss::status] ==
"success");
664 jv_submit[jss::tx_json] = jrr[jss::tx_json];
667 "submit_multisigned",
669 BEAST_EXPECT(jrr[jss::status] ==
"success");
671 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 1);
677 jv[jss::tx_json][jss::Account] =
"DEADBEEF";
679 auto jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
680 BEAST_EXPECT(jrr[jss::status] ==
"error");
681 BEAST_EXPECT(jrr[jss::error] ==
"srcActMalformed");
684 jv[jss::tx_json][jss::Account] = jimmy.human();
685 jrr = env.
rpc(
"json",
"sign_for",
to_string(jv))[jss::result];
686 BEAST_EXPECT(jrr[jss::status] ==
"error");
687 BEAST_EXPECT(jrr[jss::error] ==
"srcActNotFound");
691 aliceSeq = env.
seq(alice);
693 jv[jss::tx_json][sfSigners.fieldName] =
697 "json",
"submit_multisigned",
to_string(jv))[jss::result];
698 BEAST_EXPECT(jrr[jss::status] ==
"error");
699 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
701 jrr[jss::error_message] ==
702 "tx_json.Signers array may not be empty.");
704 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
714 Env env{*
this, features};
719 env.fund(
XRP(1000), alice, becky, cheri, daria);
740 env(
signers(alice, 1, {{becky, 1}, {cheri, 1}, {daria, 1}, {
jinni, 1}}),
743 env.require(
owners(alice, 1));
746 auto const baseFee = env.current()->fees().base;
750 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
752 aliceSeq = env.seq(alice);
755 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
757 aliceSeq = env.seq(alice);
760 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
762 aliceSeq = env.seq(alice);
765 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
767 aliceSeq = env.seq(alice);
770 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
773 aliceSeq = env.seq(alice);
778 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
790 env.require(
owners(alice, 1));
792 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);
821 env.require(
owners(alice, 1));
823 aliceSeq = env.seq(alice);
836 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
839 aliceSeq = env.seq(alice);
845 BEAST_EXPECT(env.seq(alice) == aliceSeq);
850 env.require(
owners(alice, 0));
861 Env env{*
this, features};
863 env.fund(
XRP(1000), alice);
904 auto const baseFee = env.current()->fees().base;
943 Env env{*
this, features};
945 env.fund(
XRP(1000), alice);
962 env.fund(
XRP(1000), becky);
965 env(
signers(becky, 1, {{alice, 1}}),
sig(becky));
980 Env env{*
this, features};
985 auto const USD = gw[
"USD"];
986 env.fund(
XRP(1000), alice, becky, zelda, gw);
997 env.require(
owners(alice, 1));
1000 auto const baseFee = env.current()->fees().base;
1002 env(
pay(alice, env.master,
XRP(1)),
1006 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1009 aliceSeq = env.seq(alice);
1012 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1015 aliceSeq = env.seq(alice);
1019 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1022 env(
trust(
"alice", USD(100)),
1027 env.require(
owners(alice, 2));
1030 env(
pay(gw, alice, USD(50)));
1032 env.require(
balance(alice, USD(50)));
1033 env.require(
balance(gw, alice[
"USD"](-50)));
1036 env(
offer(alice,
XRP(50), USD(50)),
1040 env.require(
owners(alice, 3));
1044 aliceSeq = env.seq(alice);
1050 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1051 env.require(
owners(alice, 2));
1059 env.require(
owners(alice, 2));
1068 using namespace jtx;
1070 Env env{*
this, features};
1073 auto submitSTTx = [&env](
STTx const& stx) {
1075 jvResult[jss::tx_blob] =
strHex(stx.getSerializer().slice());
1076 return env.rpc(
"json",
"submit",
to_string(jvResult));
1080 env.fund(
XRP(1000), alice);
1084 auto const baseFee = env.current()->fees().base;
1090 auto const info = submitSTTx(local);
1092 info[jss::result][jss::error_exception] ==
1093 "fails local checks: Empty SigningPubKey.");
1100 auto badSig = local.
getFieldVL(sfTxnSignature);
1104 auto const info = submitSTTx(local);
1106 info[jss::result][jss::error_exception] ==
1107 "fails local checks: Invalid signature.");
1117 auto const info = submitSTTx(local);
1119 info[jss::result][jss::error_exception] ==
1120 "fails local checks: Invalid signature.");
1126 local[sfSigningPubKey] = alice.pk();
1127 auto const info = submitSTTx(local);
1129 info[jss::result][jss::error_exception] ==
1130 "fails local checks: Cannot both single- and multi-sign.");
1136 local.
sign(alice.pk(), alice.sk());
1138 auto const info = submitSTTx(local);
1140 info[jss::result][jss::error_exception] ==
1141 "fails local checks: Cannot both single- and multi-sign.");
1149 auto badSig =
signer.getFieldVL(sfTxnSignature);
1151 signer.setFieldVL(sfTxnSignature, badSig);
1153 auto const info = submitSTTx(local);
1155 info[jss::result][jss::error_exception].asString().find(
1156 "Invalid signature on account r") != std::string::npos);
1163 auto const info = submitSTTx(local);
1165 info[jss::result][jss::error_exception] ==
1166 "fails local checks: Invalid Signers array size.");
1208 auto const info = submitSTTx(local);
1210 info[jss::result][jss::error_exception] ==
1211 "fails local checks: Invalid Signers array size.");
1217 auto const info = submitSTTx(local);
1219 info[jss::result][jss::error_exception] ==
1220 "fails local checks: Invalid multisigner.");
1226 auto const info = submitSTTx(local);
1228 info[jss::result][jss::error_exception] ==
1229 "fails local checks: Duplicate Signers not allowed.");
1239 auto const info = submitSTTx(local);
1241 info[jss::result][jss::error_exception] ==
1242 "fails local checks: Unsorted Signers array.");
1251 using namespace jtx;
1252 Env env{*
this, features};
1255 env.fund(
XRP(1000), alice, becky);
1258 auto const baseFee = env.current()->fees().base;
1268 testcase(
"Multisigning multisigner");
1275 using namespace jtx;
1276 Env env{*
this, features};
1279 env.fund(
XRP(1000), alice, becky);
1283 env(
signers(alice, 1, {{becky, 1}}));
1292 auto const baseFee = env.current()->fees().base;
1351 using namespace jtx;
1357 cfg->loadFromString(
"[" SECTION_SIGNING_SUPPORT
"]\ntrue");
1369 auto const baseFee = env.
current()->fees().base;
1373 jvSig1[jss::tx_json][jss::Account] = alice.human();
1374 jvSig1[jss::tx_json][jss::Amount] = 10000000;
1375 jvSig1[jss::tx_json][jss::Destination] = env.
master.
human();
1376 jvSig1[jss::tx_json][jss::Fee] = (3 * baseFee).jsonClipped();
1377 jvSig1[jss::tx_json][jss::Sequence] = env.
seq(alice);
1378 jvSig1[jss::tx_json][jss::TransactionType] = jss::Payment;
1381 BEAST_EXPECT(jvSig2[jss::result][jss::status].asString() ==
"success");
1385 jvSig2[jss::result][jss::tx_json][jss::hash].
asString();
1388 jvSig2[jss::result][jss::account] =
ghost.
human();
1389 jvSig2[jss::result][jss::secret] =
ghost.
name();
1391 env.
rpc(
"json",
"sign_for",
to_string(jvSig2[jss::result]));
1393 jvSubmit[jss::result][jss::status].asString() ==
"success");
1397 jvSubmit[jss::result][jss::tx_json][jss::hash].
asString();
1398 BEAST_EXPECT(hash1 != hash2);
1402 "json",
"submit_multisigned",
to_string(jvSubmit[jss::result]));
1404 jvResult[jss::result][jss::status].asString() ==
"success");
1406 jvResult[jss::result][jss::engine_result].asString() ==
1412 hash2 == jvResult[jss::result][jss::tx_json][jss::hash].asString());
1418 BEAST_EXPECT(jvTx[jss::result][jss::status].asString() ==
"success");
1419 BEAST_EXPECT(jvTx[jss::result][jss::validated].asString() ==
"true");
1421 jvTx[jss::result][jss::meta][sfTransactionResult.jsonName]
1430 using namespace jtx;
1431 Env env{*
this, features};
1433 env.fund(
XRP(2000), alice);
1446 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1447 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1450 auto const baseFee = env.current()->fees().base;
1456 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1457 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1462 env.require(
tickets(alice, env.seq(alice) - aliceTicketSeq));
1463 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1471 using namespace jtx;
1472 Env env{*
this, features};
1474 env.fund(
XRP(1000), alice);
1476 uint8_t tag1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1477 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1478 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1479 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1482 "hello world some ascii 32b long";
1490 env.require(
owners(alice, 1));
1493 auto const baseFee = env.current()->fees().base;
1497 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1500 aliceSeq = env.seq(alice);
1503 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1505 aliceSeq = env.seq(alice);
1508 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1511 aliceSeq = env.seq(alice);
1515 rpc(
"invalidTransaction",
1516 "fails local checks: Duplicate Signers not allowed."));
1518 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1521 aliceSeq = env.seq(alice);
1527 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1531 aliceSeq = env.seq(alice);
1534 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1537 aliceSeq = env.seq(alice);
1540 BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
1546 using namespace test::jtx;
1548 Env env{*
this, features};
1551 env.fund(
XRP(1000), alice);
1554 bool const enabled = features[fixInvalidTxFlags];
1557 (enabled ?
"enabled" :
"disabled"));
1572 using namespace jtx;
1573 Env env{*
this, features};
1575 env.fund(
XRP(1000), alice);
1585 BEAST_EXPECT(sle->getFieldArray(sfSignerEntries).size() == 2);
1586 if (features[fixIncludeKeyletFields])
1588 BEAST_EXPECT((*sle)[sfOwner] == alice.id());
1592 BEAST_EXPECT(!sle->isFieldPresent(sfOwner));
1622 using namespace jtx;
1635BEAST_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, std::optional< std::reference_wrapper< SField const > > signatureTarget={})
static base_uint fromVoid(void const *data)
void testSignersWithTickets(FeatureBitset features)
void testSignersWithTags(FeatureBitset features)
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.