16#include <boost/test/unit_test.hpp>
23 std::chrono::microseconds RandomTime8s();
24 std::chrono::microseconds RandomTime1y();
25 void BuildSingleTest(Scenario& scenario,
int config);
26 void BuildPriorityTest(Scenario& scenario,
int config);
27 void BuildBigPriorityTest(Scenario& scenario,
int peers);
28 void BuildRequestOrderTest(Scenario& scenario,
int config);
29 void BuildWtxidTest(Scenario& scenario,
int config);
30 void BuildTimeBackwardsTest(Scenario& scenario);
31 void BuildWeirdRequestsTest(Scenario& scenario);
32 void TestInterleavedScenarios();
35constexpr std::chrono::microseconds MIN_TIME = std::chrono::microseconds::min();
36constexpr std::chrono::microseconds MAX_TIME = std::chrono::microseconds::max();
37constexpr std::chrono::microseconds MICROSECOND = std::chrono::microseconds{1};
38constexpr std::chrono::microseconds NO_TIME = std::chrono::microseconds{0};
41using Action = std::pair<std::chrono::microseconds, std::function<void()>>;
53 std::vector<Action> actions;
56 std::set<NodeId> peerset;
59 std::set<uint256> txhashset;
64 std::multiset<std::pair<NodeId, GenTxid>> expired;
67std::chrono::microseconds TxRequestTest::RandomTime8s() {
return std::chrono::microseconds{1 + m_rng.randbits(23)}; }
68std::chrono::microseconds TxRequestTest::RandomTime1y() {
return std::chrono::microseconds{1 + m_rng.randbits(45)}; }
83 std::chrono::microseconds m_now;
84 std::string m_testname;
87 Scenario(
FastRandomContext& rng, Runner& runner, std::chrono::microseconds starttime) : m_rng(rng), m_runner(runner), m_now(starttime) {}
90 void SetTestName(std::string testname)
92 m_testname = std::move(testname);
96 void AdvanceTime(std::chrono::microseconds amount)
98 assert(amount.count() >= 0);
103 void ForgetTxHash(
const uint256& txhash)
105 auto& runner = m_runner;
106 runner.actions.emplace_back(m_now, [=,&runner]() {
107 runner.txrequest.ForgetTxHash(txhash);
108 runner.txrequest.SanityCheck();
113 void ReceivedInv(
NodeId peer,
const GenTxid& gtxid,
bool pref, std::chrono::microseconds reqtime)
115 auto& runner = m_runner;
116 runner.actions.emplace_back(m_now, [=,&runner]() {
117 runner.txrequest.ReceivedInv(peer, gtxid, pref, reqtime);
118 runner.txrequest.SanityCheck();
123 void DisconnectedPeer(
NodeId peer)
125 auto& runner = m_runner;
126 runner.actions.emplace_back(m_now, [=,&runner]() {
127 runner.txrequest.DisconnectedPeer(peer);
128 runner.txrequest.SanityCheck();
133 void RequestedTx(
NodeId peer,
const uint256& txhash, std::chrono::microseconds exptime)
135 auto& runner = m_runner;
136 runner.actions.emplace_back(m_now, [=,&runner]() {
137 runner.txrequest.RequestedTx(peer, txhash, exptime);
138 runner.txrequest.SanityCheck();
145 auto& runner = m_runner;
146 runner.actions.emplace_back(m_now, [=,&runner]() {
147 runner.txrequest.ReceivedResponse(peer, txhash);
148 runner.txrequest.SanityCheck();
163 void Check(
NodeId peer,
const std::vector<GenTxid>& expected,
size_t candidates,
size_t inflight,
164 size_t completed,
const std::string& checkname,
165 std::chrono::microseconds offset = std::chrono::microseconds{0})
167 const auto comment = m_testname +
" " + checkname;
168 auto& runner = m_runner;
169 const auto now = m_now;
170 assert(offset.count() <= 0);
171 runner.actions.emplace_back(m_now, [=,&runner]() {
172 std::vector<std::pair<NodeId, GenTxid>> expired_now;
173 auto ret = runner.txrequest.GetRequestable(peer, now + offset, &expired_now);
174 for (
const auto& entry : expired_now) runner.expired.insert(entry);
175 runner.txrequest.SanityCheck();
176 runner.txrequest.PostGetRequestableSanityCheck(now + offset);
177 size_t total = candidates + inflight + completed;
178 size_t real_total = runner.txrequest.Count(peer);
179 size_t real_candidates = runner.txrequest.CountCandidates(peer);
180 size_t real_inflight = runner.txrequest.CountInFlight(peer);
181 BOOST_CHECK_MESSAGE(real_total == total,
strprintf(
"[%s] total %i (%i expected)", comment, real_total, total));
182 BOOST_CHECK_MESSAGE(real_inflight == inflight,
strprintf(
"[%s] inflight %i (%i expected)", comment, real_inflight, inflight));
183 BOOST_CHECK_MESSAGE(real_candidates == candidates,
strprintf(
"[%s] candidates %i (%i expected)", comment, real_candidates, candidates));
184 BOOST_CHECK_MESSAGE(
ret == expected,
strprintf(
"[%s] mismatching requestables", comment));
194 const auto& testname = m_testname;
195 auto& runner = m_runner;
196 runner.actions.emplace_back(m_now, [=,&runner]() {
197 auto it = runner.expired.find(std::pair<NodeId, GenTxid>{peer, gtxid});
198 BOOST_CHECK_MESSAGE(it != runner.expired.end(),
"[" + testname +
"] missing expiration");
199 if (it != runner.expired.end()) runner.expired.erase(it);
211 uint256 NewTxHash(
const std::vector<std::vector<NodeId>>& orders = {})
218 for (
const auto& order : orders) {
219 for (
size_t pos = 1; pos < order.size(); ++pos) {
220 uint64_t prio_prev = m_runner.txrequest.ComputePriority(
ret, order[pos - 1],
true);
221 uint64_t prio_cur = m_runner.txrequest.ComputePriority(
ret, order[pos],
true);
222 if (prio_prev <= prio_cur) {
230 ok = m_runner.txhashset.insert(
ret).second;
237 GenTxid NewGTxid(
const std::vector<std::vector<NodeId>>& orders = {})
250 ok = m_runner.peerset.insert(
ret).second;
255 std::chrono::microseconds
Now()
const {
return m_now; }
262void TxRequestTest::BuildSingleTest(Scenario& scenario,
int config)
264 auto peer = scenario.NewPeer();
265 auto gtxid = scenario.NewGTxid();
266 bool immediate = config & 1;
267 bool preferred = config & 2;
268 auto delay = immediate ? NO_TIME : RandomTime8s();
270 scenario.SetTestName(
strprintf(
"Single(config=%i)", config));
273 scenario.ReceivedInv(peer, gtxid, preferred, immediate ? MIN_TIME : scenario.Now() + delay);
275 scenario.Check(peer, {gtxid}, 1, 0, 0,
"s1");
277 scenario.Check(peer, {}, 1, 0, 0,
"s2");
278 scenario.AdvanceTime(delay - MICROSECOND);
279 scenario.Check(peer, {}, 1, 0, 0,
"s3");
280 scenario.AdvanceTime(MICROSECOND);
281 scenario.Check(peer, {gtxid}, 1, 0, 0,
"s4");
285 scenario.AdvanceTime(RandomTime8s());
286 auto expiry = RandomTime8s();
287 scenario.Check(peer, {gtxid}, 1, 0, 0,
"s5");
288 scenario.RequestedTx(peer, gtxid.
GetHash(), scenario.Now() + expiry);
289 scenario.Check(peer, {}, 0, 1, 0,
"s6");
291 if ((config >> 3) == 1) {
292 scenario.AdvanceTime(expiry - MICROSECOND);
293 scenario.Check(peer, {}, 0, 1, 0,
"s7");
294 scenario.AdvanceTime(MICROSECOND);
295 scenario.Check(peer, {}, 0, 0, 0,
"s8");
296 scenario.CheckExpired(peer, gtxid);
299 scenario.AdvanceTime(std::chrono::microseconds{m_rng.
randrange(expiry.count())});
300 scenario.Check(peer, {}, 0, 1, 0,
"s9");
301 if ((config >> 3) == 3) {
302 scenario.ReceivedResponse(peer, gtxid.
GetHash());
303 scenario.Check(peer, {}, 0, 0, 0,
"s10");
310 scenario.DisconnectedPeer(peer);
312 scenario.ForgetTxHash(gtxid.
GetHash());
314 scenario.Check(peer, {}, 0, 0, 0,
"s11");
322void TxRequestTest::BuildPriorityTest(Scenario& scenario,
int config)
324 scenario.SetTestName(
strprintf(
"Priority(config=%i)", config));
327 auto peer1 = scenario.NewPeer(), peer2 = scenario.NewPeer();
330 bool prio1 = config & 1;
331 auto gtxid = prio1 ? scenario.NewGTxid({{peer1, peer2}}) : scenario.NewGTxid({{peer2, peer1}});
332 bool pref1 = config & 2, pref2 = config & 4;
334 scenario.ReceivedInv(peer1, gtxid, pref1, MIN_TIME);
335 scenario.Check(peer1, {gtxid}, 1, 0, 0,
"p1");
337 scenario.AdvanceTime(RandomTime8s());
338 scenario.Check(peer1, {gtxid}, 1, 0, 0,
"p2");
341 scenario.ReceivedInv(peer2, gtxid, pref2, MIN_TIME);
348 (pref1 == pref2 && !prio1);
349 NodeId priopeer = stage2_prio ? peer2 : peer1, otherpeer = stage2_prio ? peer1 : peer2;
350 scenario.Check(otherpeer, {}, 1, 0, 0,
"p3");
351 scenario.Check(priopeer, {gtxid}, 1, 0, 0,
"p4");
352 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
353 scenario.Check(otherpeer, {}, 1, 0, 0,
"p5");
354 scenario.Check(priopeer, {gtxid}, 1, 0, 0,
"p6");
358 scenario.RequestedTx(priopeer, gtxid.
GetHash(), MAX_TIME);
359 scenario.Check(priopeer, {}, 0, 1, 0,
"p7");
360 scenario.Check(otherpeer, {}, 1, 0, 0,
"p8");
361 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
366 scenario.DisconnectedPeer(priopeer);
368 scenario.ReceivedResponse(priopeer, gtxid.
GetHash());
370 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
371 scenario.Check(priopeer, {}, 0, 0, !(config & 16),
"p8");
372 scenario.Check(otherpeer, {gtxid}, 1, 0, 0,
"p9");
373 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
376 scenario.DisconnectedPeer(otherpeer);
377 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
378 scenario.Check(peer1, {}, 0, 0, 0,
"p10");
379 scenario.Check(peer2, {}, 0, 0, 0,
"p11");
384void TxRequestTest::BuildBigPriorityTest(Scenario& scenario,
int peers)
386 scenario.SetTestName(
strprintf(
"BigPriority(peers=%i)", peers));
389 std::map<NodeId, bool> preferred;
390 std::vector<NodeId> pref_peers, npref_peers;
391 int num_pref = m_rng.
randrange(peers + 1) ;
392 int num_npref = peers - num_pref;
393 for (
int i = 0; i < num_pref; ++i) {
394 pref_peers.push_back(scenario.NewPeer());
395 preferred[pref_peers.back()] =
true;
397 for (
int i = 0; i < num_npref; ++i) {
398 npref_peers.push_back(scenario.NewPeer());
399 preferred[npref_peers.back()] =
false;
402 std::vector<NodeId> request_order;
403 request_order.reserve(num_pref + num_npref);
404 for (
int i = 0; i < num_pref; ++i) request_order.push_back(pref_peers[i]);
405 for (
int i = 0; i < num_npref; ++i) request_order.push_back(npref_peers[i]);
408 std::vector<NodeId> announce_order = request_order;
409 std::shuffle(announce_order.begin(), announce_order.end(), m_rng);
413 auto gtxid = scenario.NewGTxid({pref_peers, npref_peers});
417 std::map<NodeId, std::chrono::microseconds> reqtimes;
418 auto reqtime = scenario.Now();
419 for (
int i = peers - 1; i >= 0; --i) {
420 reqtime += RandomTime8s();
421 reqtimes[request_order[i]] = reqtime;
425 for (
const auto peer : announce_order) {
426 scenario.ReceivedInv(peer, gtxid, preferred[peer], reqtimes[peer]);
428 for (
const auto peer : announce_order) {
429 scenario.Check(peer, {}, 1, 0, 0,
"b1");
434 for (
int i = peers - 1; i >= 0; --i) {
435 scenario.AdvanceTime(reqtimes[request_order[i]] - scenario.Now() - MICROSECOND);
436 scenario.Check(request_order[i], {}, 1, 0, 0,
"b2");
437 scenario.AdvanceTime(MICROSECOND);
438 scenario.Check(request_order[i], {gtxid}, 1, 0, 0,
"b3");
443 for (
int i = 0; i < peers; ++i) {
444 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
445 const int pos = m_rng.
randrange(request_order.size());
446 const auto peer = request_order[pos];
447 request_order.erase(request_order.begin() + pos);
449 scenario.DisconnectedPeer(peer);
450 scenario.Check(peer, {}, 0, 0, 0,
"b4");
452 scenario.ReceivedResponse(peer, gtxid.
GetHash());
453 scenario.Check(peer, {}, 0, 0, request_order.size() > 0,
"b5");
455 if (request_order.size()) {
456 scenario.Check(request_order[0], {gtxid}, 1, 0, 0,
"b6");
461 for (
const auto peer : announce_order) {
462 scenario.Check(peer, {}, 0, 0, 0,
"b7");
471void TxRequestTest::BuildRequestOrderTest(Scenario& scenario,
int config)
473 scenario.SetTestName(
strprintf(
"RequestOrder(config=%i)", config));
475 auto peer = scenario.NewPeer();
476 auto gtxid1 = scenario.NewGTxid();
477 auto gtxid2 = scenario.NewGTxid();
479 auto reqtime2 = scenario.Now() + RandomTime8s();
480 auto reqtime1 = reqtime2 + RandomTime8s();
482 scenario.ReceivedInv(peer, gtxid1, config & 1, reqtime1);
484 scenario.ReceivedInv(peer, gtxid2, config & 2, reqtime2);
486 scenario.AdvanceTime(reqtime2 - MICROSECOND - scenario.Now());
487 scenario.Check(peer, {}, 2, 0, 0,
"o1");
488 scenario.AdvanceTime(MICROSECOND);
489 scenario.Check(peer, {gtxid2}, 2, 0, 0,
"o2");
490 scenario.AdvanceTime(reqtime1 - MICROSECOND - scenario.Now());
491 scenario.Check(peer, {gtxid2}, 2, 0, 0,
"o3");
492 scenario.AdvanceTime(MICROSECOND);
495 scenario.Check(peer, {gtxid1, gtxid2}, 2, 0, 0,
"o4");
497 scenario.DisconnectedPeer(peer);
498 scenario.Check(peer, {}, 0, 0, 0,
"o5");
506void TxRequestTest::BuildWtxidTest(Scenario& scenario,
int config)
508 scenario.SetTestName(
strprintf(
"Wtxid(config=%i)", config));
510 auto peerT = scenario.NewPeer();
511 auto peerW = scenario.NewPeer();
512 auto txhash = scenario.NewTxHash();
516 auto reqtimeT = m_rng.
randbool() ? MIN_TIME : scenario.Now() + RandomTime8s();
517 auto reqtimeW = m_rng.
randbool() ? MIN_TIME : scenario.Now() + RandomTime8s();
521 scenario.ReceivedInv(peerT, txid, config & 2, reqtimeT);
522 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
523 scenario.ReceivedInv(peerW, wtxid, !(config & 2), reqtimeW);
525 scenario.ReceivedInv(peerW, wtxid, !(config & 2), reqtimeW);
526 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
527 scenario.ReceivedInv(peerT, txid, config & 2, reqtimeT);
532 auto max_reqtime = std::max(reqtimeT, reqtimeW);
533 if (max_reqtime > scenario.Now()) scenario.AdvanceTime(max_reqtime - scenario.Now());
535 scenario.Check(peerT, {txid}, 1, 0, 0,
"w1");
536 scenario.Check(peerW, {}, 1, 0, 0,
"w2");
538 scenario.Check(peerT, {}, 1, 0, 0,
"w3");
539 scenario.Check(peerW, {wtxid}, 1, 0, 0,
"w4");
543 auto expiry = RandomTime8s();
545 scenario.RequestedTx(peerT, txid.GetHash(), scenario.Now() + expiry);
546 scenario.Check(peerT, {}, 0, 1, 0,
"w5");
547 scenario.Check(peerW, {}, 1, 0, 0,
"w6");
549 scenario.RequestedTx(peerW, wtxid.GetHash(), scenario.Now() + expiry);
550 scenario.Check(peerT, {}, 1, 0, 0,
"w7");
551 scenario.Check(peerW, {}, 0, 1, 0,
"w8");
556 scenario.AdvanceTime(expiry);
558 scenario.Check(peerT, {}, 0, 0, 1,
"w9");
559 scenario.Check(peerW, {wtxid}, 1, 0, 0,
"w10");
560 scenario.CheckExpired(peerT, txid);
562 scenario.Check(peerT, {txid}, 1, 0, 0,
"w11");
563 scenario.Check(peerW, {}, 0, 0, 1,
"w12");
564 scenario.CheckExpired(peerW, wtxid);
569 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
570 scenario.ForgetTxHash(txhash);
571 scenario.Check(peerT, {}, 0, 0, 0,
"w13");
572 scenario.Check(peerW, {}, 0, 0, 0,
"w14");
576void TxRequestTest::BuildTimeBackwardsTest(Scenario& scenario)
578 auto peer1 = scenario.NewPeer();
579 auto peer2 = scenario.NewPeer();
580 auto gtxid = scenario.NewGTxid({{peer1, peer2}});
583 auto reqtime = scenario.Now() + RandomTime8s();
584 scenario.ReceivedInv(peer2, gtxid,
true, reqtime);
585 scenario.Check(peer2, {}, 1, 0, 0,
"r1");
586 scenario.AdvanceTime(reqtime - scenario.Now());
587 scenario.Check(peer2, {gtxid}, 1, 0, 0,
"r2");
589 scenario.Check(peer2, {}, 1, 0, 0,
"r3", -MICROSECOND);
591 scenario.Check(peer2, {gtxid}, 1, 0, 0,
"r4");
594 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
595 scenario.ReceivedInv(peer1, gtxid,
true, MAX_TIME);
596 scenario.Check(peer2, {gtxid}, 1, 0, 0,
"r5");
597 scenario.Check(peer1, {}, 1, 0, 0,
"r6");
600 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
601 auto expiry = scenario.Now() + RandomTime8s();
602 scenario.RequestedTx(peer1, gtxid.
GetHash(), expiry);
603 scenario.Check(peer1, {}, 0, 1, 0,
"r7");
604 scenario.Check(peer2, {}, 1, 0, 0,
"r8");
607 scenario.AdvanceTime(expiry - scenario.Now());
608 scenario.Check(peer1, {}, 0, 0, 1,
"r9");
609 scenario.Check(peer2, {gtxid}, 1, 0, 0,
"r10");
610 scenario.CheckExpired(peer1, gtxid);
611 scenario.Check(peer1, {}, 0, 0, 1,
"r11", -MICROSECOND);
612 scenario.Check(peer2, {gtxid}, 1, 0, 0,
"r12", -MICROSECOND);
615 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
616 scenario.DisconnectedPeer(peer2);
617 scenario.Check(peer1, {}, 0, 0, 0,
"r13");
618 scenario.Check(peer2, {}, 0, 0, 0,
"r14");
622void TxRequestTest::BuildWeirdRequestsTest(Scenario& scenario)
624 auto peer1 = scenario.NewPeer();
625 auto peer2 = scenario.NewPeer();
626 auto gtxid1 = scenario.NewGTxid({{peer1, peer2}});
627 auto gtxid2 = scenario.NewGTxid({{peer2, peer1}});
630 scenario.ReceivedInv(peer1, gtxid1,
true, MIN_TIME);
631 scenario.Check(peer1, {gtxid1}, 1, 0, 0,
"q1");
634 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
635 scenario.ReceivedInv(peer2, gtxid2,
true, MIN_TIME);
636 scenario.Check(peer1, {gtxid1}, 1, 0, 0,
"q2");
637 scenario.Check(peer2, {gtxid2}, 1, 0, 0,
"q3");
640 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
641 scenario.RequestedTx(peer1, gtxid2.GetHash(), MAX_TIME);
642 scenario.Check(peer1, {gtxid1}, 1, 0, 0,
"q4");
643 scenario.Check(peer2, {gtxid2}, 1, 0, 0,
"q5");
646 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
647 auto expiryA = scenario.Now() + RandomTime8s();
648 scenario.RequestedTx(peer1, gtxid1.GetHash(), expiryA);
649 scenario.Check(peer1, {}, 0, 1, 0,
"q6");
650 scenario.Check(peer2, {gtxid2}, 1, 0, 0,
"q7");
653 auto expiryB = expiryA + RandomTime8s();
654 scenario.RequestedTx(peer1, gtxid1.GetHash(), expiryB);
655 scenario.Check(peer1, {}, 0, 1, 0,
"q8");
656 scenario.Check(peer2, {gtxid2}, 1, 0, 0,
"q9");
659 scenario.ReceivedInv(peer2, gtxid1,
true, MIN_TIME);
660 scenario.Check(peer1, {}, 0, 1, 0,
"q10");
661 scenario.Check(peer2, {gtxid2}, 2, 0, 0,
"q11");
664 scenario.AdvanceTime(expiryA - scenario.Now());
665 scenario.Check(peer1, {}, 0, 0, 1,
"q12");
666 scenario.Check(peer2, {gtxid2, gtxid1}, 2, 0, 0,
"q13");
667 scenario.CheckExpired(peer1, gtxid1);
670 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
671 scenario.RequestedTx(peer1, gtxid1.GetHash(), MAX_TIME);
672 scenario.Check(peer1, {}, 0, 0, 1,
"q14");
673 scenario.Check(peer2, {gtxid2, gtxid1}, 2, 0, 0,
"q15");
676 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
677 scenario.ReceivedInv(peer1, gtxid2,
true, MIN_TIME);
678 scenario.Check(peer1, {}, 1, 0, 1,
"q16");
679 scenario.Check(peer2, {gtxid2, gtxid1}, 2, 0, 0,
"q17");
682 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
683 scenario.RequestedTx(peer1, gtxid2.GetHash(), MAX_TIME);
684 scenario.Check(peer1, {}, 0, 1, 1,
"q18");
685 scenario.Check(peer2, {gtxid1}, 2, 0, 0,
"q19");
688 if (m_rng.
randbool()) scenario.AdvanceTime(RandomTime8s());
689 scenario.RequestedTx(peer2, gtxid2.GetHash(), MAX_TIME);
690 scenario.Check(peer1, {}, 0, 0, 2,
"q20");
691 scenario.Check(peer2, {gtxid1}, 1, 1, 0,
"q21");
694 scenario.DisconnectedPeer(peer2);
695 scenario.Check(peer1, {}, 0, 0, 0,
"q22");
696 scenario.Check(peer2, {}, 0, 0, 0,
"q23");
699void TxRequestTest::TestInterleavedScenarios()
702 std::vector<std::function<void(Scenario&)>> builders;
704 for (
int n = 0; n < 64; ++n) {
705 builders.emplace_back([
this, n](Scenario& scenario) { BuildWtxidTest(scenario, n); });
706 builders.emplace_back([
this, n](Scenario& scenario) { BuildRequestOrderTest(scenario, n & 3); });
707 builders.emplace_back([
this, n](Scenario& scenario) { BuildSingleTest(scenario, n & 31); });
708 builders.emplace_back([
this, n](Scenario& scenario) { BuildPriorityTest(scenario, n & 31); });
709 builders.emplace_back([
this, n](Scenario& scenario) { BuildBigPriorityTest(scenario, (n & 7) + 1); });
710 builders.emplace_back([
this](Scenario& scenario) { BuildTimeBackwardsTest(scenario); });
711 builders.emplace_back([
this](Scenario& scenario) { BuildWeirdRequestsTest(scenario); });
714 std::shuffle(builders.begin(), builders.end(), m_rng);
717 auto starttime = RandomTime1y();
719 while (builders.size()) {
722 auto scenario_start = starttime + RandomTime8s() + RandomTime8s() + RandomTime8s();
723 Scenario scenario(m_rng, runner, scenario_start);
724 for (
int j = 0; builders.size() && j < 10; ++j) {
725 builders.back()(scenario);
732 std::stable_sort(runner.actions.begin(), runner.actions.end(), [](
const Action& a1,
const Action& a2) {
733 return a1.first < a2.first;
737 for (
auto& action : runner.actions) {
751 for (
int i = 0; i < 5; ++i) {
752 TestInterleavedScenarios();
A generic txid reference (txid or wtxid).
static GenTxid Wtxid(const uint256 &hash)
const uint256 & GetHash() const LIFETIMEBOUND
static GenTxid Txid(const uint256 &hash)
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
uint256 rand256() noexcept
generate a random uint256.
bool randbool() noexcept
Generate a random boolean.
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Data structure to keep track of, and schedule, transaction downloads from peers.
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
T Now()
Return the current time point cast to the given precision.
BOOST_AUTO_TEST_CASE(TxRequestTest)