rippled
Loading...
Searching...
No Matches
LedgerReplay_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2020 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <test/jtx.h>
21#include <test/jtx/envconfig.h>
22
23#include <xrpld/app/ledger/BuildLedger.h>
24#include <xrpld/app/ledger/LedgerMaster.h>
25#include <xrpld/app/ledger/LedgerReplay.h>
26#include <xrpld/app/ledger/LedgerReplayTask.h>
27#include <xrpld/app/ledger/LedgerReplayer.h>
28#include <xrpld/app/ledger/detail/LedgerDeltaAcquire.h>
29#include <xrpld/app/ledger/detail/LedgerReplayMsgHandler.h>
30#include <xrpld/app/ledger/detail/SkipListAcquire.h>
31#include <xrpld/overlay/PeerSet.h>
32#include <xrpld/overlay/detail/PeerImp.h>
33
34#include <xrpl/basics/Slice.h>
35
36#include <chrono>
37#include <thread>
38
39namespace ripple {
40namespace test {
41
43{
44 void
45 run() override
46 {
47 testcase("Replay ledger");
48
49 using namespace jtx;
50
51 // Build a ledger normally
52 auto const alice = Account("alice");
53 auto const bob = Account("bob");
54
55 Env env(*this);
56 env.fund(XRP(100000), alice, bob);
57 env.close();
58
60 auto const lastClosed = ledgerMaster.getClosedLedger();
61 auto const lastClosedParent =
62 ledgerMaster.getLedgerByHash(lastClosed->info().parentHash);
63
64 auto const replayed = buildLedger(
65 LedgerReplay(lastClosedParent, lastClosed),
66 tapNONE,
67 env.app(),
68 env.journal);
69
70 BEAST_EXPECT(replayed->info().hash == lastClosed->info().hash);
71 }
72};
73
75 Good,
76 DropAll,
77};
78
85{
86public:
94 virtual ~MagicInboundLedgers() = default;
95
98 override
99 {
101 return {};
102 if (auto l = ledgerSource.getLedgerByHash(hash); l)
103 {
105 return l;
106 }
107
108 return {};
109 }
110
111 virtual void
113 uint256 const& hash,
115 InboundLedger::Reason reason) override
116 {
117 }
118
120 find(LedgerHash const& hash) override
121 {
122 return {};
123 }
124
125 virtual bool
127 LedgerHash const& ledgerHash,
130 {
131 return false;
132 }
133
134 virtual void
138
139 virtual void
141 {
142 }
143
144 virtual bool
145 isFailure(uint256 const& h) override
146 {
147 return false;
148 }
149
150 virtual void
151 clearFailures() override
152 {
153 }
154
155 virtual Json::Value
156 getInfo() override
157 {
158 return {};
159 }
160
161 virtual std::size_t
162 fetchRate() override
163 {
164 return 0;
165 }
166
167 virtual void
169 {
170 }
171
172 virtual void
173 gotFetchPack() override
174 {
175 }
176 virtual void
177 sweep() override
178 {
179 }
180
181 virtual void
182 stop() override
183 {
184 }
185
186 virtual size_t
187 cacheSize() override
188 {
189 return 0;
190 }
191
195};
196
197enum class PeerFeature {
199 None,
200};
201
207class TestPeer : public Peer
208{
209public:
210 TestPeer(bool enableLedgerReplay)
211 : ledgerReplayEnabled_(enableLedgerReplay)
213 {
214 }
215
216 void
218 {
219 }
221 getRemoteAddress() const override
222 {
223 return {};
224 }
225 void
226 charge(Resource::Charge const& fee, std::string const& context = {})
227 override
228 {
229 }
230 id_t
231 id() const override
232 {
233 return 1234;
234 }
235 bool
236 cluster() const override
237 {
238 return false;
239 }
240 bool
241 isHighLatency() const override
242 {
243 return false;
244 }
245 int
246 getScore(bool) const override
247 {
248 return 0;
249 }
250 PublicKey const&
251 getNodePublic() const override
252 {
253 return nodePublicKey_;
254 }
256 json() override
257 {
258 return {};
259 }
260 bool
262 {
264 return true;
265 return false;
266 }
268 publisherListSequence(PublicKey const&) const override
269 {
270 return {};
271 }
272 void
274 {
275 }
276 uint256 const&
277 getClosedLedgerHash() const override
278 {
279 static uint256 hash{};
280 return hash;
281 }
282 bool
283 hasLedger(uint256 const& hash, std::uint32_t seq) const override
284 {
285 return true;
286 }
287 void
288 ledgerRange(std::uint32_t& minSeq, std::uint32_t& maxSeq) const override
289 {
290 }
291 bool
292 hasTxSet(uint256 const& hash) const override
293 {
294 return false;
295 }
296 void
297 cycleStatus() override
298 {
299 }
300 bool
302 {
303 return false;
304 }
305 bool
306 compressionEnabled() const override
307 {
308 return false;
309 }
310 void
311 sendTxQueue() override
312 {
313 }
314 void
315 addTxQueue(uint256 const&) override
316 {
317 }
318 void
319 removeTxQueue(uint256 const&) override
320 {
321 }
322 bool
323 txReduceRelayEnabled() const override
324 {
325 return false;
326 }
327
328 std::string const&
329 fingerprint() const override
330 {
331 return fingerprint_;
332 }
333
337};
338
339enum class PeerSetBehavior {
340 Good,
341 Drop50,
342 DropAll,
345 Repeat,
346};
347
354struct TestPeerSet : public PeerSet
355{
359 PeerSetBehavior bhvr,
360 bool enableLedgerReplay)
361 : local(me)
362 , remote(other)
363 , dummyPeer(std::make_shared<TestPeer>(enableLedgerReplay))
364 , behavior(bhvr)
365 {
366 }
367
368 void
370 std::size_t limit,
371 std::function<bool(std::shared_ptr<Peer> const&)> hasItem,
372 std::function<void(std::shared_ptr<Peer> const&)> onPeerAdded) override
373 {
374 hasItem(dummyPeer);
375 onPeerAdded(dummyPeer);
376 }
377
378 void
380 ::google::protobuf::Message const& msg,
381 protocol::MessageType type,
382 std::shared_ptr<Peer> const& peer) override
383 {
384 int dropRate = 0;
386 dropRate = 50;
388 dropRate = 100;
389
390 if ((rand() % 100 + 1) <= dropRate)
391 return;
392
393 switch (type)
394 {
395 case protocol::mtPROOF_PATH_REQ: {
397 return;
399 dynamic_cast<protocol::TMProofPathRequest const&>(msg));
405 break;
406 }
407 case protocol::mtREPLAY_DELTA_REQ: {
409 return;
411 dynamic_cast<protocol::TMReplayDeltaRequest const&>(msg));
417 break;
418 }
419 default:
420 return;
421 }
422 }
423
425 getPeerIds() const override
426 {
427 static std::set<Peer::id_t> emptyPeers;
428 return emptyPeers;
429 }
430
435};
436
468
474{
476 {
478 int initAccounts = 10;
479 int initAmount = 1'000'000;
481 int txAmount = 10;
482 };
483
485 : env(suite)
486 , app(env.app())
487 , ledgerMaster(env.app().getLedgerMaster())
488 , msgHandler(env.app(), env.app().getLedgerReplayer())
489 , param(p)
490 {
491 assert(param.initLedgers > 0);
495 }
496
500 void
501 createAccounts(int newAccounts)
502 {
503 auto fundedAccounts = accounts.size();
504 for (int i = 0; i < newAccounts; ++i)
505 {
506 accounts.emplace_back(
507 "alice_" + std::to_string(fundedAccounts + i));
509 }
510 env.close();
511 }
512
516 void
517 sendPayments(int newTxes)
518 {
519 int fundedAccounts = accounts.size();
520 assert(fundedAccounts >= newTxes);
522
523 // somewhat random but reproducible
524 int r = ledgerMaster.getClosedLedger()->seq() * 7;
525 int fromIdx = 0;
526 int toIdx = 0;
527 auto updateIdx = [&]() {
528 assert(fundedAccounts > senders.size());
529 fromIdx = (fromIdx + r) % fundedAccounts;
530 while (senders.count(fromIdx) != 0)
531 fromIdx = (fromIdx + 1) % fundedAccounts;
532 senders.insert(fromIdx);
533 toIdx = (toIdx + r * 2) % fundedAccounts;
534 if (toIdx == fromIdx)
535 toIdx = (toIdx + 1) % fundedAccounts;
536 };
537
538 for (int i = 0; i < newTxes; ++i)
539 {
540 updateIdx();
541 env.apply(
542 pay(accounts[fromIdx],
543 accounts[toIdx],
544 jtx::drops(ledgerMaster.getClosedLedger()->fees().base) +
549 }
550 env.close();
551 }
552
556 void
558 {
559 for (int i = 0; i < param.initLedgers - 1; ++i)
560 {
562 }
563 }
564
571};
572
573enum class TaskStatus {
574 Failed,
575 Completed,
576 NotDone,
577 NotExist,
578};
579
588{
589public:
592 LedgerServer& server,
596 : env(suite, jtx::envconfig(), nullptr, beast::severities::kDisabled)
597 , app(env.app())
598 , ledgerMaster(env.app().getLedgerMaster())
600 server.app.getLedgerMaster(),
602 inboundBhvr)
603 , serverMsgHandler(server.app, server.app.getLedgerReplayer())
605 , replayer(
606 env.app(),
608 std::make_unique<TestPeerSetBuilder>(
611 behavior,
612 peerFeature))
613 {
614 }
615
616 void
621
622 bool
623 haveLedgers(uint256 const& finishLedgerHash, int totalReplay)
624 {
625 uint256 hash = finishLedgerHash;
626 int i = 0;
627 for (; i < totalReplay; ++i)
628 {
629 auto const l = ledgerMaster.getLedgerByHash(hash);
630 if (!l)
631 return false;
632 hash = l->info().parentHash;
633 }
634 return true;
635 }
636
637 bool
638 waitForLedgers(uint256 const& finishLedgerHash, int totalReplay)
639 {
640 int totalRound = 100;
641 for (int i = 0; i < totalRound; ++i)
642 {
643 if (haveLedgers(finishLedgerHash, totalReplay))
644 return true;
645 if (i < totalRound - 1)
647 }
648 return false;
649 }
650
651 bool
653 {
654 int totalRound = 100;
655 for (int i = 0; i < totalRound; ++i)
656 {
657 bool allDone = true;
658 {
660 for (auto const& t : replayer.tasks_)
661 {
662 if (!t->finished())
663 {
664 allDone = false;
665 break;
666 }
667 }
668 }
669 if (allDone)
670 return true;
671 if (i < totalRound - 1)
673 }
674 return false;
675 }
676
679 {
681 return replayer.tasks_;
682 }
683
685 findTask(uint256 const& hash, int totalReplay)
686 {
688 auto i = std::find_if(
689 replayer.tasks_.begin(), replayer.tasks_.end(), [&](auto const& t) {
690 return t->parameter_.finishHash_ == hash &&
691 t->parameter_.totalLedgers_ == totalReplay;
692 });
693 if (i == replayer.tasks_.end())
694 return {};
695 return *i;
696 }
697
700 {
702 return replayer.deltas_.size();
703 }
704
707 {
709 return replayer.skipLists_.size();
710 }
711
712 bool
714 std::size_t tasks,
715 std::size_t skipLists,
716 std::size_t deltas)
717 {
719 return replayer.tasks_.size() == tasks &&
720 replayer.skipLists_.size() == skipLists &&
721 replayer.deltas_.size() == deltas;
722 }
723
726 {
728 auto i = replayer.skipLists_.find(hash);
729 if (i == replayer.skipLists_.end())
730 return {};
731 return i->second.lock();
732 }
733
736 {
738 auto i = replayer.deltas_.find(hash);
739 if (i == replayer.deltas_.end())
740 return {};
741 return i->second.lock();
742 }
743
744 template <typename T>
747 {
748 if (t->failed_)
749 return TaskStatus::Failed;
750 if (t->complete_)
752 return TaskStatus::NotDone;
753 }
754
755 bool
758 TaskStatus taskExpect,
759 TaskStatus skiplistExpect,
760 std::vector<TaskStatus> const& deltaExpects)
761 {
762 if (taskStatus(task) == taskExpect)
763 {
764 if (taskStatus(task->skipListAcquirer_) == skiplistExpect)
765 {
766 if (task->deltas_.size() == deltaExpects.size())
767 {
768 for (int i = 0; i < deltaExpects.size(); ++i)
769 {
770 if (taskStatus(task->deltas_[i]) != deltaExpects[i])
771 return false;
772 }
773 return true;
774 }
775 }
776 }
777 return false;
778 }
779
780 bool
782 uint256 const& hash,
783 int totalReplay,
784 TaskStatus taskExpect,
785 TaskStatus skiplistExpect,
786 std::vector<TaskStatus> const& deltaExpects)
787 {
788 auto t = findTask(hash, totalReplay);
789 if (!t)
790 {
791 if (taskExpect == TaskStatus::NotExist)
792 return true;
793 return false;
794 }
795
796 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
797 }
798
799 bool
801 uint256 const& hash,
802 int totalReplay,
803 TaskStatus taskExpect,
804 TaskStatus skiplistExpect,
805 std::vector<TaskStatus> const& deltaExpects)
806 {
807 auto t = findTask(hash, totalReplay);
808 if (!t)
809 {
810 if (taskExpect == TaskStatus::NotExist)
811 return true;
812 return false;
813 }
814
815 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
816 }
817
818 bool
820 uint256 const& hash,
821 int totalReplay,
822 TaskStatus taskExpect,
823 TaskStatus skiplistExpect,
824 std::vector<TaskStatus> const& deltaExpects)
825 {
826 if (!waitForDone())
827 return false;
828
829 return checkStatus(
830 hash, totalReplay, taskExpect, skiplistExpect, deltaExpects);
831 }
832
840};
841
842using namespace beast::severities;
843void
845 LedgerServer& server,
846 LedgerReplayClient& client,
847 beast::severities::Severity level = Severity::kTrace)
848{
849 server.app.logs().threshold(level);
850 client.app.logs().threshold(level);
851}
852// logAll(net.server, net.client);
853
854/*
855 * Create a LedgerServer and a LedgerReplayClient
856 */
858{
861 LedgerServer::Parameter const& param,
865 : server(suite, param)
866 , client(suite, server, behavior, inboundBhvr, peerFeature)
867 {
868 // logAll(server, client);
869 }
872};
873
900{
901 void
903 {
904 testcase("ProofPath");
905 LedgerServer server(*this, {1});
906 auto const l = server.ledgerMaster.getClosedLedger();
907
908 {
909 // request, missing key
911 request->set_ledgerhash(
912 l->info().hash.data(), l->info().hash.size());
913 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
915 server.msgHandler.processProofPathRequest(request));
916 BEAST_EXPECT(reply->has_error());
917 BEAST_EXPECT(!server.msgHandler.processProofPathResponse(reply));
918 }
919 {
920 // request, wrong hash
922 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
923 request->set_key(
924 keylet::skip().key.data(), keylet::skip().key.size());
925 uint256 hash(1234567);
926 request->set_ledgerhash(hash.data(), hash.size());
928 server.msgHandler.processProofPathRequest(request));
929 BEAST_EXPECT(reply->has_error());
930 }
931
932 {
933 // good request
935 request->set_ledgerhash(
936 l->info().hash.data(), l->info().hash.size());
937 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
938 request->set_key(
939 keylet::skip().key.data(), keylet::skip().key.size());
940 // generate response
942 server.msgHandler.processProofPathRequest(request));
943 BEAST_EXPECT(!reply->has_error());
944 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
945
946 {
947 // bad reply
948 // bad header
949 std::string r(reply->ledgerheader());
950 r.back()--;
951 reply->set_ledgerheader(r);
952 BEAST_EXPECT(
953 !server.msgHandler.processProofPathResponse(reply));
954 r.back()++;
955 reply->set_ledgerheader(r);
956 BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));
957 // bad proof path
958 reply->mutable_path()->RemoveLast();
959 BEAST_EXPECT(
960 !server.msgHandler.processProofPathResponse(reply));
961 }
962 }
963 }
964
965 void
967 {
968 testcase("ReplayDelta");
969 LedgerServer server(*this, {1});
970 auto const l = server.ledgerMaster.getClosedLedger();
971
972 {
973 // request, missing hash
976 server.msgHandler.processReplayDeltaRequest(request));
977 BEAST_EXPECT(reply->has_error());
978 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
979 // request, wrong hash
980 uint256 hash(1234567);
981 request->set_ledgerhash(hash.data(), hash.size());
983 server.msgHandler.processReplayDeltaRequest(request));
984 BEAST_EXPECT(reply->has_error());
985 BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(reply));
986 }
987
988 {
989 // good request
991 request->set_ledgerhash(
992 l->info().hash.data(), l->info().hash.size());
994 server.msgHandler.processReplayDeltaRequest(request));
995 BEAST_EXPECT(!reply->has_error());
996 BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));
997
998 {
999 // bad reply
1000 // bad header
1001 std::string r(reply->ledgerheader());
1002 r.back()--;
1003 reply->set_ledgerheader(r);
1004 BEAST_EXPECT(
1005 !server.msgHandler.processReplayDeltaResponse(reply));
1006 r.back()++;
1007 reply->set_ledgerheader(r);
1008 BEAST_EXPECT(
1009 server.msgHandler.processReplayDeltaResponse(reply));
1010 // bad txns
1011 reply->mutable_transaction()->RemoveLast();
1012 BEAST_EXPECT(
1013 !server.msgHandler.processReplayDeltaResponse(reply));
1014 }
1015 }
1016 }
1017
1018 void
1020 {
1021 testcase("TaskParameter");
1022
1023 auto makeSkipList = [](int count) -> std::vector<uint256> const {
1025 for (int i = 0; i < count; ++i)
1026 sList.emplace_back(i);
1027 return sList;
1028 };
1029
1032 BEAST_EXPECT(!tp10.update(uint256(777), 5, makeSkipList(10)));
1033 BEAST_EXPECT(!tp10.update(uint256(10), 5, makeSkipList(8)));
1034 BEAST_EXPECT(tp10.update(uint256(10), 10, makeSkipList(10)));
1035
1036 // can merge to self
1037 BEAST_EXPECT(tp10.canMergeInto(tp10));
1038
1039 // smaller task
1042
1043 BEAST_EXPECT(tp9.canMergeInto(tp10));
1044 BEAST_EXPECT(!tp10.canMergeInto(tp9));
1045
1046 tp9.totalLedgers_++;
1047 BEAST_EXPECT(!tp9.canMergeInto(tp10));
1048 tp9.totalLedgers_--;
1049 BEAST_EXPECT(tp9.canMergeInto(tp10));
1050
1052 BEAST_EXPECT(!tp9.canMergeInto(tp10));
1054 BEAST_EXPECT(tp9.canMergeInto(tp10));
1055
1056 tp9.finishHash_ = uint256(1234);
1057 BEAST_EXPECT(!tp9.canMergeInto(tp10));
1058 tp9.finishHash_ = uint256(9);
1059 BEAST_EXPECT(tp9.canMergeInto(tp10));
1060
1061 // larger task
1064 BEAST_EXPECT(tp20.update(uint256(20), 20, makeSkipList(20)));
1065 BEAST_EXPECT(tp10.canMergeInto(tp20));
1066 BEAST_EXPECT(tp9.canMergeInto(tp20));
1067 BEAST_EXPECT(!tp20.canMergeInto(tp10));
1068 BEAST_EXPECT(!tp20.canMergeInto(tp9));
1069 }
1070
1071 void
1073 {
1074 testcase("config test");
1075 {
1076 Config c;
1077 BEAST_EXPECT(c.LEDGER_REPLAY == false);
1078 }
1079
1080 {
1081 Config c;
1082 std::string toLoad(R"rippleConfig(
1083[ledger_replay]
10841
1085)rippleConfig");
1086 c.loadFromString(toLoad);
1087 BEAST_EXPECT(c.LEDGER_REPLAY == true);
1088 }
1089
1090 {
1091 Config c;
1092 std::string toLoad = (R"rippleConfig(
1093[ledger_replay]
10940
1095)rippleConfig");
1096 c.loadFromString(toLoad);
1097 BEAST_EXPECT(c.LEDGER_REPLAY == false);
1098 }
1099 }
1100
1101 void
1103 {
1104 testcase("handshake test");
1105 auto handshake = [&](bool client, bool server, bool expecting) -> bool {
1106 auto request =
1107 ripple::makeRequest(true, false, client, false, false);
1108 http_request_type http_request;
1109 http_request.version(request.version());
1110 http_request.base() = request.base();
1111 bool serverResult =
1112 peerFeatureEnabled(http_request, FEATURE_LEDGER_REPLAY, server);
1113 if (serverResult != expecting)
1114 return false;
1115
1116 beast::IP::Address addr =
1117 boost::asio::ip::make_address("172.1.1.100");
1118 jtx::Env serverEnv(*this);
1119 serverEnv.app().config().LEDGER_REPLAY = server;
1120 auto http_resp = ripple::makeResponse(
1121 true,
1122 http_request,
1123 addr,
1124 addr,
1125 uint256{1},
1126 1,
1127 {1, 0},
1128 serverEnv.app());
1129 auto const clientResult =
1130 peerFeatureEnabled(http_resp, FEATURE_LEDGER_REPLAY, client);
1131 if (clientResult != expecting)
1132 return false;
1133
1134 return true;
1135 };
1136
1137 BEAST_EXPECT(handshake(false, false, false));
1138 BEAST_EXPECT(handshake(false, true, false));
1139 BEAST_EXPECT(handshake(true, false, false));
1140 BEAST_EXPECT(handshake(true, true, true));
1141 }
1142
1143 void
1144 testAllLocal(int totalReplay)
1145 {
1146 testcase("local node has all the ledgers");
1147 auto psBhvr = PeerSetBehavior::DropAll;
1148 auto ilBhvr = InboundLedgersBehavior::DropAll;
1149 auto peerFeature = PeerFeature::None;
1150
1151 NetworkOfTwo net(*this, {totalReplay + 1}, psBhvr, ilBhvr, peerFeature);
1152
1153 auto l = net.server.ledgerMaster.getClosedLedger();
1154 uint256 finalHash = l->info().hash;
1155 for (int i = 0; i < totalReplay; ++i)
1156 {
1157 BEAST_EXPECT(l);
1158 if (l)
1159 {
1160 net.client.ledgerMaster.storeLedger(l);
1161 l = net.server.ledgerMaster.getLedgerByHash(
1162 l->info().parentHash);
1163 }
1164 else
1165 break;
1166 }
1167
1168 net.client.replayer.replay(
1169 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1170
1171 std::vector<TaskStatus> deltaStatuses(
1172 totalReplay - 1, TaskStatus::Completed);
1173 BEAST_EXPECT(net.client.waitAndCheckStatus(
1174 finalHash,
1175 totalReplay,
1178 deltaStatuses));
1179
1180 // sweep
1181 net.client.replayer.sweep();
1182 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1183 }
1184
1185 void
1186 testAllInboundLedgers(int totalReplay)
1187 {
1188 testcase("all the ledgers from InboundLedgers");
1189 NetworkOfTwo net(
1190 *this,
1191 {totalReplay + 1},
1195
1196 auto l = net.server.ledgerMaster.getClosedLedger();
1197 uint256 finalHash = l->info().hash;
1198 net.client.replayer.replay(
1199 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1200
1201 std::vector<TaskStatus> deltaStatuses(
1202 totalReplay - 1, TaskStatus::Completed);
1203 BEAST_EXPECT(net.client.waitAndCheckStatus(
1204 finalHash,
1205 totalReplay,
1208 deltaStatuses));
1209
1210 // sweep
1211 net.client.replayer.sweep();
1212 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1213 }
1214
1215 void
1216 testPeerSetBehavior(PeerSetBehavior peerSetBehavior, int totalReplay = 4)
1217 {
1218 switch (peerSetBehavior)
1219 {
1221 testcase("good network");
1222 break;
1224 testcase("network drops 50% messages");
1225 break;
1227 testcase("network repeats all messages");
1228 break;
1229 default:
1230 return;
1231 }
1232
1233 NetworkOfTwo net(
1234 *this,
1235 {totalReplay + 1},
1236 peerSetBehavior,
1239
1240 // feed client with start ledger since InboundLedgers drops all
1241 auto l = net.server.ledgerMaster.getClosedLedger();
1242 uint256 finalHash = l->info().hash;
1243 for (int i = 0; i < totalReplay - 1; ++i)
1244 {
1245 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1246 }
1247 net.client.ledgerMaster.storeLedger(l);
1248
1249 net.client.replayer.replay(
1250 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1251
1252 std::vector<TaskStatus> deltaStatuses(
1253 totalReplay - 1, TaskStatus::Completed);
1254 BEAST_EXPECT(net.client.waitAndCheckStatus(
1255 finalHash,
1256 totalReplay,
1259 deltaStatuses));
1260 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1261
1262 // sweep
1263 net.client.replayer.sweep();
1264 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1265 }
1266
1267 void
1269 {
1270 testcase("stop before timeout");
1271 int totalReplay = 3;
1272 NetworkOfTwo net(
1273 *this,
1274 {totalReplay + 1},
1278
1279 auto l = net.server.ledgerMaster.getClosedLedger();
1280 uint256 finalHash = l->info().hash;
1281 net.client.replayer.replay(
1282 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1283
1284 std::vector<TaskStatus> deltaStatuses;
1285 BEAST_EXPECT(net.client.checkStatus(
1286 finalHash,
1287 totalReplay,
1290 deltaStatuses));
1291
1292 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1293 net.client.replayer.stop();
1294 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1295 }
1296
1297 void
1299 {
1300 testcase("SkipListAcquire bad reply");
1301 int totalReplay = 3;
1302 NetworkOfTwo net(
1303 *this,
1304 {totalReplay + 1 + 1},
1308
1309 auto l = net.server.ledgerMaster.getClosedLedger();
1310 uint256 finalHash = l->info().hash;
1311 net.client.replayer.replay(
1312 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1313
1314 auto skipList = net.client.findSkipListAcquire(finalHash);
1315
1316 std::uint8_t payload[55] = {
1317 0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, 0xB2};
1318 auto item =
1319 make_shamapitem(uint256(12345), Slice(payload, sizeof(payload)));
1320 skipList->processData(l->seq(), item);
1321
1322 std::vector<TaskStatus> deltaStatuses;
1323 BEAST_EXPECT(net.client.waitAndCheckStatus(
1324 finalHash,
1325 totalReplay,
1328 deltaStatuses));
1329
1330 // add another task
1331 net.client.replayer.replay(
1332 InboundLedger::Reason::GENERIC, finalHash, totalReplay + 1);
1333 BEAST_EXPECT(net.client.waitAndCheckStatus(
1334 finalHash,
1335 totalReplay,
1338 deltaStatuses));
1339 BEAST_EXPECT(net.client.countsAsExpected(2, 1, 0));
1340 }
1341
1342 void
1344 {
1345 testcase("LedgerDeltaAcquire bad reply");
1346 int totalReplay = 3;
1347 NetworkOfTwo net(
1348 *this,
1349 {totalReplay + 1},
1353
1354 auto l = net.server.ledgerMaster.getClosedLedger();
1355 uint256 finalHash = l->info().hash;
1356 net.client.ledgerMaster.storeLedger(l);
1357 net.client.replayer.replay(
1358 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1359
1360 auto delta = net.client.findLedgerDeltaAcquire(l->info().parentHash);
1361 delta->processData(
1362 l->info(), // wrong ledger info
1364 BEAST_EXPECT(net.client.taskStatus(delta) == TaskStatus::Failed);
1365 BEAST_EXPECT(
1366 net.client.taskStatus(net.client.findTask(
1367 finalHash, totalReplay)) == TaskStatus::Failed);
1368
1369 // add another task
1370 net.client.replayer.replay(
1371 InboundLedger::Reason::GENERIC, finalHash, totalReplay + 1);
1372 BEAST_EXPECT(
1373 net.client.taskStatus(net.client.findTask(
1374 finalHash, totalReplay + 1)) == TaskStatus::Failed);
1375 }
1376
1377 void
1379 {
1380 testcase("Overlap tasks");
1381 int totalReplay = 5;
1382 NetworkOfTwo net(
1383 *this,
1384 {totalReplay * 3 + 1},
1388 auto l = net.server.ledgerMaster.getClosedLedger();
1389 uint256 finalHash = l->info().hash;
1390 net.client.replayer.replay(
1391 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1392 std::vector<TaskStatus> deltaStatuses(
1393 totalReplay - 1, TaskStatus::Completed);
1394 BEAST_EXPECT(net.client.waitAndCheckStatus(
1395 finalHash,
1396 totalReplay,
1399 deltaStatuses));
1400 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1401
1402 // same range, same reason
1403 net.client.replayer.replay(
1404 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1405 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1406 // same range, different reason
1407 net.client.replayer.replay(
1408 InboundLedger::Reason::CONSENSUS, finalHash, totalReplay);
1409 BEAST_EXPECT(net.client.countsAsExpected(2, 1, totalReplay - 1));
1410
1411 // no overlap
1412 for (int i = 0; i < totalReplay + 2; ++i)
1413 {
1414 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1415 }
1416 auto finalHash_early = l->info().hash;
1417 net.client.replayer.replay(
1418 InboundLedger::Reason::GENERIC, finalHash_early, totalReplay);
1419 BEAST_EXPECT(net.client.waitAndCheckStatus(
1420 finalHash_early,
1421 totalReplay,
1424 deltaStatuses)); // deltaStatuses no change
1425 BEAST_EXPECT(net.client.waitForLedgers(finalHash_early, totalReplay));
1426 BEAST_EXPECT(net.client.countsAsExpected(3, 2, 2 * (totalReplay - 1)));
1427
1428 // partial overlap
1429 l = net.server.ledgerMaster.getLedgerByHash(l->info().parentHash);
1430 auto finalHash_moreEarly = l->info().parentHash;
1431 net.client.replayer.replay(
1432 InboundLedger::Reason::GENERIC, finalHash_moreEarly, totalReplay);
1433 BEAST_EXPECT(net.client.waitAndCheckStatus(
1434 finalHash_moreEarly,
1435 totalReplay,
1438 deltaStatuses)); // deltaStatuses no change
1439 BEAST_EXPECT(
1440 net.client.waitForLedgers(finalHash_moreEarly, totalReplay));
1441 BEAST_EXPECT(
1442 net.client.countsAsExpected(4, 3, 2 * (totalReplay - 1) + 2));
1443
1444 // cover
1445 net.client.replayer.replay(
1446 InboundLedger::Reason::GENERIC, finalHash, totalReplay * 3);
1447 deltaStatuses =
1448 std::vector<TaskStatus>(totalReplay * 3 - 1, TaskStatus::Completed);
1449 BEAST_EXPECT(net.client.waitAndCheckStatus(
1450 finalHash,
1451 totalReplay * 3,
1454 deltaStatuses)); // deltaStatuses changed
1455 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3));
1456 BEAST_EXPECT(net.client.countsAsExpected(5, 3, totalReplay * 3 - 1));
1457
1458 // sweep
1459 net.client.replayer.sweep();
1460 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1461 }
1462
1463 void
1484};
1485
1487{
1488 void
1490 {
1491 testcase("SkipListAcquire timeout");
1492 int totalReplay = 3;
1493 NetworkOfTwo net(
1494 *this,
1495 {totalReplay + 1},
1499
1500 auto l = net.server.ledgerMaster.getClosedLedger();
1501 uint256 finalHash = l->info().hash;
1502 net.client.replayer.replay(
1503 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1504
1505 std::vector<TaskStatus> deltaStatuses;
1506 BEAST_EXPECT(net.client.waitAndCheckStatus(
1507 finalHash,
1508 totalReplay,
1511 deltaStatuses));
1512
1513 // sweep
1514 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1515 net.client.replayer.sweep();
1516 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1517 }
1518
1519 void
1521 {
1522 testcase("LedgerDeltaAcquire timeout");
1523 int totalReplay = 3;
1524 NetworkOfTwo net(
1525 *this,
1526 {totalReplay + 1},
1530
1531 auto l = net.server.ledgerMaster.getClosedLedger();
1532 uint256 finalHash = l->info().hash;
1533 net.client.ledgerMaster.storeLedger(l);
1534 net.client.replayer.replay(
1535 InboundLedger::Reason::GENERIC, finalHash, totalReplay);
1536
1537 std::vector<TaskStatus> deltaStatuses(
1538 totalReplay - 1, TaskStatus::Failed);
1539 deltaStatuses.back() = TaskStatus::Completed; // in client ledgerMaster
1540 BEAST_EXPECT(net.client.waitAndCheckStatus(
1541 finalHash,
1542 totalReplay,
1545 deltaStatuses));
1546
1547 // sweep
1548 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1549 net.client.replayer.sweep();
1550 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1551 }
1552
1553 void
1554 run() override
1555 {
1558 }
1559};
1560
1562{
1563 void
1564 run() override
1565 {
1566 testcase("Acquire 1000 ledgers");
1567 int totalReplay = 250;
1568 int rounds = 4;
1569 NetworkOfTwo net(
1570 *this,
1571 {totalReplay * rounds + 1},
1575
1576 std::vector<uint256> finishHashes;
1577 auto l = net.server.ledgerMaster.getClosedLedger();
1578 for (int i = 0; i < rounds; ++i)
1579 {
1580 finishHashes.push_back(l->info().hash);
1581 for (int j = 0; j < totalReplay; ++j)
1582 {
1583 l = net.server.ledgerMaster.getLedgerByHash(
1584 l->info().parentHash);
1585 }
1586 }
1587 BEAST_EXPECT(finishHashes.size() == rounds);
1588
1589 for (int i = 0; i < rounds; ++i)
1590 {
1591 net.client.replayer.replay(
1592 InboundLedger::Reason::GENERIC, finishHashes[i], totalReplay);
1593 }
1594
1595 std::vector<TaskStatus> deltaStatuses(
1596 totalReplay - 1, TaskStatus::Completed);
1597 for (int i = 0; i < rounds; ++i)
1598 {
1599 BEAST_EXPECT(net.client.waitAndCheckStatus(
1600 finishHashes[i],
1601 totalReplay,
1604 deltaStatuses));
1605 }
1606
1607 BEAST_EXPECT(
1608 net.client.waitForLedgers(finishHashes[0], totalReplay * rounds));
1609 BEAST_EXPECT(net.client.countsAsExpected(
1610 rounds, rounds, rounds * (totalReplay - 1)));
1611
1612 // sweep
1613 net.client.replayer.sweep();
1614 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1615 }
1616};
1617
1618BEAST_DEFINE_TESTSUITE(LedgerReplay, app, ripple);
1619BEAST_DEFINE_TESTSUITE_PRIO(LedgerReplayer, app, ripple, 1);
1620BEAST_DEFINE_TESTSUITE(LedgerReplayerTimeout, app, ripple);
1621BEAST_DEFINE_TESTSUITE_MANUAL(LedgerReplayerLong, app, ripple);
1622
1623} // namespace test
1624} // namespace ripple
T back(T... args)
Represents a JSON value.
Definition json_value.h:149
A version-independent IP address and port combination.
Definition IPEndpoint.h:38
A testsuite class.
Definition suite.h:55
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:155
virtual Config & config()=0
virtual LedgerMaster & getLedgerMaster()=0
virtual Logs & logs()=0
bool LEDGER_REPLAY
Definition Config.h:223
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Definition Config.cpp:479
Manages the lifetime of inbound ledgers.
std::shared_ptr< Ledger const > getClosedLedger()
bool storeLedger(std::shared_ptr< Ledger const > ledger)
std::shared_ptr< Ledger const > getLedgerByHash(uint256 const &hash)
protocol::TMReplayDeltaResponse processReplayDeltaRequest(std::shared_ptr< protocol::TMReplayDeltaRequest > const &msg)
Process TMReplayDeltaRequest and return TMReplayDeltaResponse.
bool processProofPathResponse(std::shared_ptr< protocol::TMProofPathResponse > const &msg)
Process TMProofPathResponse.
bool processReplayDeltaResponse(std::shared_ptr< protocol::TMReplayDeltaResponse > const &msg)
Process TMReplayDeltaResponse.
protocol::TMProofPathResponse processProofPathRequest(std::shared_ptr< protocol::TMProofPathRequest > const &msg)
Process TMProofPathRequest and return TMProofPathResponse.
bool update(uint256 const &hash, std::uint32_t seq, std::vector< uint256 > const &sList)
fill all the fields that was not filled during construction
bool canMergeInto(TaskParameter const &existingTask) const
check if this task can be merged into an existing task
Manages the lifetime of ledger replay tasks.
std::vector< std::shared_ptr< LedgerReplayTask > > tasks_
hash_map< uint256, std::weak_ptr< SkipListAcquire > > skipLists_
hash_map< uint256, std::weak_ptr< LedgerDeltaAcquire > > deltas_
beast::severities::Severity threshold() const
Definition Log.cpp:166
Supports data retrieval by managing a set of peers.
Definition PeerSet.h:40
Represents a peer connection in the overlay.
std::uint32_t id_t
Uniquely identifies a peer.
A public key.
Definition PublicKey.h:62
A consumption charge.
Definition Charge.h:30
An immutable linear range of bytes.
Definition Slice.h:46
static constexpr std::size_t size()
Definition base_uint.h:526
bool waitForLedgers(uint256 const &finishLedgerHash, int totalReplay)
bool asExpected(uint256 const &hash, int totalReplay, TaskStatus taskExpect, TaskStatus skiplistExpect, std::vector< TaskStatus > const &deltaExpects)
bool waitAndCheckStatus(uint256 const &hash, int totalReplay, TaskStatus taskExpect, TaskStatus skiplistExpect, std::vector< TaskStatus > const &deltaExpects)
LedgerReplayMsgHandler clientMsgHandler
std::shared_ptr< LedgerReplayTask > findTask(uint256 const &hash, int totalReplay)
LedgerReplayMsgHandler serverMsgHandler
bool countsAsExpected(std::size_t tasks, std::size_t skipLists, std::size_t deltas)
bool asExpected(std::shared_ptr< LedgerReplayTask > const &task, TaskStatus taskExpect, TaskStatus skiplistExpect, std::vector< TaskStatus > const &deltaExpects)
std::vector< std::shared_ptr< LedgerReplayTask > > getTasks()
std::shared_ptr< LedgerDeltaAcquire > findLedgerDeltaAcquire(uint256 const &hash)
bool haveLedgers(uint256 const &finishLedgerHash, int totalReplay)
LedgerReplayClient(beast::unit_test::suite &suite, LedgerServer &server, PeerSetBehavior behavior=PeerSetBehavior::Good, InboundLedgersBehavior inboundBhvr=InboundLedgersBehavior::Good, PeerFeature peerFeature=PeerFeature::LedgerReplayEnabled)
bool checkStatus(uint256 const &hash, int totalReplay, TaskStatus taskExpect, TaskStatus skiplistExpect, std::vector< TaskStatus > const &deltaExpects)
TaskStatus taskStatus(std::shared_ptr< T > const &t)
void addLedger(std::shared_ptr< Ledger const > const &l)
std::shared_ptr< SkipListAcquire > findSkipListAcquire(uint256 const &hash)
Simulate a network InboundLedgers.
virtual void acquireAsync(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason reason) override
virtual void onLedgerFetched() override
Called when a complete ledger is obtained.
virtual bool gotLedgerData(LedgerHash const &ledgerHash, std::shared_ptr< Peer >, std::shared_ptr< protocol::TMLedgerData >) override
virtual std::shared_ptr< InboundLedger > find(LedgerHash const &hash) override
virtual ~MagicInboundLedgers()=default
virtual Json::Value getInfo() override
virtual size_t cacheSize() override
virtual void logFailure(uint256 const &h, std::uint32_t seq) override
MagicInboundLedgers(LedgerMaster &ledgerSource, LedgerMaster &ledgerSink, InboundLedgersBehavior bhvr)
virtual bool isFailure(uint256 const &h) override
virtual void gotStaleData(std::shared_ptr< protocol::TMLedgerData > packet) override
virtual std::size_t fetchRate() override
Returns the rate of historical ledger fetches per minute.
virtual std::shared_ptr< Ledger const > acquire(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason) override
std::unique_ptr< PeerSet > build() override
TestPeerSetBuilder(LedgerReplayMsgHandler &me, LedgerReplayMsgHandler &other, PeerSetBehavior bhvr, PeerFeature peerFeature)
Simulate a network peer.
bool hasLedger(uint256 const &hash, std::uint32_t seq) const override
void setPublisherListSequence(PublicKey const &, std::size_t const) override
bool cluster() const override
Returns true if this connection is a member of the cluster.
std::optional< std::size_t > publisherListSequence(PublicKey const &) const override
void removeTxQueue(uint256 const &) override
Remove hash from the transactions' hashes queue.
beast::IP::Endpoint getRemoteAddress() const override
TestPeer(bool enableLedgerReplay)
int getScore(bool) const override
PublicKey const & getNodePublic() const override
void charge(Resource::Charge const &fee, std::string const &context={}) override
Adjust this peer's load balance based on the type of load imposed.
Json::Value json() override
void send(std::shared_ptr< Message > const &m) override
void ledgerRange(std::uint32_t &minSeq, std::uint32_t &maxSeq) const override
void addTxQueue(uint256 const &) override
Aggregate transaction's hash.
id_t id() const override
bool txReduceRelayEnabled() const override
bool isHighLatency() const override
bool hasTxSet(uint256 const &hash) const override
std::string const & fingerprint() const override
uint256 const & getClosedLedgerHash() const override
bool compressionEnabled() const override
bool hasRange(std::uint32_t uMin, std::uint32_t uMax) override
bool supportsFeature(ProtocolFeature f) const override
void sendTxQueue() override
Send aggregated transactions' hashes.
Immutable cryptographic account descriptor.
Definition Account.h:39
A transaction testing environment.
Definition Env.h:121
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:122
Application & app()
Definition Env.h:261
beast::Journal const journal
Definition Env.h:162
Env & apply(JsonValue &&jv, FN const &... fN)
Apply funclets and submit.
Definition Env.h:582
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:290
Set the fee on a JTx.
Definition fee.h:37
Set the regular signature on a JTx.
Definition sig.h:35
T count(T... args)
T emplace_back(T... args)
T find_if(T... args)
T insert(T... args)
T is_same_v
boost::asio::ip::address Address
Definition IPAddress.h:39
A namespace for easy access to logging severity values.
Definition Journal.h:30
Severity
Severity level / threshold of a Journal message.
Definition Journal.h:32
Keylet const & skip() noexcept
The index of the "short" skip list.
Definition Indexes.cpp:196
static autofill_t const autofill
Definition tags.h:42
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Definition pay.cpp:30
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition envconfig.h:54
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:111
static uint256 ledgerHash(LedgerInfo const &info)
void logAll(LedgerServer &server, LedgerReplayClient &client, beast::severities::Severity level=Severity::kTrace)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
base_uint< 256 > uint256
Definition base_uint.h:558
http_response_type makeResponse(bool crawlPublic, http_request_type const &req, beast::IP::Address public_ip, beast::IP::Address remote_ip, uint256 const &sharedValue, std::optional< std::uint32_t > networkID, ProtocolVersion protocol, Application &app)
Make http response.
static constexpr char FEATURE_LEDGER_REPLAY[]
Definition Handshake.h:147
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
KeyType
Definition KeyType.h:28
std::shared_ptr< Ledger > buildLedger(std::shared_ptr< Ledger const > const &parent, NetClock::time_point closeTime, bool const closeTimeCorrect, NetClock::duration closeResolution, Application &app, CanonicalTXSet &txns, std::set< TxID > &failedTxs, beast::Journal j)
Build a new ledger by applying consensus transactions.
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition Handoff.h:33
boost::intrusive_ptr< SHAMapItem > make_shamapitem(uint256 const &tag, Slice data)
Definition SHAMapItem.h:161
bool peerFeatureEnabled(headers const &request, std::string const &feature, std::string value, bool config)
Check if a feature should be enabled for a peer.
Definition Handshake.h:198
auto makeRequest(bool crawlPublic, bool comprEnabled, bool ledgerReplayEnabled, bool txReduceRelayEnabled, bool vpReduceRelayEnabled) -> request_type
Make outbound http request.
@ tapNONE
Definition ApplyView.h:31
@ ledgerMaster
ledger master data for signing
STL namespace.
T push_back(T... args)
T size(T... args)
T sleep_for(T... args)
uint256 key
Definition Keylet.h:40
void run() override
Runs the suite.
Test cases: LedgerReplayer_test: – process TMProofPathRequest and TMProofPathResponse – process TMRep...
void run() override
Runs the suite.
void testPeerSetBehavior(PeerSetBehavior peerSetBehavior, int totalReplay=4)
Utility class for (1) creating ledgers with txns and (2) providing the ledgers via the ledgerMaster.
void createAccounts(int newAccounts)
LedgerReplayMsgHandler msgHandler
std::vector< jtx::Account > accounts
void createLedgerHistory()
create ledger history
LedgerServer(beast::unit_test::suite &suite, Parameter const &p)
NetworkOfTwo(beast::unit_test::suite &suite, LedgerServer::Parameter const &param, PeerSetBehavior behavior=PeerSetBehavior::Good, InboundLedgersBehavior inboundBhvr=InboundLedgersBehavior::Good, PeerFeature peerFeature=PeerFeature::LedgerReplayEnabled)
Simulate a peerSet that supplies peers to ledger replay subtasks.
void addPeers(std::size_t limit, std::function< bool(std::shared_ptr< Peer > const &)> hasItem, std::function< void(std::shared_ptr< Peer > const &)> onPeerAdded) override
Try add more peers.
LedgerReplayMsgHandler & remote
TestPeerSet(LedgerReplayMsgHandler &me, LedgerReplayMsgHandler &other, PeerSetBehavior bhvr, bool enableLedgerReplay)
void sendRequest(::google::protobuf::Message const &msg, protocol::MessageType type, std::shared_ptr< Peer > const &peer) override
std::set< Peer::id_t > const & getPeerIds() const override
get the set of ids of previously added peers
LedgerReplayMsgHandler & local
std::shared_ptr< TestPeer > dummyPeer
Set the sequence number on a JTx.
Definition seq.h:34
T to_string(T... args)