20 #include <ripple/app/main/Application.h>
21 #include <ripple/app/misc/LoadFeeTrack.h>
22 #include <ripple/app/misc/TxQ.h>
23 #include <ripple/app/tx/apply.h>
24 #include <ripple/basics/Log.h>
25 #include <ripple/basics/mulDiv.h>
26 #include <ripple/protocol/ErrorCodes.h>
27 #include <ripple/protocol/Feature.h>
28 #include <ripple/protocol/jss.h>
29 #include <ripple/protocol/st.h>
30 #include <boost/optional.hpp>
32 #include <test/jtx/TestSuite.h>
33 #include <test/jtx/WSClient.h>
34 #include <test/jtx/envconfig.h>
35 #include <test/jtx/ticket.h>
41 class TxQ_test :
public beast::unit_test::suite
47 boost::optional<std::size_t> expectedMaxCount,
53 FeeLevel64 const expectedMin{expectedMinFeeLevel};
54 FeeLevel64 const expectedMed{expectedMedFeeLevel};
61 BEAST_EXPECT(metrics.minProcessingFeeLevel == expectedMin);
63 auto expectedCurFeeLevel = expectedInLedger > expectedPerLedger
64 ? expectedMed * expectedInLedger * expectedInLedger /
65 (expectedPerLedger * expectedPerLedger)
66 : metrics.referenceFeeLevel;
67 BEAST_EXPECT(metrics.openLedgerFeeLevel == expectedCurFeeLevel);
74 for (
int i = metrics.txInLedger; i <= metrics.txPerLedger; ++i)
83 auto const& view = *env.
current();
88 toDrops(metrics.openLedgerFeeLevel, view.fees().base).second + 1);
97 auto& section = p->section(
"transaction_queue");
98 section.set(
"ledgers_in_queue",
"2");
99 section.set(
"minimum_queue_size",
"2");
100 section.set(
"min_ledgers_to_compute_size_limit",
"3");
101 section.set(
"max_ledger_counts_to_store",
"100");
102 section.set(
"retry_sequence_percent",
"25");
103 section.set(
"zero_basefee_transaction_feelevel",
"100000000000");
104 section.set(
"normal_consensus_increase_percent",
"0");
106 for (
auto const& [k, v] : extraTxQ)
111 if (!extraVoting.
empty())
113 auto& votingSection = p->section(
"voting");
114 for (
auto const& [k, v] : extraVoting)
116 votingSection.set(k, v);
120 p->section(
"validation_seed")
121 .legacy(
"shUwVw52ofnCUX5m7kPTKzJdr4HEH");
140 for (
auto i = env.
current()->seq(); i <= 257; ++i)
147 auto const flagPerLedger =
149 auto const flagMaxQueue = ledgersInQueue * flagPerLedger;
150 checkMetrics(env, 0, flagMaxQueue, 0, flagPerLedger, 256, 100000000000);
159 using namespace std::chrono_literals;
161 checkMetrics(env, 0, flagMaxQueue, 0, expectedPerLedger, 256);
162 auto const fees = env.
current()->fees();
178 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
183 auto charlie =
Account(
"charlie");
340 auto metrics = txq.getMetrics(*env.
current());
344 for (
int i = metrics.txInLedger; i <= metrics.txPerLedger; ++i)
357 metrics.txPerLedger + 1,
367 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"2"}}));
371 auto USD = gw[
"USD"];
403 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"2"}}));
407 auto charlie =
Account(
"charlie");
459 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"2"}}));
463 auto charlie =
Account(
"charlie");
466 auto felicia =
Account(
"felicia");
489 json(R
"({"LastLedgerSequence":7})"),
506 aliceStat.begin()->second.lastValid &&
507 *aliceStat.begin()->second.lastValid == 8);
510 auto bobStat = txQ.getAccountTxs(bob.id(), *env.
current());
513 bobStat.begin()->second.feeLevel ==
568 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"2"}}));
608 auto seqBob = env.
seq(bob);
609 for (
int i = 0; i < 4; ++i)
612 feeBob = (feeBob + 1) * 125 / 100;
630 auto feeCarol = feeBob;
631 auto seqCarol = env.
seq(carol);
632 for (
int i = 0; i < 3; ++i)
635 feeCarol = (feeCarol + 1) * 125 / 100;
695 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"2"}}));
718 auto const& jt = env.
jt(
noop(alice));
748 {{
"minimum_txn_in_ledger_standalone",
"3"}},
749 {{
"account_reserve",
"200"}, {
"owner_reserve",
"50"}}));
753 auto charlie =
Account(
"charlie");
763 auto const initQueueMax =
initFee(env, 3, 2, 10, 10, 200, 50);
774 auto aliceSeq = env.
seq(alice);
775 auto bobSeq = env.
seq(bob);
776 auto charlieSeq = env.
seq(charlie);
821 aliceSeq = env.
seq(alice);
822 auto lastLedgerSeq = env.
current()->info().seq + 2;
823 for (
auto i = 0; i < 7; i++)
827 json(jss::LastLedgerSequence, lastLedgerSeq + i),
837 auto const& baseFee = env.
current()->fees().base;
838 auto seq = env.
seq(alice);
840 for (
auto const& [txSeq, details] : aliceStat)
847 (details.consequences &&
848 details.consequences->fee ==
drops(
fee) &&
849 details.consequences->potentialSpend ==
drops(0) &&
850 details.consequences->category ==
852 txSeq == env.
seq(alice) + 6);
862 json(jss::LastLedgerSequence, lastLedgerSeq + 7),
895 aliceSeq = env.
seq(alice) + 2;
914 aliceSeq = env.
seq(alice) + 1;
921 env.
le(alice)->getFieldAmount(
sfBalance).xrp().drops() - (59);
964 bobSeq = env.
seq(bob);
966 for (
int i = 0; i < 10; ++i)
984 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"4"}}));
988 auto charlie =
Account(
"charlie");
1025 auto aliceSeq = env.
seq(alice);
1026 auto bobSeq = env.
seq(bob);
1027 auto charlieSeq = env.
seq(charlie);
1028 auto dariaSeq = env.
seq(daria);
1029 auto elmoSeq = env.
seq(elmo);
1030 auto fredSeq = env.
seq(fred);
1031 auto gwenSeq = env.
seq(gwen);
1032 auto hankSeq = env.
seq(hank);
1080 aliceSeq = env.
seq(alice);
1081 bobSeq = env.
seq(bob);
1082 charlieSeq = env.
seq(charlie);
1083 dariaSeq = env.
seq(daria);
1084 elmoSeq = env.
seq(elmo);
1119 using namespace jtx;
1121 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"1"}}));
1123 auto alice =
Account(
"alice");
1139 json(R
"({"AccountTxnID": "0"})"),
1157 using namespace jtx;
1158 using namespace std::string_literals;
1164 {{
"minimum_txn_in_ledger_standalone",
"2"},
1165 {
"target_txn_in_ledger",
"4"},
1166 {
"maximum_txn_in_ledger",
"5"}}));
1168 auto alice =
Account(
"alice");
1175 for (
int i = 0; i < 10; ++i)
1190 {{
"minimum_txn_in_ledger",
"200"},
1191 {
"minimum_txn_in_ledger_standalone",
"200"},
1192 {
"target_txn_in_ledger",
"4"},
1193 {
"maximum_txn_in_ledger",
"5"}}));
1201 "The minimum number of low-fee transactions allowed "
1202 "per ledger (minimum_txn_in_ledger) exceeds "
1203 "the maximum number of low-fee transactions allowed per "
1204 "ledger (maximum_txn_in_ledger)."s);
1211 {{
"minimum_txn_in_ledger",
"200"},
1212 {
"minimum_txn_in_ledger_standalone",
"2"},
1213 {
"target_txn_in_ledger",
"4"},
1214 {
"maximum_txn_in_ledger",
"5"}}));
1222 "The minimum number of low-fee transactions allowed "
1223 "per ledger (minimum_txn_in_ledger) exceeds "
1224 "the maximum number of low-fee transactions allowed per "
1225 "ledger (maximum_txn_in_ledger)."s);
1232 {{
"minimum_txn_in_ledger",
"2"},
1233 {
"minimum_txn_in_ledger_standalone",
"200"},
1234 {
"target_txn_in_ledger",
"4"},
1235 {
"maximum_txn_in_ledger",
"5"}}));
1243 "The minimum number of low-fee transactions allowed "
1244 "per ledger (minimum_txn_in_ledger_standalone) exceeds "
1245 "the maximum number of low-fee transactions allowed per "
1246 "ledger (maximum_txn_in_ledger)."s);
1253 using namespace jtx;
1258 {{
"minimum_txn_in_ledger_standalone",
"3"}},
1259 {{
"account_reserve",
"200"}, {
"owner_reserve",
"50"}}));
1261 auto alice =
Account(
"alice");
1267 auto const initQueueMax =
initFee(env, 3, 2, 10, 10, 200, 50);
1276 auto USD = bob[
"USD"];
1290 auto aliceSeq = env.
seq(alice);
1299 env(offer(bob,
drops(5000), USD(5000)),
1334 for (
int i = 0; i < 9; ++i)
1349 using namespace jtx;
1351 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
1353 auto alice =
Account(
"alice");
1355 auto charlie =
Account(
"charlie");
1356 auto daria =
Account(
"daria");
1372 env(
regkey(alice, charlie));
1376 auto aliceSeq = env.
seq(alice);
1390 env(signers(alice, 2, {{bob}, {charlie}, {daria}}),
1395 env(signers(alice, 2, {{bob}, {charlie}, {daria}}),
1420 using namespace jtx;
1421 testcase(
"In-flight balance checks");
1426 {{
"minimum_txn_in_ledger_standalone",
"3"}},
1427 {{
"account_reserve",
"200"}, {
"owner_reserve",
"50"}}));
1429 auto alice =
Account(
"alice");
1430 auto charlie =
Account(
"charlie");
1441 auto const initQueueMax =
initFee(env, 3, 2, 10, 10, 200, 50);
1448 checkMetrics(env, 0, initQueueMax, limit + 1, limit, 256);
1450 auto USD = gw[
"USD"];
1451 auto BUX = gw[
"BUX"];
1455 auto aliceSeq = env.
seq(alice);
1456 auto aliceBal = env.
balance(alice);
1462 env(offer(alice, BUX(5000),
XRP(50000)),
queued);
1463 checkMetrics(env, 1, initQueueMax, limit + 1, limit, 256);
1468 checkMetrics(env, 2, initQueueMax, limit + 1, limit, 256);
1484 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1485 aliceSeq = env.
seq(alice);
1486 aliceBal = env.
balance(alice);
1492 checkMetrics(env, 1, limit * 2, limit + 1, limit, 256);
1497 checkMetrics(env, 2, limit * 2, limit + 1, limit, 256);
1505 checkMetrics(env, 2, limit * 2, limit + 1, limit, 256);
1521 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1522 aliceSeq = env.
seq(alice);
1523 aliceBal = env.
balance(alice);
1530 checkMetrics(env, 1, limit * 2, limit + 1, limit, 256);
1538 checkMetrics(env, 1, limit * 2, limit + 1, limit, 256);
1554 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1555 aliceSeq = env.
seq(alice);
1556 aliceBal = env.
balance(alice);
1560 env(offer(alice, BUX(50),
XRP(500)),
queued);
1564 checkMetrics(env, 2, limit * 2, limit + 1, limit, 256);
1580 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1582 aliceSeq = env.
seq(alice);
1583 aliceBal = env.
balance(alice);
1593 checkMetrics(env, 2, limit * 2, limit + 1, limit, 256);
1607 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1609 aliceSeq = env.
seq(alice);
1610 aliceBal = env.
balance(alice);
1618 checkMetrics(env, 2, limit * 2, limit + 1, limit, 256);
1630 auto const amount = USD(500000);
1631 env(
trust(alice, USD(50000000)));
1632 env(
trust(charlie, USD(50000000)));
1638 env(
pay(gw, alice, amount));
1645 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1647 aliceSeq = env.
seq(alice);
1648 aliceBal = env.
balance(alice);
1649 auto aliceUSD = env.
balance(alice, USD);
1653 env(
pay(alice, charlie, amount),
queued);
1658 checkMetrics(env, 2, limit * 2, limit + 1, limit, 256);
1676 env(offer(gw,
XRP(500000), USD(50000)));
1682 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1684 aliceSeq = env.
seq(alice);
1685 aliceBal = env.
balance(alice);
1686 auto charlieUSD = env.
balance(charlie, USD);
1698 checkMetrics(env, 2, limit * 2, limit + 1, limit, 256);
1709 balance(charlie, charlieUSD + USD(1000)),
1717 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1719 aliceSeq = env.
seq(alice);
1720 aliceBal = env.
balance(alice);
1721 charlieUSD = env.
balance(charlie, USD);
1732 checkMetrics(env, 2, limit * 2, limit + 1, limit, 256);
1743 balance(charlie, charlieUSD + USD(500)),
1753 checkMetrics(env, 0, limit * 2, limit + 1, limit, 256);
1755 aliceSeq = env.
seq(alice);
1756 aliceBal = env.
balance(alice);
1763 checkMetrics(env, 1, limit * 2, limit + 1, limit, 256);
1774 using namespace jtx;
1777 auto const alice =
Account(
"alice");
1783 cancelOffer[jss::Account] = alice.human();
1784 cancelOffer[jss::OfferSequence] = 3;
1785 cancelOffer[jss::TransactionType] = jss::OfferCancel;
1786 auto const jtx = env.
jt(cancelOffer,
seq(1),
fee(10));
1801 auto USD = alice[
"USD"];
1820 env.
jt(ticket::create(alice,
"bob", 60),
seq(1),
fee(10));
1836 cancelTicket[jss::Account] = alice.human();
1838 cancelTicket[jss::TransactionType] = jss::TicketCancel;
1839 auto const jtx = env.
jt(cancelTicket,
seq(1),
fee(10));
1857 using namespace jtx;
1860 auto fee = env.
rpc(
"fee");
1867 result.isMember(jss::ledger_current_index) &&
1868 result[jss::ledger_current_index] == 3);
1880 auto const& levels =
result[jss::levels];
1896 result.isMember(jss::ledger_current_index) &&
1897 result[jss::ledger_current_index] == 4);
1908 auto const& levels =
result[jss::levels];
1930 using namespace jtx;
1935 {{
"minimum_txn_in_ledger_standalone",
"1"},
1936 {
"ledgers_in_queue",
"10"},
1937 {
"maximum_txn_per_account",
"20"}}));
1940 auto const alice =
Account(
"alice");
1941 auto const bob =
Account(
"bob");
1946 auto const aliceSeq = env.
seq(alice);
1950 json(R
"({"LastLedgerSequence":5})"),
1954 json(R"({"LastLedgerSequence":5})"),
1958 json(R"({"LastLedgerSequence":10})"),
1962 json(R"({"LastLedgerSequence":11})"),
1965 auto const bobSeq = env.
seq(bob);
1969 for (
int i = 0; i < 3 + 4 + 5; ++i)
1973 checkMetrics(env, 4 + 3 + 4 + 5, boost::none, 2, 1, 256);
2022 testcase(
"Autofilled sequence should account for TxQ");
2023 using namespace jtx;
2024 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"6"}}));
2028 auto const alice =
Account(
"alice");
2029 auto const bob =
Account(
"bob");
2030 env.
fund(
XRP(100000), alice, bob);
2036 auto const aliceSeq = env.
seq(alice);
2037 auto const lastLedgerSeq = env.
current()->info().seq + 2;
2040 for (
int i = 0; i < 5; ++i)
2047 json(jss::LastLedgerSequence, lastLedgerSeq),
2055 auto aliceStat = txQ.getAccountTxs(alice.id(), *env.
current());
2056 auto seq = aliceSeq;
2058 for (
auto const& tx : aliceStat)
2062 if (
seq == aliceSeq + 2)
2065 tx.second.lastValid &&
2066 *tx.second.lastValid == lastLedgerSeq);
2077 for (
int i = 0; i < 8; ++i)
2086 for (
int i = 0; i < 9; ++i)
2093 for (
int i = 0; i < 10; ++i)
2100 auto bobStat = txQ.getAccountTxs(bob.id(), *env.
current());
2106 auto aliceStat = txQ.getAccountTxs(alice.id(), *env.
current());
2107 auto seq = aliceSeq;
2109 for (
auto const& tx : aliceStat)
2112 if (
seq == aliceSeq + 2)
2125 auto aliceStat = txQ.getAccountTxs(alice.id(), *env.
current());
2126 auto seq = aliceSeq;
2128 for (
auto const& tx : aliceStat)
2141 auto bobStat = txQ.getAccountTxs(bob.id(), *env.
current());
2145 auto aliceStat = txQ.getAccountTxs(alice.id(), *env.
current());
2153 using namespace jtx;
2154 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
2158 env.
fund(
XRP(1000000), alice);
2161 auto const withQueue =
2162 R
"({ "account": ")" + alice.human() + R"(", "queue": true })";
2165 R"(", "queue": true, "ledger_index": 3 })";
2172 info.isMember(jss::result) &&
2173 info[jss::result].isMember(jss::account_data));
2174 BEAST_EXPECT(!info[jss::result].isMember(jss::queue_data));
2178 auto const info = env.
rpc(
"json",
"account_info", withQueue);
2180 info.isMember(jss::result) &&
2181 info[jss::result].isMember(jss::account_data));
2200 auto const info = env.
rpc(
"json",
"account_info", withQueue);
2202 info.isMember(jss::result) &&
2203 info[jss::result].isMember(jss::account_data));
2204 auto const&
result = info[jss::result];
2225 auto const info = env.
rpc(
"json",
"account_info", withQueue);
2227 info.isMember(jss::result) &&
2228 info[jss::result].isMember(jss::account_data));
2229 auto const&
result = info[jss::result];
2242 data[jss::Sequence].asUInt() +
2251 auto const& item =
queued[i];
2256 if (i ==
queued.size() - 1)
2279 json(jss::LastLedgerSequence, 10),
2284 auto const info = env.
rpc(
"json",
"account_info", withQueue);
2286 info.isMember(jss::result) &&
2287 info[jss::result].isMember(jss::account_data));
2288 auto const&
result = info[jss::result];
2289 auto const&
data =
result[jss::account_data];
2301 data[jss::Sequence].asUInt() +
2310 auto const& item =
queued[i];
2314 if (i ==
queued.size() - 1)
2340 auto const info = env.
rpc(
"json",
"account_info", withQueue);
2342 info.isMember(jss::result) &&
2343 info[jss::result].isMember(jss::account_data));
2344 auto const&
result = info[jss::result];
2345 auto const&
data =
result[jss::account_data];
2357 data[jss::Sequence].asUInt() +
2368 auto const& item =
queued[i];
2372 if (i ==
queued.size() - 1)
2400 info.isMember(jss::result) &&
2410 auto const info = env.
rpc(
"json",
"account_info", withQueue);
2412 info.isMember(jss::result) &&
2413 info[jss::result].isMember(jss::account_data));
2414 auto const&
result = info[jss::result];
2431 using namespace jtx;
2432 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
2436 env.
fund(
XRP(1000000), alice);
2440 auto const server_info = env.
rpc(
"server_info");
2442 server_info.isMember(jss::result) &&
2443 server_info[jss::result].isMember(jss::info));
2444 auto const& info = server_info[jss::result][jss::info];
2446 info.isMember(jss::load_factor) && info[jss::load_factor] == 1);
2450 BEAST_EXPECT(!info.isMember(jss::load_factor_fee_escalation));
2453 auto const server_state = env.
rpc(
"server_state");
2454 auto const& state = server_state[jss::result][jss::state];
2456 state.isMember(jss::load_factor) &&
2457 state[jss::load_factor] == 256);
2459 state.isMember(jss::load_base) && state[jss::load_base] == 256);
2461 state.isMember(jss::load_factor_server) &&
2462 state[jss::load_factor_server] == 256);
2464 state.isMember(jss::load_factor_fee_escalation) &&
2465 state[jss::load_factor_fee_escalation] == 256);
2467 state.isMember(jss::load_factor_fee_queue) &&
2468 state[jss::load_factor_fee_queue] == 256);
2470 state.isMember(jss::load_factor_fee_reference) &&
2471 state[jss::load_factor_fee_reference] == 256);
2479 auto aliceSeq = env.
seq(alice);
2481 for (
auto i = 0; i < 4; ++i)
2487 auto const server_info = env.
rpc(
"server_info");
2489 server_info.isMember(jss::result) &&
2490 server_info[jss::result].isMember(jss::info));
2491 auto const& info = server_info[jss::result][jss::info];
2494 info.isMember(jss::load_factor) &&
2495 info[jss::load_factor] > 888.88 &&
2496 info[jss::load_factor] < 888.89);
2498 info.isMember(jss::load_factor_server) &&
2499 info[jss::load_factor_server] == 1);
2503 info.isMember(jss::load_factor_fee_escalation) &&
2504 info[jss::load_factor_fee_escalation] > 888.88 &&
2505 info[jss::load_factor_fee_escalation] < 888.89);
2508 auto const server_state = env.
rpc(
"server_state");
2509 auto const& state = server_state[jss::result][jss::state];
2511 state.isMember(jss::load_factor) &&
2512 state[jss::load_factor] == 227555);
2514 state.isMember(jss::load_base) && state[jss::load_base] == 256);
2516 state.isMember(jss::load_factor_server) &&
2517 state[jss::load_factor_server] == 256);
2519 state.isMember(jss::load_factor_fee_escalation) &&
2520 state[jss::load_factor_fee_escalation] == 227555);
2522 state.isMember(jss::load_factor_fee_queue) &&
2523 state[jss::load_factor_fee_queue] == 256);
2525 state.isMember(jss::load_factor_fee_reference) &&
2526 state[jss::load_factor_fee_reference] == 256);
2532 auto const server_info = env.
rpc(
"server_info");
2534 server_info.isMember(jss::result) &&
2535 server_info[jss::result].isMember(jss::info));
2536 auto const& info = server_info[jss::result][jss::info];
2539 info.isMember(jss::load_factor) &&
2540 info[jss::load_factor] == 1000);
2544 info.isMember(jss::load_factor_net) &&
2545 info[jss::load_factor_net] == 1000);
2547 info.isMember(jss::load_factor_fee_escalation) &&
2548 info[jss::load_factor_fee_escalation] > 888.88 &&
2549 info[jss::load_factor_fee_escalation] < 888.89);
2552 auto const server_state = env.
rpc(
"server_state");
2553 auto const& state = server_state[jss::result][jss::state];
2555 state.isMember(jss::load_factor) &&
2556 state[jss::load_factor] == 256000);
2558 state.isMember(jss::load_base) && state[jss::load_base] == 256);
2560 state.isMember(jss::load_factor_server) &&
2561 state[jss::load_factor_server] == 256000);
2563 state.isMember(jss::load_factor_fee_escalation) &&
2564 state[jss::load_factor_fee_escalation] == 227555);
2566 state.isMember(jss::load_factor_fee_queue) &&
2567 state[jss::load_factor_fee_queue] == 256);
2569 state.isMember(jss::load_factor_fee_reference) &&
2570 state[jss::load_factor_fee_reference] == 256);
2576 for (
int i = 0; i < 5; ++i)
2581 auto const server_info = env.
rpc(
"server_info");
2583 server_info.isMember(jss::result) &&
2584 server_info[jss::result].isMember(jss::info));
2585 auto const& info = server_info[jss::result][jss::info];
2588 info.isMember(jss::load_factor) &&
2589 info[jss::load_factor] > 888.88 &&
2590 info[jss::load_factor] < 888.89);
2595 info.isMember(jss::load_factor_server) &&
2596 info[jss::load_factor_server] > 1.245 &&
2597 info[jss::load_factor_server] < 2.4415);
2599 info.isMember(jss::load_factor_local) &&
2600 info[jss::load_factor_local] > 1.245 &&
2601 info[jss::load_factor_local] < 2.4415);
2604 info.isMember(jss::load_factor_fee_escalation) &&
2605 info[jss::load_factor_fee_escalation] > 888.88 &&
2606 info[jss::load_factor_fee_escalation] < 888.89);
2609 auto const server_state = env.
rpc(
"server_state");
2610 auto const& state = server_state[jss::result][jss::state];
2612 state.isMember(jss::load_factor) &&
2613 state[jss::load_factor] == 227555);
2615 state.isMember(jss::load_base) && state[jss::load_base] == 256);
2620 state.isMember(jss::load_factor_server) &&
2621 state[jss::load_factor_server] >= 320 &&
2622 state[jss::load_factor_server] <= 625);
2624 state.isMember(jss::load_factor_fee_escalation) &&
2625 state[jss::load_factor_fee_escalation] == 227555);
2627 state.isMember(jss::load_factor_fee_queue) &&
2628 state[jss::load_factor_fee_queue] == 256);
2630 state.isMember(jss::load_factor_fee_reference) &&
2631 state[jss::load_factor_fee_reference] == 256);
2637 auto const server_info = env.
rpc(
"server_info");
2639 server_info.isMember(jss::result) &&
2640 server_info[jss::result].isMember(jss::info));
2641 auto const& info = server_info[jss::result][jss::info];
2648 info.isMember(jss::load_factor) &&
2649 info[jss::load_factor] > 1.245 &&
2650 info[jss::load_factor] < 2.4415);
2653 info.isMember(jss::load_factor_local) &&
2654 info[jss::load_factor_local] > 1.245 &&
2655 info[jss::load_factor_local] < 2.4415);
2657 BEAST_EXPECT(!info.isMember(jss::load_factor_fee_escalation));
2660 auto const server_state = env.
rpc(
"server_state");
2661 auto const& state = server_state[jss::result][jss::state];
2663 state.isMember(jss::load_factor) &&
2664 state[jss::load_factor] >= 320 &&
2665 state[jss::load_factor] <= 625);
2667 state.isMember(jss::load_base) && state[jss::load_base] == 256);
2672 state.isMember(jss::load_factor_server) &&
2673 state[jss::load_factor_server] >= 320 &&
2674 state[jss::load_factor_server] <= 625);
2676 state.isMember(jss::load_factor_fee_escalation) &&
2677 state[jss::load_factor_fee_escalation] == 256);
2679 state.isMember(jss::load_factor_fee_queue) &&
2680 state[jss::load_factor_fee_queue] == 256);
2682 state.isMember(jss::load_factor_fee_reference) &&
2683 state[jss::load_factor_fee_reference] == 256);
2690 using namespace jtx;
2692 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
2696 stream[jss::streams].append(
"server");
2699 auto jv = wsc->invoke(
"subscribe", stream);
2703 Account a{
"a"}, b{
"b"}, c{
"c"}, d{
"d"}, e{
"e"}, f{
"f"}, g{
"g"}, h{
"h"},
2711 using namespace std::chrono_literals;
2713 return jv[jss::type] ==
"serverStatus" &&
2714 jv.isMember(jss::load_factor) && jv[jss::load_factor] == 256 &&
2715 jv.isMember(jss::load_base) && jv[jss::load_base] == 256 &&
2716 jv.isMember(jss::load_factor_server) &&
2717 jv[jss::load_factor_server] == 256 &&
2718 jv.isMember(jss::load_factor_fee_escalation) &&
2719 jv[jss::load_factor_fee_escalation] == 256 &&
2720 jv.isMember(jss::load_factor_fee_queue) &&
2721 jv[jss::load_factor_fee_queue] == 256 &&
2722 jv.isMember(jss::load_factor_fee_reference) &&
2723 jv[jss::load_factor_fee_reference] == 256;
2727 return jv[jss::type] ==
"serverStatus" &&
2728 jv.isMember(jss::load_factor) &&
2729 jv[jss::load_factor] == 227555 && jv.isMember(jss::load_base) &&
2730 jv[jss::load_base] == 256 &&
2731 jv.isMember(jss::load_factor_server) &&
2732 jv[jss::load_factor_server] == 256 &&
2733 jv.isMember(jss::load_factor_fee_escalation) &&
2734 jv[jss::load_factor_fee_escalation] == 227555 &&
2735 jv.isMember(jss::load_factor_fee_queue) &&
2736 jv[jss::load_factor_fee_queue] == 256 &&
2737 jv.isMember(jss::load_factor_fee_reference) &&
2738 jv[jss::load_factor_fee_reference] == 256;
2745 return jv[jss::type] ==
"serverStatus" &&
2746 jv.isMember(jss::load_factor) && jv[jss::load_factor] == 256 &&
2747 jv.isMember(jss::load_base) && jv[jss::load_base] == 256 &&
2748 jv.isMember(jss::load_factor_server) &&
2749 jv[jss::load_factor_server] == 256 &&
2750 jv.isMember(jss::load_factor_fee_escalation) &&
2751 jv[jss::load_factor_fee_escalation] == 256 &&
2752 jv.isMember(jss::load_factor_fee_queue) &&
2753 jv[jss::load_factor_fee_queue] == 256 &&
2754 jv.isMember(jss::load_factor_fee_reference) &&
2755 jv[jss::load_factor_fee_reference] == 256;
2776 return jv[jss::type] ==
"serverStatus" &&
2777 jv.isMember(jss::load_factor) &&
2778 jv[jss::load_factor] == 200000 && jv.isMember(jss::load_base) &&
2779 jv[jss::load_base] == 256 &&
2780 jv.isMember(jss::load_factor_server) &&
2781 jv[jss::load_factor_server] == 256 &&
2782 jv.isMember(jss::load_factor_fee_escalation) &&
2783 jv[jss::load_factor_fee_escalation] == 200000 &&
2784 jv.isMember(jss::load_factor_fee_queue) &&
2785 jv[jss::load_factor_fee_queue] == 256 &&
2786 jv.isMember(jss::load_factor_fee_reference) &&
2787 jv[jss::load_factor_fee_reference] == 256;
2793 return jv[jss::type] ==
"serverStatus" &&
2794 jv.isMember(jss::load_factor) &&
2795 jv[jss::load_factor] == 184320 && jv.isMember(jss::load_base) &&
2796 jv[jss::load_base] == 256 &&
2797 jv.isMember(jss::load_factor_server) &&
2798 jv[jss::load_factor_server] == 256 &&
2799 jv.isMember(jss::load_factor_fee_escalation) &&
2800 jv[jss::load_factor_fee_escalation] == 184320 &&
2801 jv.isMember(jss::load_factor_fee_queue) &&
2802 jv[jss::load_factor_fee_queue] == 256 &&
2803 jv.isMember(jss::load_factor_fee_reference) &&
2804 jv[jss::load_factor_fee_reference] == 256;
2810 return jv[jss::type] ==
"serverStatus" &&
2811 jv.isMember(jss::load_factor) && jv[jss::load_factor] == 256 &&
2812 jv.isMember(jss::load_base) && jv[jss::load_base] == 256 &&
2813 jv.isMember(jss::load_factor_server) &&
2814 jv[jss::load_factor_server] == 256 &&
2815 jv.isMember(jss::load_factor_fee_escalation) &&
2816 jv[jss::load_factor_fee_escalation] == 256 &&
2817 jv.isMember(jss::load_factor_fee_queue) &&
2818 jv[jss::load_factor_fee_queue] == 256 &&
2819 jv.isMember(jss::load_factor_fee_reference) &&
2820 jv[jss::load_factor_fee_reference] == 256;
2824 return jv[jss::type] ==
"serverStatus";
2827 auto jv = wsc->invoke(
"unsubscribe", stream);
2834 using namespace jtx;
2836 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
2837 auto alice =
Account(
"alice");
2841 env.
fund(
XRP(50000000), alice, bob);
2846 boost::optional<std::size_t> numToClear =
2848 auto totalFactor = 0;
2851 numToClear.emplace(metrics.txCount + 1);
2852 for (
int i = 0; i < *numToClear; ++i)
2855 totalFactor += inLedger * inLedger;
2858 metrics.medFeeLevel * totalFactor /
2859 (metrics.txPerLedger * metrics.txPerLedger),
2869 testcase(
"straightfoward positive case");
2872 auto aliceSeq = env.
seq(alice);
2873 for (
int i = 0; i < 2; ++i)
2904 calcTotalFee(100 * 2 + 8889 + 60911);
2907 env(
noop(alice),
fee(totalFee2),
seq(aliceSeq++));
2912 testcase(
"replace last tx with enough to clear queue");
2915 auto aliceSeq = env.
seq(alice);
2916 for (
int i = 0; i < 2; ++i)
2935 calcTotalFee(100 * 2, metrics.txCount);
2939 env(
noop(alice),
fee(totalFee),
seq(aliceSeq++));
2948 testcase(
"replace middle tx with enough to clear queue");
2952 auto aliceSeq = env.
seq(alice);
2953 for (
int i = 0; i < 5; ++i)
2965 env(
noop(alice),
fee(totalFee),
seq(aliceSeq++));
2968 auto const aliceQueue =
2971 auto seq = aliceSeq;
2972 for (
auto const& tx : aliceQueue)
2984 testcase(
"clear queue failure (load)");
2988 auto aliceSeq = env.
seq(alice);
2989 for (
int i = 0; i < 2; ++i)
2993 for (
int i = 0; i < 2; ++i)
3002 std::uint64_t const totalFee = calcTotalFee(200 * 2 + 22 * 2);
3007 feeTrack.setRemoteFee(origFee * 5);
3020 feeTrack.setRemoteFee(origFee);
3039 using namespace jtx;
3040 using namespace std::chrono_literals;
3046 {{
"minimum_txn_in_ledger_standalone",
"3"},
3047 {
"normal_consensus_increase_percent",
"25"},
3048 {
"slow_consensus_decrease_percent",
"50"},
3049 {
"target_txn_in_ledger",
"10"},
3050 {
"maximum_txn_per_account",
"200"}}));
3051 auto alice =
Account(
"alice");
3054 env.
fund(
XRP(50000000), alice);
3058 auto seqAlice = env.
seq(alice);
3060 for (
int i = 0; i < txCount; ++i)
3104 env.
close(env.
now() + 5s, 10000ms);
3109 env.
close(env.
now() + 5s, 10000ms);
3114 env.
close(env.
now() + 5s, 10000ms);
3121 env.
close(env.
now() + 5s, 10000ms);
3132 {{
"minimum_txn_in_ledger_standalone",
"3"},
3133 {
"normal_consensus_increase_percent",
"150"},
3134 {
"slow_consensus_decrease_percent",
"150"},
3135 {
"target_txn_in_ledger",
"10"},
3136 {
"maximum_txn_per_account",
"200"}}));
3137 auto alice =
Account(
"alice");
3140 env.
fund(
XRP(50000000), alice);
3144 auto seqAlice = env.
seq(alice);
3146 for (
int i = 0; i < txCount; ++i)
3165 env.
close(env.
now() + 5s, 10000ms);