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);
201 : ledgerReplayEnabled_(enableLedgerReplay)
242 return nodePublicKey_;
342 bool enableLedgerReplay)
345 , dummyPeer(
std::make_shared<
TestPeer>(enableLedgerReplay))
357 onPeerAdded(dummyPeer);
362 ::google::protobuf::Message
const& msg,
363 protocol::MessageType type,
372 if ((rand() % 100 + 1) <= dropRate)
377 case protocol::mtPROOF_PATH_REQ: {
380 auto request = std::make_shared<protocol::TMProofPathRequest>(
381 dynamic_cast<protocol::TMProofPathRequest const&
>(msg));
382 auto reply = std::make_shared<protocol::TMProofPathResponse>(
383 remote.processProofPathRequest(request));
384 local.processProofPathResponse(reply);
386 local.processProofPathResponse(reply);
389 case protocol::mtREPLAY_DELTA_REQ: {
392 auto request = std::make_shared<protocol::TMReplayDeltaRequest>(
393 dynamic_cast<protocol::TMReplayDeltaRequest const&
>(msg));
394 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
395 remote.processReplayDeltaRequest(request));
396 local.processReplayDeltaResponse(reply);
398 local.processReplayDeltaResponse(reply);
440 return std::make_unique<TestPeerSet>(
441 local, remote, behavior, enableLedgerReplay);
460 int initAccounts = 10;
461 int initAmount = 1
'000'000;
462 int numTxPerLedger = 10;
470 , msgHandler(env.app(), env.app().getLedgerReplayer())
473 assert(param.initLedgers > 0);
474 createAccounts(param.initAccounts);
475 createLedgerHistory();
485 auto fundedAccounts = accounts.size();
486 for (
int i = 0; i < newAccounts; ++i)
488 accounts.emplace_back(
490 env.fund(
jtx::XRP(param.initAmount), accounts.back());
501 int fundedAccounts = accounts.size();
502 assert(fundedAccounts >= newTxes);
509 auto updateIdx = [&]() {
510 assert(fundedAccounts > senders.
size());
511 fromIdx = (fromIdx + r) % fundedAccounts;
512 while (senders.
count(fromIdx) != 0)
513 fromIdx = (fromIdx + 1) % fundedAccounts;
515 toIdx = (toIdx + r * 2) % fundedAccounts;
516 if (toIdx == fromIdx)
517 toIdx = (toIdx + 1) % fundedAccounts;
520 for (
int i = 0; i < newTxes; ++i)
524 pay(accounts[fromIdx],
541 for (
int i = 0; i < param.initLedgers - 1; ++i)
543 sendPayments(param.numTxPerLedger);
573 beast::unit_test::suite& suite,
585 server.app.getLedgerMaster(),
588 , serverMsgHandler(server.app, server.app.getLedgerReplayer())
589 , clientMsgHandler(env.app(), replayer)
610 uint256 hash = finishLedgerHash;
612 for (; i < totalReplay; ++i)
617 hash = l->info().parentHash;
625 int totalRound = 100;
626 for (
int i = 0; i < totalRound; ++i)
628 if (haveLedgers(finishLedgerHash, totalReplay))
630 if (i < totalRound - 1)
639 int totalRound = 100;
640 for (
int i = 0; i < totalRound; ++i)
645 for (
auto const& t : replayer.tasks_)
656 if (i < totalRound - 1)
666 return replayer.tasks_;
674 replayer.tasks_.begin(), replayer.tasks_.end(), [&](
auto const& t) {
675 return t->parameter_.finishHash_ == hash &&
676 t->parameter_.totalLedgers_ == totalReplay;
678 if (i == replayer.tasks_.end())
687 return replayer.deltas_.size();
694 return replayer.skipLists_.size();
704 return replayer.tasks_.size() == tasks &&
705 replayer.skipLists_.size() == skipLists &&
706 replayer.deltas_.size() == deltas;
713 auto i = replayer.skipLists_.find(hash);
714 if (i == replayer.skipLists_.end())
716 return i->second.lock();
723 auto i = replayer.deltas_.find(hash);
724 if (i == replayer.deltas_.end())
726 return i->second.lock();
729 template <
typename T>
747 if (taskStatus(task) == taskExpect)
749 if (taskStatus(task->skipListAcquirer_) == skiplistExpect)
751 if (task->deltas_.size() == deltaExpects.
size())
753 for (
int i = 0; i < deltaExpects.
size(); ++i)
755 if (taskStatus(task->deltas_[i]) != deltaExpects[i])
773 auto t = findTask(hash, totalReplay);
781 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
792 auto t = findTask(hash, totalReplay);
800 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
815 hash, totalReplay, taskExpect, skiplistExpect, deltaExpects);
845 beast::unit_test::suite& suite,
850 : server(suite, param)
851 , client(suite, server, behavior, inboundBhvr, peerFeature)
889 testcase(
"ProofPath");
895 auto request = std::make_shared<protocol::TMProofPathRequest>();
896 request->set_ledgerhash(
897 l->info().hash.data(), l->info().hash.size());
898 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
899 auto reply = std::make_shared<protocol::TMProofPathResponse>(
900 server.msgHandler.processProofPathRequest(request));
901 BEAST_EXPECT(reply->has_error());
902 BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
906 auto request = std::make_shared<protocol::TMProofPathRequest>();
907 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
911 request->set_ledgerhash(hash.
data(), hash.
size());
912 auto reply = std::make_shared<protocol::TMProofPathResponse>(
913 server.msgHandler.processProofPathRequest(request));
914 BEAST_EXPECT(reply->has_error());
919 auto request = std::make_shared<protocol::TMProofPathRequest>();
920 request->set_ledgerhash(
921 l->info().hash.data(), l->info().hash.size());
922 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
926 auto reply = std::make_shared<protocol::TMProofPathResponse>(
927 server.msgHandler.processProofPathRequest(request));
928 BEAST_EXPECT(!reply->has_error());
929 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
936 reply->set_ledgerheader(r);
938 !server.msgHandler.processProofPathResponse(reply));
940 reply->set_ledgerheader(r);
941 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
943 reply->mutable_path()->RemoveLast();
945 !server.msgHandler.processProofPathResponse(reply));
953 testcase(
"ReplayDelta");
959 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
960 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
961 server.msgHandler.processReplayDeltaRequest(request));
962 BEAST_EXPECT(reply->has_error());
963 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
966 request->set_ledgerhash(hash.
data(), hash.
size());
967 reply = std::make_shared<protocol::TMReplayDeltaResponse>(
968 server.msgHandler.processReplayDeltaRequest(request));
969 BEAST_EXPECT(reply->has_error());
970 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
975 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
976 request->set_ledgerhash(
977 l->info().hash.data(), l->info().hash.size());
978 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
979 server.msgHandler.processReplayDeltaRequest(request));
980 BEAST_EXPECT(!reply->has_error());
981 BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
988 reply->set_ledgerheader(r);
990 !server.msgHandler.processReplayDeltaResponse(reply));
992 reply->set_ledgerheader(r);
994 server.msgHandler.processReplayDeltaResponse(reply));
996 reply->mutable_transaction()->RemoveLast();
998 !server.msgHandler.processReplayDeltaResponse(reply));
1006 testcase(
"TaskParameter");
1010 for (
int i = 0; i < count; ++i)
1017 BEAST_EXPECT(!tp10.
update(
uint256(777), 5, makeSkipList(10)));
1018 BEAST_EXPECT(!tp10.
update(
uint256(10), 5, makeSkipList(8)));
1019 BEAST_EXPECT(tp10.
update(
uint256(10), 10, makeSkipList(10)));
1049 BEAST_EXPECT(tp20.
update(
uint256(20), 20, makeSkipList(20)));
1059 testcase(
"config test");
1089 testcase(
"handshake test");
1090 auto handshake = [&](
bool client,
bool server,
bool expecting) ->
bool {
1094 http_request.version(request.version());
1095 http_request.base() = request.base();
1098 if (serverResult != expecting)
1102 boost::asio::ip::address::from_string(
"172.1.1.100");
1114 auto const clientResult =
1116 if (clientResult != expecting)
1122 BEAST_EXPECT(handshake(
false,
false,
false));
1123 BEAST_EXPECT(handshake(
false,
true,
false));
1124 BEAST_EXPECT(handshake(
true,
false,
false));
1125 BEAST_EXPECT(handshake(
true,
true,
true));
1131 testcase(
"local node has all the ledgers");
1136 NetworkOfTwo net(*
this, {totalReplay + 1}, psBhvr, ilBhvr, peerFeature);
1139 uint256 finalHash = l->info().hash;
1140 for (
int i = 0; i < totalReplay; ++i)
1145 net.client.ledgerMaster.storeLedger(l);
1146 l = net.server.ledgerMaster.getLedgerByHash(
1147 l->info().parentHash);
1153 net.client.replayer.replay(
1158 BEAST_EXPECT(net.client.waitAndCheckStatus(
1166 net.client.replayer.sweep();
1167 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1173 testcase(
"all the ledgers from InboundLedgers");
1182 uint256 finalHash = l->info().hash;
1183 net.client.replayer.replay(
1188 BEAST_EXPECT(net.client.waitAndCheckStatus(
1196 net.client.replayer.sweep();
1197 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1203 switch (peerSetBehavior)
1206 testcase(
"good network");
1209 testcase(
"network drops 50% messages");
1212 testcase(
"network repeats all messages");
1227 uint256 finalHash = l->info().hash;
1228 for (
int i = 0; i < totalReplay - 1; ++i)
1230 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1232 net.client.ledgerMaster.storeLedger(l);
1234 net.client.replayer.replay(
1239 BEAST_EXPECT(net.client.waitAndCheckStatus(
1245 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1248 net.client.replayer.sweep();
1249 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1255 testcase(
"stop before timeout");
1256 int totalReplay = 3;
1265 uint256 finalHash = l->info().hash;
1266 net.client.replayer.replay(
1270 BEAST_EXPECT(net.client.checkStatus(
1277 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1278 net.client.replayer.stop();
1279 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1285 testcase(
"SkipListAcquire bad reply");
1286 int totalReplay = 3;
1289 {totalReplay + 1 + 1},
1295 uint256 finalHash = l->info().hash;
1296 net.client.replayer.replay(
1299 auto skipList = net.client.findSkipListAcquire(finalHash);
1302 0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, 0xB2};
1305 skipList->processData(l->seq(), item);
1308 BEAST_EXPECT(net.client.waitAndCheckStatus(
1316 net.client.replayer.replay(
1318 BEAST_EXPECT(net.client.waitAndCheckStatus(
1324 BEAST_EXPECT(net.client.countsAsExpected(2, 1, 0));
1330 testcase(
"LedgerDeltaAcquire bad reply");
1331 int totalReplay = 3;
1340 uint256 finalHash = l->info().hash;
1341 net.client.ledgerMaster.storeLedger(l);
1342 net.client.replayer.replay(
1345 auto delta = net.client.findLedgerDeltaAcquire(l->info().parentHash);
1351 net.client.taskStatus(net.client.findTask(
1355 net.client.replayer.replay(
1358 net.client.taskStatus(net.client.findTask(
1365 testcase(
"Overlap tasks");
1366 int totalReplay = 5;
1369 {totalReplay * 3 + 1},
1374 uint256 finalHash = l->info().hash;
1375 net.client.replayer.replay(
1379 BEAST_EXPECT(net.client.waitAndCheckStatus(
1385 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1388 net.client.replayer.replay(
1390 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1392 net.client.replayer.replay(
1394 BEAST_EXPECT(net.client.countsAsExpected(2, 1, totalReplay - 1));
1397 for (
int i = 0; i < totalReplay + 2; ++i)
1399 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1401 auto finalHash_early = l->info().hash;
1402 net.client.replayer.replay(
1404 BEAST_EXPECT(net.client.waitAndCheckStatus(
1410 BEAST_EXPECT(net.client.waitForLedgers(finalHash_early, totalReplay));
1411 BEAST_EXPECT(net.client.countsAsExpected(3, 2, 2 * (totalReplay - 1)));
1414 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1415 auto finalHash_moreEarly = l->info().parentHash;
1416 net.client.replayer.replay(
1418 BEAST_EXPECT(net.client.waitAndCheckStatus(
1419 finalHash_moreEarly,
1425 net.client.waitForLedgers(finalHash_moreEarly, totalReplay));
1427 net.client.countsAsExpected(4, 3, 2 * (totalReplay - 1) + 2));
1430 net.client.replayer.replay(
1434 BEAST_EXPECT(net.client.waitAndCheckStatus(
1440 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3));
1441 BEAST_EXPECT(net.client.countsAsExpected(5, 3, totalReplay * 3 - 1));
1444 net.client.replayer.sweep();
1445 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1453 testTaskParameter();
1458 testAllInboundLedgers(1);
1459 testAllInboundLedgers(4);
1465 testSkipListBadReply();
1466 testLedgerDeltaBadReply();
1467 testLedgerReplayOverlap();
1476 testcase(
"SkipListAcquire timeout");
1477 int totalReplay = 3;
1486 uint256 finalHash = l->info().hash;
1487 net.client.replayer.replay(
1491 BEAST_EXPECT(net.client.waitAndCheckStatus(
1499 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1500 net.client.replayer.sweep();
1501 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1507 testcase(
"LedgerDeltaAcquire timeout");
1508 int totalReplay = 3;
1517 uint256 finalHash = l->info().hash;
1518 net.client.ledgerMaster.storeLedger(l);
1519 net.client.replayer.replay(
1525 BEAST_EXPECT(net.client.waitAndCheckStatus(
1533 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1534 net.client.replayer.sweep();
1535 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1541 testSkipListTimeout();
1542 testLedgerDeltaTimeout();
1551 testcase(
"Acquire 1000 ledgers");
1552 int totalReplay = 250;
1556 {totalReplay * rounds + 1},
1562 auto l = net.server.ledgerMaster.getClosedLedger();
1563 for (
int i = 0; i < rounds; ++i)
1566 for (
int j = 0; j < totalReplay; ++j)
1568 l = net.server.ledgerMaster.getLedgerByHash(
1569 l->info().parentHash);
1572 BEAST_EXPECT(finishHashes.size() == rounds);
1574 for (
int i = 0; i < rounds; ++i)
1576 net.client.replayer.replay(
1582 for (
int i = 0; i < rounds; ++i)
1584 BEAST_EXPECT(net.client.waitAndCheckStatus(
1593 net.client.waitForLedgers(finishHashes[0], totalReplay * rounds));
1594 BEAST_EXPECT(net.client.countsAsExpected(
1595 rounds, rounds, rounds * (totalReplay - 1)));
1598 net.client.replayer.sweep();
1599 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));