20 #include <ripple/app/ledger/BuildLedger.h>
21 #include <ripple/app/ledger/LedgerMaster.h>
22 #include <ripple/app/ledger/LedgerReplay.h>
23 #include <ripple/app/ledger/LedgerReplayTask.h>
24 #include <ripple/app/ledger/LedgerReplayer.h>
25 #include <ripple/app/ledger/impl/LedgerDeltaAcquire.h>
26 #include <ripple/app/ledger/impl/LedgerReplayMsgHandler.h>
27 #include <ripple/app/ledger/impl/SkipListAcquire.h>
28 #include <ripple/basics/Slice.h>
29 #include <ripple/overlay/PeerSet.h>
30 #include <ripple/overlay/impl/PeerImp.h>
32 #include <test/jtx/envconfig.h>
45 testcase(
"Replay ledger");
50 auto const alice =
Account(
"alice");
51 auto const bob =
Account(
"bob");
54 env.
fund(
XRP(100000), alice, bob);
59 auto const lastClosedParent =
60 ledgerMaster.getLedgerByHash(lastClosed->info().parentHash);
68 BEAST_EXPECT(replayed->info().hash == lastClosed->info().hash);
89 : ledgerSource(ledgerSource), ledgerSink(ledgerSink), bhvr(bhvr)
100 if (
auto l = ledgerSource.getLedgerByHash(hash); l)
102 ledgerSink.storeLedger(l);
194 TestPeer(
bool enableLedgerReplay) : ledgerReplayEnabled_(enableLedgerReplay)
334 bool enableLedgerReplay)
337 , dummyPeer(
std::make_shared<
TestPeer>(enableLedgerReplay))
349 onPeerAdded(dummyPeer);
354 ::google::protobuf::Message
const& msg,
355 protocol::MessageType type,
364 if ((rand() % 100 + 1) <= dropRate)
369 case protocol::mtPROOF_PATH_REQ: {
372 auto request = std::make_shared<protocol::TMProofPathRequest>(
373 dynamic_cast<protocol::TMProofPathRequest const&
>(msg));
374 auto reply = std::make_shared<protocol::TMProofPathResponse>(
375 remote.processProofPathRequest(request));
376 local.processProofPathResponse(reply);
378 local.processProofPathResponse(reply);
381 case protocol::mtREPLAY_DELTA_REQ: {
384 auto request = std::make_shared<protocol::TMReplayDeltaRequest>(
385 dynamic_cast<protocol::TMReplayDeltaRequest const&
>(msg));
386 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
387 remote.processReplayDeltaRequest(request));
388 local.processReplayDeltaResponse(reply);
390 local.processReplayDeltaResponse(reply);
432 return std::make_unique<TestPeerSet>(
433 local, remote, behavior, enableLedgerReplay);
452 int initAccounts = 10;
453 int initAmount = 1
'000'000;
454 int numTxPerLedger = 10;
462 , msgHandler(env.app(), env.app().getLedgerReplayer())
465 assert(param.initLedgers > 0);
466 createAccounts(param.initAccounts);
467 createLedgerHistory();
468 app.logs().threshold(beast::severities::Severity::kWarning);
477 auto fundedAccounts = accounts.size();
478 for (
int i = 0; i < newAccounts; ++i)
480 accounts.emplace_back(
482 env.fund(
jtx::XRP(param.initAmount), accounts.back());
493 int fundedAccounts = accounts.size();
494 assert(fundedAccounts >= newTxes);
501 auto updateIdx = [&]() {
502 assert(fundedAccounts > senders.
size());
503 fromIdx = (fromIdx + r) % fundedAccounts;
504 while (senders.
count(fromIdx) != 0)
505 fromIdx = (fromIdx + 1) % fundedAccounts;
507 toIdx = (toIdx + r * 2) % fundedAccounts;
508 if (toIdx == fromIdx)
509 toIdx = (toIdx + 1) % fundedAccounts;
512 for (
int i = 0; i < newTxes; ++i)
516 pay(accounts[fromIdx],
533 for (
int i = 0; i < param.initLedgers - 1; ++i)
535 sendPayments(param.numTxPerLedger);
565 beast::unit_test::suite& suite,
574 server.app.getLedgerMaster(),
577 , serverMsgHandler(server.app, server.app.getLedgerReplayer())
578 , clientMsgHandler(env.app(), replayer)
599 uint256 hash = finishLedgerHash;
601 for (; i < totalReplay; ++i)
606 hash = l->info().parentHash;
614 int totalRound = 100;
615 for (
int i = 0; i < totalRound; ++i)
617 if (haveLedgers(finishLedgerHash, totalReplay))
619 if (i < totalRound - 1)
628 int totalRound = 100;
629 for (
int i = 0; i < totalRound; ++i)
634 for (
auto const& t : replayer.tasks_)
645 if (i < totalRound - 1)
655 return replayer.tasks_;
663 replayer.tasks_.begin(), replayer.tasks_.end(), [&](
auto const& t) {
664 return t->parameter_.finishHash_ == hash &&
665 t->parameter_.totalLedgers_ == totalReplay;
667 if (i == replayer.tasks_.end())
676 return replayer.deltas_.size();
683 return replayer.skipLists_.size();
693 return replayer.tasks_.size() == tasks &&
694 replayer.skipLists_.size() == skipLists &&
695 replayer.deltas_.size() == deltas;
702 auto i = replayer.skipLists_.find(hash);
703 if (i == replayer.skipLists_.end())
705 return i->second.lock();
712 auto i = replayer.deltas_.find(hash);
713 if (i == replayer.deltas_.end())
715 return i->second.lock();
718 template <
typename T>
736 if (taskStatus(task) == taskExpect)
738 if (taskStatus(task->skipListAcquirer_) == skiplistExpect)
740 if (task->deltas_.size() == deltaExpects.
size())
742 for (
int i = 0; i < deltaExpects.
size(); ++i)
744 if (taskStatus(task->deltas_[i]) != deltaExpects[i])
762 auto t = findTask(hash, totalReplay);
770 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
781 auto t = findTask(hash, totalReplay);
789 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
804 hash, totalReplay, taskExpect, skiplistExpect, deltaExpects);
834 beast::unit_test::suite& suite,
839 : server(suite, param)
840 , client(suite, server, behavior, inboundBhvr, peerFeature)
878 testcase(
"ProofPath");
884 auto request = std::make_shared<protocol::TMProofPathRequest>();
885 request->set_ledgerhash(
886 l->info().hash.data(), l->info().hash.size());
887 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
888 auto reply = std::make_shared<protocol::TMProofPathResponse>(
889 server.msgHandler.processProofPathRequest(request));
890 BEAST_EXPECT(reply->has_error());
891 BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
895 auto request = std::make_shared<protocol::TMProofPathRequest>();
896 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
900 request->set_ledgerhash(hash.
data(), hash.
size());
901 auto reply = std::make_shared<protocol::TMProofPathResponse>(
902 server.msgHandler.processProofPathRequest(request));
903 BEAST_EXPECT(reply->has_error());
908 auto request = std::make_shared<protocol::TMProofPathRequest>();
909 request->set_ledgerhash(
910 l->info().hash.data(), l->info().hash.size());
911 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
915 auto reply = std::make_shared<protocol::TMProofPathResponse>(
916 server.msgHandler.processProofPathRequest(request));
917 BEAST_EXPECT(!reply->has_error());
918 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
925 reply->set_ledgerheader(r);
927 !server.msgHandler.processProofPathResponse(reply));
929 reply->set_ledgerheader(r);
930 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
932 reply->mutable_path()->RemoveLast();
934 !server.msgHandler.processProofPathResponse(reply));
942 testcase(
"ReplayDelta");
948 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
949 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
950 server.msgHandler.processReplayDeltaRequest(request));
951 BEAST_EXPECT(reply->has_error());
952 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
955 request->set_ledgerhash(hash.
data(), hash.
size());
956 reply = std::make_shared<protocol::TMReplayDeltaResponse>(
957 server.msgHandler.processReplayDeltaRequest(request));
958 BEAST_EXPECT(reply->has_error());
959 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
964 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
965 request->set_ledgerhash(
966 l->info().hash.data(), l->info().hash.size());
967 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
968 server.msgHandler.processReplayDeltaRequest(request));
969 BEAST_EXPECT(!reply->has_error());
970 BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
977 reply->set_ledgerheader(r);
979 !server.msgHandler.processReplayDeltaResponse(reply));
981 reply->set_ledgerheader(r);
983 server.msgHandler.processReplayDeltaResponse(reply));
985 reply->mutable_transaction()->RemoveLast();
987 !server.msgHandler.processReplayDeltaResponse(reply));
995 testcase(
"TaskParameter");
999 for (
int i = 0; i < count; ++i)
1006 BEAST_EXPECT(!tp10.
update(
uint256(777), 5, makeSkipList(10)));
1007 BEAST_EXPECT(!tp10.
update(
uint256(10), 5, makeSkipList(8)));
1008 BEAST_EXPECT(tp10.
update(
uint256(10), 10, makeSkipList(10)));
1038 BEAST_EXPECT(tp20.
update(
uint256(20), 20, makeSkipList(20)));
1048 testcase(
"config test");
1078 testcase(
"handshake test");
1079 auto handshake = [&](
bool client,
bool server,
bool expecting) ->
bool {
1083 http_request.version(request.version());
1084 http_request.base() = request.base();
1087 if (serverResult != expecting)
1091 boost::asio::ip::address::from_string(
"172.1.1.100");
1103 auto const clientResult =
1105 if (clientResult != expecting)
1111 BEAST_EXPECT(handshake(
false,
false,
false));
1112 BEAST_EXPECT(handshake(
false,
true,
false));
1113 BEAST_EXPECT(handshake(
true,
false,
false));
1114 BEAST_EXPECT(handshake(
true,
true,
true));
1120 testcase(
"local node has all the ledgers");
1125 NetworkOfTwo net(*
this, {totalReplay + 1}, psBhvr, ilBhvr, peerFeature);
1128 uint256 finalHash = l->info().hash;
1129 for (
int i = 0; i < totalReplay; ++i)
1134 net.client.ledgerMaster.storeLedger(l);
1135 l = net.server.ledgerMaster.getLedgerByHash(
1136 l->info().parentHash);
1142 net.client.replayer.replay(
1147 BEAST_EXPECT(net.client.waitAndCheckStatus(
1155 net.client.replayer.sweep();
1156 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1162 testcase(
"all the ledgers from InboundLedgers");
1171 uint256 finalHash = l->info().hash;
1172 net.client.replayer.replay(
1177 BEAST_EXPECT(net.client.waitAndCheckStatus(
1185 net.client.replayer.sweep();
1186 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1192 switch (peerSetBehavior)
1195 testcase(
"good network");
1198 testcase(
"network drops 50% messages");
1201 testcase(
"network repeats all messages");
1216 uint256 finalHash = l->info().hash;
1217 for (
int i = 0; i < totalReplay - 1; ++i)
1219 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1221 net.client.ledgerMaster.storeLedger(l);
1223 net.client.replayer.replay(
1228 BEAST_EXPECT(net.client.waitAndCheckStatus(
1234 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1237 net.client.replayer.sweep();
1238 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1244 testcase(
"stop before timeout");
1245 int totalReplay = 3;
1254 uint256 finalHash = l->info().hash;
1255 net.client.replayer.replay(
1259 BEAST_EXPECT(net.client.checkStatus(
1266 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1267 net.client.replayer.stop();
1268 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1274 testcase(
"SkipListAcquire bad reply");
1275 int totalReplay = 3;
1278 {totalReplay + 1 + 1},
1284 uint256 finalHash = l->info().hash;
1285 net.client.replayer.replay(
1288 auto skipList = net.client.findSkipListAcquire(finalHash);
1291 0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, 0xB2};
1292 auto item = std::make_shared<SHAMapItem>(
1294 skipList->processData(l->seq(), item);
1297 BEAST_EXPECT(net.client.waitAndCheckStatus(
1305 net.client.replayer.replay(
1307 BEAST_EXPECT(net.client.waitAndCheckStatus(
1313 BEAST_EXPECT(net.client.countsAsExpected(2, 1, 0));
1319 testcase(
"LedgerDeltaAcquire bad reply");
1320 int totalReplay = 3;
1329 uint256 finalHash = l->info().hash;
1330 net.client.ledgerMaster.storeLedger(l);
1331 net.client.replayer.replay(
1334 auto delta = net.client.findLedgerDeltaAcquire(l->info().parentHash);
1340 net.client.taskStatus(net.client.findTask(
1344 net.client.replayer.replay(
1347 net.client.taskStatus(net.client.findTask(
1354 testcase(
"Overlap tasks");
1355 int totalReplay = 5;
1358 {totalReplay * 3 + 1},
1363 uint256 finalHash = l->info().hash;
1364 net.client.replayer.replay(
1368 BEAST_EXPECT(net.client.waitAndCheckStatus(
1374 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1377 net.client.replayer.replay(
1379 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1381 net.client.replayer.replay(
1383 BEAST_EXPECT(net.client.countsAsExpected(2, 1, totalReplay - 1));
1386 for (
int i = 0; i < totalReplay + 2; ++i)
1388 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1390 auto finalHash_early = l->info().hash;
1391 net.client.replayer.replay(
1393 BEAST_EXPECT(net.client.waitAndCheckStatus(
1399 BEAST_EXPECT(net.client.waitForLedgers(finalHash_early, totalReplay));
1400 BEAST_EXPECT(net.client.countsAsExpected(3, 2, 2 * (totalReplay - 1)));
1403 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1404 auto finalHash_moreEarly = l->info().parentHash;
1405 net.client.replayer.replay(
1407 BEAST_EXPECT(net.client.waitAndCheckStatus(
1408 finalHash_moreEarly,
1414 net.client.waitForLedgers(finalHash_moreEarly, totalReplay));
1416 net.client.countsAsExpected(4, 3, 2 * (totalReplay - 1) + 2));
1419 net.client.replayer.replay(
1423 BEAST_EXPECT(net.client.waitAndCheckStatus(
1429 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3));
1430 BEAST_EXPECT(net.client.countsAsExpected(5, 3, totalReplay * 3 - 1));
1433 net.client.replayer.sweep();
1434 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1442 testTaskParameter();
1447 testAllInboundLedgers(1);
1448 testAllInboundLedgers(4);
1454 testSkipListBadReply();
1455 testLedgerDeltaBadReply();
1456 testLedgerReplayOverlap();
1465 testcase(
"SkipListAcquire timeout");
1466 int totalReplay = 3;
1475 uint256 finalHash = l->info().hash;
1476 net.client.replayer.replay(
1480 BEAST_EXPECT(net.client.waitAndCheckStatus(
1488 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1489 net.client.replayer.sweep();
1490 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1496 testcase(
"LedgerDeltaAcquire timeout");
1497 int totalReplay = 3;
1506 uint256 finalHash = l->info().hash;
1507 net.client.ledgerMaster.storeLedger(l);
1508 net.client.replayer.replay(
1514 BEAST_EXPECT(net.client.waitAndCheckStatus(
1522 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1523 net.client.replayer.sweep();
1524 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1530 testSkipListTimeout();
1531 testLedgerDeltaTimeout();
1540 testcase(
"Acquire 1000 ledgers");
1541 int totalReplay = 250;
1545 {totalReplay * rounds + 1},
1551 auto l = net.server.ledgerMaster.getClosedLedger();
1552 for (
int i = 0; i < rounds; ++i)
1555 for (
int j = 0; j < totalReplay; ++j)
1557 l = net.server.ledgerMaster.getLedgerByHash(
1558 l->info().parentHash);
1561 BEAST_EXPECT(finishHashes.size() == rounds);
1563 for (
int i = 0; i < rounds; ++i)
1565 net.client.replayer.replay(
1571 for (
int i = 0; i < rounds; ++i)
1573 BEAST_EXPECT(net.client.waitAndCheckStatus(
1582 net.client.waitForLedgers(finishHashes[0], totalReplay * rounds));
1583 BEAST_EXPECT(net.client.countsAsExpected(
1584 rounds, rounds, rounds * (totalReplay - 1)));
1587 net.client.replayer.sweep();
1588 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));