36 using namespace test::jtx;
39 char const* COMMAND = jss::tx.c_str();
40 char const* BINARY = jss::binary.c_str();
45 Env env{*
this, features};
46 auto const alice = Account(
"alice");
47 env.fund(XRP(1000), alice);
52 auto const startLegSeq = env.current()->header().seq;
53 for (
int i = 0; i < 750; ++i)
58 metas.
emplace_back(env.closed()->txRead(env.tx()->getTransactionID()).second);
60 auto const endLegSeq = env.closed()->header().seq;
63 for (
size_t i = 0; i < txns.
size(); ++i)
65 auto const& tx = txns[i];
66 auto const& meta = metas[i];
67 auto const result = env.rpc(
70 BEAST_EXPECT(result[jss::result][jss::status] == jss::success);
71 BEAST_EXPECT(result[jss::result][jss::tx] ==
strHex(tx->getSerializer().getData()));
72 BEAST_EXPECT(result[jss::result][jss::meta] ==
strHex(meta->getSerializer().getData()));
75 auto const tx = env.jt(
noop(alice), seq(env.seq(alice))).stx;
76 for (
int deltaEndSeq = 0; deltaEndSeq < 2; ++deltaEndSeq)
78 auto const result = env.rpc(
86 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND);
89 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
91 BEAST_EXPECT(result[jss::result][jss::searched_all].asBool());
95 for (
auto&& tx : txns)
97 auto const result = env.rpc(
104 BEAST_EXPECT(result[jss::result][jss::status] == jss::success);
105 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
108 auto const deletedLedger = (startLegSeq + endLegSeq) / 2;
111 env.app().getRelationalDatabase().deleteTransactionByLedgerSeq(deletedLedger);
114 for (
int deltaEndSeq = 0; deltaEndSeq < 2; ++deltaEndSeq)
116 auto const result = env.rpc(
124 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND);
125 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
135 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND);
137 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
143 auto const result = env.rpc(
147 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND);
149 BEAST_EXPECT(result[jss::result][jss::searched_all].asBool());
155 auto const result = env.rpc(
158 BEAST_EXPECT(result[jss::result][jss::status] == jss::success);
159 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
164 auto const result = env.rpc(
171 BEAST_EXPECT(result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] ==
INVALID);
173 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
178 auto const result = env.rpc(
181 BEAST_EXPECT(result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] ==
INVALID);
183 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
191 BEAST_EXPECT(result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] ==
INVALID);
193 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
198 auto const result = env.rpc(COMMAND,
to_string(tx->getTransactionID()), BINARY,
to_string(20));
200 BEAST_EXPECT(result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] ==
INVALID);
202 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
207 auto const result = env.rpc(COMMAND,
to_string(tx->getTransactionID()),
to_string(20));
214 BEAST_EXPECT(result[jss::result][jss::status] == jss::error);
216 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
221 auto const result = env.rpc(
229 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == EXCESSIVE);
231 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
240 using namespace test::jtx;
243 char const* COMMAND = jss::tx.c_str();
244 char const* BINARY = jss::binary.c_str();
250 uint32_t netID = env.app().config().NETWORK_ID;
252 auto const alice = Account(
"alice");
253 env.fund(XRP(1000), alice);
258 auto const startLegSeq = env.current()->header().seq;
259 for (
int i = 0; i < 750; ++i)
264 metas.
emplace_back(env.closed()->txRead(env.tx()->getTransactionID()).second);
266 auto const endLegSeq = env.closed()->header().seq;
269 for (
size_t i = 0; i < txns.
size(); ++i)
271 auto const& tx = txns[i];
272 auto const& meta = metas[i];
273 uint32_t txnIdx = meta->getFieldU32(sfTransactionIndex);
274 auto const result = env.rpc(
281 BEAST_EXPECT(result[jss::result][jss::status] == jss::success);
282 BEAST_EXPECT(result[jss::result][jss::tx] ==
strHex(tx->getSerializer().getData()));
283 BEAST_EXPECT(result[jss::result][jss::meta] ==
strHex(meta->getSerializer().getData()));
286 auto const tx = env.jt(
noop(alice), seq(env.seq(alice))).stx;
287 auto const ctid = *
RPC::encodeCTID(endLegSeq, tx->getSeqValue(), netID);
288 for (
int deltaEndSeq = 0; deltaEndSeq < 2; ++deltaEndSeq)
291 env.rpc(COMMAND, ctid, BINARY,
to_string(startLegSeq),
to_string(endLegSeq + deltaEndSeq));
294 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND);
297 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
299 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
303 for (
size_t i = 0; i < txns.
size(); ++i)
306 auto const& meta = metas[i];
307 uint32_t txnIdx = meta->getFieldU32(sfTransactionIndex);
308 auto const result = env.rpc(
315 BEAST_EXPECT(result[jss::result][jss::status] == jss::success);
316 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
319 auto const deletedLedger = (startLegSeq + endLegSeq) / 2;
322 env.app().getRelationalDatabase().deleteTransactionByLedgerSeq(deletedLedger);
325 for (
int deltaEndSeq = 0; deltaEndSeq < 2; ++deltaEndSeq)
328 env.rpc(COMMAND, ctid, BINARY,
to_string(startLegSeq),
to_string(endLegSeq + deltaEndSeq));
331 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND);
332 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
338 auto const result = env.rpc(COMMAND, ctid,
to_string(startLegSeq),
to_string(endLegSeq));
341 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND);
343 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
349 auto const result = env.rpc(COMMAND, ctid,
to_string(startLegSeq),
to_string(deletedLedger - 1));
352 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == NOT_FOUND);
354 BEAST_EXPECT(!result[jss::result][jss::searched_all].asBool());
360 auto const& meta = metas[0];
361 uint32_t txnIdx = meta->getFieldU32(sfTransactionIndex);
362 auto const result = env.rpc(
368 BEAST_EXPECT(result[jss::result][jss::status] == jss::success);
369 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
374 auto const result = env.rpc(COMMAND, ctid, BINARY,
to_string(deletedLedger - 1),
to_string(startLegSeq));
376 BEAST_EXPECT(result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] ==
INVALID);
378 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
383 auto const result = env.rpc(COMMAND, ctid, BINARY,
to_string(-1),
to_string(deletedLedger - 1));
385 BEAST_EXPECT(result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] ==
INVALID);
387 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
394 BEAST_EXPECT(result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] ==
INVALID);
396 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
401 auto const result = env.rpc(COMMAND, ctid, BINARY,
to_string(20));
403 BEAST_EXPECT(result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] ==
INVALID);
405 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
410 auto const result = env.rpc(COMMAND, ctid,
to_string(20));
417 BEAST_EXPECT(result[jss::result][jss::status] == jss::error);
419 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
424 auto const result = env.rpc(COMMAND, ctid, BINARY,
to_string(startLegSeq),
to_string(startLegSeq + 1001));
427 result[jss::result][jss::status] == jss::error && result[jss::result][jss::error] == EXCESSIVE);
429 BEAST_EXPECT(!result[jss::result].isMember(jss::searched_all));
438 using namespace test::jtx;
445 BEAST_EXPECT(
RPC::encodeCTID(0x0FFF'FFFFUL, 0xFFFFU, 0xFFFFU) == expected11);
451 BEAST_EXPECT(
RPC::encodeCTID(13249191UL, 12911U, 65535U) == expected14);
467 auto const expected53 =
517 using namespace test::jtx;
520 for (uint32_t netID : {11111, 65535, 65536})
523 BEAST_EXPECT(netID == env.app().config().NETWORK_ID);
525 auto const alice = Account(
"alice");
526 auto const bob = Account(
"bob");
528 auto const startLegSeq = env.current()->header().seq;
529 env.fund(XRP(10000), alice, bob);
530 env(pay(alice, bob, XRP(10)));
542 jsonTx[jss::binary] =
false;
543 jsonTx[jss::ctid] = *ctid;
545 auto const jrr = env.rpc(
"json",
"tx",
to_string(jsonTx))[jss::result];
546 BEAST_EXPECT(jrr[jss::ctid] == ctid);
547 BEAST_EXPECT(jrr.isMember(jss::hash));
555 Account
const alice = Account(
"alice");
556 Account
const bob = Account(
"bob");
558 std::uint32_t const startLegSeq = env.current()->header().seq;
559 env.fund(XRP(10000), alice, bob);
560 env(pay(alice, bob, XRP(10)));
564 auto isUpper = [](
char c) {
return std::isupper(c) != 0; };
574 *iter = std::tolower(*iter);
576 BEAST_EXPECT(ctid != mixedCase);
579 jsonTx[jss::binary] =
false;
580 jsonTx[jss::ctid] = mixedCase;
583 BEAST_EXPECT(jrr[jss::ctid] == ctid);
584 BEAST_EXPECT(jrr[jss::hash]);
591 for (uint32_t netID : {2, 1024, 65535, 65536})
594 BEAST_EXPECT(netID == env.app().config().NETWORK_ID);
596 auto const alice = Account(
"alice");
597 auto const bob = Account(
"bob");
599 env.fund(XRP(10000), alice, bob);
600 env(pay(alice, bob, XRP(10)));
603 auto const ledgerSeq = env.current()->header().seq;
611 params[jss::transaction] = hash;
612 auto const jrr = env.rpc(
"json",
"tx",
to_string(params))[jss::result];
613 BEAST_EXPECT(jrr[jss::hash] == hash);
615 BEAST_EXPECT(jrr.isMember(jss::ctid) == (netID <= 0xFFFF));
616 if (jrr.isMember(jss::ctid))
619 BEAST_EXPECT(jrr[jss::ctid] == *ctid);
626 uint32_t netID = env.app().config().NETWORK_ID;
628 auto const alice = Account(
"alice");
629 auto const bob = Account(
"bob");
631 auto const startLegSeq = env.current()->header().seq;
632 env.fund(XRP(10000), alice, bob);
633 env(pay(alice, bob, XRP(10)));
638 jsonTx[jss::binary] =
false;
639 jsonTx[jss::ctid] = ctid;
641 auto const jrr = env.rpc(
"json",
"tx",
to_string(jsonTx))[jss::result];
642 BEAST_EXPECT(jrr[jss::error] ==
"wrongNetwork");
645 jrr[jss::error_message] ==
646 "Wrong network. You should submit this request to a node "
647 "running on NetworkID: 21338");
656 using namespace test::jtx;
660 cfg->FEES.reference_fee = 10;
663 Account
const alice{
"alice"};
664 Account
const alie{
"alie"};
665 Account
const gw{
"gw"};
666 auto const USD{gw[
"USD"]};
668 env.fund(XRP(1000000), alice, gw);
675 env(pay(alice, gw, XRP(100)));
682 expected[jss::DeliverMax] = expected[jss::Amount];
689 Json::Value const result = {[&env, txn, apiVersion]() {
691 params[jss::transaction] =
to_string(txn->getTransactionID());
692 params[jss::binary] =
false;
693 params[jss::api_version] = apiVersion;
694 return env.client().invoke(
"tx", params);
697 BEAST_EXPECT(result[jss::result][jss::status] == jss::success);
700 BEAST_EXPECT(result[jss::result][jss::close_time_iso] ==
"2000-01-01T00:00:20Z");
701 BEAST_EXPECT(result[jss::result][jss::hash] ==
to_string(txn->getTransactionID()));
702 BEAST_EXPECT(result[jss::result][jss::validated] ==
true);
703 BEAST_EXPECT(result[jss::result][jss::ledger_index] == 4);
705 result[jss::result][jss::ledger_hash] ==
706 "B41882E20F0EC6228417D28B9AE0F33833645D35F6799DFB782AC97FC4BB51"
710 for (
auto memberIt = expected.
begin(); memberIt != expected.
end(); memberIt++)
713 auto const& result_transaction = (apiVersion > 1 ? result[jss::result][jss::tx_json] : result[jss::result]);
714 if (BEAST_EXPECT(result_transaction.isMember(name)))
716 auto const received = result_transaction[name];
718 received == *memberIt,
719 "Transaction contains \n\"" + name +
"\": "
732 using namespace test::jtx;
736 cfg->FEES.reference_fee = 10;
739 Account
const alice{
"alice"};
740 Account
const gw{
"gw"};
741 auto const USD{gw[
"USD"]};
743 env.fund(XRP(1000000), alice, gw);
746 to_string(txn->getTransactionID()) ==
"3F8BDE5A5F82C4F4708E5E9255B713E303E6E1A371FD5C7A704AFD1387C23981");
753 Json::Value const result = [&env, txn, apiVersion]() {
755 params[jss::transaction] =
to_string(txn->getTransactionID());
756 params[jss::binary] =
true;
757 params[jss::api_version] = apiVersion;
758 return env.client().invoke(
"tx", params);
761 if (BEAST_EXPECT(result[jss::status] ==
"success"))
763 BEAST_EXPECT(result[jss::result][jss::status] ==
"success");
764 BEAST_EXPECT(result[jss::result][jss::validated] ==
true);
765 BEAST_EXPECT(result[jss::result][jss::hash] ==
to_string(txn->getTransactionID()));
766 BEAST_EXPECT(result[jss::result][jss::ledger_index] == 3);
767 BEAST_EXPECT(result[jss::result][jss::ctid] ==
"C000000300030000");
771 BEAST_EXPECT(result[jss::result][jss::tx_blob] == expected_tx_blob);
772 BEAST_EXPECT(result[jss::result][jss::meta_blob] == expected_meta_blob);
774 result[jss::result][jss::ledger_hash] ==
775 "2D5150E5A5AA436736A732291E437ABF01BC9E206C2DF3C77C4F856915"
777 BEAST_EXPECT(result[jss::result][jss::close_time_iso] ==
"2000-01-01T00:00:10Z");
781 BEAST_EXPECT(result[jss::result][jss::tx] == expected_tx_blob);
782 BEAST_EXPECT(result[jss::result][jss::meta] == expected_meta_blob);
783 BEAST_EXPECT(result[jss::result][jss::date] == 10);