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);
200 TestPeer(
bool enableLedgerReplay) : ledgerReplayEnabled_(enableLedgerReplay)
340 bool enableLedgerReplay)
343 , dummyPeer(
std::make_shared<
TestPeer>(enableLedgerReplay))
355 onPeerAdded(dummyPeer);
360 ::google::protobuf::Message
const& msg,
361 protocol::MessageType type,
370 if ((rand() % 100 + 1) <= dropRate)
375 case protocol::mtPROOF_PATH_REQ: {
378 auto request = std::make_shared<protocol::TMProofPathRequest>(
379 dynamic_cast<protocol::TMProofPathRequest const&
>(msg));
380 auto reply = std::make_shared<protocol::TMProofPathResponse>(
381 remote.processProofPathRequest(request));
382 local.processProofPathResponse(reply);
384 local.processProofPathResponse(reply);
387 case protocol::mtREPLAY_DELTA_REQ: {
390 auto request = std::make_shared<protocol::TMReplayDeltaRequest>(
391 dynamic_cast<protocol::TMReplayDeltaRequest const&
>(msg));
392 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
393 remote.processReplayDeltaRequest(request));
394 local.processReplayDeltaResponse(reply);
396 local.processReplayDeltaResponse(reply);
438 return std::make_unique<TestPeerSet>(
439 local, remote, behavior, enableLedgerReplay);
458 int initAccounts = 10;
459 int initAmount = 1
'000'000;
460 int numTxPerLedger = 10;
468 , msgHandler(env.app(), env.app().getLedgerReplayer())
471 assert(param.initLedgers > 0);
472 createAccounts(param.initAccounts);
473 createLedgerHistory();
483 auto fundedAccounts = accounts.size();
484 for (
int i = 0; i < newAccounts; ++i)
486 accounts.emplace_back(
488 env.fund(
jtx::XRP(param.initAmount), accounts.back());
499 int fundedAccounts = accounts.size();
500 assert(fundedAccounts >= newTxes);
507 auto updateIdx = [&]() {
508 assert(fundedAccounts > senders.
size());
509 fromIdx = (fromIdx + r) % fundedAccounts;
510 while (senders.
count(fromIdx) != 0)
511 fromIdx = (fromIdx + 1) % fundedAccounts;
513 toIdx = (toIdx + r * 2) % fundedAccounts;
514 if (toIdx == fromIdx)
515 toIdx = (toIdx + 1) % fundedAccounts;
518 for (
int i = 0; i < newTxes; ++i)
522 pay(accounts[fromIdx],
539 for (
int i = 0; i < param.initLedgers - 1; ++i)
541 sendPayments(param.numTxPerLedger);
571 beast::unit_test::suite& suite,
583 server.app.getLedgerMaster(),
586 , serverMsgHandler(server.app, server.app.getLedgerReplayer())
587 , clientMsgHandler(env.app(), replayer)
608 uint256 hash = finishLedgerHash;
610 for (; i < totalReplay; ++i)
615 hash = l->info().parentHash;
623 int totalRound = 100;
624 for (
int i = 0; i < totalRound; ++i)
626 if (haveLedgers(finishLedgerHash, totalReplay))
628 if (i < totalRound - 1)
637 int totalRound = 100;
638 for (
int i = 0; i < totalRound; ++i)
643 for (
auto const& t : replayer.tasks_)
654 if (i < totalRound - 1)
664 return replayer.tasks_;
672 replayer.tasks_.begin(), replayer.tasks_.end(), [&](
auto const& t) {
673 return t->parameter_.finishHash_ == hash &&
674 t->parameter_.totalLedgers_ == totalReplay;
676 if (i == replayer.tasks_.end())
685 return replayer.deltas_.size();
692 return replayer.skipLists_.size();
702 return replayer.tasks_.size() == tasks &&
703 replayer.skipLists_.size() == skipLists &&
704 replayer.deltas_.size() == deltas;
711 auto i = replayer.skipLists_.find(hash);
712 if (i == replayer.skipLists_.end())
714 return i->second.lock();
721 auto i = replayer.deltas_.find(hash);
722 if (i == replayer.deltas_.end())
724 return i->second.lock();
727 template <
typename T>
745 if (taskStatus(task) == taskExpect)
747 if (taskStatus(task->skipListAcquirer_) == skiplistExpect)
749 if (task->deltas_.size() == deltaExpects.
size())
751 for (
int i = 0; i < deltaExpects.
size(); ++i)
753 if (taskStatus(task->deltas_[i]) != deltaExpects[i])
771 auto t = findTask(hash, totalReplay);
779 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
790 auto t = findTask(hash, totalReplay);
798 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
813 hash, totalReplay, taskExpect, skiplistExpect, deltaExpects);
843 beast::unit_test::suite& suite,
848 : server(suite, param)
849 , client(suite, server, behavior, inboundBhvr, peerFeature)
887 testcase(
"ProofPath");
893 auto request = std::make_shared<protocol::TMProofPathRequest>();
894 request->set_ledgerhash(
895 l->info().hash.data(), l->info().hash.size());
896 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
897 auto reply = std::make_shared<protocol::TMProofPathResponse>(
898 server.msgHandler.processProofPathRequest(request));
899 BEAST_EXPECT(reply->has_error());
900 BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
904 auto request = std::make_shared<protocol::TMProofPathRequest>();
905 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
909 request->set_ledgerhash(hash.
data(), hash.
size());
910 auto reply = std::make_shared<protocol::TMProofPathResponse>(
911 server.msgHandler.processProofPathRequest(request));
912 BEAST_EXPECT(reply->has_error());
917 auto request = std::make_shared<protocol::TMProofPathRequest>();
918 request->set_ledgerhash(
919 l->info().hash.data(), l->info().hash.size());
920 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
924 auto reply = std::make_shared<protocol::TMProofPathResponse>(
925 server.msgHandler.processProofPathRequest(request));
926 BEAST_EXPECT(!reply->has_error());
927 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
934 reply->set_ledgerheader(r);
936 !server.msgHandler.processProofPathResponse(reply));
938 reply->set_ledgerheader(r);
939 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
941 reply->mutable_path()->RemoveLast();
943 !server.msgHandler.processProofPathResponse(reply));
951 testcase(
"ReplayDelta");
957 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
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));
964 request->set_ledgerhash(hash.
data(), hash.
size());
965 reply = std::make_shared<protocol::TMReplayDeltaResponse>(
966 server.msgHandler.processReplayDeltaRequest(request));
967 BEAST_EXPECT(reply->has_error());
968 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
973 auto request = std::make_shared<protocol::TMReplayDeltaRequest>();
974 request->set_ledgerhash(
975 l->info().hash.data(), l->info().hash.size());
976 auto reply = std::make_shared<protocol::TMReplayDeltaResponse>(
977 server.msgHandler.processReplayDeltaRequest(request));
978 BEAST_EXPECT(!reply->has_error());
979 BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
986 reply->set_ledgerheader(r);
988 !server.msgHandler.processReplayDeltaResponse(reply));
990 reply->set_ledgerheader(r);
992 server.msgHandler.processReplayDeltaResponse(reply));
994 reply->mutable_transaction()->RemoveLast();
996 !server.msgHandler.processReplayDeltaResponse(reply));
1004 testcase(
"TaskParameter");
1008 for (
int i = 0; i < count; ++i)
1015 BEAST_EXPECT(!tp10.
update(
uint256(777), 5, makeSkipList(10)));
1016 BEAST_EXPECT(!tp10.
update(
uint256(10), 5, makeSkipList(8)));
1017 BEAST_EXPECT(tp10.
update(
uint256(10), 10, makeSkipList(10)));
1047 BEAST_EXPECT(tp20.
update(
uint256(20), 20, makeSkipList(20)));
1057 testcase(
"config test");
1087 testcase(
"handshake test");
1088 auto handshake = [&](
bool client,
bool server,
bool expecting) ->
bool {
1092 http_request.version(request.version());
1093 http_request.base() = request.base();
1096 if (serverResult != expecting)
1100 boost::asio::ip::address::from_string(
"172.1.1.100");
1112 auto const clientResult =
1114 if (clientResult != expecting)
1120 BEAST_EXPECT(handshake(
false,
false,
false));
1121 BEAST_EXPECT(handshake(
false,
true,
false));
1122 BEAST_EXPECT(handshake(
true,
false,
false));
1123 BEAST_EXPECT(handshake(
true,
true,
true));
1129 testcase(
"local node has all the ledgers");
1134 NetworkOfTwo net(*
this, {totalReplay + 1}, psBhvr, ilBhvr, peerFeature);
1137 uint256 finalHash = l->info().hash;
1138 for (
int i = 0; i < totalReplay; ++i)
1143 net.client.ledgerMaster.storeLedger(l);
1144 l = net.server.ledgerMaster.getLedgerByHash(
1145 l->info().parentHash);
1151 net.client.replayer.replay(
1156 BEAST_EXPECT(net.client.waitAndCheckStatus(
1164 net.client.replayer.sweep();
1165 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1171 testcase(
"all the ledgers from InboundLedgers");
1180 uint256 finalHash = l->info().hash;
1181 net.client.replayer.replay(
1186 BEAST_EXPECT(net.client.waitAndCheckStatus(
1194 net.client.replayer.sweep();
1195 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1201 switch (peerSetBehavior)
1204 testcase(
"good network");
1207 testcase(
"network drops 50% messages");
1210 testcase(
"network repeats all messages");
1225 uint256 finalHash = l->info().hash;
1226 for (
int i = 0; i < totalReplay - 1; ++i)
1228 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1230 net.client.ledgerMaster.storeLedger(l);
1232 net.client.replayer.replay(
1237 BEAST_EXPECT(net.client.waitAndCheckStatus(
1243 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1246 net.client.replayer.sweep();
1247 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1253 testcase(
"stop before timeout");
1254 int totalReplay = 3;
1263 uint256 finalHash = l->info().hash;
1264 net.client.replayer.replay(
1268 BEAST_EXPECT(net.client.checkStatus(
1275 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1276 net.client.replayer.stop();
1277 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1283 testcase(
"SkipListAcquire bad reply");
1284 int totalReplay = 3;
1287 {totalReplay + 1 + 1},
1293 uint256 finalHash = l->info().hash;
1294 net.client.replayer.replay(
1297 auto skipList = net.client.findSkipListAcquire(finalHash);
1300 0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, 0xB2};
1303 skipList->processData(l->seq(), item);
1306 BEAST_EXPECT(net.client.waitAndCheckStatus(
1314 net.client.replayer.replay(
1316 BEAST_EXPECT(net.client.waitAndCheckStatus(
1322 BEAST_EXPECT(net.client.countsAsExpected(2, 1, 0));
1328 testcase(
"LedgerDeltaAcquire bad reply");
1329 int totalReplay = 3;
1338 uint256 finalHash = l->info().hash;
1339 net.client.ledgerMaster.storeLedger(l);
1340 net.client.replayer.replay(
1343 auto delta = net.client.findLedgerDeltaAcquire(l->info().parentHash);
1349 net.client.taskStatus(net.client.findTask(
1353 net.client.replayer.replay(
1356 net.client.taskStatus(net.client.findTask(
1363 testcase(
"Overlap tasks");
1364 int totalReplay = 5;
1367 {totalReplay * 3 + 1},
1372 uint256 finalHash = l->info().hash;
1373 net.client.replayer.replay(
1377 BEAST_EXPECT(net.client.waitAndCheckStatus(
1383 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1386 net.client.replayer.replay(
1388 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1390 net.client.replayer.replay(
1392 BEAST_EXPECT(net.client.countsAsExpected(2, 1, totalReplay - 1));
1395 for (
int i = 0; i < totalReplay + 2; ++i)
1397 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1399 auto finalHash_early = l->info().hash;
1400 net.client.replayer.replay(
1402 BEAST_EXPECT(net.client.waitAndCheckStatus(
1408 BEAST_EXPECT(net.client.waitForLedgers(finalHash_early, totalReplay));
1409 BEAST_EXPECT(net.client.countsAsExpected(3, 2, 2 * (totalReplay - 1)));
1412 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1413 auto finalHash_moreEarly = l->info().parentHash;
1414 net.client.replayer.replay(
1416 BEAST_EXPECT(net.client.waitAndCheckStatus(
1417 finalHash_moreEarly,
1423 net.client.waitForLedgers(finalHash_moreEarly, totalReplay));
1425 net.client.countsAsExpected(4, 3, 2 * (totalReplay - 1) + 2));
1428 net.client.replayer.replay(
1432 BEAST_EXPECT(net.client.waitAndCheckStatus(
1438 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3));
1439 BEAST_EXPECT(net.client.countsAsExpected(5, 3, totalReplay * 3 - 1));
1442 net.client.replayer.sweep();
1443 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1451 testTaskParameter();
1456 testAllInboundLedgers(1);
1457 testAllInboundLedgers(4);
1463 testSkipListBadReply();
1464 testLedgerDeltaBadReply();
1465 testLedgerReplayOverlap();
1474 testcase(
"SkipListAcquire timeout");
1475 int totalReplay = 3;
1484 uint256 finalHash = l->info().hash;
1485 net.client.replayer.replay(
1489 BEAST_EXPECT(net.client.waitAndCheckStatus(
1497 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1498 net.client.replayer.sweep();
1499 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1505 testcase(
"LedgerDeltaAcquire timeout");
1506 int totalReplay = 3;
1515 uint256 finalHash = l->info().hash;
1516 net.client.ledgerMaster.storeLedger(l);
1517 net.client.replayer.replay(
1523 BEAST_EXPECT(net.client.waitAndCheckStatus(
1531 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1532 net.client.replayer.sweep();
1533 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1539 testSkipListTimeout();
1540 testLedgerDeltaTimeout();
1549 testcase(
"Acquire 1000 ledgers");
1550 int totalReplay = 250;
1554 {totalReplay * rounds + 1},
1560 auto l = net.server.ledgerMaster.getClosedLedger();
1561 for (
int i = 0; i < rounds; ++i)
1564 for (
int j = 0; j < totalReplay; ++j)
1566 l = net.server.ledgerMaster.getLedgerByHash(
1567 l->info().parentHash);
1570 BEAST_EXPECT(finishHashes.size() == rounds);
1572 for (
int i = 0; i < rounds; ++i)
1574 net.client.replayer.replay(
1580 for (
int i = 0; i < rounds; ++i)
1582 BEAST_EXPECT(net.client.waitAndCheckStatus(
1591 net.client.waitForLedgers(finishHashes[0], totalReplay * rounds));
1592 BEAST_EXPECT(net.client.countsAsExpected(
1593 rounds, rounds, rounds * (totalReplay - 1)));
1596 net.client.replayer.sweep();
1597 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));