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)
322 bool enableLedgerReplay)
325 , dummyPeer(
std::make_shared<
TestPeer>(enableLedgerReplay))
337 onPeerAdded(dummyPeer);
342 ::google::protobuf::Message
const& msg,
343 protocol::MessageType type,
352 if ((rand() % 100 + 1) <= dropRate)
357 case protocol::mtPROOF_PATH_REQ: {
360 auto request = std::make_shared<protocol::TMProofPathRequest>(
361 dynamic_cast<protocol::TMProofPathRequest const&
>(msg));
362 auto reply = std::make_shared<protocol::TMProofPathResponse>(
363 remote.processProofPathRequest(request));
364 local.processProofPathResponse(reply);
366 local.processProofPathResponse(reply);
369 case protocol::mtREPLAY_DELTA_REQ: {
372 auto request = std::make_shared<protocol::TMReplayDeltaRequest>(
373 dynamic_cast<protocol::TMReplayDeltaRequest const&
>(msg));
374 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
375 remote.processReplayDeltaRequest(request));
376 local.processReplayDeltaResponse(reply);
378 local.processReplayDeltaResponse(reply);
420 return std::make_unique<TestPeerSet>(
421 local, remote, behavior, enableLedgerReplay);
440 int initAccounts = 10;
441 int initAmount = 1
'000'000;
442 int numTxPerLedger = 10;
450 , msgHandler(env.app(), env.app().getLedgerReplayer())
453 assert(param.initLedgers > 0);
454 createAccounts(param.initAccounts);
455 createLedgerHistory();
456 app.logs().threshold(beast::severities::Severity::kWarning);
465 auto fundedAccounts = accounts.size();
466 for (
int i = 0; i < newAccounts; ++i)
468 accounts.emplace_back(
470 env.fund(
jtx::XRP(param.initAmount), accounts.back());
481 int fundedAccounts = accounts.size();
482 assert(fundedAccounts >= newTxes);
489 auto updateIdx = [&]() {
490 assert(fundedAccounts > senders.
size());
491 fromIdx = (fromIdx + r) % fundedAccounts;
492 while (senders.
count(fromIdx) != 0)
493 fromIdx = (fromIdx + 1) % fundedAccounts;
495 toIdx = (toIdx + r * 2) % fundedAccounts;
496 if (toIdx == fromIdx)
497 toIdx = (toIdx + 1) % fundedAccounts;
500 for (
int i = 0; i < newTxes; ++i)
504 pay(accounts[fromIdx],
521 for (
int i = 0; i < param.initLedgers - 1; ++i)
523 sendPayments(param.numTxPerLedger);
553 beast::unit_test::suite& suite,
562 server.app.getLedgerMaster(),
565 , serverMsgHandler(server.app, server.app.getLedgerReplayer())
566 , clientMsgHandler(env.app(), replayer)
567 , stopableParent(
"replayerStopParent")
589 uint256 hash = finishLedgerHash;
591 for (; i < totalReplay; ++i)
596 hash = l->info().parentHash;
604 int totalRound = 100;
605 for (
int i = 0; i < totalRound; ++i)
607 if (haveLedgers(finishLedgerHash, totalReplay))
609 if (i < totalRound - 1)
618 int totalRound = 100;
619 for (
int i = 0; i < totalRound; ++i)
624 for (
auto const& t : replayer.tasks_)
635 if (i < totalRound - 1)
645 return replayer.tasks_;
653 replayer.tasks_.begin(), replayer.tasks_.end(), [&](
auto const& t) {
654 return t->parameter_.finishHash_ == hash &&
655 t->parameter_.totalLedgers_ == totalReplay;
657 if (i == replayer.tasks_.end())
666 return replayer.deltas_.size();
673 return replayer.skipLists_.size();
683 return replayer.tasks_.size() == tasks &&
684 replayer.skipLists_.size() == skipLists &&
685 replayer.deltas_.size() == deltas;
692 auto i = replayer.skipLists_.find(hash);
693 if (i == replayer.skipLists_.end())
695 return i->second.lock();
702 auto i = replayer.deltas_.find(hash);
703 if (i == replayer.deltas_.end())
705 return i->second.lock();
708 template <
typename T>
726 if (taskStatus(task) == taskExpect)
728 if (taskStatus(task->skipListAcquirer_) == skiplistExpect)
730 if (task->deltas_.size() == deltaExpects.
size())
732 for (
int i = 0; i < deltaExpects.
size(); ++i)
734 if (taskStatus(task->deltas_[i]) != deltaExpects[i])
752 auto t = findTask(hash, totalReplay);
760 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
771 auto t = findTask(hash, totalReplay);
779 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
794 hash, totalReplay, taskExpect, skiplistExpect, deltaExpects);
825 beast::unit_test::suite& suite,
830 : server(suite, param)
831 , client(suite, server, behavior, inboundBhvr, peerFeature)
869 testcase(
"ProofPath");
875 auto request = std::make_shared<protocol::TMProofPathRequest>();
876 request->set_ledgerhash(
877 l->info().hash.data(), l->info().hash.size());
878 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
879 auto reply = std::make_shared<protocol::TMProofPathResponse>(
880 server.msgHandler.processProofPathRequest(request));
881 BEAST_EXPECT(reply->has_error());
882 BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
886 auto request = std::make_shared<protocol::TMProofPathRequest>();
887 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
891 request->set_ledgerhash(hash.
data(), hash.
size());
892 auto reply = std::make_shared<protocol::TMProofPathResponse>(
893 server.msgHandler.processProofPathRequest(request));
894 BEAST_EXPECT(reply->has_error());
899 auto request = std::make_shared<protocol::TMProofPathRequest>();
900 request->set_ledgerhash(
901 l->info().hash.data(), l->info().hash.size());
902 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
906 auto reply = std::make_shared<protocol::TMProofPathResponse>(
907 server.msgHandler.processProofPathRequest(request));
908 BEAST_EXPECT(!reply->has_error());
909 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
916 reply->set_ledgerheader(r);
918 !server.msgHandler.processProofPathResponse(reply));
920 reply->set_ledgerheader(r);
921 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
923 reply->mutable_path()->RemoveLast();
925 !server.msgHandler.processProofPathResponse(reply));
933 testcase(
"ReplayDelta");
939 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
940 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
941 server.msgHandler.processReplayDeltaRequest(request));
942 BEAST_EXPECT(reply->has_error());
943 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
946 request->set_ledgerhash(hash.
data(), hash.
size());
947 reply = std::make_shared<protocol::TMReplayDeltaResponse>(
948 server.msgHandler.processReplayDeltaRequest(request));
949 BEAST_EXPECT(reply->has_error());
950 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
955 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
956 request->set_ledgerhash(
957 l->info().hash.data(), l->info().hash.size());
958 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
959 server.msgHandler.processReplayDeltaRequest(request));
960 BEAST_EXPECT(!reply->has_error());
961 BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
968 reply->set_ledgerheader(r);
970 !server.msgHandler.processReplayDeltaResponse(reply));
972 reply->set_ledgerheader(r);
974 server.msgHandler.processReplayDeltaResponse(reply));
976 reply->mutable_transaction()->RemoveLast();
978 !server.msgHandler.processReplayDeltaResponse(reply));
986 testcase(
"TaskParameter");
990 for (
int i = 0; i < count; ++i)
997 BEAST_EXPECT(!tp10.
update(
uint256(777), 5, makeSkipList(10)));
999 BEAST_EXPECT(tp10.
update(
uint256(10), 10, makeSkipList(10)));
1029 BEAST_EXPECT(tp20.
update(
uint256(20), 20, makeSkipList(20)));
1039 testcase(
"config test");
1069 testcase(
"handshake test");
1070 auto handshake = [&](
bool client,
bool server,
bool expecting) ->
bool {
1073 http_request.version(request.version());
1074 http_request.base() = request.base();
1077 if (serverResult != expecting)
1081 boost::asio::ip::address::from_string(
"172.1.1.100");
1093 auto const clientResult =
1095 if (clientResult != expecting)
1101 BEAST_EXPECT(handshake(
false,
false,
false));
1102 BEAST_EXPECT(handshake(
false,
true,
false));
1103 BEAST_EXPECT(handshake(
true,
false,
false));
1104 BEAST_EXPECT(handshake(
true,
true,
true));
1110 testcase(
"local node has all the ledgers");
1115 NetworkOfTwo net(*
this, {totalReplay + 1}, psBhvr, ilBhvr, peerFeature);
1118 uint256 finalHash = l->info().hash;
1119 for (
int i = 0; i < totalReplay; ++i)
1124 net.client.ledgerMaster.storeLedger(l);
1125 l = net.server.ledgerMaster.getLedgerByHash(
1126 l->info().parentHash);
1132 net.client.replayer.replay(
1137 BEAST_EXPECT(net.client.waitAndCheckStatus(
1145 net.client.replayer.sweep();
1146 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1152 testcase(
"all the ledgers from InboundLedgers");
1161 uint256 finalHash = l->info().hash;
1162 net.client.replayer.replay(
1167 BEAST_EXPECT(net.client.waitAndCheckStatus(
1175 net.client.replayer.sweep();
1176 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1182 switch (peerSetBehavior)
1185 testcase(
"good network");
1188 testcase(
"network drops 50% messages");
1191 testcase(
"network repeats all messages");
1206 uint256 finalHash = l->info().hash;
1207 for (
int i = 0; i < totalReplay - 1; ++i)
1209 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1211 net.client.ledgerMaster.storeLedger(l);
1213 net.client.replayer.replay(
1218 BEAST_EXPECT(net.client.waitAndCheckStatus(
1224 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1227 net.client.replayer.sweep();
1228 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1234 testcase(
"onStop before timeout");
1235 int totalReplay = 3;
1244 uint256 finalHash = l->info().hash;
1245 net.client.replayer.replay(
1249 BEAST_EXPECT(net.client.checkStatus(
1257 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1258 net.client.replayer.onStop();
1259 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1265 testcase(
"SkipListAcquire bad reply");
1266 int totalReplay = 3;
1269 {totalReplay + 1 + 1},
1275 uint256 finalHash = l->info().hash;
1276 net.client.replayer.replay(
1279 auto skipList = net.client.findSkipListAcquire(finalHash);
1282 0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, 0xB2};
1283 auto item = std::make_shared<SHAMapItem>(
1285 skipList->processData(l->seq(), item);
1288 BEAST_EXPECT(net.client.waitAndCheckStatus(
1296 net.client.replayer.replay(
1298 BEAST_EXPECT(net.client.waitAndCheckStatus(
1304 BEAST_EXPECT(net.client.countsAsExpected(2, 1, 0));
1310 testcase(
"LedgerDeltaAcquire bad reply");
1311 int totalReplay = 3;
1320 uint256 finalHash = l->info().hash;
1321 net.client.ledgerMaster.storeLedger(l);
1322 net.client.replayer.replay(
1325 auto delta = net.client.findLedgerDeltaAcquire(l->info().parentHash);
1331 net.client.taskStatus(net.client.findTask(
1335 net.client.replayer.replay(
1338 net.client.taskStatus(net.client.findTask(
1345 testcase(
"Overlap tasks");
1346 int totalReplay = 5;
1349 {totalReplay * 3 + 1},
1354 uint256 finalHash = l->info().hash;
1355 net.client.replayer.replay(
1359 BEAST_EXPECT(net.client.waitAndCheckStatus(
1365 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1368 net.client.replayer.replay(
1370 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1372 net.client.replayer.replay(
1374 BEAST_EXPECT(net.client.countsAsExpected(2, 1, totalReplay - 1));
1377 for (
int i = 0; i < totalReplay + 2; ++i)
1379 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1381 auto finalHash_early = l->info().hash;
1382 net.client.replayer.replay(
1384 BEAST_EXPECT(net.client.waitAndCheckStatus(
1390 BEAST_EXPECT(net.client.waitForLedgers(finalHash_early, totalReplay));
1391 BEAST_EXPECT(net.client.countsAsExpected(3, 2, 2 * (totalReplay - 1)));
1394 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1395 auto finalHash_moreEarly = l->info().parentHash;
1396 net.client.replayer.replay(
1398 BEAST_EXPECT(net.client.waitAndCheckStatus(
1399 finalHash_moreEarly,
1405 net.client.waitForLedgers(finalHash_moreEarly, totalReplay));
1407 net.client.countsAsExpected(4, 3, 2 * (totalReplay - 1) + 2));
1410 net.client.replayer.replay(
1414 BEAST_EXPECT(net.client.waitAndCheckStatus(
1420 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3));
1421 BEAST_EXPECT(net.client.countsAsExpected(5, 3, totalReplay * 3 - 1));
1424 net.client.replayer.sweep();
1425 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1433 testTaskParameter();
1438 testAllInboundLedgers(1);
1439 testAllInboundLedgers(4);
1445 testSkipListBadReply();
1446 testLedgerDeltaBadReply();
1447 testLedgerReplayOverlap();
1456 testcase(
"SkipListAcquire timeout");
1457 int totalReplay = 3;
1466 uint256 finalHash = l->info().hash;
1467 net.client.replayer.replay(
1471 BEAST_EXPECT(net.client.waitAndCheckStatus(
1479 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1480 net.client.replayer.sweep();
1481 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1487 testcase(
"LedgerDeltaAcquire timeout");
1488 int totalReplay = 3;
1497 uint256 finalHash = l->info().hash;
1498 net.client.ledgerMaster.storeLedger(l);
1499 net.client.replayer.replay(
1505 BEAST_EXPECT(net.client.waitAndCheckStatus(
1513 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1514 net.client.replayer.sweep();
1515 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1521 testSkipListTimeout();
1522 testLedgerDeltaTimeout();
1531 testcase(
"Acquire 1000 ledgers");
1532 int totalReplay = 250;
1536 {totalReplay * rounds + 1},
1542 auto l = net.server.ledgerMaster.getClosedLedger();
1543 for (
int i = 0; i < rounds; ++i)
1546 for (
int j = 0; j < totalReplay; ++j)
1548 l = net.server.ledgerMaster.getLedgerByHash(
1549 l->info().parentHash);
1552 BEAST_EXPECT(finishHashes.size() == rounds);
1554 for (
int i = 0; i < rounds; ++i)
1556 net.client.replayer.replay(
1562 for (
int i = 0; i < rounds; ++i)
1564 BEAST_EXPECT(net.client.waitAndCheckStatus(
1573 net.client.waitForLedgers(finishHashes[0], totalReplay * rounds));
1574 BEAST_EXPECT(net.client.countsAsExpected(
1575 rounds, rounds, rounds * (totalReplay - 1)));
1578 net.client.replayer.sweep();
1579 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));