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)
317 bool enableLedgerReplay)
320 , dummyPeer(
std::make_shared<
TestPeer>(enableLedgerReplay))
332 onPeerAdded(dummyPeer);
337 ::google::protobuf::Message
const& msg,
338 protocol::MessageType type,
347 if ((rand() % 100 + 1) <= dropRate)
352 case protocol::mtPROOF_PATH_REQ: {
355 auto request = std::make_shared<protocol::TMProofPathRequest>(
356 dynamic_cast<protocol::TMProofPathRequest const&
>(msg));
357 auto reply = std::make_shared<protocol::TMProofPathResponse>(
358 remote.processProofPathRequest(request));
359 local.processProofPathResponse(reply);
361 local.processProofPathResponse(reply);
364 case protocol::mtREPLAY_DELTA_REQ: {
367 auto request = std::make_shared<protocol::TMReplayDeltaRequest>(
368 dynamic_cast<protocol::TMReplayDeltaRequest const&
>(msg));
369 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
370 remote.processReplayDeltaRequest(request));
371 local.processReplayDeltaResponse(reply);
373 local.processReplayDeltaResponse(reply);
415 return std::make_unique<TestPeerSet>(
416 local, remote, behavior, enableLedgerReplay);
435 int initAccounts = 10;
436 int initAmount = 1
'000'000;
437 int numTxPerLedger = 10;
445 , msgHandler(env.app(), env.app().getLedgerReplayer())
448 assert(param.initLedgers > 0);
449 createAccounts(param.initAccounts);
450 createLedgerHistory();
451 app.logs().threshold(beast::severities::Severity::kWarning);
460 auto fundedAccounts = accounts.size();
461 for (
int i = 0; i < newAccounts; ++i)
463 accounts.emplace_back(
465 env.fund(
jtx::XRP(param.initAmount), accounts.back());
476 int fundedAccounts = accounts.size();
477 assert(fundedAccounts >= newTxes);
484 auto updateIdx = [&]() {
485 assert(fundedAccounts > senders.
size());
486 fromIdx = (fromIdx + r) % fundedAccounts;
487 while (senders.
count(fromIdx) != 0)
488 fromIdx = (fromIdx + 1) % fundedAccounts;
490 toIdx = (toIdx + r * 2) % fundedAccounts;
491 if (toIdx == fromIdx)
492 toIdx = (toIdx + 1) % fundedAccounts;
495 for (
int i = 0; i < newTxes; ++i)
499 pay(accounts[fromIdx],
516 for (
int i = 0; i < param.initLedgers - 1; ++i)
518 sendPayments(param.numTxPerLedger);
548 beast::unit_test::suite& suite,
557 server.app.getLedgerMaster(),
560 , serverMsgHandler(server.app, server.app.getLedgerReplayer())
561 , clientMsgHandler(env.app(), replayer)
582 uint256 hash = finishLedgerHash;
584 for (; i < totalReplay; ++i)
589 hash = l->info().parentHash;
597 int totalRound = 100;
598 for (
int i = 0; i < totalRound; ++i)
600 if (haveLedgers(finishLedgerHash, totalReplay))
602 if (i < totalRound - 1)
611 int totalRound = 100;
612 for (
int i = 0; i < totalRound; ++i)
617 for (
auto const& t : replayer.tasks_)
628 if (i < totalRound - 1)
638 return replayer.tasks_;
646 replayer.tasks_.begin(), replayer.tasks_.end(), [&](
auto const& t) {
647 return t->parameter_.finishHash_ == hash &&
648 t->parameter_.totalLedgers_ == totalReplay;
650 if (i == replayer.tasks_.end())
659 return replayer.deltas_.size();
666 return replayer.skipLists_.size();
676 return replayer.tasks_.size() == tasks &&
677 replayer.skipLists_.size() == skipLists &&
678 replayer.deltas_.size() == deltas;
685 auto i = replayer.skipLists_.find(hash);
686 if (i == replayer.skipLists_.end())
688 return i->second.lock();
695 auto i = replayer.deltas_.find(hash);
696 if (i == replayer.deltas_.end())
698 return i->second.lock();
701 template <
typename T>
719 if (taskStatus(task) == taskExpect)
721 if (taskStatus(task->skipListAcquirer_) == skiplistExpect)
723 if (task->deltas_.size() == deltaExpects.
size())
725 for (
int i = 0; i < deltaExpects.
size(); ++i)
727 if (taskStatus(task->deltas_[i]) != deltaExpects[i])
745 auto t = findTask(hash, totalReplay);
753 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
764 auto t = findTask(hash, totalReplay);
772 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
787 hash, totalReplay, taskExpect, skiplistExpect, deltaExpects);
817 beast::unit_test::suite& suite,
822 : server(suite, param)
823 , client(suite, server, behavior, inboundBhvr, peerFeature)
861 testcase(
"ProofPath");
867 auto request = std::make_shared<protocol::TMProofPathRequest>();
868 request->set_ledgerhash(
869 l->info().hash.data(), l->info().hash.size());
870 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
871 auto reply = std::make_shared<protocol::TMProofPathResponse>(
872 server.msgHandler.processProofPathRequest(request));
873 BEAST_EXPECT(reply->has_error());
874 BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
878 auto request = std::make_shared<protocol::TMProofPathRequest>();
879 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
883 request->set_ledgerhash(hash.
data(), hash.
size());
884 auto reply = std::make_shared<protocol::TMProofPathResponse>(
885 server.msgHandler.processProofPathRequest(request));
886 BEAST_EXPECT(reply->has_error());
891 auto request = std::make_shared<protocol::TMProofPathRequest>();
892 request->set_ledgerhash(
893 l->info().hash.data(), l->info().hash.size());
894 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
898 auto reply = std::make_shared<protocol::TMProofPathResponse>(
899 server.msgHandler.processProofPathRequest(request));
900 BEAST_EXPECT(!reply->has_error());
901 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
908 reply->set_ledgerheader(r);
910 !server.msgHandler.processProofPathResponse(reply));
912 reply->set_ledgerheader(r);
913 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
915 reply->mutable_path()->RemoveLast();
917 !server.msgHandler.processProofPathResponse(reply));
925 testcase(
"ReplayDelta");
931 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
932 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
933 server.msgHandler.processReplayDeltaRequest(request));
934 BEAST_EXPECT(reply->has_error());
935 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
938 request->set_ledgerhash(hash.
data(), hash.
size());
939 reply = std::make_shared<protocol::TMReplayDeltaResponse>(
940 server.msgHandler.processReplayDeltaRequest(request));
941 BEAST_EXPECT(reply->has_error());
942 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
947 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
948 request->set_ledgerhash(
949 l->info().hash.data(), l->info().hash.size());
950 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
951 server.msgHandler.processReplayDeltaRequest(request));
952 BEAST_EXPECT(!reply->has_error());
953 BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
960 reply->set_ledgerheader(r);
962 !server.msgHandler.processReplayDeltaResponse(reply));
964 reply->set_ledgerheader(r);
966 server.msgHandler.processReplayDeltaResponse(reply));
968 reply->mutable_transaction()->RemoveLast();
970 !server.msgHandler.processReplayDeltaResponse(reply));
978 testcase(
"TaskParameter");
982 for (
int i = 0; i < count; ++i)
989 BEAST_EXPECT(!tp10.
update(
uint256(777), 5, makeSkipList(10)));
991 BEAST_EXPECT(tp10.
update(
uint256(10), 10, makeSkipList(10)));
1021 BEAST_EXPECT(tp20.
update(
uint256(20), 20, makeSkipList(20)));
1031 testcase(
"config test");
1061 testcase(
"handshake test");
1062 auto handshake = [&](
bool client,
bool server,
bool expecting) ->
bool {
1065 http_request.version(request.version());
1066 http_request.base() = request.base();
1069 if (serverResult != expecting)
1073 boost::asio::ip::address::from_string(
"172.1.1.100");
1085 auto const clientResult =
1087 if (clientResult != expecting)
1093 BEAST_EXPECT(handshake(
false,
false,
false));
1094 BEAST_EXPECT(handshake(
false,
true,
false));
1095 BEAST_EXPECT(handshake(
true,
false,
false));
1096 BEAST_EXPECT(handshake(
true,
true,
true));
1102 testcase(
"local node has all the ledgers");
1107 NetworkOfTwo net(*
this, {totalReplay + 1}, psBhvr, ilBhvr, peerFeature);
1110 uint256 finalHash = l->info().hash;
1111 for (
int i = 0; i < totalReplay; ++i)
1116 net.client.ledgerMaster.storeLedger(l);
1117 l = net.server.ledgerMaster.getLedgerByHash(
1118 l->info().parentHash);
1124 net.client.replayer.replay(
1129 BEAST_EXPECT(net.client.waitAndCheckStatus(
1137 net.client.replayer.sweep();
1138 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1144 testcase(
"all the ledgers from InboundLedgers");
1153 uint256 finalHash = l->info().hash;
1154 net.client.replayer.replay(
1159 BEAST_EXPECT(net.client.waitAndCheckStatus(
1167 net.client.replayer.sweep();
1168 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1174 switch (peerSetBehavior)
1177 testcase(
"good network");
1180 testcase(
"network drops 50% messages");
1183 testcase(
"network repeats all messages");
1198 uint256 finalHash = l->info().hash;
1199 for (
int i = 0; i < totalReplay - 1; ++i)
1201 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1203 net.client.ledgerMaster.storeLedger(l);
1205 net.client.replayer.replay(
1210 BEAST_EXPECT(net.client.waitAndCheckStatus(
1216 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1219 net.client.replayer.sweep();
1220 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1226 testcase(
"stop before timeout");
1227 int totalReplay = 3;
1236 uint256 finalHash = l->info().hash;
1237 net.client.replayer.replay(
1241 BEAST_EXPECT(net.client.checkStatus(
1248 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1249 net.client.replayer.stop();
1250 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1256 testcase(
"SkipListAcquire bad reply");
1257 int totalReplay = 3;
1260 {totalReplay + 1 + 1},
1266 uint256 finalHash = l->info().hash;
1267 net.client.replayer.replay(
1270 auto skipList = net.client.findSkipListAcquire(finalHash);
1273 0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, 0xB2};
1274 auto item = std::make_shared<SHAMapItem>(
1276 skipList->processData(l->seq(), item);
1279 BEAST_EXPECT(net.client.waitAndCheckStatus(
1287 net.client.replayer.replay(
1289 BEAST_EXPECT(net.client.waitAndCheckStatus(
1295 BEAST_EXPECT(net.client.countsAsExpected(2, 1, 0));
1301 testcase(
"LedgerDeltaAcquire bad reply");
1302 int totalReplay = 3;
1311 uint256 finalHash = l->info().hash;
1312 net.client.ledgerMaster.storeLedger(l);
1313 net.client.replayer.replay(
1316 auto delta = net.client.findLedgerDeltaAcquire(l->info().parentHash);
1322 net.client.taskStatus(net.client.findTask(
1326 net.client.replayer.replay(
1329 net.client.taskStatus(net.client.findTask(
1336 testcase(
"Overlap tasks");
1337 int totalReplay = 5;
1340 {totalReplay * 3 + 1},
1345 uint256 finalHash = l->info().hash;
1346 net.client.replayer.replay(
1350 BEAST_EXPECT(net.client.waitAndCheckStatus(
1356 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1359 net.client.replayer.replay(
1361 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1363 net.client.replayer.replay(
1365 BEAST_EXPECT(net.client.countsAsExpected(2, 1, totalReplay - 1));
1368 for (
int i = 0; i < totalReplay + 2; ++i)
1370 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1372 auto finalHash_early = l->info().hash;
1373 net.client.replayer.replay(
1375 BEAST_EXPECT(net.client.waitAndCheckStatus(
1381 BEAST_EXPECT(net.client.waitForLedgers(finalHash_early, totalReplay));
1382 BEAST_EXPECT(net.client.countsAsExpected(3, 2, 2 * (totalReplay - 1)));
1385 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1386 auto finalHash_moreEarly = l->info().parentHash;
1387 net.client.replayer.replay(
1389 BEAST_EXPECT(net.client.waitAndCheckStatus(
1390 finalHash_moreEarly,
1396 net.client.waitForLedgers(finalHash_moreEarly, totalReplay));
1398 net.client.countsAsExpected(4, 3, 2 * (totalReplay - 1) + 2));
1401 net.client.replayer.replay(
1405 BEAST_EXPECT(net.client.waitAndCheckStatus(
1411 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3));
1412 BEAST_EXPECT(net.client.countsAsExpected(5, 3, totalReplay * 3 - 1));
1415 net.client.replayer.sweep();
1416 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1424 testTaskParameter();
1429 testAllInboundLedgers(1);
1430 testAllInboundLedgers(4);
1436 testSkipListBadReply();
1437 testLedgerDeltaBadReply();
1438 testLedgerReplayOverlap();
1447 testcase(
"SkipListAcquire timeout");
1448 int totalReplay = 3;
1457 uint256 finalHash = l->info().hash;
1458 net.client.replayer.replay(
1462 BEAST_EXPECT(net.client.waitAndCheckStatus(
1470 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1471 net.client.replayer.sweep();
1472 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1478 testcase(
"LedgerDeltaAcquire timeout");
1479 int totalReplay = 3;
1488 uint256 finalHash = l->info().hash;
1489 net.client.ledgerMaster.storeLedger(l);
1490 net.client.replayer.replay(
1496 BEAST_EXPECT(net.client.waitAndCheckStatus(
1504 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1505 net.client.replayer.sweep();
1506 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1512 testSkipListTimeout();
1513 testLedgerDeltaTimeout();
1522 testcase(
"Acquire 1000 ledgers");
1523 int totalReplay = 250;
1527 {totalReplay * rounds + 1},
1533 auto l = net.server.ledgerMaster.getClosedLedger();
1534 for (
int i = 0; i < rounds; ++i)
1537 for (
int j = 0; j < totalReplay; ++j)
1539 l = net.server.ledgerMaster.getLedgerByHash(
1540 l->info().parentHash);
1543 BEAST_EXPECT(finishHashes.size() == rounds);
1545 for (
int i = 0; i < rounds; ++i)
1547 net.client.replayer.replay(
1553 for (
int i = 0; i < rounds; ++i)
1555 BEAST_EXPECT(net.client.waitAndCheckStatus(
1564 net.client.waitForLedgers(finishHashes[0], totalReplay * rounds));
1565 BEAST_EXPECT(net.client.countsAsExpected(
1566 rounds, rounds, rounds * (totalReplay - 1)));
1569 net.client.replayer.sweep();
1570 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));