1000 using namespace jtx;
1006 {{
"minimum_txn_in_ledger_standalone",
"3"}},
1007 {{
"account_reserve",
"200"}, {
"owner_reserve",
"50"}}));
1009 auto alice =
Account(
"alice");
1011 auto charlie =
Account(
"charlie");
1012 auto daria =
Account(
"daria");
1019 auto const initQueueMax =
initFee(env, 3, 2, 10, 200, 50);
1027 env(
noop(alice),
fee(11), queued);
1030 auto aliceSeq = env.
seq(alice);
1031 auto bobSeq = env.
seq(bob);
1032 auto charlieSeq = env.
seq(charlie);
1039 env(
noop(alice),
seq(aliceSeq + 1),
fee(13), queued);
1043 env(
noop(alice),
seq(aliceSeq + 2),
fee(17), queued);
1047 env(
noop(bob), queued);
1051 env(
noop(bob),
seq(bobSeq + 1),
fee(50), queued);
1056 env(
noop(charlie),
fee(15), queued);
1059 BEAST_EXPECT(env.
seq(alice) == aliceSeq);
1060 BEAST_EXPECT(env.
seq(bob) == bobSeq);
1061 BEAST_EXPECT(env.
seq(charlie) == charlieSeq);
1071 BEAST_EXPECT(env.
seq(alice) == aliceSeq + 3);
1072 BEAST_EXPECT(env.
seq(bob) == bobSeq + 1);
1073 BEAST_EXPECT(env.
seq(charlie) == charlieSeq + 1);
1077 aliceSeq = env.
seq(alice);
1078 auto lastLedgerSeq = env.
current()->info().seq + 2;
1079 for (
auto i = 0; i < 7; i++)
1083 json(jss::LastLedgerSequence, lastLedgerSeq + i),
1093 auto const& baseFee = env.
current()->fees().base;
1094 auto seq = env.
seq(alice);
1095 BEAST_EXPECT(aliceStat.size() == 7);
1096 for (
auto const& tx : aliceStat)
1098 BEAST_EXPECT(tx.seqProxy.isSeq() && tx.seqProxy.value() ==
seq);
1101 BEAST_EXPECT(tx.lastValid);
1103 (tx.consequences.fee() ==
drops(aliceFee) &&
1104 tx.consequences.potentialSpend() ==
drops(0) &&
1105 !tx.consequences.isBlocker()) ||
1106 tx.seqProxy.value() == env.
seq(alice) + 6);
1116 json(jss::LastLedgerSequence, lastLedgerSeq + 7),
1129 env(
noop(charlie),
fee(30), queued);
1149 aliceSeq = env.
seq(alice) + 2;
1159 env(
noop(alice),
seq(aliceSeq),
fee(aliceFee), queued);
1168 aliceSeq = env.
seq(alice) + 1;
1175 env.
le(alice)->getFieldAmount(sfBalance).xrp().drops() - (62);
1190 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);
1235 env.
le(bob)->getFieldAmount(sfBalance).xrp().drops() - (9 * 10 - 1);
1249 env.
le(bob)->getFieldAmount(sfBalance).xrp().drops() - (9 * 10);
1268 using namespace jtx;
1272 auto cfg =
makeConfig({{
"minimum_txn_in_ledger_standalone",
"4"}});
1273 cfg->FEES.reference_fee = 10;
1274 Env env(*
this, std::move(cfg));
1276 auto alice =
Account(
"alice");
1278 auto charlie =
Account(
"charlie");
1279 auto daria =
Account(
"daria");
1287 BEAST_EXPECT(env.
current()->fees().base == 10);
1315 auto aliceSeq = env.
seq(alice);
1316 auto bobSeq = env.
seq(bob);
1317 auto charlieSeq = env.
seq(charlie);
1318 auto dariaSeq = env.
seq(daria);
1319 auto elmoSeq = env.
seq(elmo);
1320 auto fredSeq = env.
seq(fred);
1321 auto gwenSeq = env.
seq(gwen);
1322 auto hankSeq = env.
seq(hank);
1328 env(
noop(alice),
fee(15), queued);
1329 env(
noop(bob),
fee(15), queued);
1330 env(
noop(charlie),
fee(15), queued);
1331 env(
noop(daria),
fee(15), queued);
1332 env(
noop(elmo),
fee(15), queued);
1333 env(
noop(fred),
fee(15), queued);
1334 env(
noop(gwen),
fee(15), queued);
1335 env(
noop(hank),
fee(15), queued);
1350 env(
noop(charlie),
fee(100),
seq(charlieSeq + 1), queued);
1364 aliceSeq + bobSeq + charlieSeq + dariaSeq + elmoSeq + fredSeq +
1365 gwenSeq + hankSeq + 6 ==
1366 env.
seq(alice) + env.
seq(bob) + env.
seq(charlie) + env.
seq(daria) +
1367 env.
seq(elmo) + env.
seq(fred) + env.
seq(gwen) + env.
seq(hank));
1369 using namespace std::string_literals;
1371 aliceSeq == env.
seq(alice),
1375 bobSeq + 1 == env.
seq(bob),
1379 charlieSeq + 2 == env.
seq(charlie),
1383 dariaSeq + 1 == env.
seq(daria),
1387 elmoSeq + 1 == env.
seq(elmo),
1391 fredSeq == env.
seq(fred),
1395 gwenSeq == env.
seq(gwen),
1399 hankSeq + 1 == env.
seq(hank),
1414 auto getTxsQueued = [&]() {
1417 for (
auto const& tx : txs)
1419 ++result[tx.txn->at(sfAccount)];
1423 auto qTxCount1 = getTxsQueued();
1424 BEAST_EXPECT(qTxCount1.size() <= 3);
1428 seq(aliceSeq + qTxCount1[alice.id()]++),
1431 env(
noop(bob),
seq(bobSeq + qTxCount1[bob.id()]++),
fee(15), queued);
1433 seq(charlieSeq + qTxCount1[charlie.id()]++),
1437 seq(dariaSeq + qTxCount1[daria.id()]++),
1440 env(
noop(elmo),
seq(elmoSeq + qTxCount1[elmo.id()]++),
fee(15), queued);
1441 env(
noop(fred),
seq(fredSeq + qTxCount1[fred.id()]++),
fee(15), queued);
1442 env(
noop(gwen),
seq(gwenSeq + qTxCount1[gwen.id()]++),
fee(15), queued);
1452 seq(aliceSeq + qTxCount1[alice.id()]++),
1464 auto qTxCount2 = getTxsQueued();
1465 BEAST_EXPECT(qTxCount2.size() <= 4);
1470 aliceSeq + bobSeq + charlieSeq + dariaSeq + elmoSeq + fredSeq +
1471 gwenSeq + hankSeq + 7 ==
1472 env.
seq(alice) + env.
seq(bob) + env.
seq(charlie) + env.
seq(daria) +
1473 env.
seq(elmo) + env.
seq(fred) + env.
seq(gwen) + env.
seq(hank));
1476 aliceSeq + qTxCount1[alice.id()] - qTxCount2[alice.id()] ==
1481 bobSeq + qTxCount1[bob.id()] - qTxCount2[bob.id()] == env.
seq(bob),
1485 charlieSeq + qTxCount1[charlie.id()] - qTxCount2[charlie.id()] ==
1490 dariaSeq + qTxCount1[daria.id()] - qTxCount2[daria.id()] ==
1495 elmoSeq + qTxCount1[elmo.id()] - qTxCount2[elmo.id()] ==
1500 fredSeq + qTxCount1[fred.id()] - qTxCount2[fred.id()] ==
1505 gwenSeq + qTxCount1[gwen.id()] - qTxCount2[gwen.id()] ==
1510 hankSeq + qTxCount1[hank.id()] - qTxCount2[hank.id()] ==
2065 using namespace jtx;
2066 testcase(
"In-flight balance checks");
2071 {{
"minimum_txn_in_ledger_standalone",
"3"}},
2072 {{
"account_reserve",
"200"}, {
"owner_reserve",
"50"}}));
2074 auto alice =
Account(
"alice");
2075 auto charlie =
Account(
"charlie");
2086 auto const initQueueMax =
initFee(env, 3, 2, 10, 200, 50);
2093 checkMetrics(*
this, env, 0, initQueueMax, limit + 1, limit);
2095 auto USD = gw[
"USD"];
2096 auto BUX = gw[
"BUX"];
2100 auto aliceSeq = env.
seq(alice);
2101 auto aliceBal = env.
balance(alice);
2107 env(
offer(alice, BUX(5000),
XRP(50000)), queued);
2108 checkMetrics(*
this, env, 1, initQueueMax, limit + 1, limit);
2112 env(
noop(alice),
seq(aliceSeq + 1), queued);
2113 checkMetrics(*
this, env, 2, initQueueMax, limit + 1, limit);
2129 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2130 aliceSeq = env.
seq(alice);
2131 aliceBal = env.
balance(alice);
2137 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2142 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2150 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2166 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2167 aliceSeq = env.
seq(alice);
2168 aliceBal = env.
balance(alice);
2175 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2183 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2199 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2200 aliceSeq = env.
seq(alice);
2201 aliceBal = env.
balance(alice);
2205 env(
offer(alice, BUX(50),
XRP(500)), queued);
2208 env(
noop(alice),
seq(aliceSeq + 1), queued);
2209 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2225 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2227 aliceSeq = env.
seq(alice);
2228 aliceBal = env.
balance(alice);
2233 env(
pay(alice, charlie,
XRP(50000)), queued);
2237 env(
noop(alice),
seq(aliceSeq + 1), queued);
2238 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2252 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2254 aliceSeq = env.
seq(alice);
2255 aliceBal = env.
balance(alice);
2259 env(
pay(alice, charlie,
XRP(500)), queued);
2262 env(
noop(alice),
seq(aliceSeq + 1), queued);
2263 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2275 auto const amount = USD(500000);
2276 env(
trust(alice, USD(50000000)));
2277 env(
trust(charlie, USD(50000000)));
2283 env(
pay(gw, alice, amount));
2290 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2292 aliceSeq = env.
seq(alice);
2293 aliceBal = env.
balance(alice);
2294 auto aliceUSD = env.
balance(alice, USD);
2298 env(
pay(alice, charlie, amount), queued);
2302 env(
noop(alice),
seq(aliceSeq + 1), queued);
2303 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2321 env(
offer(gw,
XRP(500000), USD(50000)));
2327 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2329 aliceSeq = env.
seq(alice);
2330 aliceBal = env.
balance(alice);
2331 auto charlieUSD = env.
balance(charlie, USD);
2337 BEAST_EXPECT(
XRP(60000) > aliceBal);
2338 env(
pay(alice, charlie, USD(1000)),
sendmax(
XRP(60000)), queued);
2342 env(
noop(alice),
seq(aliceSeq + 1), queued);
2343 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2354 balance(charlie, charlieUSD + USD(1000)),
2362 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2364 aliceSeq = env.
seq(alice);
2365 aliceBal = env.
balance(alice);
2366 charlieUSD = env.
balance(charlie, USD);
2372 BEAST_EXPECT(aliceBal >
XRP(6001));
2373 env(
pay(alice, charlie, USD(500)),
sendmax(
XRP(6000)), queued);
2376 env(
noop(alice),
seq(aliceSeq + 1), queued);
2377 checkMetrics(*
this, env, 2, limit * 2, limit + 1, limit);
2388 balance(charlie, charlieUSD + USD(500)),
2398 checkMetrics(*
this, env, 0, limit * 2, limit + 1, limit);
2400 aliceSeq = env.
seq(alice);
2401 aliceBal = env.
balance(alice);
2402 BEAST_EXPECT(aliceBal ==
drops(30));
2408 checkMetrics(*
this, env, 1, limit * 2, limit + 1, limit);
2591 using namespace jtx;
2596 auto fee = env.
rpc(
"fee");
2598 if (BEAST_EXPECT(
fee.isMember(jss::result)) &&
2601 auto const& result =
fee[jss::result];
2603 result.isMember(jss::ledger_current_index) &&
2604 result[jss::ledger_current_index] == 3);
2605 BEAST_EXPECT(result.isMember(jss::current_ledger_size));
2606 BEAST_EXPECT(result.isMember(jss::current_queue_size));
2607 BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
2608 BEAST_EXPECT(!result.isMember(jss::max_queue_size));
2609 BEAST_EXPECT(result.isMember(jss::drops));
2610 auto const&
drops = result[jss::drops];
2611 BEAST_EXPECT(
drops.isMember(jss::base_fee));
2612 BEAST_EXPECT(
drops.isMember(jss::median_fee));
2613 BEAST_EXPECT(
drops.isMember(jss::minimum_fee));
2614 BEAST_EXPECT(
drops.isMember(jss::open_ledger_fee));
2615 BEAST_EXPECT(result.isMember(jss::levels));
2616 auto const& levels = result[jss::levels];
2617 BEAST_EXPECT(levels.isMember(jss::median_level));
2618 BEAST_EXPECT(levels.isMember(jss::minimum_level));
2619 BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
2620 BEAST_EXPECT(levels.isMember(jss::reference_level));
2627 if (BEAST_EXPECT(
fee.isMember(jss::result)) &&
2630 auto const& result =
fee[jss::result];
2632 result.isMember(jss::ledger_current_index) &&
2633 result[jss::ledger_current_index] == 4);
2634 BEAST_EXPECT(result.isMember(jss::current_ledger_size));
2635 BEAST_EXPECT(result.isMember(jss::current_queue_size));
2636 BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
2637 BEAST_EXPECT(result.isMember(jss::max_queue_size));
2638 auto const&
drops = result[jss::drops];
2639 BEAST_EXPECT(
drops.isMember(jss::base_fee));
2640 BEAST_EXPECT(
drops.isMember(jss::median_fee));
2641 BEAST_EXPECT(
drops.isMember(jss::minimum_fee));
2642 BEAST_EXPECT(
drops.isMember(jss::open_ledger_fee));
2643 BEAST_EXPECT(result.isMember(jss::levels));
2644 auto const& levels = result[jss::levels];
2645 BEAST_EXPECT(levels.isMember(jss::median_level));
2646 BEAST_EXPECT(levels.isMember(jss::minimum_level));
2647 BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
2648 BEAST_EXPECT(levels.isMember(jss::reference_level));
3054 using namespace jtx;
3057 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
3058 auto const baseFee = env.
current()->fees().base.drops();
3062 env.
fund(
XRP(1000000), alice);
3066 withQueue[jss::account] = alice.human();
3067 withQueue[jss::queue] =
true;
3070 withoutQueue[jss::account] = alice.human();
3073 prevLedgerWithQueue[jss::account] = alice.human();
3074 prevLedgerWithQueue[jss::queue] =
true;
3075 prevLedgerWithQueue[jss::ledger_index] = 3;
3076 BEAST_EXPECT(env.
current()->info().seq > 3);
3081 env.
rpc(
"json",
"account_info",
to_string(withoutQueue));
3083 info.isMember(jss::result) &&
3084 info[jss::result].isMember(jss::account_data));
3085 BEAST_EXPECT(!info[jss::result].isMember(jss::queue_data));
3092 info.isMember(jss::result) &&
3093 info[jss::result].isMember(jss::account_data));
3094 auto const& result = info[jss::result];
3095 BEAST_EXPECT(result.isMember(jss::queue_data));
3096 auto const& queue_data = result[jss::queue_data];
3097 BEAST_EXPECT(queue_data.isObject());
3098 BEAST_EXPECT(queue_data.isMember(jss::txn_count));
3099 BEAST_EXPECT(queue_data[jss::txn_count] == 0);
3100 BEAST_EXPECT(!queue_data.isMember(jss::lowest_sequence));
3101 BEAST_EXPECT(!queue_data.isMember(jss::highest_sequence));
3102 BEAST_EXPECT(!queue_data.isMember(jss::auth_change_queued));
3103 BEAST_EXPECT(!queue_data.isMember(jss::max_spend_drops_total));
3104 BEAST_EXPECT(!queue_data.isMember(jss::transactions));
3115 info.isMember(jss::result) &&
3116 info[jss::result].isMember(jss::account_data));
3117 auto const& result = info[jss::result];
3118 BEAST_EXPECT(result.isMember(jss::queue_data));
3119 auto const& queue_data = result[jss::queue_data];
3120 BEAST_EXPECT(queue_data.isObject());
3121 BEAST_EXPECT(queue_data.isMember(jss::txn_count));
3122 BEAST_EXPECT(queue_data[jss::txn_count] == 0);
3123 BEAST_EXPECT(!queue_data.isMember(jss::lowest_sequence));
3124 BEAST_EXPECT(!queue_data.isMember(jss::highest_sequence));
3125 BEAST_EXPECT(!queue_data.isMember(jss::auth_change_queued));
3126 BEAST_EXPECT(!queue_data.isMember(jss::max_spend_drops_total));
3127 BEAST_EXPECT(!queue_data.isMember(jss::transactions));
3145 info.isMember(jss::result) &&
3146 info[jss::result].isMember(jss::account_data));
3147 auto const& result = info[jss::result];
3148 auto const&
data = result[jss::account_data];
3149 BEAST_EXPECT(result.isMember(jss::queue_data));
3150 auto const& queue_data = result[jss::queue_data];
3151 BEAST_EXPECT(queue_data.isObject());
3152 BEAST_EXPECT(queue_data.isMember(jss::txn_count));
3153 BEAST_EXPECT(queue_data[jss::txn_count] == 4);
3154 BEAST_EXPECT(queue_data.isMember(jss::lowest_sequence));
3156 queue_data[jss::lowest_sequence] ==
data[jss::Sequence]);
3157 BEAST_EXPECT(queue_data.isMember(jss::highest_sequence));
3159 queue_data[jss::highest_sequence] ==
3160 data[jss::Sequence].asUInt() +
3161 queue_data[jss::txn_count].asUInt() - 1);
3162 BEAST_EXPECT(queue_data.isMember(jss::auth_change_queued));
3163 BEAST_EXPECT(queue_data[jss::auth_change_queued] ==
false);
3164 BEAST_EXPECT(queue_data.isMember(jss::max_spend_drops_total));
3166 queue_data[jss::max_spend_drops_total] ==
3168 BEAST_EXPECT(queue_data.isMember(jss::transactions));
3169 auto const& queued = queue_data[jss::transactions];
3170 BEAST_EXPECT(queued.size() == queue_data[jss::txn_count]);
3171 for (
unsigned i = 0; i < queued.size(); ++i)
3173 auto const& item = queued[i];
3174 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3176 item[jss::fee_level] ==
3178 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3180 BEAST_EXPECT(item.isMember(jss::fee));
3182 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3185 BEAST_EXPECT(item.isMember(jss::auth_change));
3186 BEAST_EXPECT(item[jss::auth_change].asBool() ==
false);
3201 json(jss::LastLedgerSequence, 10),
3209 info.isMember(jss::result) &&
3210 info[jss::result].isMember(jss::account_data));
3211 auto const& result = info[jss::result];
3212 auto const&
data = result[jss::account_data];
3213 BEAST_EXPECT(result.isMember(jss::queue_data));
3214 auto const& queue_data = result[jss::queue_data];
3215 BEAST_EXPECT(queue_data.isObject());
3216 BEAST_EXPECT(queue_data.isMember(jss::txn_count));
3217 BEAST_EXPECT(queue_data[jss::txn_count] == 1);
3218 BEAST_EXPECT(queue_data.isMember(jss::lowest_sequence));
3220 queue_data[jss::lowest_sequence] ==
data[jss::Sequence]);
3221 BEAST_EXPECT(queue_data.isMember(jss::highest_sequence));
3223 queue_data[jss::highest_sequence] ==
3224 data[jss::Sequence].asUInt() +
3225 queue_data[jss::txn_count].asUInt() - 1);
3226 BEAST_EXPECT(queue_data.isMember(jss::auth_change_queued));
3227 BEAST_EXPECT(queue_data[jss::auth_change_queued] ==
true);
3228 BEAST_EXPECT(queue_data.isMember(jss::max_spend_drops_total));
3230 queue_data[jss::max_spend_drops_total] ==
3232 BEAST_EXPECT(queue_data.isMember(jss::transactions));
3233 auto const& queued = queue_data[jss::transactions];
3234 BEAST_EXPECT(queued.size() == queue_data[jss::txn_count]);
3235 for (
unsigned i = 0; i < queued.size(); ++i)
3237 auto const& item = queued[i];
3238 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3240 item[jss::fee_level] ==
3242 BEAST_EXPECT(item.isMember(jss::fee));
3244 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3247 BEAST_EXPECT(item.isMember(jss::auth_change));
3249 if (i == queued.size() - 1)
3251 BEAST_EXPECT(item[jss::auth_change].asBool() ==
true);
3252 BEAST_EXPECT(item.isMember(jss::LastLedgerSequence));
3253 BEAST_EXPECT(item[jss::LastLedgerSequence] == 10);
3257 BEAST_EXPECT(item[jss::auth_change].asBool() ==
false);
3258 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3274 info.isMember(jss::result) &&
3275 info[jss::result].isMember(jss::account_data));
3276 auto const& result = info[jss::result];
3277 auto const&
data = result[jss::account_data];
3278 BEAST_EXPECT(result.isMember(jss::queue_data));
3279 auto const& queue_data = result[jss::queue_data];
3280 BEAST_EXPECT(queue_data.isObject());
3281 BEAST_EXPECT(queue_data.isMember(jss::txn_count));
3282 BEAST_EXPECT(queue_data[jss::txn_count] == 1);
3283 BEAST_EXPECT(queue_data.isMember(jss::lowest_sequence));
3285 queue_data[jss::lowest_sequence] ==
data[jss::Sequence]);
3286 BEAST_EXPECT(queue_data.isMember(jss::highest_sequence));
3288 queue_data[jss::highest_sequence] ==
3289 data[jss::Sequence].asUInt() +
3290 queue_data[jss::txn_count].asUInt() - 1);
3291 BEAST_EXPECT(queue_data.isMember(jss::auth_change_queued));
3292 BEAST_EXPECT(queue_data[jss::auth_change_queued].asBool());
3293 BEAST_EXPECT(queue_data.isMember(jss::max_spend_drops_total));
3295 queue_data[jss::max_spend_drops_total] ==
3297 BEAST_EXPECT(queue_data.isMember(jss::transactions));
3298 auto const& queued = queue_data[jss::transactions];
3299 BEAST_EXPECT(queued.size() == queue_data[jss::txn_count]);
3300 for (
unsigned i = 0; i < queued.size(); ++i)
3302 auto const& item = queued[i];
3303 BEAST_EXPECT(item[jss::seq] ==
data[jss::Sequence].asInt() + i);
3305 item[jss::fee_level] ==
3308 if (i == queued.size() - 1)
3310 BEAST_EXPECT(item.isMember(jss::fee));
3313 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3315 item[jss::max_spend_drops] ==
3317 BEAST_EXPECT(item.isMember(jss::auth_change));
3318 BEAST_EXPECT(item[jss::auth_change].asBool());
3319 BEAST_EXPECT(item.isMember(jss::LastLedgerSequence));
3320 BEAST_EXPECT(item[jss::LastLedgerSequence] == 10);
3324 BEAST_EXPECT(item.isMember(jss::fee));
3327 BEAST_EXPECT(item.isMember(jss::max_spend_drops));
3329 item[jss::max_spend_drops] ==
3331 BEAST_EXPECT(item.isMember(jss::auth_change));
3332 BEAST_EXPECT(!item[jss::auth_change].asBool());
3333 BEAST_EXPECT(!item.isMember(jss::LastLedgerSequence));
3340 env.
rpc(
"json",
"account_info",
to_string(prevLedgerWithQueue));
3342 info.isMember(jss::result) &&
3355 info.isMember(jss::result) &&
3356 info[jss::result].isMember(jss::account_data));
3357 auto const& result = info[jss::result];
3358 BEAST_EXPECT(result.isMember(jss::queue_data));
3359 auto const& queue_data = result[jss::queue_data];
3360 BEAST_EXPECT(queue_data.isObject());
3361 BEAST_EXPECT(queue_data.isMember(jss::txn_count));
3362 BEAST_EXPECT(queue_data[jss::txn_count] == 0);
3363 BEAST_EXPECT(!queue_data.isMember(jss::lowest_sequence));
3364 BEAST_EXPECT(!queue_data.isMember(jss::highest_sequence));
3365 BEAST_EXPECT(!queue_data.isMember(jss::auth_change_queued));
3366 BEAST_EXPECT(!queue_data.isMember(jss::max_spend_drops_total));
3367 BEAST_EXPECT(!queue_data.isMember(jss::transactions));
3374 using namespace jtx;
3377 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
3378 auto const baseFee = env.
current()->fees().base.drops();
3382 env.
fund(
XRP(1000000), alice);
3386 auto const server_info = env.
rpc(
"server_info");
3388 server_info.isMember(jss::result) &&
3389 server_info[jss::result].isMember(jss::info));
3390 auto const& info = server_info[jss::result][jss::info];
3392 info.isMember(jss::load_factor) && info[jss::load_factor] == 1);
3393 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3394 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3395 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3396 BEAST_EXPECT(!info.isMember(jss::load_factor_fee_escalation));
3399 auto const server_state = env.
rpc(
"server_state");
3400 auto const& state = server_state[jss::result][jss::state];
3402 state.isMember(jss::load_factor) &&
3403 state[jss::load_factor] == 256);
3405 state.isMember(jss::load_base) && state[jss::load_base] == 256);
3407 state.isMember(jss::load_factor_server) &&
3408 state[jss::load_factor_server] == 256);
3410 state.isMember(jss::load_factor_fee_escalation) &&
3411 state[jss::load_factor_fee_escalation] == 256);
3413 state.isMember(jss::load_factor_fee_queue) &&
3414 state[jss::load_factor_fee_queue] == 256);
3416 state.isMember(jss::load_factor_fee_reference) &&
3417 state[jss::load_factor_fee_reference] == 256);
3425 auto aliceSeq = env.
seq(alice);
3427 for (
auto i = 0; i < 4; ++i)
3436 auto const server_info = env.
rpc(
"server_info");
3438 server_info.isMember(jss::result) &&
3439 server_info[jss::result].isMember(jss::info));
3440 auto const& info = server_info[jss::result][jss::info];
3443 info.isMember(jss::load_factor) &&
3444 info[jss::load_factor] > 888.88 &&
3445 info[jss::load_factor] < 888.89);
3447 info.isMember(jss::load_factor_server) &&
3448 info[jss::load_factor_server] == 1);
3449 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3450 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3452 info.isMember(jss::load_factor_fee_escalation) &&
3453 info[jss::load_factor_fee_escalation] > 888.88 &&
3454 info[jss::load_factor_fee_escalation] < 888.89);
3457 auto const server_state = env.
rpc(
"server_state");
3458 auto const& state = server_state[jss::result][jss::state];
3460 state.isMember(jss::load_factor) &&
3461 state[jss::load_factor] == 227555);
3463 state.isMember(jss::load_base) && state[jss::load_base] == 256);
3465 state.isMember(jss::load_factor_server) &&
3466 state[jss::load_factor_server] == 256);
3468 state.isMember(jss::load_factor_fee_escalation) &&
3469 state[jss::load_factor_fee_escalation] == 227555);
3471 state.isMember(jss::load_factor_fee_queue) &&
3472 state[jss::load_factor_fee_queue] == 256);
3474 state.isMember(jss::load_factor_fee_reference) &&
3475 state[jss::load_factor_fee_reference] == 256);
3481 auto const server_info = env.
rpc(
"server_info");
3483 server_info.isMember(jss::result) &&
3484 server_info[jss::result].isMember(jss::info));
3485 auto const& info = server_info[jss::result][jss::info];
3488 info.isMember(jss::load_factor) &&
3489 info[jss::load_factor] == 1000);
3490 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3491 BEAST_EXPECT(!info.isMember(jss::load_factor_local));
3493 info.isMember(jss::load_factor_net) &&
3494 info[jss::load_factor_net] == 1000);
3496 info.isMember(jss::load_factor_fee_escalation) &&
3497 info[jss::load_factor_fee_escalation] > 888.88 &&
3498 info[jss::load_factor_fee_escalation] < 888.89);
3501 auto const server_state = env.
rpc(
"server_state");
3502 auto const& state = server_state[jss::result][jss::state];
3504 state.isMember(jss::load_factor) &&
3505 state[jss::load_factor] == 256000);
3507 state.isMember(jss::load_base) && state[jss::load_base] == 256);
3509 state.isMember(jss::load_factor_server) &&
3510 state[jss::load_factor_server] == 256000);
3512 state.isMember(jss::load_factor_fee_escalation) &&
3513 state[jss::load_factor_fee_escalation] == 227555);
3515 state.isMember(jss::load_factor_fee_queue) &&
3516 state[jss::load_factor_fee_queue] == 256);
3518 state.isMember(jss::load_factor_fee_reference) &&
3519 state[jss::load_factor_fee_reference] == 256);
3525 for (
int i = 0; i < 5; ++i)
3530 auto const server_info = env.
rpc(
"server_info");
3532 server_info.isMember(jss::result) &&
3533 server_info[jss::result].isMember(jss::info));
3534 auto const& info = server_info[jss::result][jss::info];
3537 info.isMember(jss::load_factor) &&
3538 info[jss::load_factor] > 888.88 &&
3539 info[jss::load_factor] < 888.89);
3544 info.isMember(jss::load_factor_server) &&
3545 info[jss::load_factor_server] > 1.245 &&
3546 info[jss::load_factor_server] < 2.4415);
3548 info.isMember(jss::load_factor_local) &&
3549 info[jss::load_factor_local] > 1.245 &&
3550 info[jss::load_factor_local] < 2.4415);
3551 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3553 info.isMember(jss::load_factor_fee_escalation) &&
3554 info[jss::load_factor_fee_escalation] > 888.88 &&
3555 info[jss::load_factor_fee_escalation] < 888.89);
3558 auto const server_state = env.
rpc(
"server_state");
3559 auto const& state = server_state[jss::result][jss::state];
3561 state.isMember(jss::load_factor) &&
3562 state[jss::load_factor] == 227555);
3564 state.isMember(jss::load_base) && state[jss::load_base] == 256);
3569 state.isMember(jss::load_factor_server) &&
3570 state[jss::load_factor_server] >= 320 &&
3571 state[jss::load_factor_server] <= 625);
3573 state.isMember(jss::load_factor_fee_escalation) &&
3574 state[jss::load_factor_fee_escalation] == 227555);
3576 state.isMember(jss::load_factor_fee_queue) &&
3577 state[jss::load_factor_fee_queue] == 256);
3579 state.isMember(jss::load_factor_fee_reference) &&
3580 state[jss::load_factor_fee_reference] == 256);
3586 auto const server_info = env.
rpc(
"server_info");
3588 server_info.isMember(jss::result) &&
3589 server_info[jss::result].isMember(jss::info));
3590 auto const& info = server_info[jss::result][jss::info];
3597 info.isMember(jss::load_factor) &&
3598 info[jss::load_factor] > 1.245 &&
3599 info[jss::load_factor] < 2.4415);
3600 BEAST_EXPECT(!info.isMember(jss::load_factor_server));
3602 info.isMember(jss::load_factor_local) &&
3603 info[jss::load_factor_local] > 1.245 &&
3604 info[jss::load_factor_local] < 2.4415);
3605 BEAST_EXPECT(!info.isMember(jss::load_factor_net));
3606 BEAST_EXPECT(!info.isMember(jss::load_factor_fee_escalation));
3609 auto const server_state = env.
rpc(
"server_state");
3610 auto const& state = server_state[jss::result][jss::state];
3612 state.isMember(jss::load_factor) &&
3613 state[jss::load_factor] >= 320 &&
3614 state[jss::load_factor] <= 625);
3616 state.isMember(jss::load_base) && state[jss::load_base] == 256);
3621 state.isMember(jss::load_factor_server) &&
3622 state[jss::load_factor_server] >= 320 &&
3623 state[jss::load_factor_server] <= 625);
3625 state.isMember(jss::load_factor_fee_escalation) &&
3626 state[jss::load_factor_fee_escalation] == 256);
3628 state.isMember(jss::load_factor_fee_queue) &&
3629 state[jss::load_factor_fee_queue] == 256);
3631 state.isMember(jss::load_factor_fee_reference) &&
3632 state[jss::load_factor_fee_reference] == 256);
3639 using namespace jtx;
3642 Env env(*
this,
makeConfig({{
"minimum_txn_in_ledger_standalone",
"3"}}));
3643 auto const baseFee = env.
current()->fees().base.drops();
3647 stream[jss::streams].append(
"server");
3650 auto jv = wsc->invoke(
"subscribe", stream);
3651 BEAST_EXPECT(jv[jss::status] ==
"success");
3654 Account a{
"a"}, b{
"b"}, c{
"c"}, d{
"d"}, e{
"e"}, f{
"f"}, g{
"g"}, h{
"h"},
3662 using namespace std::chrono_literals;
3663 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3664 return jv[jss::type] ==
"serverStatus" &&
3665 jv.isMember(jss::load_factor) && jv[jss::load_factor] == 256 &&
3666 jv.isMember(jss::load_base) && jv[jss::load_base] == 256 &&
3667 jv.isMember(jss::load_factor_server) &&
3668 jv[jss::load_factor_server] == 256 &&
3669 jv.isMember(jss::load_factor_fee_escalation) &&
3670 jv[jss::load_factor_fee_escalation] == 256 &&
3671 jv.isMember(jss::load_factor_fee_queue) &&
3672 jv[jss::load_factor_fee_queue] == 256 &&
3673 jv.isMember(jss::load_factor_fee_reference) &&
3674 jv[jss::load_factor_fee_reference] == 256;
3677 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3678 return jv[jss::type] ==
"serverStatus" &&
3679 jv.isMember(jss::load_factor) &&
3680 jv[jss::load_factor] == 227555 && jv.isMember(jss::load_base) &&
3681 jv[jss::load_base] == 256 &&
3682 jv.isMember(jss::load_factor_server) &&
3683 jv[jss::load_factor_server] == 256 &&
3684 jv.isMember(jss::load_factor_fee_escalation) &&
3685 jv[jss::load_factor_fee_escalation] == 227555 &&
3686 jv.isMember(jss::load_factor_fee_queue) &&
3687 jv[jss::load_factor_fee_queue] == 256 &&
3688 jv.isMember(jss::load_factor_fee_reference) &&
3689 jv[jss::load_factor_fee_reference] == 256;
3695 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3696 return jv[jss::type] ==
"serverStatus" &&
3697 jv.isMember(jss::load_factor) && jv[jss::load_factor] == 256 &&
3698 jv.isMember(jss::load_base) && jv[jss::load_base] == 256 &&
3699 jv.isMember(jss::load_factor_server) &&
3700 jv[jss::load_factor_server] == 256 &&
3701 jv.isMember(jss::load_factor_fee_escalation) &&
3702 jv[jss::load_factor_fee_escalation] == 256 &&
3703 jv.isMember(jss::load_factor_fee_queue) &&
3704 jv[jss::load_factor_fee_queue] == 256 &&
3705 jv.isMember(jss::load_factor_fee_reference) &&
3706 jv[jss::load_factor_fee_reference] == 256;
3716 env(
noop(a),
fee(baseFee), queued);
3717 env(
noop(b),
fee(baseFee), queued);
3718 env(
noop(c),
fee(baseFee), queued);
3719 env(
noop(d),
fee(baseFee), queued);
3720 env(
noop(e),
fee(baseFee), queued);
3721 env(
noop(f),
fee(baseFee), queued);
3722 env(
noop(g),
fee(baseFee), queued);
3726 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3727 return jv[jss::type] ==
"serverStatus" &&
3728 jv.isMember(jss::load_factor) &&
3729 jv[jss::load_factor] == 200000 && jv.isMember(jss::load_base) &&
3730 jv[jss::load_base] == 256 &&
3731 jv.isMember(jss::load_factor_server) &&
3732 jv[jss::load_factor_server] == 256 &&
3733 jv.isMember(jss::load_factor_fee_escalation) &&
3734 jv[jss::load_factor_fee_escalation] == 200000 &&
3735 jv.isMember(jss::load_factor_fee_queue) &&
3736 jv[jss::load_factor_fee_queue] == 256 &&
3737 jv.isMember(jss::load_factor_fee_reference) &&
3738 jv[jss::load_factor_fee_reference] == 256;
3743 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3744 return jv[jss::type] ==
"serverStatus" &&
3745 jv.isMember(jss::load_factor) &&
3746 jv[jss::load_factor] == 184320 && jv.isMember(jss::load_base) &&
3747 jv[jss::load_base] == 256 &&
3748 jv.isMember(jss::load_factor_server) &&
3749 jv[jss::load_factor_server] == 256 &&
3750 jv.isMember(jss::load_factor_fee_escalation) &&
3751 jv[jss::load_factor_fee_escalation] == 184320 &&
3752 jv.isMember(jss::load_factor_fee_queue) &&
3753 jv[jss::load_factor_fee_queue] == 256 &&
3754 jv.isMember(jss::load_factor_fee_reference) &&
3755 jv[jss::load_factor_fee_reference] == 256;
3760 BEAST_EXPECT(wsc->findMsg(5s, [&](
auto const& jv) {
3761 return jv[jss::type] ==
"serverStatus" &&
3762 jv.isMember(jss::load_factor) && jv[jss::load_factor] == 256 &&
3763 jv.isMember(jss::load_base) && jv[jss::load_base] == 256 &&
3764 jv.isMember(jss::load_factor_server) &&
3765 jv[jss::load_factor_server] == 256 &&
3766 jv.isMember(jss::load_factor_fee_escalation) &&
3767 jv[jss::load_factor_fee_escalation] == 256 &&
3768 jv.isMember(jss::load_factor_fee_queue) &&
3769 jv[jss::load_factor_fee_queue] == 256 &&
3770 jv.isMember(jss::load_factor_fee_reference) &&
3771 jv[jss::load_factor_fee_reference] == 256;
3774 BEAST_EXPECT(!wsc->findMsg(1s, [&](
auto const& jv) {
3775 return jv[jss::type] ==
"serverStatus";
3778 auto jv = wsc->invoke(
"unsubscribe", stream);
3779 BEAST_EXPECT(jv[jss::status] ==
"success");
4014 using namespace jtx;
4015 using namespace std::chrono_literals;
4022 {{
"minimum_txn_in_ledger_standalone",
"3"},
4023 {
"normal_consensus_increase_percent",
"25"},
4024 {
"slow_consensus_decrease_percent",
"50"},
4025 {
"target_txn_in_ledger",
"10"},
4026 {
"maximum_txn_per_account",
"200"}}));
4027 auto alice =
Account(
"alice");
4030 env.
fund(
XRP(50000000), alice);
4034 auto seqAlice = env.
seq(alice);
4036 for (
int i = 0; i < txCount; ++i)
4080 env.
close(env.
now() + 5s, 10000ms);
4085 env.
close(env.
now() + 5s, 10000ms);
4090 env.
close(env.
now() + 5s, 10000ms);
4097 env.
close(env.
now() + 5s, 10000ms);
4101 BEAST_EXPECT(!txCount);
4108 {{
"minimum_txn_in_ledger_standalone",
"3"},
4109 {
"normal_consensus_increase_percent",
"150"},
4110 {
"slow_consensus_decrease_percent",
"150"},
4111 {
"target_txn_in_ledger",
"10"},
4112 {
"maximum_txn_per_account",
"200"}}));
4113 auto alice =
Account(
"alice");
4116 env.
fund(
XRP(50000000), alice);
4120 auto seqAlice = env.
seq(alice);
4122 for (
int i = 0; i < txCount; ++i)
4141 env.
close(env.
now() + 5s, 10000ms);
4147 BEAST_EXPECT(!txCount);
4324 using namespace jtx;
4333 constexpr int ledgersInQueue = 10;
4335 {{
"minimum_txn_in_ledger_standalone",
"1"},
4337 {
"maximum_txn_per_account",
"10"}},
4338 {{
"account_reserve",
"1000"}, {
"owner_reserve",
"50"}});
4340 auto& votingSection = cfg->section(
"voting");
4346 "reference_fee",
std::to_string(cfg->FEES.reference_fee.drops()));
4348 Env env(*
this, std::move(cfg));
4364 checkMetrics(*
this, env, 0, ledgersInQueue * metrics.txPerLedger, 0, 2);
4368 for (i = 0; i <= 257; ++i)
4379 ledgersInQueue * expectedPerLedger,
4386 using namespace std::chrono_literals;
4387 auto closeDuration = 80min;
4388 for (i = 0; i <= 255; ++i)
4390 env.
close(closeDuration);
4393 auto const baseFee = env.
current()->fees().base.drops();
4400 ledgersInQueue * expectedPerLedger,
4401 expectedPerLedger + 1,
4405 auto seqAlice = env.
seq(alice);
4406 auto seqBob = env.
seq(bob);
4407 auto seqCarol = env.
seq(carol);
4408 auto seqDaria = env.
seq(daria);
4409 auto seqEllie = env.
seq(ellie);
4410 auto seqFiona = env.
seq(fiona);
4413 int txFee{
static_cast<int>(baseFee * 9)};
4414 auto prepareFee = [&](
uint64_t multiplier) {
4415 return fee(txFee - multiplier * baseFee / 10);
4419 for (
int i = 0; i < 10; ++i)
4423 prepareFee(++multiplier),
4427 prepareFee(++multiplier),
4431 prepareFee(++multiplier),
4435 prepareFee(++multiplier),
4439 prepareFee(++multiplier),
4443 prepareFee(++multiplier),
4451 ledgersInQueue * expectedPerLedger,
4452 expectedPerLedger + 1,
4466 env.
close(closeDuration);
4467 auto expectedInLedger = expectedInQueue;
4469 (expectedInQueue > expectedPerLedger + 2
4470 ? expectedInQueue - (expectedPerLedger + 2)
4472 expectedInLedger -= expectedInQueue;
4473 ++expectedPerLedger;
4478 ledgersInQueue * expectedPerLedger,
4482 auto const expectedPerAccount = expectedInQueue / 6;
4483 auto const expectedRemainder = expectedInQueue % 6;
4484 BEAST_EXPECT(env.
seq(alice) == seqAlice - expectedPerAccount);
4487 seqBob - expectedPerAccount -
4488 (expectedRemainder > 4 ? 1 : 0));
4491 seqCarol - expectedPerAccount -
4492 (expectedRemainder > 3 ? 1 : 0));
4495 seqDaria - expectedPerAccount -
4496 (expectedRemainder > 2 ? 1 : 0));
4499 seqEllie - expectedPerAccount -
4500 (expectedRemainder > 1 ? 1 : 0));
4503 seqFiona - expectedPerAccount -
4504 (expectedRemainder > 0 ? 1 : 0));
4506 }
while (expectedInQueue > 0);
4870 using namespace jtx;
4878 {{
"minimum_txn_in_ledger_standalone",
"3"}},
4879 {{
"reference_fee",
"0"},
4880 {
"account_reserve",
"0"},
4881 {
"owner_reserve",
"0"}}));
4886 auto const initQueueMax =
initFee(env, 3, 2, 0, 0, 0);
4888 BEAST_EXPECT(env.
current()->fees().base == 0);
4891 auto const fee = env.
rpc(
"fee");
4893 if (BEAST_EXPECT(
fee.isMember(jss::result)) &&
4896 auto const& result =
fee[jss::result];
4898 BEAST_EXPECT(result.isMember(jss::levels));
4899 auto const& levels = result[jss::levels];
4901 levels.isMember(jss::median_level) &&
4902 levels[jss::median_level] ==
"128000");
4904 levels.isMember(jss::minimum_level) &&
4905 levels[jss::minimum_level] ==
"256");
4907 levels.isMember(jss::open_ledger_level) &&
4908 levels[jss::open_ledger_level] ==
"256");
4910 levels.isMember(jss::reference_level) &&
4911 levels[jss::reference_level] ==
"256");
4913 auto const&
drops = result[jss::drops];
4915 drops.isMember(jss::base_fee) &&
4916 drops[jss::base_fee] ==
"0");
4918 drops.isMember(jss::median_fee) &&
4919 drops[jss::median_fee] ==
"0");
4921 drops.isMember(jss::minimum_fee) &&
4922 drops[jss::minimum_fee] ==
"0");
4924 drops.isMember(jss::open_ledger_fee) &&
4925 drops[jss::open_ledger_fee] ==
"0");
4949 auto aliceSeq = env.
seq(alice);
4950 env(
noop(alice), queued);
4954 env(
noop(alice),
seq(aliceSeq + 1),
fee(10), queued);
4959 auto const fee = env.
rpc(
"fee");
4961 if (BEAST_EXPECT(
fee.isMember(jss::result)) &&
4964 auto const& result =
fee[jss::result];
4966 BEAST_EXPECT(result.isMember(jss::levels));
4967 auto const& levels = result[jss::levels];
4969 levels.isMember(jss::median_level) &&
4970 levels[jss::median_level] ==
"128000");
4972 levels.isMember(jss::minimum_level) &&
4973 levels[jss::minimum_level] ==
"256");
4975 levels.isMember(jss::open_ledger_level) &&
4976 levels[jss::open_ledger_level] ==
"355555");
4978 levels.isMember(jss::reference_level) &&
4979 levels[jss::reference_level] ==
"256");
4981 auto const&
drops = result[jss::drops];
4983 drops.isMember(jss::base_fee) &&
4984 drops[jss::base_fee] ==
"0");
4986 drops.isMember(jss::median_fee) &&
4987 drops[jss::median_fee] ==
"0");
4989 drops.isMember(jss::minimum_fee) &&
4990 drops[jss::minimum_fee] ==
"0");
4992 drops.isMember(jss::open_ledger_fee) &&
4993 drops[jss::open_ledger_fee] ==
"1389");