176 auto charlie =
Account(
"charlie");
185 auto const baseFee = env.current()->fees().base.drops();
190 env.fund(
XRP(50000),
noripple(alice, bob, charlie, daria));
194 env(
noop(alice), queued);
202 env(
noop(daria),
Fee(baseFee * 100), queued);
212 env.fund(
XRP(50000),
noripple(elmo, fred, gwen, hank));
216 env(
noop(alice),
Fee(baseFee * 1.2), queued);
219 env(
noop(bob),
Fee(baseFee), queued);
220 env(
noop(charlie),
Fee(baseFee * 2), queued);
221 env(
noop(daria),
Fee(baseFee * 1.5), queued);
222 env(
noop(elmo),
Fee(baseFee * 1.1), queued);
223 env(
noop(fred),
Fee(baseFee * 1.9), queued);
224 env(
noop(gwen),
Fee(baseFee * 1.6), queued);
225 env(
noop(hank),
Fee(baseFee * 1.8), queued);
237 env(
noop(hank),
Fee(baseFee), queued);
249 env(
noop(hank),
Fee(baseFee * 600), queued);
262 env(
noop(hank),
Fee(baseFee * 2), queued);
272 env.close(env.now() + 5s, 10000ms);
281 static constexpr auto kLargeFeeMultiplier = 700;
282 auto const largeFee = baseFee * kLargeFeeMultiplier;
286 env(
noop(hank),
Fee(largeFee));
287 env(
noop(gwen),
Fee(largeFee));
288 env(
noop(fred),
Fee(largeFee));
289 env(
noop(elmo),
Fee(largeFee));
296 env(
noop(daria),
Fee(baseFee * 1.5), queued);
298 env(
noop(elmo),
Fee(baseFee * 1.6), queued);
299 env(
noop(fred),
Fee(baseFee * 1.7), queued);
300 env(
noop(gwen),
Fee(baseFee * 1.8), queued);
301 env(
noop(hank),
Fee(baseFee * 1.9), queued);
302 env(
noop(alice),
Fee(baseFee * 2.0), queued);
313 env(
noop(charlie),
Fee(baseFee * 10), queued);
340 env(
pay(alice, iris,
XRP(1000)), queued);
348 BEAST_EXPECT(env.seq(iris) == 11);
357 auto metrics = env.app().getTxQ().getMetrics(*env.current());
358 BEAST_EXPECT(
metrics.txCount == 0);
363 env(
noop(env.master));
367 env(
noop(env.master),
Fee(baseFee * 2), queued);
390 auto const baseFee = env.current()->fees().base.drops();
416 BEAST_EXPECT(env.seq(alice) == tkt1 + 250);
440 checkMetrics(*
this, env, 8, 8, 5, 4, expectedMinFeeLevel);
486 env(
noop(alice),
Seq(nextSeq + 0), queued);
490 env(
noop(alice),
Seq(nextSeq + 1), queued);
497 env(
noop(alice),
Seq(nextSeq + 2), queued);
498 env(
noop(alice),
Seq(nextSeq + 3), queued);
499 env(
noop(alice),
Seq(nextSeq + 4), queued);
500 env(
noop(alice),
Seq(nextSeq + 5), queued);
501 env(
noop(alice),
Seq(nextSeq + 6), queued);
532 BEAST_EXPECT(env.seq(alice) == nextSeq + 4);
580 BEAST_EXPECT(env.seq(alice) == nextSeq + 6);
591 Fee((baseFee * 2.1 * 1.25) - 1),
598 Fee((baseFee * 2.2 * 1.25) - 1),
613 BEAST_EXPECT(env.seq(alice) == nextSeq + 8);
717 auto charlie =
Account(
"charlie");
720 auto felicia =
Account(
"felicia");
723 auto const baseFee = env.current()->fees().base.drops();
729 env.close(env.now() + 5s, 10000ms);
731 env.close(env.now() + 5s, 10000ms);
733 env.close(env.now() + 5s, 10000ms);
741 BEAST_EXPECT(env.current()->header().seq == 6);
747 static constexpr auto kLargeFeeMultiplier = 700;
748 auto const largeFee = baseFee * kLargeFeeMultiplier;
752 env(
noop(bob),
Fee(largeFee), queued);
753 env(
noop(charlie),
Fee(largeFee), queued);
754 env(
noop(daria),
Fee(largeFee), queued);
755 env(
noop(edgar),
Fee(largeFee), queued);
758 auto& txQ = env.app().getTxQ();
759 auto aliceStat = txQ.getAccountTxs(alice.id());
760 BEAST_EXPECT(aliceStat.size() == 1);
763 BEAST_EXPECT(aliceStat.begin()->lastValid && *aliceStat.begin()->lastValid == 8);
764 BEAST_EXPECT(!aliceStat.begin()->consequences.isBlocker());
766 auto bobStat = txQ.getAccountTxs(bob.id());
767 BEAST_EXPECT(bobStat.size() == 1);
769 bobStat.begin()->feeLevel ==
FeeLevel64{kBaseFeeLevel.fee() * kLargeFeeMultiplier});
770 BEAST_EXPECT(!bobStat.begin()->lastValid);
771 BEAST_EXPECT(!bobStat.begin()->consequences.isBlocker());
774 BEAST_EXPECT(noStat.empty());
781 env(
noop(bob),
Fee(largeFee), queued);
782 env(
noop(charlie),
Fee(largeFee), queued);
783 env(
noop(daria),
Fee(largeFee), queued);
784 env(
noop(edgar),
Fee(largeFee), queued);
785 env(
noop(felicia),
Fee(largeFee - 1), queued);
793 BEAST_EXPECT(env.seq(alice) == 3);
795 static constexpr auto kAnotherLargeFeeMultiplier = 800;
796 auto const anotherLargeFee = baseFee * kAnotherLargeFeeMultiplier;
799 env(
noop(bob),
Fee(anotherLargeFee), queued);
800 env(
noop(charlie),
Fee(anotherLargeFee), queued);
801 env(
noop(daria),
Fee(anotherLargeFee), queued);
802 env(
noop(daria),
Fee(anotherLargeFee),
Seq(env.seq(daria) + 1), queued);
803 env(
noop(edgar),
Fee(anotherLargeFee), queued);
804 env(
noop(felicia),
Fee(anotherLargeFee - 1), queued);
805 env(
noop(felicia),
Fee(anotherLargeFee - 1),
Seq(env.seq(felicia) + 1), queued);
816 BEAST_EXPECT(env.seq(alice) == 3);
817 BEAST_EXPECT(env.seq(felicia) == 7);
824 BEAST_EXPECT(env.seq(alice) == 3);
825 BEAST_EXPECT(env.seq(felicia) == 8);
842 auto const baseFee = env.current()->fees().base.drops();
848 env.close(env.now() + 5s, 10000ms);
850 env.close(env.now() + 5s, 10000ms);
858 env(
noop(bob), queued);
872 static constexpr auto kAliceFeeMultiplier = 3;
873 auto feeAlice = baseFee * kAliceFeeMultiplier;
874 auto seqAlice = env.seq(alice);
875 for (
int i = 0; i < 4; ++i)
877 env(
noop(alice),
Fee(feeAlice),
Seq(seqAlice), queued);
878 feeAlice = (feeAlice + 1) * 125 / 100;
884 auto const seqBob = env.seq(bob);
889 auto feeCarol = feeAlice;
890 auto seqCarol = env.seq(carol);
891 for (
int i = 0; i < 4; ++i)
893 env(
noop(carol),
Fee(feeCarol),
Seq(seqCarol), queued);
894 feeCarol = (feeCarol + 1) * 125 / 100;
911 BEAST_EXPECT(env.seq(alice) == seqAlice - 4);
912 BEAST_EXPECT(env.seq(bob) == seqBob);
913 BEAST_EXPECT(env.seq(carol) == seqCarol + 1);
918 BEAST_EXPECT(env.seq(alice) == seqAlice);
919 BEAST_EXPECT(env.seq(bob) == seqBob + 1);
920 BEAST_EXPECT(env.seq(carol) == seqCarol + 1);
924 BEAST_EXPECT(env.seq(alice) == seqAlice);
925 BEAST_EXPECT(env.seq(bob) == seqBob + 1);
926 BEAST_EXPECT(env.seq(carol) == seqCarol + 1);
1008 using namespace jtx;
1017 auto alice =
Account(
"alice");
1019 auto charlie =
Account(
"charlie");
1020 auto daria =
Account(
"daria");
1027 initFee(env, 3, 2, 10, 200, 50);
1036 env.fund(
XRP(500000),
noripple(bob, charlie, daria));
1040 env(
noop(alice),
Fee(11), queued);
1043 auto aliceSeq = env.seq(alice);
1044 auto bobSeq = env.seq(bob);
1045 auto charlieSeq = env.seq(charlie);
1052 env(
noop(alice),
Seq(aliceSeq + 1),
Fee(13), queued);
1056 env(
noop(alice),
Seq(aliceSeq + 2),
Fee(17), queued);
1060 env(
noop(bob), queued);
1064 env(
noop(bob),
Seq(bobSeq + 1),
Fee(50), queued);
1069 env(
noop(charlie),
Fee(15), queued);
1072 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1073 BEAST_EXPECT(env.seq(bob) == bobSeq);
1074 BEAST_EXPECT(env.seq(charlie) == charlieSeq);
1084 BEAST_EXPECT(env.seq(alice) == aliceSeq + 3);
1085 BEAST_EXPECT(env.seq(bob) == bobSeq + 1);
1086 BEAST_EXPECT(env.seq(charlie) == charlieSeq + 1);
1090 aliceSeq = env.seq(alice);
1091 auto lastLedgerSeq = env.current()->header().seq + 2;
1092 for (
auto i = 0; i < 7; i++)
1096 Json(jss::LastLedgerSequence, lastLedgerSeq + i),
1103 auto& txQ = env.app().getTxQ();
1104 auto aliceStat = txQ.getAccountTxs(alice.id());
1106 auto const& baseFee = env.current()->fees().base;
1107 auto seq = env.seq(alice);
1108 BEAST_EXPECT(aliceStat.size() == 7);
1109 for (
auto const& tx : aliceStat)
1111 BEAST_EXPECT(tx.seqProxy.isSeq() && tx.seqProxy.value() == seq);
1113 BEAST_EXPECT(tx.lastValid);
1115 (tx.consequences.fee() ==
drops(aliceFee) &&
1116 tx.consequences.potentialSpend() ==
drops(0) &&
1117 !tx.consequences.isBlocker()) ||
1118 tx.seqProxy.value() == env.seq(alice) + 6);
1128 Json(jss::LastLedgerSequence, lastLedgerSeq + 7),
1141 env(
noop(charlie),
Fee(30), queued);
1158 aliceSeq = env.seq(alice) + 2;
1165 env(
noop(alice),
Seq(aliceSeq),
Fee(aliceFee), queued);
1174 aliceSeq = env.seq(alice) + 1;
1180 aliceFee = env.le(alice)->getFieldAmount(sfBalance).xrp().drops() - 62;
1192 env(
noop(alice),
Seq(aliceSeq),
Fee(aliceFee), queued);
1217 bobSeq = env.seq(bob);
1219 for (
int i = 0; i < 10; ++i)
1220 env(
noop(bob),
Seq(bobSeq + i), queued);
1227 env(
noop(bob),
Seq(bobSeq + 5),
Fee(20), queued);
1233 std::int64_t bobFee = env.le(bob)->getFieldAmount(sfBalance).xrp().drops() - ((9 * 10) - 1);
1243 bobFee = env.le(bob)->getFieldAmount(sfBalance).xrp().drops() - (9 * 10);
1259 using namespace jtx;
1264 cfg->fees.referenceFee = 10;
1265 Env env(*
this, std::move(cfg));
1267 auto alice =
Account(
"alice");
1269 auto charlie =
Account(
"charlie");
1270 auto daria =
Account(
"daria");
1278 BEAST_EXPECT(env.
current()->fees().base == 10);
1306 auto aliceSeq = env.
seq(alice);
1307 auto bobSeq = env.
seq(bob);
1308 auto charlieSeq = env.
seq(charlie);
1309 auto dariaSeq = env.
seq(daria);
1310 auto elmoSeq = env.
seq(elmo);
1311 auto fredSeq = env.
seq(fred);
1312 auto gwenSeq = env.
seq(gwen);
1313 auto hankSeq = env.
seq(hank);
1319 env(
noop(alice),
Fee(15), queued);
1320 env(
noop(bob),
Fee(15), queued);
1321 env(
noop(charlie),
Fee(15), queued);
1322 env(
noop(daria),
Fee(15), queued);
1323 env(
noop(elmo),
Fee(15), queued);
1324 env(
noop(fred),
Fee(15), queued);
1325 env(
noop(gwen),
Fee(15), queued);
1326 env(
noop(hank),
Fee(15), queued);
1341 env(
noop(charlie),
Fee(100),
Seq(charlieSeq + 1), queued);
1355 aliceSeq + bobSeq + charlieSeq + dariaSeq + elmoSeq + fredSeq + gwenSeq + hankSeq + 6 ==
1356 env.
seq(alice) + env.
seq(bob) + env.
seq(charlie) + env.
seq(daria) + env.
seq(elmo) +
1357 env.
seq(fred) + env.
seq(gwen) + env.
seq(hank));
1359 using namespace std::string_literals;
1361 aliceSeq == env.
seq(alice),
1364 bobSeq + 1 == env.
seq(bob),
1367 charlieSeq + 2 == env.
seq(charlie),
1370 dariaSeq + 1 == env.
seq(daria),
1373 elmoSeq + 1 == env.
seq(elmo),
1376 fredSeq == env.
seq(fred),
1379 gwenSeq == env.
seq(gwen),
1382 hankSeq + 1 == env.
seq(hank),
1396 auto getTxsQueued = [&]() {
1399 for (
auto const& tx : txs)
1401 ++result[tx.txn->at(sfAccount)];
1405 auto qTxCount1 = getTxsQueued();
1406 BEAST_EXPECT(qTxCount1.size() <= 3);
1409 env(
noop(alice),
Seq(aliceSeq + qTxCount1[alice.id()]++),
Fee(15), queued);
1410 env(
noop(bob),
Seq(bobSeq + qTxCount1[bob.id()]++),
Fee(15), queued);
1411 env(
noop(charlie),
Seq(charlieSeq + qTxCount1[charlie.id()]++),
Fee(15), queued);
1412 env(
noop(daria),
Seq(dariaSeq + qTxCount1[daria.id()]++),
Fee(15), queued);
1413 env(
noop(elmo),
Seq(elmoSeq + qTxCount1[elmo.id()]++),
Fee(15), queued);
1414 env(
noop(fred),
Seq(fredSeq + qTxCount1[fred.id()]++),
Fee(15), queued);
1415 env(
noop(gwen),
Seq(gwenSeq + qTxCount1[gwen.id()]++),
Fee(15), queued);
1423 env(
noop(alice),
Fee(100),
Seq(aliceSeq + qTxCount1[alice.id()]++), queued);
1434 auto qTxCount2 = getTxsQueued();
1435 BEAST_EXPECT(qTxCount2.size() <= 4);
1440 aliceSeq + bobSeq + charlieSeq + dariaSeq + elmoSeq + fredSeq + gwenSeq + hankSeq + 7 ==
1441 env.
seq(alice) + env.
seq(bob) + env.
seq(charlie) + env.
seq(daria) + env.
seq(elmo) +
1442 env.
seq(fred) + env.
seq(gwen) + env.
seq(hank));
1445 aliceSeq + qTxCount1[alice.id()] - qTxCount2[alice.id()] == env.
seq(alice),
1448 bobSeq + qTxCount1[bob.id()] - qTxCount2[bob.id()] == env.
seq(bob),
1451 charlieSeq + qTxCount1[charlie.id()] - qTxCount2[charlie.id()] == env.
seq(charlie),
1454 dariaSeq + qTxCount1[daria.id()] - qTxCount2[daria.id()] == env.
seq(daria),
1457 elmoSeq + qTxCount1[elmo.id()] - qTxCount2[elmo.id()] == env.
seq(elmo),
1460 fredSeq + qTxCount1[fred.id()] - qTxCount2[fred.id()] == env.
seq(fred),
1463 gwenSeq + qTxCount1[gwen.id()] - qTxCount2[gwen.id()] == env.
seq(gwen),
1466 hankSeq + qTxCount1[hank.id()] - qTxCount2[hank.id()] == env.
seq(hank),
1995 using namespace jtx;
1996 testcase(
"In-flight balance checks");
2004 auto alice =
Account(
"alice");
2005 auto charlie =
Account(
"charlie");
2016 auto const initQueueMax =
initFee(env, 3, 2, 10, 200, 50);
2022 env.fund(
XRP(50000),
noripple(alice, charlie), gw);
2023 checkMetrics(*
this, env, 0, initQueueMax, limit + 1, limit);
2025 auto usd = gw[
"USD"];
2026 auto bux = gw[
"BUX"];
2030 auto aliceSeq = env.seq(alice);
2031 auto aliceBal = env.balance(alice);
2037 env(
offer(alice, bux(5000),
XRP(50000)), queued);
2038 checkMetrics(*
this, env, 1, initQueueMax, limit + 1, limit);
2042 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2043 checkMetrics(*
this, env, 2, initQueueMax, limit + 1, limit);
2059 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2060 aliceSeq = env.seq(alice);
2061 aliceBal = env.balance(alice);
2063 env.require(
Owners(alice, 0));
2067 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2072 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2077 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2093 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2094 aliceSeq = env.seq(alice);
2095 aliceBal = env.balance(alice);
2097 env.require(
Owners(alice, 0));
2102 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2107 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2123 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2124 aliceSeq = env.seq(alice);
2125 aliceBal = env.balance(alice);
2129 env(
offer(alice, bux(50),
XRP(500)), queued);
2132 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2133 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2149 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2151 aliceSeq = env.seq(alice);
2152 aliceBal = env.balance(alice);
2157 env(
pay(alice, charlie,
XRP(50000)), queued);
2161 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2162 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2176 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2178 aliceSeq = env.seq(alice);
2179 aliceBal = env.balance(alice);
2183 env(
pay(alice, charlie,
XRP(500)), queued);
2186 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2187 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2198 auto const amount = usd(500000);
2199 env(
trust(alice, usd(50000000)));
2200 env(
trust(charlie, usd(50000000)));
2206 env(
pay(gw, alice, amount));
2213 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2215 aliceSeq = env.seq(alice);
2216 aliceBal = env.balance(alice);
2217 auto aliceUSD = env.balance(alice, usd);
2221 env(
pay(alice, charlie, amount), queued);
2225 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2226 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2244 env(
offer(gw,
XRP(500000), usd(50000)));
2250 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2252 aliceSeq = env.seq(alice);
2253 aliceBal = env.balance(alice);
2254 auto charlieUSD = env.balance(charlie, usd);
2260 BEAST_EXPECT(
XRP(60000) > aliceBal);
2261 env(
pay(alice, charlie, usd(1000)),
Sendmax(
XRP(60000)), queued);
2265 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2266 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2277 Balance(charlie, charlieUSD + usd(1000)),
2285 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2287 aliceSeq = env.seq(alice);
2288 aliceBal = env.balance(alice);
2289 charlieUSD = env.balance(charlie, usd);
2295 BEAST_EXPECT(aliceBal >
XRP(6001));
2296 env(
pay(alice, charlie, usd(500)),
Sendmax(
XRP(6000)), queued);
2299 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2300 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2311 Balance(charlie, charlieUSD + usd(500)),
2321 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2323 aliceSeq = env.seq(alice);
2324 aliceBal = env.balance(alice);
2325 BEAST_EXPECT(aliceBal ==
drops(30));
2329 BEAST_EXPECT(env.balance(alice) ==
drops(30));
2331 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2336 BEAST_EXPECT(env.balance(alice) ==
drops(5));
2528 using namespace jtx;
2533 auto fee = env.
rpc(
"fee");
2535 if (BEAST_EXPECT(fee.isMember(jss::result)) &&
2538 auto const& result = fee[jss::result];
2540 result.isMember(jss::ledger_current_index) &&
2541 result[jss::ledger_current_index] == 3);
2542 BEAST_EXPECT(result.isMember(jss::current_ledger_size));
2543 BEAST_EXPECT(result.isMember(jss::current_queue_size));
2544 BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
2545 BEAST_EXPECT(!result.isMember(jss::max_queue_size));
2546 BEAST_EXPECT(result.isMember(jss::drops));
2547 auto const&
drops = result[jss::drops];
2548 BEAST_EXPECT(
drops.isMember(jss::base_fee));
2549 BEAST_EXPECT(
drops.isMember(jss::median_fee));
2550 BEAST_EXPECT(
drops.isMember(jss::minimum_fee));
2551 BEAST_EXPECT(
drops.isMember(jss::open_ledger_fee));
2552 BEAST_EXPECT(result.isMember(jss::levels));
2553 auto const& levels = result[jss::levels];
2554 BEAST_EXPECT(levels.isMember(jss::median_level));
2555 BEAST_EXPECT(levels.isMember(jss::minimum_level));
2556 BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
2557 BEAST_EXPECT(levels.isMember(jss::reference_level));
2562 fee = env.
rpc(
"fee");
2564 if (BEAST_EXPECT(fee.isMember(jss::result)) &&
2567 auto const& result = fee[jss::result];
2569 result.isMember(jss::ledger_current_index) &&
2570 result[jss::ledger_current_index] == 4);
2571 BEAST_EXPECT(result.isMember(jss::current_ledger_size));
2572 BEAST_EXPECT(result.isMember(jss::current_queue_size));
2573 BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
2574 BEAST_EXPECT(result.isMember(jss::max_queue_size));
2575 auto const&
drops = result[jss::drops];
2576 BEAST_EXPECT(
drops.isMember(jss::base_fee));
2577 BEAST_EXPECT(
drops.isMember(jss::median_fee));
2578 BEAST_EXPECT(
drops.isMember(jss::minimum_fee));
2579 BEAST_EXPECT(
drops.isMember(jss::open_ledger_fee));
2580 BEAST_EXPECT(result.isMember(jss::levels));
2581 auto const& levels = result[jss::levels];
2582 BEAST_EXPECT(levels.isMember(jss::median_level));
2583 BEAST_EXPECT(levels.isMember(jss::minimum_level));
2584 BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
2585 BEAST_EXPECT(levels.isMember(jss::reference_level));
2816 testcase(
"Autofilled sequence should account for TxQ");
2817 using namespace jtx;
2819 auto const baseFee = env.
current()->fees().base.drops();
2821 auto const& txQ = env.app().getTxQ();
2823 auto const alice =
Account(
"alice");
2824 auto const bob =
Account(
"bob");
2825 env.fund(
XRP(100000), alice, bob);
2831 auto const aliceSeq = env.seq(alice);
2832 auto const lastLedgerSeq = env.current()->header().seq + 2;
2835 for (
int i = 0; i < 5; ++i)
2843 Json(jss::LastLedgerSequence, lastLedgerSeq),
2853 auto aliceStat = txQ.getAccountTxs(alice.id());
2855 BEAST_EXPECT(aliceStat.size() == 5);
2856 for (
auto const& tx : aliceStat)
2858 BEAST_EXPECT(tx.seqProxy == seq);
2859 BEAST_EXPECT(tx.feeLevel ==
FeeLevel64{kBaseFeeLevel.fee() * 100});
2860 if (seq.
value() == aliceSeq + 2)
2862 BEAST_EXPECT(tx.lastValid && *tx.lastValid == lastLedgerSeq);
2866 BEAST_EXPECT(!tx.lastValid);
2873 for (
int i = 0; i < 8; ++i)
2882 for (
int i = 0; i < 9; ++i)
2889 for (
int i = 0; i < 10; ++i)
2896 auto bobStat = txQ.getAccountTxs(bob.id());
2897 BEAST_EXPECT(bobStat.empty());
2902 auto aliceStat = txQ.getAccountTxs(alice.id());
2903 auto seq = aliceSeq;
2904 BEAST_EXPECT(aliceStat.size() == 4);
2905 for (
auto const& tx : aliceStat)
2908 if (seq == aliceSeq + 2)
2911 BEAST_EXPECT(tx.seqProxy.isSeq() && tx.seqProxy.value() == seq);
2912 BEAST_EXPECT(tx.feeLevel ==
FeeLevel64{kBaseFeeLevel.fee() * 100});
2913 BEAST_EXPECT(!tx.lastValid);
2921 auto aliceStat = txQ.getAccountTxs(alice.id());
2922 auto seq = aliceSeq;
2923 BEAST_EXPECT(aliceStat.size() == 5);
2924 for (
auto const& tx : aliceStat)
2926 BEAST_EXPECT(tx.seqProxy.isSeq() && tx.seqProxy.value() == seq);
2927 BEAST_EXPECT(tx.feeLevel ==
FeeLevel64{kBaseFeeLevel * 100});
2928 BEAST_EXPECT(!tx.lastValid);
2937 auto bobStat = txQ.getAccountTxs(bob.id());
2938 BEAST_EXPECT(bobStat.empty());
2941 auto aliceStat = txQ.getAccountTxs(alice.id());
2942 BEAST_EXPECT(aliceStat.empty());
2949 using namespace jtx;
2953 auto const baseFee = env.
current()->fees().base.drops();
2957 env.fund(
XRP(1000000), alice);
2961 withQueue[jss::account] = alice.
human();
2962 withQueue[jss::queue] =
true;
2965 withoutQueue[jss::account] = alice.
human();
2968 prevLedgerWithQueue[jss::account] = alice.
human();
2969 prevLedgerWithQueue[jss::queue] =
true;
2970 prevLedgerWithQueue[jss::ledger_index] = 3;
2971 BEAST_EXPECT(env.current()->header().seq > 3);
2975 auto const info = env.rpc(
"json",
"account_info",
to_string(withoutQueue));
2977 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
2978 BEAST_EXPECT(!info[jss::result].isMember(jss::queue_data));
2982 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
2984 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
2985 auto const& result = info[jss::result];
2986 BEAST_EXPECT(result.isMember(jss::queue_data));
2987 auto const& queueData = result[jss::queue_data];
2988 BEAST_EXPECT(queueData.isObject());
2989 BEAST_EXPECT(queueData.isMember(jss::txn_count));
2990 BEAST_EXPECT(queueData[jss::txn_count] == 0);
2991 BEAST_EXPECT(!queueData.isMember(jss::lowest_sequence));
2992 BEAST_EXPECT(!queueData.isMember(jss::highest_sequence));
2993 BEAST_EXPECT(!queueData.isMember(jss::auth_change_queued));
2994 BEAST_EXPECT(!queueData.isMember(jss::max_spend_drops_total));
2995 BEAST_EXPECT(!queueData.isMember(jss::transactions));
3003 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3005 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3006 auto const& result = info[jss::result];
3007 BEAST_EXPECT(result.isMember(jss::queue_data));
3008 auto const& queueData = result[jss::queue_data];
3009 BEAST_EXPECT(queueData.isObject());
3010 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3011 BEAST_EXPECT(queueData[jss::txn_count] == 0);
3012 BEAST_EXPECT(!queueData.isMember(jss::lowest_sequence));
3013 BEAST_EXPECT(!queueData.isMember(jss::highest_sequence));
3014 BEAST_EXPECT(!queueData.isMember(jss::auth_change_queued));
3015 BEAST_EXPECT(!queueData.isMember(jss::max_spend_drops_total));
3016 BEAST_EXPECT(!queueData.isMember(jss::transactions));
3027 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3029 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3030 auto const& result = info[jss::result];
3031 auto const&
data = result[jss::account_data];
3032 BEAST_EXPECT(result.isMember(jss::queue_data));
3033 auto const& queueData = result[jss::queue_data];
3034 BEAST_EXPECT(queueData.isObject());
3035 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3036 BEAST_EXPECT(queueData[jss::txn_count] == 4);
3037 BEAST_EXPECT(queueData.isMember(jss::lowest_sequence));
3038 BEAST_EXPECT(queueData[jss::lowest_sequence] ==
data[jss::Sequence]);
3039 BEAST_EXPECT(queueData.isMember(jss::highest_sequence));
3041 queueData[jss::highest_sequence] ==
3042 data[jss::Sequence].asUInt() + queueData[jss::txn_count].asUInt() - 1);
3043 BEAST_EXPECT(queueData.isMember(jss::auth_change_queued));
3044 BEAST_EXPECT(queueData[jss::auth_change_queued] ==
false);
3045 BEAST_EXPECT(queueData.isMember(jss::max_spend_drops_total));
3046 BEAST_EXPECT(queueData[jss::max_spend_drops_total] ==
std::to_string(baseFee * 40));
3047 BEAST_EXPECT(queueData.isMember(jss::transactions));
3048 auto const& queued = queueData[jss::transactions];
3049 BEAST_EXPECT(queued.size() == queueData[jss::txn_count]);
3050 for (
unsigned i = 0; i < queued.size(); ++i)
3052 auto const& item = queued[i];
3053 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3055 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3057 BEAST_EXPECT(item.isMember(jss::fee));
3059 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3060 BEAST_EXPECT(item[jss::max_spend_drops] ==
std::to_string(baseFee * 10));
3061 BEAST_EXPECT(item.isMember(jss::auth_change));
3062 BEAST_EXPECT(item[jss::auth_change].asBool() ==
false);
3074 fset(alice, asfAccountTxnID),
3077 Json(jss::LastLedgerSequence, 10),
3082 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3084 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3085 auto const& result = info[jss::result];
3086 auto const&
data = result[jss::account_data];
3087 BEAST_EXPECT(result.isMember(jss::queue_data));
3088 auto const& queueData = result[jss::queue_data];
3089 BEAST_EXPECT(queueData.isObject());
3090 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3091 BEAST_EXPECT(queueData[jss::txn_count] == 1);
3092 BEAST_EXPECT(queueData.isMember(jss::lowest_sequence));
3093 BEAST_EXPECT(queueData[jss::lowest_sequence] ==
data[jss::Sequence]);
3094 BEAST_EXPECT(queueData.isMember(jss::highest_sequence));
3096 queueData[jss::highest_sequence] ==
3097 data[jss::Sequence].asUInt() + queueData[jss::txn_count].asUInt() - 1);
3098 BEAST_EXPECT(queueData.isMember(jss::auth_change_queued));
3099 BEAST_EXPECT(queueData[jss::auth_change_queued] ==
true);
3100 BEAST_EXPECT(queueData.isMember(jss::max_spend_drops_total));
3101 BEAST_EXPECT(queueData[jss::max_spend_drops_total] ==
std::to_string(baseFee * 10));
3102 BEAST_EXPECT(queueData.isMember(jss::transactions));
3103 auto const& queued = queueData[jss::transactions];
3104 BEAST_EXPECT(queued.size() == queueData[jss::txn_count]);
3105 for (
unsigned i = 0; i < queued.size(); ++i)
3107 auto const& item = queued[i];
3108 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3110 BEAST_EXPECT(item.isMember(jss::fee));
3112 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3113 BEAST_EXPECT(item[jss::max_spend_drops] ==
std::to_string(baseFee * 10));
3114 BEAST_EXPECT(item.isMember(jss::auth_change));
3116 if (i == queued.size() - 1)
3118 BEAST_EXPECT(item[jss::auth_change].asBool() ==
true);
3119 BEAST_EXPECT(item.isMember(jss::LastLedgerSequence));
3120 BEAST_EXPECT(item[jss::LastLedgerSequence] == 10);
3124 BEAST_EXPECT(item[jss::auth_change].asBool() ==
false);
3125 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3135 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3137 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3138 auto const& result = info[jss::result];
3139 auto const&
data = result[jss::account_data];
3140 BEAST_EXPECT(result.isMember(jss::queue_data));
3141 auto const& queueData = result[jss::queue_data];
3142 BEAST_EXPECT(queueData.isObject());
3143 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3144 BEAST_EXPECT(queueData[jss::txn_count] == 1);
3145 BEAST_EXPECT(queueData.isMember(jss::lowest_sequence));
3146 BEAST_EXPECT(queueData[jss::lowest_sequence] ==
data[jss::Sequence]);
3147 BEAST_EXPECT(queueData.isMember(jss::highest_sequence));
3149 queueData[jss::highest_sequence] ==
3150 data[jss::Sequence].asUInt() + queueData[jss::txn_count].asUInt() - 1);
3151 BEAST_EXPECT(queueData.isMember(jss::auth_change_queued));
3152 BEAST_EXPECT(queueData[jss::auth_change_queued].asBool());
3153 BEAST_EXPECT(queueData.isMember(jss::max_spend_drops_total));
3154 BEAST_EXPECT(queueData[jss::max_spend_drops_total] ==
std::to_string(baseFee * 10));
3155 BEAST_EXPECT(queueData.isMember(jss::transactions));
3156 auto const& queued = queueData[jss::transactions];
3157 BEAST_EXPECT(queued.size() == queueData[jss::txn_count]);
3158 for (
unsigned i = 0; i < queued.size(); ++i)
3160 auto const& item = queued[i];
3161 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3164 if (i == queued.size() - 1)
3166 BEAST_EXPECT(item.isMember(jss::fee));
3168 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3169 BEAST_EXPECT(item[jss::max_spend_drops] ==
std::to_string(baseFee * 10));
3170 BEAST_EXPECT(item.isMember(jss::auth_change));
3171 BEAST_EXPECT(item[jss::auth_change].asBool());
3172 BEAST_EXPECT(item.isMember(jss::LastLedgerSequence));
3173 BEAST_EXPECT(item[jss::LastLedgerSequence] == 10);
3177 BEAST_EXPECT(item.isMember(jss::fee));
3179 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3180 BEAST_EXPECT(item[jss::max_spend_drops] ==
std::to_string(baseFee * 10));
3181 BEAST_EXPECT(item.isMember(jss::auth_change));
3182 BEAST_EXPECT(!item[jss::auth_change].asBool());
3183 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3189 auto const info = env.rpc(
"json",
"account_info",
to_string(prevLedgerWithQueue));
3199 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3201 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3202 auto const& result = info[jss::result];
3203 BEAST_EXPECT(result.isMember(jss::queue_data));
3204 auto const& queueData = result[jss::queue_data];
3205 BEAST_EXPECT(queueData.isObject());
3206 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3207 BEAST_EXPECT(queueData[jss::txn_count] == 0);
3208 BEAST_EXPECT(!queueData.isMember(jss::lowest_sequence));
3209 BEAST_EXPECT(!queueData.isMember(jss::highest_sequence));
3210 BEAST_EXPECT(!queueData.isMember(jss::auth_change_queued));
3211 BEAST_EXPECT(!queueData.isMember(jss::max_spend_drops_total));
3212 BEAST_EXPECT(!queueData.isMember(jss::transactions));
3219 using namespace jtx;
3223 auto const baseFee = env.
current()->fees().base.drops();
3227 env.fund(
XRP(1000000), alice);
3231 auto const serverInfo = env.rpc(
"server_info");
3233 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3234 auto const& info = serverInfo[jss::result][jss::info];
3235 BEAST_EXPECT(info.isMember(jss::load_factor) && info[jss::load_factor] == 1);
3236 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3237 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3238 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3239 BEAST_EXPECT(!info.isMember(jss::load_factor_fee_escalation));
3242 auto const serverState = env.rpc(
"server_state");
3243 auto const& state = serverState[jss::result][jss::state];
3244 BEAST_EXPECT(state.isMember(jss::load_factor) && state[jss::load_factor] == 256);
3245 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3247 state.isMember(jss::load_factor_server) && state[jss::load_factor_server] == 256);
3249 state.isMember(jss::load_factor_fee_escalation) &&
3250 state[jss::load_factor_fee_escalation] == 256);
3252 state.isMember(jss::load_factor_fee_queue) &&
3253 state[jss::load_factor_fee_queue] == 256);
3255 state.isMember(jss::load_factor_fee_reference) &&
3256 state[jss::load_factor_fee_reference] == 256);
3264 auto aliceSeq = env.seq(alice);
3266 for (
auto i = 0; i < 4; ++i)
3271 auto const serverInfo = env.rpc(
"server_info");
3273 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3274 auto const& info = serverInfo[jss::result][jss::info];
3277 info.isMember(jss::load_factor) && info[jss::load_factor] > 888.88 &&
3278 info[jss::load_factor] < 888.89);
3280 info.isMember(jss::load_factor_server) && info[jss::load_factor_server] == 1);
3281 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3282 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3284 info.isMember(jss::load_factor_fee_escalation) &&
3285 info[jss::load_factor_fee_escalation] > 888.88 &&
3286 info[jss::load_factor_fee_escalation] < 888.89);
3289 auto const serverState = env.rpc(
"server_state");
3290 auto const& state = serverState[jss::result][jss::state];
3291 BEAST_EXPECT(state.isMember(jss::load_factor) && state[jss::load_factor] == 227555);
3292 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3294 state.isMember(jss::load_factor_server) && state[jss::load_factor_server] == 256);
3296 state.isMember(jss::load_factor_fee_escalation) &&
3297 state[jss::load_factor_fee_escalation] == 227555);
3299 state.isMember(jss::load_factor_fee_queue) &&
3300 state[jss::load_factor_fee_queue] == 256);
3302 state.isMember(jss::load_factor_fee_reference) &&
3303 state[jss::load_factor_fee_reference] == 256);
3306 env.app().getFeeTrack().setRemoteFee(256000);
3309 auto const serverInfo = env.rpc(
"server_info");
3311 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3312 auto const& info = serverInfo[jss::result][jss::info];
3314 BEAST_EXPECT(info.isMember(jss::load_factor) && info[jss::load_factor] == 1000);
3315 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3316 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3317 BEAST_EXPECT(info.isMember(jss::load_factor_net) && info[jss::load_factor_net] == 1000);
3319 info.isMember(jss::load_factor_fee_escalation) &&
3320 info[jss::load_factor_fee_escalation] > 888.88 &&
3321 info[jss::load_factor_fee_escalation] < 888.89);
3324 auto const serverState = env.rpc(
"server_state");
3325 auto const& state = serverState[jss::result][jss::state];
3326 BEAST_EXPECT(state.isMember(jss::load_factor) && state[jss::load_factor] == 256000);
3327 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3329 state.isMember(jss::load_factor_server) &&
3330 state[jss::load_factor_server] == 256000);
3332 state.isMember(jss::load_factor_fee_escalation) &&
3333 state[jss::load_factor_fee_escalation] == 227555);
3335 state.isMember(jss::load_factor_fee_queue) &&
3336 state[jss::load_factor_fee_queue] == 256);
3338 state.isMember(jss::load_factor_fee_reference) &&
3339 state[jss::load_factor_fee_reference] == 256);
3342 env.app().getFeeTrack().setRemoteFee(256);
3345 for (
int i = 0; i < 5; ++i)
3346 env.app().getFeeTrack().raiseLocalFee();
3347 BEAST_EXPECT(env.app().getFeeTrack().getLoadFactor() == 625);
3350 auto const serverInfo = env.rpc(
"server_info");
3352 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3353 auto const& info = serverInfo[jss::result][jss::info];
3356 info.isMember(jss::load_factor) && info[jss::load_factor] > 888.88 &&
3357 info[jss::load_factor] < 888.89);
3362 info.isMember(jss::load_factor_server) && info[jss::load_factor_server] > 1.245 &&
3363 info[jss::load_factor_server] < 2.4415);
3365 info.isMember(jss::load_factor_local) && info[jss::load_factor_local] > 1.245 &&
3366 info[jss::load_factor_local] < 2.4415);
3367 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3369 info.isMember(jss::load_factor_fee_escalation) &&
3370 info[jss::load_factor_fee_escalation] > 888.88 &&
3371 info[jss::load_factor_fee_escalation] < 888.89);
3374 auto const serverState = env.rpc(
"server_state");
3375 auto const& state = serverState[jss::result][jss::state];
3376 BEAST_EXPECT(state.isMember(jss::load_factor) && state[jss::load_factor] == 227555);
3377 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3382 state.isMember(jss::load_factor_server) && state[jss::load_factor_server] >= 320 &&
3383 state[jss::load_factor_server] <= 625);
3385 state.isMember(jss::load_factor_fee_escalation) &&
3386 state[jss::load_factor_fee_escalation] == 227555);
3388 state.isMember(jss::load_factor_fee_queue) &&
3389 state[jss::load_factor_fee_queue] == 256);
3391 state.isMember(jss::load_factor_fee_reference) &&
3392 state[jss::load_factor_fee_reference] == 256);
3398 auto const serverInfo = env.rpc(
"server_info");
3400 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3401 auto const& info = serverInfo[jss::result][jss::info];
3408 info.isMember(jss::load_factor) && info[jss::load_factor] > 1.245 &&
3409 info[jss::load_factor] < 2.4415);
3410 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3412 info.isMember(jss::load_factor_local) && info[jss::load_factor_local] > 1.245 &&
3413 info[jss::load_factor_local] < 2.4415);
3414 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3415 BEAST_EXPECT(!info.isMember(jss::load_factor_fee_escalation));
3418 auto const serverState = env.rpc(
"server_state");
3419 auto const& state = serverState[jss::result][jss::state];
3421 state.isMember(jss::load_factor) && state[jss::load_factor] >= 320 &&
3422 state[jss::load_factor] <= 625);
3423 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3428 state.isMember(jss::load_factor_server) && state[jss::load_factor_server] >= 320 &&
3429 state[jss::load_factor_server] <= 625);
3431 state.isMember(jss::load_factor_fee_escalation) &&
3432 state[jss::load_factor_fee_escalation] == 256);
3434 state.isMember(jss::load_factor_fee_queue) &&
3435 state[jss::load_factor_fee_queue] == 256);
3437 state.isMember(jss::load_factor_fee_reference) &&
3438 state[jss::load_factor_fee_reference] == 256);
3445 using namespace jtx;
3449 auto const baseFee = env.
current()->fees().base.drops();
3453 stream[jss::streams].append(
"server");
3456 auto jv = wsc->invoke(
"subscribe", stream);
3457 BEAST_EXPECT(jv[jss::status] ==
"success");
3461 Account a{
"a"}, b{
"b"}, c{
"c"}, d{
"d"}, e{
"e"}, f{
"f"}, g{
"g"}, h{
"h"}, i{
"i"};
3468 using namespace std::chrono_literals;
3469 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3470 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3471 jv[jss::load_factor] == 256 && jv.isMember(jss::load_base) &&
3472 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3473 jv[jss::load_factor_server] == 256 &&
3474 jv.isMember(jss::load_factor_fee_escalation) &&
3475 jv[jss::load_factor_fee_escalation] == 256 &&
3476 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3477 jv.isMember(jss::load_factor_fee_reference) &&
3478 jv[jss::load_factor_fee_reference] == 256;
3481 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3482 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3483 jv[jss::load_factor] == 227555 && jv.isMember(jss::load_base) &&
3484 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3485 jv[jss::load_factor_server] == 256 &&
3486 jv.isMember(jss::load_factor_fee_escalation) &&
3487 jv[jss::load_factor_fee_escalation] == 227555 &&
3488 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3489 jv.isMember(jss::load_factor_fee_reference) &&
3490 jv[jss::load_factor_fee_reference] == 256;
3496 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3497 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3498 jv[jss::load_factor] == 256 && jv.isMember(jss::load_base) &&
3499 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3500 jv[jss::load_factor_server] == 256 &&
3501 jv.isMember(jss::load_factor_fee_escalation) &&
3502 jv[jss::load_factor_fee_escalation] == 256 &&
3503 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3504 jv.isMember(jss::load_factor_fee_reference) &&
3505 jv[jss::load_factor_fee_reference] == 256;
3515 env(
noop(a),
Fee(baseFee), queued);
3516 env(
noop(b),
Fee(baseFee), queued);
3517 env(
noop(c),
Fee(baseFee), queued);
3518 env(
noop(d),
Fee(baseFee), queued);
3519 env(
noop(e),
Fee(baseFee), queued);
3520 env(
noop(f),
Fee(baseFee), queued);
3521 env(
noop(g),
Fee(baseFee), queued);
3525 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3526 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3527 jv[jss::load_factor] == 200000 && jv.isMember(jss::load_base) &&
3528 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3529 jv[jss::load_factor_server] == 256 &&
3530 jv.isMember(jss::load_factor_fee_escalation) &&
3531 jv[jss::load_factor_fee_escalation] == 200000 &&
3532 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3533 jv.isMember(jss::load_factor_fee_reference) &&
3534 jv[jss::load_factor_fee_reference] == 256;
3539 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3540 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3541 jv[jss::load_factor] == 184320 && jv.isMember(jss::load_base) &&
3542 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3543 jv[jss::load_factor_server] == 256 &&
3544 jv.isMember(jss::load_factor_fee_escalation) &&
3545 jv[jss::load_factor_fee_escalation] == 184320 &&
3546 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3547 jv.isMember(jss::load_factor_fee_reference) &&
3548 jv[jss::load_factor_fee_reference] == 256;
3553 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3554 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3555 jv[jss::load_factor] == 256 && jv.isMember(jss::load_base) &&
3556 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3557 jv[jss::load_factor_server] == 256 &&
3558 jv.isMember(jss::load_factor_fee_escalation) &&
3559 jv[jss::load_factor_fee_escalation] == 256 &&
3560 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3561 jv.isMember(jss::load_factor_fee_reference) &&
3562 jv[jss::load_factor_fee_reference] == 256;
3571 if (!wsc->findMsg(1s, [&](
auto const& jv) { return jv[jss::type] ==
"serverStatus"; }))
3577 auto jv = wsc->invoke(
"unsubscribe", stream);
3578 BEAST_EXPECT(jv[jss::status] ==
"success");
3584 using namespace jtx;
3588 auto const baseFee = env.
current()->fees().base.drops();
3589 auto alice =
Account(
"alice");
3593 env.fund(
XRP(50000000), alice, bob);
3600 auto totalFactor = 0;
3601 auto const metrics = env.app().getTxQ().getMetrics(*env.current());
3603 numToClear.emplace(
metrics.txCount + 1);
3604 for (
int i = 0; i < *numToClear; ++i)
3606 auto inLedger =
metrics.txInLedger + i;
3607 totalFactor += inLedger * inLedger;
3614 auto result =
toDrops(feeLevel, env.current()->fees().base).
drops();
3617 result -= alreadyPaid;
3623 testcase(
"straightforward positive case");
3626 auto aliceSeq = env.seq(alice);
3628 for (
int i = 0; i < 2; ++i)
3631 totalPaid += baseFee * 10;
3656 totalPaid += totalFee;
3657 totalFee = calcTotalFee(totalPaid);
3660 env(
noop(alice),
Fee(totalFee),
Seq(aliceSeq++));
3665 testcase(
"replace last tx with enough to clear queue");
3668 auto aliceSeq = env.seq(alice);
3670 for (
int i = 0; i < 2; ++i)
3673 totalPaid += baseFee * 10;
3685 auto const metrics = env.app().getTxQ().getMetrics(*env.current());
3689 env(
noop(alice),
Fee(totalFee),
Seq(aliceSeq++));
3698 testcase(
"replace middle tx with enough to clear queue");
3702 auto aliceSeq = env.seq(alice);
3703 for (
int i = 0; i < 5; ++i)
3711 uint64_t const totalFee = calcTotalFee(baseFee * 10 * 2, 3);
3714 env(
noop(alice),
Fee(totalFee),
Seq(aliceSeq++));
3717 auto const aliceQueue = env.app().getTxQ().getAccountTxs(alice.id());
3718 BEAST_EXPECT(aliceQueue.size() == 2);
3720 for (
auto const& tx : aliceQueue)
3722 BEAST_EXPECT(tx.seqProxy == seq);
3723 BEAST_EXPECT(tx.feeLevel ==
FeeLevel64{kBaseFeeLevel.fee() * 10});
3732 testcase(
"clear queue failure (load)");
3736 auto aliceSeq = env.seq(alice);
3738 for (
int i = 0; i < 2; ++i)
3741 totalPaid += baseFee * 20;
3743 for (
int i = 0; i < 2; ++i)
3746 totalPaid += baseFee * 2.2;
3755 auto& feeTrack = env.app().getFeeTrack();
3756 auto const origFee = feeTrack.getRemoteFee();
3757 feeTrack.setRemoteFee(origFee * 5);
3770 feeTrack.setRemoteFee(origFee);
3789 using namespace jtx;
3790 using namespace std::chrono_literals;
3802 auto alice =
Account(
"alice");
3805 env.fund(
XRP(50000000), alice);
3809 auto seqAlice = env.seq(alice);
3811 for (
int i = 0; i < txCount; ++i)
3855 env.close(env.now() + 5s, 10000ms);
3860 env.close(env.now() + 5s, 10000ms);
3865 env.close(env.now() + 5s, 10000ms);
3872 env.close(env.now() + 5s, 10000ms);
3876 BEAST_EXPECT(!txCount);
3888 auto alice =
Account(
"alice");
3891 env.fund(
XRP(50000000), alice);
3895 auto seqAlice = env.seq(alice);
3897 for (
int i = 0; i < txCount; ++i)
3916 env.close(env.now() + 5s, 10000ms);
3922 BEAST_EXPECT(!txCount);
4093 using namespace jtx;
4102 static constexpr int kLedgersInQueue = 30;
4115 Env env(*
this, std::move(cfg));
4135 for (i = 0; i <= 257; ++i)
4142 checkMetrics(*
this, env, 0, kLedgersInQueue * expectedPerLedger, 0, expectedPerLedger);
4147 using namespace std::chrono_literals;
4148 auto closeDuration = 80
min;
4149 for (i = 0; i <= 255; ++i)
4151 env.
close(closeDuration);
4154 auto const baseFee = env.
current()->fees().base.drops();
4161 kLedgersInQueue * expectedPerLedger,
4162 expectedPerLedger + 1,
4166 auto seqAlice = env.
seq(alice);
4167 auto seqBob = env.
seq(bob);
4168 auto seqCarol = env.
seq(carol);
4169 auto seqDaria = env.
seq(daria);
4170 auto seqEllie = env.
seq(ellie);
4171 auto seqFiona = env.
seq(fiona);
4174 int txFee{
static_cast<int>(baseFee * 9)};
4175 auto prepareFee = [&](
uint64_t multiplier) {
4176 return Fee(
txFee - (multiplier * baseFee / 10));
4180 for (
int i = 0; i < 10; ++i)
4194 kLedgersInQueue * expectedPerLedger,
4195 expectedPerLedger + 1,
4209 env.
close(closeDuration);
4210 auto expectedInLedger = expectedInQueue;
4212 (expectedInQueue > expectedPerLedger + 2 ? expectedInQueue - (expectedPerLedger + 2)
4214 expectedInLedger -= expectedInQueue;
4215 ++expectedPerLedger;
4220 kLedgersInQueue * expectedPerLedger,
4224 auto const expectedPerAccount = expectedInQueue / 6;
4225 auto const expectedRemainder = expectedInQueue % 6;
4226 BEAST_EXPECT(env.
seq(alice) == seqAlice - expectedPerAccount);
4228 env.
seq(bob) == seqBob - expectedPerAccount - (expectedRemainder > 4 ? 1 : 0));
4231 seqCarol - expectedPerAccount - (expectedRemainder > 3 ? 1 : 0));
4234 seqDaria - expectedPerAccount - (expectedRemainder > 2 ? 1 : 0));
4237 seqEllie - expectedPerAccount - (expectedRemainder > 1 ? 1 : 0));
4240 seqFiona - expectedPerAccount - (expectedRemainder > 0 ? 1 : 0));
4242 }
while (expectedInQueue > 0);
4571 using namespace jtx;
4587 auto const initQueueMax =
initFee(env, 3, 2, 0, 0, 0);
4589 BEAST_EXPECT(env.current()->fees().base == 0);
4592 auto const fee = env.rpc(
"fee");
4594 if (BEAST_EXPECT(fee.isMember(jss::result)) &&
4597 auto const& result = fee[jss::result];
4599 BEAST_EXPECT(result.isMember(jss::levels));
4600 auto const& levels = result[jss::levels];
4602 levels.isMember(jss::median_level) && levels[jss::median_level] ==
"128000");
4604 levels.isMember(jss::minimum_level) && levels[jss::minimum_level] ==
"256");
4606 levels.isMember(jss::open_ledger_level) &&
4607 levels[jss::open_ledger_level] ==
"256");
4609 levels.isMember(jss::reference_level) && levels[jss::reference_level] ==
"256");
4611 auto const&
drops = result[jss::drops];
4612 BEAST_EXPECT(
drops.isMember(jss::base_fee) &&
drops[jss::base_fee] ==
"0");
4613 BEAST_EXPECT(
drops.isMember(jss::median_fee) &&
drops[jss::median_fee] ==
"0");
4614 BEAST_EXPECT(
drops.isMember(jss::minimum_fee) &&
drops[jss::minimum_fee] ==
"0");
4616 drops.isMember(jss::open_ledger_fee) &&
drops[jss::open_ledger_fee] ==
"0");
4640 auto aliceSeq = env.seq(alice);
4641 env(
noop(alice), queued);
4645 env(
noop(alice),
Seq(aliceSeq + 1),
Fee(10), queued);
4650 auto const fee = env.rpc(
"fee");
4652 if (BEAST_EXPECT(fee.isMember(jss::result)) &&
4655 auto const& result = fee[jss::result];
4657 BEAST_EXPECT(result.isMember(jss::levels));
4658 auto const& levels = result[jss::levels];
4660 levels.isMember(jss::median_level) && levels[jss::median_level] ==
"128000");
4662 levels.isMember(jss::minimum_level) && levels[jss::minimum_level] ==
"256");
4664 levels.isMember(jss::open_ledger_level) &&
4665 levels[jss::open_ledger_level] ==
"355555");
4667 levels.isMember(jss::reference_level) && levels[jss::reference_level] ==
"256");
4669 auto const&
drops = result[jss::drops];
4670 BEAST_EXPECT(
drops.isMember(jss::base_fee) &&
drops[jss::base_fee] ==
"0");
4671 BEAST_EXPECT(
drops.isMember(jss::median_fee) &&
drops[jss::median_fee] ==
"0");
4672 BEAST_EXPECT(
drops.isMember(jss::minimum_fee) &&
drops[jss::minimum_fee] ==
"0");
4674 drops.isMember(jss::open_ledger_fee) &&
drops[jss::open_ledger_fee] ==
"1389");