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();
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,
577 server.app.getLedgerMaster(),
580 , serverMsgHandler(server.app, server.app.getLedgerReplayer())
581 , clientMsgHandler(env.app(), replayer)
602 uint256 hash = finishLedgerHash;
604 for (; i < totalReplay; ++i)
609 hash = l->info().parentHash;
617 int totalRound = 100;
618 for (
int i = 0; i < totalRound; ++i)
620 if (haveLedgers(finishLedgerHash, totalReplay))
622 if (i < totalRound - 1)
631 int totalRound = 100;
632 for (
int i = 0; i < totalRound; ++i)
637 for (
auto const& t : replayer.tasks_)
648 if (i < totalRound - 1)
658 return replayer.tasks_;
666 replayer.tasks_.begin(), replayer.tasks_.end(), [&](
auto const& t) {
667 return t->parameter_.finishHash_ == hash &&
668 t->parameter_.totalLedgers_ == totalReplay;
670 if (i == replayer.tasks_.end())
679 return replayer.deltas_.size();
686 return replayer.skipLists_.size();
696 return replayer.tasks_.size() == tasks &&
697 replayer.skipLists_.size() == skipLists &&
698 replayer.deltas_.size() == deltas;
705 auto i = replayer.skipLists_.find(hash);
706 if (i == replayer.skipLists_.end())
708 return i->second.lock();
715 auto i = replayer.deltas_.find(hash);
716 if (i == replayer.deltas_.end())
718 return i->second.lock();
721 template <
typename T>
739 if (taskStatus(task) == taskExpect)
741 if (taskStatus(task->skipListAcquirer_) == skiplistExpect)
743 if (task->deltas_.size() == deltaExpects.
size())
745 for (
int i = 0; i < deltaExpects.
size(); ++i)
747 if (taskStatus(task->deltas_[i]) != deltaExpects[i])
765 auto t = findTask(hash, totalReplay);
773 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
784 auto t = findTask(hash, totalReplay);
792 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
807 hash, totalReplay, taskExpect, skiplistExpect, deltaExpects);
837 beast::unit_test::suite& suite,
842 : server(suite, param)
843 , client(suite, server, behavior, inboundBhvr, peerFeature)
881 testcase(
"ProofPath");
887 auto request = std::make_shared<protocol::TMProofPathRequest>();
888 request->set_ledgerhash(
889 l->info().hash.data(), l->info().hash.size());
890 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
891 auto reply = std::make_shared<protocol::TMProofPathResponse>(
892 server.msgHandler.processProofPathRequest(request));
893 BEAST_EXPECT(reply->has_error());
894 BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
898 auto request = std::make_shared<protocol::TMProofPathRequest>();
899 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
903 request->set_ledgerhash(hash.
data(), hash.
size());
904 auto reply = std::make_shared<protocol::TMProofPathResponse>(
905 server.msgHandler.processProofPathRequest(request));
906 BEAST_EXPECT(reply->has_error());
911 auto request = std::make_shared<protocol::TMProofPathRequest>();
912 request->set_ledgerhash(
913 l->info().hash.data(), l->info().hash.size());
914 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
918 auto reply = std::make_shared<protocol::TMProofPathResponse>(
919 server.msgHandler.processProofPathRequest(request));
920 BEAST_EXPECT(!reply->has_error());
921 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
928 reply->set_ledgerheader(r);
930 !server.msgHandler.processProofPathResponse(reply));
932 reply->set_ledgerheader(r);
933 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
935 reply->mutable_path()->RemoveLast();
937 !server.msgHandler.processProofPathResponse(reply));
945 testcase(
"ReplayDelta");
951 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
952 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
953 server.msgHandler.processReplayDeltaRequest(request));
954 BEAST_EXPECT(reply->has_error());
955 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
958 request->set_ledgerhash(hash.
data(), hash.
size());
959 reply = std::make_shared<protocol::TMReplayDeltaResponse>(
960 server.msgHandler.processReplayDeltaRequest(request));
961 BEAST_EXPECT(reply->has_error());
962 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
967 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
968 request->set_ledgerhash(
969 l->info().hash.data(), l->info().hash.size());
970 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
971 server.msgHandler.processReplayDeltaRequest(request));
972 BEAST_EXPECT(!reply->has_error());
973 BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
980 reply->set_ledgerheader(r);
982 !server.msgHandler.processReplayDeltaResponse(reply));
984 reply->set_ledgerheader(r);
986 server.msgHandler.processReplayDeltaResponse(reply));
988 reply->mutable_transaction()->RemoveLast();
990 !server.msgHandler.processReplayDeltaResponse(reply));
998 testcase(
"TaskParameter");
1002 for (
int i = 0; i < count; ++i)
1009 BEAST_EXPECT(!tp10.
update(
uint256(777), 5, makeSkipList(10)));
1010 BEAST_EXPECT(!tp10.
update(
uint256(10), 5, makeSkipList(8)));
1011 BEAST_EXPECT(tp10.
update(
uint256(10), 10, makeSkipList(10)));
1041 BEAST_EXPECT(tp20.
update(
uint256(20), 20, makeSkipList(20)));
1051 testcase(
"config test");
1081 testcase(
"handshake test");
1082 auto handshake = [&](
bool client,
bool server,
bool expecting) ->
bool {
1086 http_request.version(request.version());
1087 http_request.base() = request.base();
1090 if (serverResult != expecting)
1094 boost::asio::ip::address::from_string(
"172.1.1.100");
1106 auto const clientResult =
1108 if (clientResult != expecting)
1114 BEAST_EXPECT(handshake(
false,
false,
false));
1115 BEAST_EXPECT(handshake(
false,
true,
false));
1116 BEAST_EXPECT(handshake(
true,
false,
false));
1117 BEAST_EXPECT(handshake(
true,
true,
true));
1123 testcase(
"local node has all the ledgers");
1128 NetworkOfTwo net(*
this, {totalReplay + 1}, psBhvr, ilBhvr, peerFeature);
1131 uint256 finalHash = l->info().hash;
1132 for (
int i = 0; i < totalReplay; ++i)
1137 net.client.ledgerMaster.storeLedger(l);
1138 l = net.server.ledgerMaster.getLedgerByHash(
1139 l->info().parentHash);
1145 net.client.replayer.replay(
1150 BEAST_EXPECT(net.client.waitAndCheckStatus(
1158 net.client.replayer.sweep();
1159 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1165 testcase(
"all the ledgers from InboundLedgers");
1174 uint256 finalHash = l->info().hash;
1175 net.client.replayer.replay(
1180 BEAST_EXPECT(net.client.waitAndCheckStatus(
1188 net.client.replayer.sweep();
1189 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1195 switch (peerSetBehavior)
1198 testcase(
"good network");
1201 testcase(
"network drops 50% messages");
1204 testcase(
"network repeats all messages");
1219 uint256 finalHash = l->info().hash;
1220 for (
int i = 0; i < totalReplay - 1; ++i)
1222 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1224 net.client.ledgerMaster.storeLedger(l);
1226 net.client.replayer.replay(
1231 BEAST_EXPECT(net.client.waitAndCheckStatus(
1237 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1240 net.client.replayer.sweep();
1241 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1247 testcase(
"stop before timeout");
1248 int totalReplay = 3;
1257 uint256 finalHash = l->info().hash;
1258 net.client.replayer.replay(
1262 BEAST_EXPECT(net.client.checkStatus(
1269 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1270 net.client.replayer.stop();
1271 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1277 testcase(
"SkipListAcquire bad reply");
1278 int totalReplay = 3;
1281 {totalReplay + 1 + 1},
1287 uint256 finalHash = l->info().hash;
1288 net.client.replayer.replay(
1291 auto skipList = net.client.findSkipListAcquire(finalHash);
1294 0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, 0xB2};
1297 skipList->processData(l->seq(), item);
1300 BEAST_EXPECT(net.client.waitAndCheckStatus(
1308 net.client.replayer.replay(
1310 BEAST_EXPECT(net.client.waitAndCheckStatus(
1316 BEAST_EXPECT(net.client.countsAsExpected(2, 1, 0));
1322 testcase(
"LedgerDeltaAcquire bad reply");
1323 int totalReplay = 3;
1332 uint256 finalHash = l->info().hash;
1333 net.client.ledgerMaster.storeLedger(l);
1334 net.client.replayer.replay(
1337 auto delta = net.client.findLedgerDeltaAcquire(l->info().parentHash);
1343 net.client.taskStatus(net.client.findTask(
1347 net.client.replayer.replay(
1350 net.client.taskStatus(net.client.findTask(
1357 testcase(
"Overlap tasks");
1358 int totalReplay = 5;
1361 {totalReplay * 3 + 1},
1366 uint256 finalHash = l->info().hash;
1367 net.client.replayer.replay(
1371 BEAST_EXPECT(net.client.waitAndCheckStatus(
1377 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1380 net.client.replayer.replay(
1382 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1384 net.client.replayer.replay(
1386 BEAST_EXPECT(net.client.countsAsExpected(2, 1, totalReplay - 1));
1389 for (
int i = 0; i < totalReplay + 2; ++i)
1391 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1393 auto finalHash_early = l->info().hash;
1394 net.client.replayer.replay(
1396 BEAST_EXPECT(net.client.waitAndCheckStatus(
1402 BEAST_EXPECT(net.client.waitForLedgers(finalHash_early, totalReplay));
1403 BEAST_EXPECT(net.client.countsAsExpected(3, 2, 2 * (totalReplay - 1)));
1406 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1407 auto finalHash_moreEarly = l->info().parentHash;
1408 net.client.replayer.replay(
1410 BEAST_EXPECT(net.client.waitAndCheckStatus(
1411 finalHash_moreEarly,
1417 net.client.waitForLedgers(finalHash_moreEarly, totalReplay));
1419 net.client.countsAsExpected(4, 3, 2 * (totalReplay - 1) + 2));
1422 net.client.replayer.replay(
1426 BEAST_EXPECT(net.client.waitAndCheckStatus(
1432 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3));
1433 BEAST_EXPECT(net.client.countsAsExpected(5, 3, totalReplay * 3 - 1));
1436 net.client.replayer.sweep();
1437 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1445 testTaskParameter();
1450 testAllInboundLedgers(1);
1451 testAllInboundLedgers(4);
1457 testSkipListBadReply();
1458 testLedgerDeltaBadReply();
1459 testLedgerReplayOverlap();
1468 testcase(
"SkipListAcquire timeout");
1469 int totalReplay = 3;
1478 uint256 finalHash = l->info().hash;
1479 net.client.replayer.replay(
1483 BEAST_EXPECT(net.client.waitAndCheckStatus(
1491 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1492 net.client.replayer.sweep();
1493 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1499 testcase(
"LedgerDeltaAcquire timeout");
1500 int totalReplay = 3;
1509 uint256 finalHash = l->info().hash;
1510 net.client.ledgerMaster.storeLedger(l);
1511 net.client.replayer.replay(
1517 BEAST_EXPECT(net.client.waitAndCheckStatus(
1525 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1526 net.client.replayer.sweep();
1527 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1533 testSkipListTimeout();
1534 testLedgerDeltaTimeout();
1543 testcase(
"Acquire 1000 ledgers");
1544 int totalReplay = 250;
1548 {totalReplay * rounds + 1},
1554 auto l = net.server.ledgerMaster.getClosedLedger();
1555 for (
int i = 0; i < rounds; ++i)
1558 for (
int j = 0; j < totalReplay; ++j)
1560 l = net.server.ledgerMaster.getLedgerByHash(
1561 l->info().parentHash);
1564 BEAST_EXPECT(finishHashes.size() == rounds);
1566 for (
int i = 0; i < rounds; ++i)
1568 net.client.replayer.replay(
1574 for (
int i = 0; i < rounds; ++i)
1576 BEAST_EXPECT(net.client.waitAndCheckStatus(
1585 net.client.waitForLedgers(finishHashes[0], totalReplay * rounds));
1586 BEAST_EXPECT(net.client.countsAsExpected(
1587 rounds, rounds, rounds * (totalReplay - 1)));
1590 net.client.replayer.sweep();
1591 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));