177 auto charlie =
Account(
"charlie");
186 auto const baseFee = env.current()->fees().base.drops();
191 env.fund(
XRP(50000),
noripple(alice, bob, charlie, daria));
195 env(
noop(alice), queued);
203 env(
noop(daria),
Fee(baseFee * 100), queued);
213 env.fund(
XRP(50000),
noripple(elmo, fred, gwen, hank));
217 env(
noop(alice),
Fee(baseFee * 1.2), queued);
220 env(
noop(bob),
Fee(baseFee), queued);
221 env(
noop(charlie),
Fee(baseFee * 2), queued);
222 env(
noop(daria),
Fee(baseFee * 1.5), queued);
223 env(
noop(elmo),
Fee(baseFee * 1.1), queued);
224 env(
noop(fred),
Fee(baseFee * 1.9), queued);
225 env(
noop(gwen),
Fee(baseFee * 1.6), queued);
226 env(
noop(hank),
Fee(baseFee * 1.8), queued);
238 env(
noop(hank),
Fee(baseFee), queued);
250 env(
noop(hank),
Fee(baseFee * 600), queued);
263 env(
noop(hank),
Fee(baseFee * 2), queued);
273 env.close(env.now() + 5s, 10000ms);
282 static constexpr auto kLargeFeeMultiplier = 700;
283 auto const largeFee = baseFee * kLargeFeeMultiplier;
287 env(
noop(hank),
Fee(largeFee));
288 env(
noop(gwen),
Fee(largeFee));
289 env(
noop(fred),
Fee(largeFee));
290 env(
noop(elmo),
Fee(largeFee));
297 env(
noop(daria),
Fee(baseFee * 1.5), queued);
299 env(
noop(elmo),
Fee(baseFee * 1.6), queued);
300 env(
noop(fred),
Fee(baseFee * 1.7), queued);
301 env(
noop(gwen),
Fee(baseFee * 1.8), queued);
302 env(
noop(hank),
Fee(baseFee * 1.9), queued);
303 env(
noop(alice),
Fee(baseFee * 2.0), queued);
314 env(
noop(charlie),
Fee(baseFee * 10), queued);
341 env(
pay(alice, iris,
XRP(1000)), queued);
349 BEAST_EXPECT(env.seq(iris) == 11);
358 auto metrics = env.app().getTxQ().getMetrics(*env.current());
359 BEAST_EXPECT(
metrics.txCount == 0);
364 env(
noop(env.master));
368 env(
noop(env.master),
Fee(baseFee * 2), queued);
391 auto const baseFee = env.current()->fees().base.drops();
417 BEAST_EXPECT(env.seq(alice) == tkt1 + 250);
441 checkMetrics(*
this, env, 8, 8, 5, 4, expectedMinFeeLevel);
487 env(
noop(alice),
Seq(nextSeq + 0), queued);
491 env(
noop(alice),
Seq(nextSeq + 1), queued);
498 env(
noop(alice),
Seq(nextSeq + 2), queued);
499 env(
noop(alice),
Seq(nextSeq + 3), queued);
500 env(
noop(alice),
Seq(nextSeq + 4), queued);
501 env(
noop(alice),
Seq(nextSeq + 5), queued);
502 env(
noop(alice),
Seq(nextSeq + 6), queued);
533 BEAST_EXPECT(env.seq(alice) == nextSeq + 4);
581 BEAST_EXPECT(env.seq(alice) == nextSeq + 6);
592 Fee((baseFee * 2.1 * 1.25) - 1),
599 Fee((baseFee * 2.2 * 1.25) - 1),
614 BEAST_EXPECT(env.seq(alice) == nextSeq + 8);
718 auto charlie =
Account(
"charlie");
721 auto felicia =
Account(
"felicia");
724 auto const baseFee = env.current()->fees().base.drops();
730 env.close(env.now() + 5s, 10000ms);
732 env.close(env.now() + 5s, 10000ms);
734 env.close(env.now() + 5s, 10000ms);
742 BEAST_EXPECT(env.current()->header().seq == 6);
748 static constexpr auto kLargeFeeMultiplier = 700;
749 auto const largeFee = baseFee * kLargeFeeMultiplier;
753 env(
noop(bob),
Fee(largeFee), queued);
754 env(
noop(charlie),
Fee(largeFee), queued);
755 env(
noop(daria),
Fee(largeFee), queued);
756 env(
noop(edgar),
Fee(largeFee), queued);
759 auto& txQ = env.app().getTxQ();
760 auto aliceStat = txQ.getAccountTxs(alice.id());
761 BEAST_EXPECT(aliceStat.size() == 1);
764 BEAST_EXPECT(aliceStat.begin()->lastValid && *aliceStat.begin()->lastValid == 8);
765 BEAST_EXPECT(!aliceStat.begin()->consequences.isBlocker());
767 auto bobStat = txQ.getAccountTxs(bob.id());
768 BEAST_EXPECT(bobStat.size() == 1);
770 bobStat.begin()->feeLevel ==
FeeLevel64{kBaseFeeLevel.fee() * kLargeFeeMultiplier});
771 BEAST_EXPECT(!bobStat.begin()->lastValid);
772 BEAST_EXPECT(!bobStat.begin()->consequences.isBlocker());
775 BEAST_EXPECT(noStat.empty());
782 env(
noop(bob),
Fee(largeFee), queued);
783 env(
noop(charlie),
Fee(largeFee), queued);
784 env(
noop(daria),
Fee(largeFee), queued);
785 env(
noop(edgar),
Fee(largeFee), queued);
786 env(
noop(felicia),
Fee(largeFee - 1), queued);
794 BEAST_EXPECT(env.seq(alice) == 3);
796 static constexpr auto kAnotherLargeFeeMultiplier = 800;
797 auto const anotherLargeFee = baseFee * kAnotherLargeFeeMultiplier;
800 env(
noop(bob),
Fee(anotherLargeFee), queued);
801 env(
noop(charlie),
Fee(anotherLargeFee), queued);
802 env(
noop(daria),
Fee(anotherLargeFee), queued);
803 env(
noop(daria),
Fee(anotherLargeFee),
Seq(env.seq(daria) + 1), queued);
804 env(
noop(edgar),
Fee(anotherLargeFee), queued);
805 env(
noop(felicia),
Fee(anotherLargeFee - 1), queued);
806 env(
noop(felicia),
Fee(anotherLargeFee - 1),
Seq(env.seq(felicia) + 1), queued);
817 BEAST_EXPECT(env.seq(alice) == 3);
818 BEAST_EXPECT(env.seq(felicia) == 7);
825 BEAST_EXPECT(env.seq(alice) == 3);
826 BEAST_EXPECT(env.seq(felicia) == 8);
843 auto const baseFee = env.current()->fees().base.drops();
849 env.close(env.now() + 5s, 10000ms);
851 env.close(env.now() + 5s, 10000ms);
859 env(
noop(bob), queued);
873 static constexpr auto kAliceFeeMultiplier = 3;
874 auto feeAlice = baseFee * kAliceFeeMultiplier;
875 auto seqAlice = env.seq(alice);
876 for (
int i = 0; i < 4; ++i)
878 env(
noop(alice),
Fee(feeAlice),
Seq(seqAlice), queued);
879 feeAlice = (feeAlice + 1) * 125 / 100;
885 auto const seqBob = env.seq(bob);
890 auto feeCarol = feeAlice;
891 auto seqCarol = env.seq(carol);
892 for (
int i = 0; i < 4; ++i)
894 env(
noop(carol),
Fee(feeCarol),
Seq(seqCarol), queued);
895 feeCarol = (feeCarol + 1) * 125 / 100;
912 BEAST_EXPECT(env.seq(alice) == seqAlice - 4);
913 BEAST_EXPECT(env.seq(bob) == seqBob);
914 BEAST_EXPECT(env.seq(carol) == seqCarol + 1);
919 BEAST_EXPECT(env.seq(alice) == seqAlice);
920 BEAST_EXPECT(env.seq(bob) == seqBob + 1);
921 BEAST_EXPECT(env.seq(carol) == seqCarol + 1);
925 BEAST_EXPECT(env.seq(alice) == seqAlice);
926 BEAST_EXPECT(env.seq(bob) == seqBob + 1);
927 BEAST_EXPECT(env.seq(carol) == seqCarol + 1);
1009 using namespace jtx;
1018 auto alice =
Account(
"alice");
1020 auto charlie =
Account(
"charlie");
1021 auto daria =
Account(
"daria");
1028 initFee(env, 3, 2, 10, 200, 50);
1037 env.fund(
XRP(500000),
noripple(bob, charlie, daria));
1041 env(
noop(alice),
Fee(11), queued);
1044 auto aliceSeq = env.seq(alice);
1045 auto bobSeq = env.seq(bob);
1046 auto charlieSeq = env.seq(charlie);
1053 env(
noop(alice),
Seq(aliceSeq + 1),
Fee(13), queued);
1057 env(
noop(alice),
Seq(aliceSeq + 2),
Fee(17), queued);
1061 env(
noop(bob), queued);
1065 env(
noop(bob),
Seq(bobSeq + 1),
Fee(50), queued);
1070 env(
noop(charlie),
Fee(15), queued);
1073 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1074 BEAST_EXPECT(env.seq(bob) == bobSeq);
1075 BEAST_EXPECT(env.seq(charlie) == charlieSeq);
1085 BEAST_EXPECT(env.seq(alice) == aliceSeq + 3);
1086 BEAST_EXPECT(env.seq(bob) == bobSeq + 1);
1087 BEAST_EXPECT(env.seq(charlie) == charlieSeq + 1);
1091 aliceSeq = env.seq(alice);
1092 auto lastLedgerSeq = env.current()->header().seq + 2;
1093 for (
auto i = 0; i < 7; i++)
1097 Json(jss::LastLedgerSequence, lastLedgerSeq + i),
1104 auto& txQ = env.app().getTxQ();
1105 auto aliceStat = txQ.getAccountTxs(alice.id());
1107 auto const& baseFee = env.current()->fees().base;
1108 auto seq = env.seq(alice);
1109 BEAST_EXPECT(aliceStat.size() == 7);
1110 for (
auto const& tx : aliceStat)
1112 BEAST_EXPECT(tx.seqProxy.isSeq() && tx.seqProxy.value() == seq);
1114 BEAST_EXPECT(tx.lastValid);
1116 (tx.consequences.fee() ==
drops(aliceFee) &&
1117 tx.consequences.potentialSpend() ==
drops(0) &&
1118 !tx.consequences.isBlocker()) ||
1119 tx.seqProxy.value() == env.seq(alice) + 6);
1129 Json(jss::LastLedgerSequence, lastLedgerSeq + 7),
1142 env(
noop(charlie),
Fee(30), queued);
1159 aliceSeq = env.seq(alice) + 2;
1166 env(
noop(alice),
Seq(aliceSeq),
Fee(aliceFee), queued);
1175 aliceSeq = env.seq(alice) + 1;
1181 aliceFee = env.le(alice)->getFieldAmount(sfBalance).xrp().drops() - 62;
1193 env(
noop(alice),
Seq(aliceSeq),
Fee(aliceFee), queued);
1218 bobSeq = env.seq(bob);
1220 for (
int i = 0; i < 10; ++i)
1221 env(
noop(bob),
Seq(bobSeq + i), queued);
1228 env(
noop(bob),
Seq(bobSeq + 5),
Fee(20), queued);
1234 std::int64_t bobFee = env.le(bob)->getFieldAmount(sfBalance).xrp().drops() - ((9 * 10) - 1);
1244 bobFee = env.le(bob)->getFieldAmount(sfBalance).xrp().drops() - (9 * 10);
1260 using namespace jtx;
1265 cfg->fees.referenceFee = 10;
1266 Env env(*
this, std::move(cfg));
1268 auto alice =
Account(
"alice");
1270 auto charlie =
Account(
"charlie");
1271 auto daria =
Account(
"daria");
1279 BEAST_EXPECT(env.
current()->fees().base == 10);
1307 auto aliceSeq = env.
seq(alice);
1308 auto bobSeq = env.
seq(bob);
1309 auto charlieSeq = env.
seq(charlie);
1310 auto dariaSeq = env.
seq(daria);
1311 auto elmoSeq = env.
seq(elmo);
1312 auto fredSeq = env.
seq(fred);
1313 auto gwenSeq = env.
seq(gwen);
1314 auto hankSeq = env.
seq(hank);
1320 env(
noop(alice),
Fee(15), queued);
1321 env(
noop(bob),
Fee(15), queued);
1322 env(
noop(charlie),
Fee(15), queued);
1323 env(
noop(daria),
Fee(15), queued);
1324 env(
noop(elmo),
Fee(15), queued);
1325 env(
noop(fred),
Fee(15), queued);
1326 env(
noop(gwen),
Fee(15), queued);
1327 env(
noop(hank),
Fee(15), queued);
1342 env(
noop(charlie),
Fee(100),
Seq(charlieSeq + 1), queued);
1356 aliceSeq + bobSeq + charlieSeq + dariaSeq + elmoSeq + fredSeq + gwenSeq + hankSeq + 6 ==
1357 env.
seq(alice) + env.
seq(bob) + env.
seq(charlie) + env.
seq(daria) + env.
seq(elmo) +
1358 env.
seq(fred) + env.
seq(gwen) + env.
seq(hank));
1360 using namespace std::string_literals;
1362 aliceSeq == env.
seq(alice),
1365 bobSeq + 1 == env.
seq(bob),
1368 charlieSeq + 2 == env.
seq(charlie),
1371 dariaSeq + 1 == env.
seq(daria),
1374 elmoSeq + 1 == env.
seq(elmo),
1377 fredSeq == env.
seq(fred),
1380 gwenSeq == env.
seq(gwen),
1383 hankSeq + 1 == env.
seq(hank),
1397 auto getTxsQueued = [&]() {
1400 for (
auto const& tx : txs)
1402 ++result[tx.txn->at(sfAccount)];
1406 auto qTxCount1 = getTxsQueued();
1407 BEAST_EXPECT(qTxCount1.size() <= 3);
1410 env(
noop(alice),
Seq(aliceSeq + qTxCount1[alice.id()]++),
Fee(15), queued);
1411 env(
noop(bob),
Seq(bobSeq + qTxCount1[bob.id()]++),
Fee(15), queued);
1412 env(
noop(charlie),
Seq(charlieSeq + qTxCount1[charlie.id()]++),
Fee(15), queued);
1413 env(
noop(daria),
Seq(dariaSeq + qTxCount1[daria.id()]++),
Fee(15), queued);
1414 env(
noop(elmo),
Seq(elmoSeq + qTxCount1[elmo.id()]++),
Fee(15), queued);
1415 env(
noop(fred),
Seq(fredSeq + qTxCount1[fred.id()]++),
Fee(15), queued);
1416 env(
noop(gwen),
Seq(gwenSeq + qTxCount1[gwen.id()]++),
Fee(15), queued);
1424 env(
noop(alice),
Fee(100),
Seq(aliceSeq + qTxCount1[alice.id()]++), queued);
1435 auto qTxCount2 = getTxsQueued();
1436 BEAST_EXPECT(qTxCount2.size() <= 4);
1441 aliceSeq + bobSeq + charlieSeq + dariaSeq + elmoSeq + fredSeq + gwenSeq + hankSeq + 7 ==
1442 env.
seq(alice) + env.
seq(bob) + env.
seq(charlie) + env.
seq(daria) + env.
seq(elmo) +
1443 env.
seq(fred) + env.
seq(gwen) + env.
seq(hank));
1446 aliceSeq + qTxCount1[alice.id()] - qTxCount2[alice.id()] == env.
seq(alice),
1449 bobSeq + qTxCount1[bob.id()] - qTxCount2[bob.id()] == env.
seq(bob),
1452 charlieSeq + qTxCount1[charlie.id()] - qTxCount2[charlie.id()] == env.
seq(charlie),
1455 dariaSeq + qTxCount1[daria.id()] - qTxCount2[daria.id()] == env.
seq(daria),
1458 elmoSeq + qTxCount1[elmo.id()] - qTxCount2[elmo.id()] == env.
seq(elmo),
1461 fredSeq + qTxCount1[fred.id()] - qTxCount2[fred.id()] == env.
seq(fred),
1464 gwenSeq + qTxCount1[gwen.id()] - qTxCount2[gwen.id()] == env.
seq(gwen),
1467 hankSeq + qTxCount1[hank.id()] - qTxCount2[hank.id()] == env.
seq(hank),
1996 using namespace jtx;
1997 testcase(
"In-flight balance checks");
2005 auto alice =
Account(
"alice");
2006 auto charlie =
Account(
"charlie");
2017 auto const initQueueMax =
initFee(env, 3, 2, 10, 200, 50);
2023 env.fund(
XRP(50000),
noripple(alice, charlie), gw);
2024 checkMetrics(*
this, env, 0, initQueueMax, limit + 1, limit);
2026 auto usd = gw[
"USD"];
2027 auto bux = gw[
"BUX"];
2031 auto aliceSeq = env.seq(alice);
2032 auto aliceBal = env.balance(alice);
2038 env(
offer(alice, bux(5000),
XRP(50000)), queued);
2039 checkMetrics(*
this, env, 1, initQueueMax, limit + 1, limit);
2043 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2044 checkMetrics(*
this, env, 2, initQueueMax, limit + 1, limit);
2060 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2061 aliceSeq = env.seq(alice);
2062 aliceBal = env.balance(alice);
2064 env.require(
Owners(alice, 0));
2068 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2073 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2078 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2094 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2095 aliceSeq = env.seq(alice);
2096 aliceBal = env.balance(alice);
2098 env.require(
Owners(alice, 0));
2103 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2108 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2124 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2125 aliceSeq = env.seq(alice);
2126 aliceBal = env.balance(alice);
2130 env(
offer(alice, bux(50),
XRP(500)), queued);
2133 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2134 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2150 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2152 aliceSeq = env.seq(alice);
2153 aliceBal = env.balance(alice);
2158 env(
pay(alice, charlie,
XRP(50000)), queued);
2162 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2163 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2177 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2179 aliceSeq = env.seq(alice);
2180 aliceBal = env.balance(alice);
2184 env(
pay(alice, charlie,
XRP(500)), queued);
2187 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2188 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2199 auto const amount = usd(500000);
2200 env(
trust(alice, usd(50000000)));
2201 env(
trust(charlie, usd(50000000)));
2207 env(
pay(gw, alice, amount));
2214 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2216 aliceSeq = env.seq(alice);
2217 aliceBal = env.balance(alice);
2218 auto aliceUSD = env.balance(alice, usd);
2222 env(
pay(alice, charlie, amount), queued);
2226 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2227 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2245 env(
offer(gw,
XRP(500000), usd(50000)));
2251 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2253 aliceSeq = env.seq(alice);
2254 aliceBal = env.balance(alice);
2255 auto charlieUSD = env.balance(charlie, usd);
2261 BEAST_EXPECT(
XRP(60000) > aliceBal);
2262 env(
pay(alice, charlie, usd(1000)),
Sendmax(
XRP(60000)), queued);
2266 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2267 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2278 Balance(charlie, charlieUSD + usd(1000)),
2286 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2288 aliceSeq = env.seq(alice);
2289 aliceBal = env.balance(alice);
2290 charlieUSD = env.balance(charlie, usd);
2296 BEAST_EXPECT(aliceBal >
XRP(6001));
2297 env(
pay(alice, charlie, usd(500)),
Sendmax(
XRP(6000)), queued);
2300 env(
noop(alice),
Seq(aliceSeq + 1), queued);
2301 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2312 Balance(charlie, charlieUSD + usd(500)),
2322 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2324 aliceSeq = env.seq(alice);
2325 aliceBal = env.balance(alice);
2326 BEAST_EXPECT(aliceBal ==
drops(30));
2330 BEAST_EXPECT(env.balance(alice) ==
drops(30));
2332 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2337 BEAST_EXPECT(env.balance(alice) ==
drops(5));
2566 using namespace jtx;
2571 auto fee = env.
rpc(
"fee");
2573 if (BEAST_EXPECT(fee.isMember(jss::result)) &&
2576 auto const& result = fee[jss::result];
2578 result.isMember(jss::ledger_current_index) &&
2579 result[jss::ledger_current_index] == 3);
2580 BEAST_EXPECT(result.isMember(jss::current_ledger_size));
2581 BEAST_EXPECT(result.isMember(jss::current_queue_size));
2582 BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
2583 BEAST_EXPECT(!result.isMember(jss::max_queue_size));
2584 BEAST_EXPECT(result.isMember(jss::drops));
2585 auto const&
drops = result[jss::drops];
2586 BEAST_EXPECT(
drops.isMember(jss::base_fee));
2587 BEAST_EXPECT(
drops.isMember(jss::median_fee));
2588 BEAST_EXPECT(
drops.isMember(jss::minimum_fee));
2589 BEAST_EXPECT(
drops.isMember(jss::open_ledger_fee));
2590 BEAST_EXPECT(result.isMember(jss::levels));
2591 auto const& levels = result[jss::levels];
2592 BEAST_EXPECT(levels.isMember(jss::median_level));
2593 BEAST_EXPECT(levels.isMember(jss::minimum_level));
2594 BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
2595 BEAST_EXPECT(levels.isMember(jss::reference_level));
2600 fee = env.
rpc(
"fee");
2602 if (BEAST_EXPECT(fee.isMember(jss::result)) &&
2605 auto const& result = fee[jss::result];
2607 result.isMember(jss::ledger_current_index) &&
2608 result[jss::ledger_current_index] == 4);
2609 BEAST_EXPECT(result.isMember(jss::current_ledger_size));
2610 BEAST_EXPECT(result.isMember(jss::current_queue_size));
2611 BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
2612 BEAST_EXPECT(result.isMember(jss::max_queue_size));
2613 auto const&
drops = result[jss::drops];
2614 BEAST_EXPECT(
drops.isMember(jss::base_fee));
2615 BEAST_EXPECT(
drops.isMember(jss::median_fee));
2616 BEAST_EXPECT(
drops.isMember(jss::minimum_fee));
2617 BEAST_EXPECT(
drops.isMember(jss::open_ledger_fee));
2618 BEAST_EXPECT(result.isMember(jss::levels));
2619 auto const& levels = result[jss::levels];
2620 BEAST_EXPECT(levels.isMember(jss::median_level));
2621 BEAST_EXPECT(levels.isMember(jss::minimum_level));
2622 BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
2623 BEAST_EXPECT(levels.isMember(jss::reference_level));
2854 testcase(
"Autofilled sequence should account for TxQ");
2855 using namespace jtx;
2857 auto const baseFee = env.
current()->fees().base.drops();
2859 auto const& txQ = env.app().getTxQ();
2861 auto const alice =
Account(
"alice");
2862 auto const bob =
Account(
"bob");
2863 env.fund(
XRP(100000), alice, bob);
2869 auto const aliceSeq = env.seq(alice);
2870 auto const lastLedgerSeq = env.current()->header().seq + 2;
2873 for (
int i = 0; i < 5; ++i)
2881 Json(jss::LastLedgerSequence, lastLedgerSeq),
2891 auto aliceStat = txQ.getAccountTxs(alice.id());
2893 BEAST_EXPECT(aliceStat.size() == 5);
2894 for (
auto const& tx : aliceStat)
2896 BEAST_EXPECT(tx.seqProxy == seq);
2897 BEAST_EXPECT(tx.feeLevel ==
FeeLevel64{kBaseFeeLevel.fee() * 100});
2898 if (seq.
value() == aliceSeq + 2)
2900 BEAST_EXPECT(tx.lastValid && *tx.lastValid == lastLedgerSeq);
2904 BEAST_EXPECT(!tx.lastValid);
2911 for (
int i = 0; i < 8; ++i)
2920 for (
int i = 0; i < 9; ++i)
2927 for (
int i = 0; i < 10; ++i)
2934 auto bobStat = txQ.getAccountTxs(bob.id());
2935 BEAST_EXPECT(bobStat.empty());
2940 auto aliceStat = txQ.getAccountTxs(alice.id());
2941 auto seq = aliceSeq;
2942 BEAST_EXPECT(aliceStat.size() == 4);
2943 for (
auto const& tx : aliceStat)
2946 if (seq == aliceSeq + 2)
2949 BEAST_EXPECT(tx.seqProxy.isSeq() && tx.seqProxy.value() == seq);
2950 BEAST_EXPECT(tx.feeLevel ==
FeeLevel64{kBaseFeeLevel.fee() * 100});
2951 BEAST_EXPECT(!tx.lastValid);
2959 auto aliceStat = txQ.getAccountTxs(alice.id());
2960 auto seq = aliceSeq;
2961 BEAST_EXPECT(aliceStat.size() == 5);
2962 for (
auto const& tx : aliceStat)
2964 BEAST_EXPECT(tx.seqProxy.isSeq() && tx.seqProxy.value() == seq);
2965 BEAST_EXPECT(tx.feeLevel ==
FeeLevel64{kBaseFeeLevel * 100});
2966 BEAST_EXPECT(!tx.lastValid);
2975 auto bobStat = txQ.getAccountTxs(bob.id());
2976 BEAST_EXPECT(bobStat.empty());
2979 auto aliceStat = txQ.getAccountTxs(alice.id());
2980 BEAST_EXPECT(aliceStat.empty());
2987 using namespace jtx;
2991 auto const baseFee = env.
current()->fees().base.drops();
2995 env.fund(
XRP(1000000), alice);
2999 withQueue[jss::account] = alice.
human();
3000 withQueue[jss::queue] =
true;
3003 withoutQueue[jss::account] = alice.
human();
3006 prevLedgerWithQueue[jss::account] = alice.
human();
3007 prevLedgerWithQueue[jss::queue] =
true;
3008 prevLedgerWithQueue[jss::ledger_index] = 3;
3009 BEAST_EXPECT(env.current()->header().seq > 3);
3013 auto const info = env.rpc(
"json",
"account_info",
to_string(withoutQueue));
3015 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3016 BEAST_EXPECT(!info[jss::result].isMember(jss::queue_data));
3020 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3022 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3023 auto const& result = info[jss::result];
3024 BEAST_EXPECT(result.isMember(jss::queue_data));
3025 auto const& queueData = result[jss::queue_data];
3026 BEAST_EXPECT(queueData.isObject());
3027 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3028 BEAST_EXPECT(queueData[jss::txn_count] == 0);
3029 BEAST_EXPECT(!queueData.isMember(jss::lowest_sequence));
3030 BEAST_EXPECT(!queueData.isMember(jss::highest_sequence));
3031 BEAST_EXPECT(!queueData.isMember(jss::auth_change_queued));
3032 BEAST_EXPECT(!queueData.isMember(jss::max_spend_drops_total));
3033 BEAST_EXPECT(!queueData.isMember(jss::transactions));
3041 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3043 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3044 auto const& result = info[jss::result];
3045 BEAST_EXPECT(result.isMember(jss::queue_data));
3046 auto const& queueData = result[jss::queue_data];
3047 BEAST_EXPECT(queueData.isObject());
3048 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3049 BEAST_EXPECT(queueData[jss::txn_count] == 0);
3050 BEAST_EXPECT(!queueData.isMember(jss::lowest_sequence));
3051 BEAST_EXPECT(!queueData.isMember(jss::highest_sequence));
3052 BEAST_EXPECT(!queueData.isMember(jss::auth_change_queued));
3053 BEAST_EXPECT(!queueData.isMember(jss::max_spend_drops_total));
3054 BEAST_EXPECT(!queueData.isMember(jss::transactions));
3065 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3067 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3068 auto const& result = info[jss::result];
3069 auto const&
data = result[jss::account_data];
3070 BEAST_EXPECT(result.isMember(jss::queue_data));
3071 auto const& queueData = result[jss::queue_data];
3072 BEAST_EXPECT(queueData.isObject());
3073 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3074 BEAST_EXPECT(queueData[jss::txn_count] == 4);
3075 BEAST_EXPECT(queueData.isMember(jss::lowest_sequence));
3076 BEAST_EXPECT(queueData[jss::lowest_sequence] ==
data[jss::Sequence]);
3077 BEAST_EXPECT(queueData.isMember(jss::highest_sequence));
3079 queueData[jss::highest_sequence] ==
3080 data[jss::Sequence].asUInt() + queueData[jss::txn_count].asUInt() - 1);
3081 BEAST_EXPECT(queueData.isMember(jss::auth_change_queued));
3082 BEAST_EXPECT(queueData[jss::auth_change_queued] ==
false);
3083 BEAST_EXPECT(queueData.isMember(jss::max_spend_drops_total));
3084 BEAST_EXPECT(queueData[jss::max_spend_drops_total] ==
std::to_string(baseFee * 40));
3085 BEAST_EXPECT(queueData.isMember(jss::transactions));
3086 auto const& queued = queueData[jss::transactions];
3087 BEAST_EXPECT(queued.size() == queueData[jss::txn_count]);
3088 for (
unsigned i = 0; i < queued.size(); ++i)
3090 auto const& item = queued[i];
3091 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3093 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3095 BEAST_EXPECT(item.isMember(jss::fee));
3097 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3098 BEAST_EXPECT(item[jss::max_spend_drops] ==
std::to_string(baseFee * 10));
3099 BEAST_EXPECT(item.isMember(jss::auth_change));
3100 BEAST_EXPECT(item[jss::auth_change].asBool() ==
false);
3112 fset(alice, asfAccountTxnID),
3115 Json(jss::LastLedgerSequence, 10),
3120 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3122 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3123 auto const& result = info[jss::result];
3124 auto const&
data = result[jss::account_data];
3125 BEAST_EXPECT(result.isMember(jss::queue_data));
3126 auto const& queueData = result[jss::queue_data];
3127 BEAST_EXPECT(queueData.isObject());
3128 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3129 BEAST_EXPECT(queueData[jss::txn_count] == 1);
3130 BEAST_EXPECT(queueData.isMember(jss::lowest_sequence));
3131 BEAST_EXPECT(queueData[jss::lowest_sequence] ==
data[jss::Sequence]);
3132 BEAST_EXPECT(queueData.isMember(jss::highest_sequence));
3134 queueData[jss::highest_sequence] ==
3135 data[jss::Sequence].asUInt() + queueData[jss::txn_count].asUInt() - 1);
3136 BEAST_EXPECT(queueData.isMember(jss::auth_change_queued));
3137 BEAST_EXPECT(queueData[jss::auth_change_queued] ==
true);
3138 BEAST_EXPECT(queueData.isMember(jss::max_spend_drops_total));
3139 BEAST_EXPECT(queueData[jss::max_spend_drops_total] ==
std::to_string(baseFee * 10));
3140 BEAST_EXPECT(queueData.isMember(jss::transactions));
3141 auto const& queued = queueData[jss::transactions];
3142 BEAST_EXPECT(queued.size() == queueData[jss::txn_count]);
3143 for (
unsigned i = 0; i < queued.size(); ++i)
3145 auto const& item = queued[i];
3146 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3148 BEAST_EXPECT(item.isMember(jss::fee));
3150 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3151 BEAST_EXPECT(item[jss::max_spend_drops] ==
std::to_string(baseFee * 10));
3152 BEAST_EXPECT(item.isMember(jss::auth_change));
3154 if (i == queued.size() - 1)
3156 BEAST_EXPECT(item[jss::auth_change].asBool() ==
true);
3157 BEAST_EXPECT(item.isMember(jss::LastLedgerSequence));
3158 BEAST_EXPECT(item[jss::LastLedgerSequence] == 10);
3162 BEAST_EXPECT(item[jss::auth_change].asBool() ==
false);
3163 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3173 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3175 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3176 auto const& result = info[jss::result];
3177 auto const&
data = result[jss::account_data];
3178 BEAST_EXPECT(result.isMember(jss::queue_data));
3179 auto const& queueData = result[jss::queue_data];
3180 BEAST_EXPECT(queueData.isObject());
3181 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3182 BEAST_EXPECT(queueData[jss::txn_count] == 1);
3183 BEAST_EXPECT(queueData.isMember(jss::lowest_sequence));
3184 BEAST_EXPECT(queueData[jss::lowest_sequence] ==
data[jss::Sequence]);
3185 BEAST_EXPECT(queueData.isMember(jss::highest_sequence));
3187 queueData[jss::highest_sequence] ==
3188 data[jss::Sequence].asUInt() + queueData[jss::txn_count].asUInt() - 1);
3189 BEAST_EXPECT(queueData.isMember(jss::auth_change_queued));
3190 BEAST_EXPECT(queueData[jss::auth_change_queued].asBool());
3191 BEAST_EXPECT(queueData.isMember(jss::max_spend_drops_total));
3192 BEAST_EXPECT(queueData[jss::max_spend_drops_total] ==
std::to_string(baseFee * 10));
3193 BEAST_EXPECT(queueData.isMember(jss::transactions));
3194 auto const& queued = queueData[jss::transactions];
3195 BEAST_EXPECT(queued.size() == queueData[jss::txn_count]);
3196 for (
unsigned i = 0; i < queued.size(); ++i)
3198 auto const& item = queued[i];
3199 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3202 if (i == queued.size() - 1)
3204 BEAST_EXPECT(item.isMember(jss::fee));
3206 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3207 BEAST_EXPECT(item[jss::max_spend_drops] ==
std::to_string(baseFee * 10));
3208 BEAST_EXPECT(item.isMember(jss::auth_change));
3209 BEAST_EXPECT(item[jss::auth_change].asBool());
3210 BEAST_EXPECT(item.isMember(jss::LastLedgerSequence));
3211 BEAST_EXPECT(item[jss::LastLedgerSequence] == 10);
3215 BEAST_EXPECT(item.isMember(jss::fee));
3217 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3218 BEAST_EXPECT(item[jss::max_spend_drops] ==
std::to_string(baseFee * 10));
3219 BEAST_EXPECT(item.isMember(jss::auth_change));
3220 BEAST_EXPECT(!item[jss::auth_change].asBool());
3221 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3227 auto const info = env.rpc(
"json",
"account_info",
to_string(prevLedgerWithQueue));
3237 auto const info = env.rpc(
"json",
"account_info",
to_string(withQueue));
3239 info.isMember(jss::result) && info[jss::result].isMember(jss::account_data));
3240 auto const& result = info[jss::result];
3241 BEAST_EXPECT(result.isMember(jss::queue_data));
3242 auto const& queueData = result[jss::queue_data];
3243 BEAST_EXPECT(queueData.isObject());
3244 BEAST_EXPECT(queueData.isMember(jss::txn_count));
3245 BEAST_EXPECT(queueData[jss::txn_count] == 0);
3246 BEAST_EXPECT(!queueData.isMember(jss::lowest_sequence));
3247 BEAST_EXPECT(!queueData.isMember(jss::highest_sequence));
3248 BEAST_EXPECT(!queueData.isMember(jss::auth_change_queued));
3249 BEAST_EXPECT(!queueData.isMember(jss::max_spend_drops_total));
3250 BEAST_EXPECT(!queueData.isMember(jss::transactions));
3257 using namespace jtx;
3261 auto const baseFee = env.
current()->fees().base.drops();
3265 env.fund(
XRP(1000000), alice);
3269 auto const serverInfo = env.rpc(
"server_info");
3271 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3272 auto const& info = serverInfo[jss::result][jss::info];
3273 BEAST_EXPECT(info.isMember(jss::load_factor) && info[jss::load_factor] == 1);
3274 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3275 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3276 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3277 BEAST_EXPECT(!info.isMember(jss::load_factor_fee_escalation));
3280 auto const serverState = env.rpc(
"server_state");
3281 auto const& state = serverState[jss::result][jss::state];
3282 BEAST_EXPECT(state.isMember(jss::load_factor) && state[jss::load_factor] == 256);
3283 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3285 state.isMember(jss::load_factor_server) && state[jss::load_factor_server] == 256);
3287 state.isMember(jss::load_factor_fee_escalation) &&
3288 state[jss::load_factor_fee_escalation] == 256);
3290 state.isMember(jss::load_factor_fee_queue) &&
3291 state[jss::load_factor_fee_queue] == 256);
3293 state.isMember(jss::load_factor_fee_reference) &&
3294 state[jss::load_factor_fee_reference] == 256);
3302 auto aliceSeq = env.seq(alice);
3304 for (
auto i = 0; i < 4; ++i)
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];
3315 info.isMember(jss::load_factor) && info[jss::load_factor] > 888.88 &&
3316 info[jss::load_factor] < 888.89);
3318 info.isMember(jss::load_factor_server) && info[jss::load_factor_server] == 1);
3319 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3320 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3322 info.isMember(jss::load_factor_fee_escalation) &&
3323 info[jss::load_factor_fee_escalation] > 888.88 &&
3324 info[jss::load_factor_fee_escalation] < 888.89);
3327 auto const serverState = env.rpc(
"server_state");
3328 auto const& state = serverState[jss::result][jss::state];
3329 BEAST_EXPECT(state.isMember(jss::load_factor) && state[jss::load_factor] == 227555);
3330 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3332 state.isMember(jss::load_factor_server) && state[jss::load_factor_server] == 256);
3334 state.isMember(jss::load_factor_fee_escalation) &&
3335 state[jss::load_factor_fee_escalation] == 227555);
3337 state.isMember(jss::load_factor_fee_queue) &&
3338 state[jss::load_factor_fee_queue] == 256);
3340 state.isMember(jss::load_factor_fee_reference) &&
3341 state[jss::load_factor_fee_reference] == 256);
3344 env.app().getFeeTrack().setRemoteFee(256000);
3347 auto const serverInfo = env.rpc(
"server_info");
3349 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3350 auto const& info = serverInfo[jss::result][jss::info];
3352 BEAST_EXPECT(info.isMember(jss::load_factor) && info[jss::load_factor] == 1000);
3353 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3354 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3355 BEAST_EXPECT(info.isMember(jss::load_factor_net) && info[jss::load_factor_net] == 1000);
3357 info.isMember(jss::load_factor_fee_escalation) &&
3358 info[jss::load_factor_fee_escalation] > 888.88 &&
3359 info[jss::load_factor_fee_escalation] < 888.89);
3362 auto const serverState = env.rpc(
"server_state");
3363 auto const& state = serverState[jss::result][jss::state];
3364 BEAST_EXPECT(state.isMember(jss::load_factor) && state[jss::load_factor] == 256000);
3365 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3367 state.isMember(jss::load_factor_server) &&
3368 state[jss::load_factor_server] == 256000);
3370 state.isMember(jss::load_factor_fee_escalation) &&
3371 state[jss::load_factor_fee_escalation] == 227555);
3373 state.isMember(jss::load_factor_fee_queue) &&
3374 state[jss::load_factor_fee_queue] == 256);
3376 state.isMember(jss::load_factor_fee_reference) &&
3377 state[jss::load_factor_fee_reference] == 256);
3380 env.app().getFeeTrack().setRemoteFee(256);
3383 for (
int i = 0; i < 5; ++i)
3384 env.app().getFeeTrack().raiseLocalFee();
3385 BEAST_EXPECT(env.app().getFeeTrack().getLoadFactor() == 625);
3388 auto const serverInfo = env.rpc(
"server_info");
3390 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3391 auto const& info = serverInfo[jss::result][jss::info];
3394 info.isMember(jss::load_factor) && info[jss::load_factor] > 888.88 &&
3395 info[jss::load_factor] < 888.89);
3400 info.isMember(jss::load_factor_server) && info[jss::load_factor_server] > 1.245 &&
3401 info[jss::load_factor_server] < 2.4415);
3403 info.isMember(jss::load_factor_local) && info[jss::load_factor_local] > 1.245 &&
3404 info[jss::load_factor_local] < 2.4415);
3405 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3407 info.isMember(jss::load_factor_fee_escalation) &&
3408 info[jss::load_factor_fee_escalation] > 888.88 &&
3409 info[jss::load_factor_fee_escalation] < 888.89);
3412 auto const serverState = env.rpc(
"server_state");
3413 auto const& state = serverState[jss::result][jss::state];
3414 BEAST_EXPECT(state.isMember(jss::load_factor) && state[jss::load_factor] == 227555);
3415 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3420 state.isMember(jss::load_factor_server) && state[jss::load_factor_server] >= 320 &&
3421 state[jss::load_factor_server] <= 625);
3423 state.isMember(jss::load_factor_fee_escalation) &&
3424 state[jss::load_factor_fee_escalation] == 227555);
3426 state.isMember(jss::load_factor_fee_queue) &&
3427 state[jss::load_factor_fee_queue] == 256);
3429 state.isMember(jss::load_factor_fee_reference) &&
3430 state[jss::load_factor_fee_reference] == 256);
3436 auto const serverInfo = env.rpc(
"server_info");
3438 serverInfo.isMember(jss::result) && serverInfo[jss::result].isMember(jss::info));
3439 auto const& info = serverInfo[jss::result][jss::info];
3446 info.isMember(jss::load_factor) && info[jss::load_factor] > 1.245 &&
3447 info[jss::load_factor] < 2.4415);
3448 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3450 info.isMember(jss::load_factor_local) && info[jss::load_factor_local] > 1.245 &&
3451 info[jss::load_factor_local] < 2.4415);
3452 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3453 BEAST_EXPECT(!info.isMember(jss::load_factor_fee_escalation));
3456 auto const serverState = env.rpc(
"server_state");
3457 auto const& state = serverState[jss::result][jss::state];
3459 state.isMember(jss::load_factor) && state[jss::load_factor] >= 320 &&
3460 state[jss::load_factor] <= 625);
3461 BEAST_EXPECT(state.isMember(jss::load_base) && state[jss::load_base] == 256);
3466 state.isMember(jss::load_factor_server) && state[jss::load_factor_server] >= 320 &&
3467 state[jss::load_factor_server] <= 625);
3469 state.isMember(jss::load_factor_fee_escalation) &&
3470 state[jss::load_factor_fee_escalation] == 256);
3472 state.isMember(jss::load_factor_fee_queue) &&
3473 state[jss::load_factor_fee_queue] == 256);
3475 state.isMember(jss::load_factor_fee_reference) &&
3476 state[jss::load_factor_fee_reference] == 256);
3483 using namespace jtx;
3487 auto const baseFee = env.
current()->fees().base.drops();
3491 stream[jss::streams].append(
"server");
3494 auto jv = wsc->invoke(
"subscribe", stream);
3495 BEAST_EXPECT(jv[jss::status] ==
"success");
3499 Account a{
"a"}, b{
"b"}, c{
"c"}, d{
"d"}, e{
"e"}, f{
"f"}, g{
"g"}, h{
"h"}, i{
"i"};
3506 using namespace std::chrono_literals;
3507 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3508 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3509 jv[jss::load_factor] == 256 && jv.isMember(jss::load_base) &&
3510 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3511 jv[jss::load_factor_server] == 256 &&
3512 jv.isMember(jss::load_factor_fee_escalation) &&
3513 jv[jss::load_factor_fee_escalation] == 256 &&
3514 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3515 jv.isMember(jss::load_factor_fee_reference) &&
3516 jv[jss::load_factor_fee_reference] == 256;
3519 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3520 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3521 jv[jss::load_factor] == 227555 && jv.isMember(jss::load_base) &&
3522 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3523 jv[jss::load_factor_server] == 256 &&
3524 jv.isMember(jss::load_factor_fee_escalation) &&
3525 jv[jss::load_factor_fee_escalation] == 227555 &&
3526 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3527 jv.isMember(jss::load_factor_fee_reference) &&
3528 jv[jss::load_factor_fee_reference] == 256;
3534 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3535 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3536 jv[jss::load_factor] == 256 && jv.isMember(jss::load_base) &&
3537 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3538 jv[jss::load_factor_server] == 256 &&
3539 jv.isMember(jss::load_factor_fee_escalation) &&
3540 jv[jss::load_factor_fee_escalation] == 256 &&
3541 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3542 jv.isMember(jss::load_factor_fee_reference) &&
3543 jv[jss::load_factor_fee_reference] == 256;
3553 env(
noop(a),
Fee(baseFee), queued);
3554 env(
noop(b),
Fee(baseFee), queued);
3555 env(
noop(c),
Fee(baseFee), queued);
3556 env(
noop(d),
Fee(baseFee), queued);
3557 env(
noop(e),
Fee(baseFee), queued);
3558 env(
noop(f),
Fee(baseFee), queued);
3559 env(
noop(g),
Fee(baseFee), queued);
3563 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3564 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3565 jv[jss::load_factor] == 200000 && jv.isMember(jss::load_base) &&
3566 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3567 jv[jss::load_factor_server] == 256 &&
3568 jv.isMember(jss::load_factor_fee_escalation) &&
3569 jv[jss::load_factor_fee_escalation] == 200000 &&
3570 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3571 jv.isMember(jss::load_factor_fee_reference) &&
3572 jv[jss::load_factor_fee_reference] == 256;
3577 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3578 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3579 jv[jss::load_factor] == 184320 && jv.isMember(jss::load_base) &&
3580 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3581 jv[jss::load_factor_server] == 256 &&
3582 jv.isMember(jss::load_factor_fee_escalation) &&
3583 jv[jss::load_factor_fee_escalation] == 184320 &&
3584 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3585 jv.isMember(jss::load_factor_fee_reference) &&
3586 jv[jss::load_factor_fee_reference] == 256;
3591 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3592 return jv[jss::type] ==
"serverStatus" && jv.isMember(jss::load_factor) &&
3593 jv[jss::load_factor] == 256 && jv.isMember(jss::load_base) &&
3594 jv[jss::load_base] == 256 && jv.isMember(jss::load_factor_server) &&
3595 jv[jss::load_factor_server] == 256 &&
3596 jv.isMember(jss::load_factor_fee_escalation) &&
3597 jv[jss::load_factor_fee_escalation] == 256 &&
3598 jv.isMember(jss::load_factor_fee_queue) && jv[jss::load_factor_fee_queue] == 256 &&
3599 jv.isMember(jss::load_factor_fee_reference) &&
3600 jv[jss::load_factor_fee_reference] == 256;
3609 if (!wsc->findMsg(1s, [&](
auto const& jv) { return jv[jss::type] ==
"serverStatus"; }))
3615 auto jv = wsc->invoke(
"unsubscribe", stream);
3616 BEAST_EXPECT(jv[jss::status] ==
"success");
3622 using namespace jtx;
3626 auto const baseFee = env.
current()->fees().base.drops();
3627 auto alice =
Account(
"alice");
3631 env.fund(
XRP(50000000), alice, bob);
3638 auto totalFactor = 0;
3639 auto const metrics = env.app().getTxQ().getMetrics(*env.current());
3641 numToClear.emplace(
metrics.txCount + 1);
3642 for (
int i = 0; i < *numToClear; ++i)
3644 auto inLedger =
metrics.txInLedger + i;
3645 totalFactor += inLedger * inLedger;
3652 auto result =
toDrops(feeLevel, env.current()->fees().base).
drops();
3655 result -= alreadyPaid;
3661 testcase(
"straightforward positive case");
3664 auto aliceSeq = env.seq(alice);
3666 for (
int i = 0; i < 2; ++i)
3669 totalPaid += baseFee * 10;
3694 totalPaid += totalFee;
3695 totalFee = calcTotalFee(totalPaid);
3698 env(
noop(alice),
Fee(totalFee),
Seq(aliceSeq++));
3703 testcase(
"replace last tx with enough to clear queue");
3706 auto aliceSeq = env.seq(alice);
3708 for (
int i = 0; i < 2; ++i)
3711 totalPaid += baseFee * 10;
3723 auto const metrics = env.app().getTxQ().getMetrics(*env.current());
3727 env(
noop(alice),
Fee(totalFee),
Seq(aliceSeq++));
3736 testcase(
"replace middle tx with enough to clear queue");
3740 auto aliceSeq = env.seq(alice);
3741 for (
int i = 0; i < 5; ++i)
3749 uint64_t const totalFee = calcTotalFee(baseFee * 10 * 2, 3);
3752 env(
noop(alice),
Fee(totalFee),
Seq(aliceSeq++));
3755 auto const aliceQueue = env.app().getTxQ().getAccountTxs(alice.id());
3756 BEAST_EXPECT(aliceQueue.size() == 2);
3758 for (
auto const& tx : aliceQueue)
3760 BEAST_EXPECT(tx.seqProxy == seq);
3761 BEAST_EXPECT(tx.feeLevel ==
FeeLevel64{kBaseFeeLevel.fee() * 10});
3770 testcase(
"clear queue failure (load)");
3774 auto aliceSeq = env.seq(alice);
3776 for (
int i = 0; i < 2; ++i)
3779 totalPaid += baseFee * 20;
3781 for (
int i = 0; i < 2; ++i)
3784 totalPaid += baseFee * 2.2;
3793 auto& feeTrack = env.app().getFeeTrack();
3794 auto const origFee = feeTrack.getRemoteFee();
3795 feeTrack.setRemoteFee(origFee * 5);
3808 feeTrack.setRemoteFee(origFee);
3827 using namespace jtx;
3828 using namespace std::chrono_literals;
3840 auto alice =
Account(
"alice");
3843 env.fund(
XRP(50000000), alice);
3847 auto seqAlice = env.seq(alice);
3849 for (
int i = 0; i < txCount; ++i)
3893 env.close(env.now() + 5s, 10000ms);
3898 env.close(env.now() + 5s, 10000ms);
3903 env.close(env.now() + 5s, 10000ms);
3910 env.close(env.now() + 5s, 10000ms);
3914 BEAST_EXPECT(!txCount);
3926 auto alice =
Account(
"alice");
3929 env.fund(
XRP(50000000), alice);
3933 auto seqAlice = env.seq(alice);
3935 for (
int i = 0; i < txCount; ++i)
3954 env.close(env.now() + 5s, 10000ms);
3960 BEAST_EXPECT(!txCount);
4131 using namespace jtx;
4140 static constexpr int kLedgersInQueue = 30;
4153 Env env(*
this, std::move(cfg));
4173 for (i = 0; i <= 257; ++i)
4180 checkMetrics(*
this, env, 0, kLedgersInQueue * expectedPerLedger, 0, expectedPerLedger);
4185 using namespace std::chrono_literals;
4186 auto closeDuration = 80
min;
4187 for (i = 0; i <= 255; ++i)
4189 env.
close(closeDuration);
4192 auto const baseFee = env.
current()->fees().base.drops();
4199 kLedgersInQueue * expectedPerLedger,
4200 expectedPerLedger + 1,
4204 auto seqAlice = env.
seq(alice);
4205 auto seqBob = env.
seq(bob);
4206 auto seqCarol = env.
seq(carol);
4207 auto seqDaria = env.
seq(daria);
4208 auto seqEllie = env.
seq(ellie);
4209 auto seqFiona = env.
seq(fiona);
4212 int txFee{
static_cast<int>(baseFee * 9)};
4213 auto prepareFee = [&](
uint64_t multiplier) {
4214 return Fee(
txFee - (multiplier * baseFee / 10));
4218 for (
int i = 0; i < 10; ++i)
4232 kLedgersInQueue * expectedPerLedger,
4233 expectedPerLedger + 1,
4247 env.
close(closeDuration);
4248 auto expectedInLedger = expectedInQueue;
4250 (expectedInQueue > expectedPerLedger + 2 ? expectedInQueue - (expectedPerLedger + 2)
4252 expectedInLedger -= expectedInQueue;
4253 ++expectedPerLedger;
4258 kLedgersInQueue * expectedPerLedger,
4262 auto const expectedPerAccount = expectedInQueue / 6;
4263 auto const expectedRemainder = expectedInQueue % 6;
4264 BEAST_EXPECT(env.
seq(alice) == seqAlice - expectedPerAccount);
4266 env.
seq(bob) == seqBob - expectedPerAccount - (expectedRemainder > 4 ? 1 : 0));
4269 seqCarol - expectedPerAccount - (expectedRemainder > 3 ? 1 : 0));
4272 seqDaria - expectedPerAccount - (expectedRemainder > 2 ? 1 : 0));
4275 seqEllie - expectedPerAccount - (expectedRemainder > 1 ? 1 : 0));
4278 seqFiona - expectedPerAccount - (expectedRemainder > 0 ? 1 : 0));
4280 }
while (expectedInQueue > 0);
4609 using namespace jtx;
4625 auto const initQueueMax =
initFee(env, 3, 2, 0, 0, 0);
4627 BEAST_EXPECT(env.current()->fees().base == 0);
4630 auto const fee = env.rpc(
"fee");
4632 if (BEAST_EXPECT(fee.isMember(jss::result)) &&
4635 auto const& result = fee[jss::result];
4637 BEAST_EXPECT(result.isMember(jss::levels));
4638 auto const& levels = result[jss::levels];
4640 levels.isMember(jss::median_level) && levels[jss::median_level] ==
"128000");
4642 levels.isMember(jss::minimum_level) && levels[jss::minimum_level] ==
"256");
4644 levels.isMember(jss::open_ledger_level) &&
4645 levels[jss::open_ledger_level] ==
"256");
4647 levels.isMember(jss::reference_level) && levels[jss::reference_level] ==
"256");
4649 auto const&
drops = result[jss::drops];
4650 BEAST_EXPECT(
drops.isMember(jss::base_fee) &&
drops[jss::base_fee] ==
"0");
4651 BEAST_EXPECT(
drops.isMember(jss::median_fee) &&
drops[jss::median_fee] ==
"0");
4652 BEAST_EXPECT(
drops.isMember(jss::minimum_fee) &&
drops[jss::minimum_fee] ==
"0");
4654 drops.isMember(jss::open_ledger_fee) &&
drops[jss::open_ledger_fee] ==
"0");
4678 auto aliceSeq = env.seq(alice);
4679 env(
noop(alice), queued);
4683 env(
noop(alice),
Seq(aliceSeq + 1),
Fee(10), queued);
4688 auto const fee = env.rpc(
"fee");
4690 if (BEAST_EXPECT(fee.isMember(jss::result)) &&
4693 auto const& result = fee[jss::result];
4695 BEAST_EXPECT(result.isMember(jss::levels));
4696 auto const& levels = result[jss::levels];
4698 levels.isMember(jss::median_level) && levels[jss::median_level] ==
"128000");
4700 levels.isMember(jss::minimum_level) && levels[jss::minimum_level] ==
"256");
4702 levels.isMember(jss::open_ledger_level) &&
4703 levels[jss::open_ledger_level] ==
"355555");
4705 levels.isMember(jss::reference_level) && levels[jss::reference_level] ==
"256");
4707 auto const&
drops = result[jss::drops];
4708 BEAST_EXPECT(
drops.isMember(jss::base_fee) &&
drops[jss::base_fee] ==
"0");
4709 BEAST_EXPECT(
drops.isMember(jss::median_fee) &&
drops[jss::median_fee] ==
"0");
4710 BEAST_EXPECT(
drops.isMember(jss::minimum_fee) &&
drops[jss::minimum_fee] ==
"0");
4712 drops.isMember(jss::open_ledger_fee) &&
drops[jss::open_ledger_fee] ==
"1389");