20 #include <validation.h>
22 #include <test/util/blockindex.h>
23 #include <test/util/setup_common.h>
25 #include <boost/test/unit_test.hpp>
29 #include <unordered_map>
35 struct TestPeerManager {
39 return node.peerid == peerid;
44 auto &pendingNodesView = pm.
pendingNodes.get<by_nodeid>();
45 return pendingNodesView.find(nodeid) != pendingNodesView.end();
50 auto &pview = pm.
peers.get<by_proofid>();
51 auto it = pview.find(proofid);
52 return it == pview.end() ?
NO_PEER : it->peerid;
58 return getPeerIdForProofId(pm, proof->
getId());
61 static std::vector<uint32_t> getOrderedScores(
const PeerManager &pm) {
62 std::vector<uint32_t> scores;
64 auto &peerView = pm.
peers.get<by_score>();
65 for (
const Peer &peer : peerView) {
66 scores.push_back(peer.getScore());
72 static void cleanupDanglingProofs(
74 std::unordered_set<ProofRef, SaltedProofHasher> ®isteredProofs) {
78 static void cleanupDanglingProofs(
PeerManager &pm) {
79 std::unordered_set<ProofRef, SaltedProofHasher> dummy;
83 static std::optional<RemoteProof> getRemoteProof(
const PeerManager &pm,
86 auto it = pm.
remoteProofs.find(boost::make_tuple(proofid, nodeid));
90 return std::make_optional(*it);
94 return pm.
peers.size();
97 static std::optional<bool>
103 std::vector<PeerId> peerIds;
104 for (
auto &peer : pm.
peers) {
105 peerIds.push_back(peer.peerid);
107 for (
const PeerId &peerid : peerIds) {
125 uint32_t height = 100,
bool is_coinbase =
false) {
131 Coin(
CTxOut(amount, script), height, is_coinbase),
false);
136 uint32_t height = 100,
137 bool is_coinbase =
false) {
139 addCoin(chainstate, outpoint, key, amount, height, is_coinbase);
144 buildProof(
const CKey &key,
145 const std::vector<std::tuple<COutPoint, Amount>> &outpoints,
147 int64_t sequence = 1, uint32_t height = 100,
148 bool is_coinbase =
false, int64_t expirationTime = 0,
150 ProofBuilder pb(sequence, expirationTime, master, payoutScript);
151 for (
const auto &[outpoint, amount] : outpoints) {
152 BOOST_CHECK(pb.addUTXO(outpoint, amount, height, is_coinbase, key));
157 template <
typename... Args>
159 buildProofWithOutpoints(
const CKey &key,
160 const std::vector<COutPoint> &outpoints,
161 Amount amount, Args &&...args) {
162 std::vector<std::tuple<COutPoint, Amount>> outpointsWithAmount;
164 outpoints.begin(), outpoints.end(),
165 std::back_inserter(outpointsWithAmount),
166 [amount](
const auto &o) { return std::make_tuple(o, amount); });
167 return buildProof(key, outpointsWithAmount,
168 std::forward<Args>(args)...);
172 buildProofWithSequence(
const CKey &key,
173 const std::vector<COutPoint> &outpoints,
182 struct PeerManagerFixture :
public TestChain100Setup {
183 PeerManagerFixture() {
186 ~PeerManagerFixture() {
193 struct NoCoolDownFixture :
public PeerManagerFixture {
194 NoCoolDownFixture() {
197 ~NoCoolDownFixture() {
211 const std::vector<Slot> oneslot = {{100, 100, 23}};
229 const std::vector<Slot> twoslots = {{100, 100, 69}, {300, 100, 42}};
258 std::vector<Slot> slots;
262 for (
int i = 0; i < 100; i++) {
263 slots.emplace_back(max, 1, i);
270 for (
int i = 0; i < 100; i++) {
278 slots[99] = slots[99].withScore(101);
279 max = slots[99].getStop();
282 for (
int i = 0; i < 100; i++) {
293 for (
int i = 0; i < 100; i++) {
294 slots[i] = slots[i].withStart(slots[i].getStart() + 100);
297 slots[0] =
Slot(1, slots[0].getStop() - 1, slots[0].getPeerId());
298 slots[99] = slots[99].withScore(1);
299 max = slots[99].getStop();
306 for (
int i = 0; i < 100; i++) {
313 for (
int c = 0; c < 1000; c++) {
314 size_t size = InsecureRandBits(10) + 1;
315 std::vector<Slot> slots;
318 uint64_t max = InsecureRandBits(3);
321 max += InsecureRandBits(3);
325 for (
size_t i = 0; i < size; i++) {
326 const uint64_t start = next();
327 const uint32_t score = InsecureRandBits(3);
329 slots.emplace_back(start, score, i);
332 for (
int k = 0; k < 100; k++) {
333 uint64_t s = max > 0 ? InsecureRandRange(max) : 0;
356 const NodeId node0 = 42, node1 = 69, node2 = 37;
358 Chainstate &active_chainstate = chainman.ActiveChainstate();
366 std::unordered_map<PeerId, int> results = {};
367 for (
int i = 0; i < 10000; i++) {
373 BOOST_CHECK(abs(2 * results[0] - results[1]) < 500);
379 for (
int i = 0; i < 10000; i++) {
381 BOOST_CHECK(n == node0 || n == node1 || n == node2);
385 BOOST_CHECK(abs(results[0] - results[1] + results[2]) < 500);
394 Chainstate &active_chainstate = chainman.ActiveChainstate();
396 std::array<PeerId, 8> peerids;
397 for (
int i = 0; i < 4; i++) {
399 peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p);
406 for (
int i = 0; i < 100; i++) {
408 BOOST_CHECK(p == peerids[0] || p == peerids[1] || p == peerids[2] ||
423 for (
int i = 0; i < 100; i++) {
425 BOOST_CHECK(p == peerids[0] || p == peerids[1] || p == peerids[3]);
429 for (
int i = 0; i < 4; i++) {
431 peerids[i + 4] = TestPeerManager::registerAndGetPeerId(pm, p);
453 for (
int i = 0; i < 100; i++) {
455 BOOST_CHECK(p == peerids[1] || p == peerids[3] || p == peerids[4] ||
456 p == peerids[5] || p == peerids[6]);
471 std::array<PeerId, 4> peerids;
472 for (
int i = 0; i < 4; i++) {
475 peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p);
480 for (
auto p : peerids) {
487 for (
int i = 0; i < 100; i++) {
501 Chainstate &active_chainstate = chainman.ActiveChainstate();
511 for (
int i = 0; i < 4; i++) {
515 for (
int i = 0; i < 100; i++) {
524 for (
int i = 0; i < 100; i++) {
532 std::chrono::hours(24)));
534 for (
int i = 0; i < 100; i++) {
544 int node3selected = 0;
545 for (
int i = 0; i < 100; i++) {
561 Chainstate &active_chainstate = chainman.ActiveChainstate();
570 for (
int i = 0; i < 10; i++) {
572 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
578 const PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
579 BOOST_CHECK_NE(peerid,
NO_PEER);
580 for (
int i = 0; i < 10; i++) {
581 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
582 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
589 for (
int i = 0; i < 5; i++) {
591 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
592 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
598 for (
int i = 0; i < 5; i++) {
600 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
601 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
607 const ProofId &alt_proofid = alt_proof->getId();
610 for (
int i = 0; i < 5; i++) {
612 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
613 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
620 const ProofId &alt2_proofid = alt2_proof->getId();
623 for (
int i = 0; i < 5; i++) {
625 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
631 for (
int i = 0; i < 5; i++) {
633 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
634 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
642 for (
int i = 0; i < 10; i++) {
643 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
644 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
651 for (
int i = 0; i < 10; i++) {
653 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
654 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
670 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
671 BOOST_CHECK_NE(peerid,
NO_PEER);
675 for (
int i = 0; i < 10; i++) {
677 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
678 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
684 chainman.ActiveChainstate().InvalidateBlock(
693 for (
int i = 0; i < 10; i++) {
694 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
695 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
706 BOOST_CHECK(chainman.ActiveChainstate().ActivateBestChain(state));
715 peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
716 BOOST_CHECK_NE(peerid,
NO_PEER);
717 for (
int i = 0; i < 10; i++) {
718 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
719 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
732 const int height = 100;
735 for (uint32_t i = 0; i < 10; i++) {
736 addCoin(chainman.ActiveChainstate(), {txid1, i}, key);
737 addCoin(chainman.ActiveChainstate(), {txid2, i}, key);
742 const auto getPeerId = [&](
const std::vector<COutPoint> &outpoints) {
743 return TestPeerManager::registerAndGetPeerId(
744 pm, buildProofWithOutpoints(key, outpoints, v, masterKey, 0, height,
799 int immatureHeight = 100;
801 auto registerImmature = [&](
const ProofRef &proof) {
807 auto checkImmature = [&](
const ProofRef &proof,
bool expectedImmature) {
824 std::vector<ProofRef> immatureProofs;
829 auto proof = buildProofWithOutpoints(
831 addCoin(chainman.ActiveChainstate(), outpoint, key,
833 registerImmature(proof);
834 checkImmature(proof,
true);
835 immatureProofs.push_back(proof);
839 for (
auto i = 0; i < 100; i++) {
843 key, 0, immatureHeight);
844 addCoin(chainman.ActiveChainstate(), outpoint, key,
846 registerImmature(proof);
847 checkImmature(proof,
true);
848 immatureProofs.push_back(proof);
850 immatureProofs.erase(immatureProofs.begin());
856 immatureProofs.front()->getStakes()[0].getStake().getUTXO();
859 key, 1, immatureHeight);
860 registerImmature(proof);
861 checkImmature(proof,
true);
862 immatureProofs.push_back(proof);
864 immatureProofs.erase(immatureProofs.begin());
871 for (
const auto &proof : immatureProofs) {
872 checkImmature(proof,
false);
880 Chainstate &active_chainstate = chainman.ActiveChainstate();
883 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
884 BOOST_CHECK_NE(peerid,
NO_PEER);
887 std::chrono::hours(24));
890 for (
int i = 0; i < 10; i++) {
899 for (
int i = 0; i < 10; i++) {
905 peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
906 BOOST_CHECK_NE(peerid,
NO_PEER);
909 for (
int i = 0; i < 10; i++) {
912 i, [&](
const Node &n) { return n.nextRequestTime == theFuture; }));
919 for (
int i = 0; i < 10; i++) {
928 constexpr
int numProofs = 10;
930 std::vector<ProofRef> proofs;
931 proofs.reserve(numProofs);
932 for (
int i = 0; i < numProofs; i++) {
937 for (
int i = 0; i < numProofs; i++) {
948 for (
int added = 0; added <= i; added++) {
949 auto proof = pm.
getProof(proofs[added]->getId());
958 const std::string badProofHex(
959 "96527eae083f1f24625f049d9e54bb9a21023beefdde700a6bc02036335b4df141c8b"
960 "c67bb05a971f5ac2745fd683797dde3002321023beefdde700a6bc02036335b4df141"
961 "c8bc67bb05a971f5ac2745fd683797dde3ac135da984db510334abe41134e3d4ef09a"
962 "d006b1152be8bc413182bf6f947eac1f8580fe265a382195aa2d73935cabf86d90a8f"
963 "666d0a62385ae24732eca51575");
979 Chainstate &active_chainstate = chainman.ActiveChainstate();
981 const COutPoint conflictingOutpoint = createUtxo(active_chainstate, key);
982 const COutPoint outpointToSend = createUtxo(active_chainstate, key);
985 buildProofWithSequence(key, {conflictingOutpoint, outpointToSend}, 20);
989 buildProofWithSequence(key, {conflictingOutpoint}, 10);
1014 const uint32_t height = 100;
1015 const bool is_coinbase =
false;
1018 Chainstate &active_chainstate = chainman.ActiveChainstate();
1021 auto conflictingOutpoint = createUtxo(active_chainstate, key, amount);
1023 auto proof_base = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1026 auto checkPreferred = [&](
const ProofRef &candidate,
1027 const ProofRef &reference,
bool expectAccepted) {
1053 checkPreferred(buildProofWithSequence(key, {conflictingOutpoint}, 9),
1056 checkPreferred(buildProofWithSequence(key, {conflictingOutpoint}, 11),
1059 auto buildProofFromAmounts = [&](
const CKey &master,
1060 std::vector<Amount> &&amounts) {
1061 std::vector<std::tuple<COutPoint, Amount>> outpointsWithAmount{
1062 {conflictingOutpoint, amount}};
1063 std::transform(amounts.begin(), amounts.end(),
1064 std::back_inserter(outpointsWithAmount),
1065 [&key, &active_chainstate](
const Amount amount) {
1066 return std::make_tuple(
1067 createUtxo(active_chainstate, key, amount),
1070 return buildProof(key, outpointsWithAmount, master, 0, height,
1074 auto proof_multiUtxo = buildProofFromAmounts(
1081 checkPreferred(buildProofFromAmounts(
1083 proof_multiUtxo,
false);
1087 proof_multiUtxo,
true);
1090 proof_multiUtxo,
true);
1095 proof_multiUtxo,
false);
1097 auto proofSimilar = buildProofFromAmounts(
1099 checkPreferred(proofSimilar, proof_multiUtxo,
1100 proofSimilar->getId() < proof_multiUtxo->getId());
1111 Chainstate &active_chainstate = chainman.ActiveChainstate();
1113 const COutPoint conflictingOutpoint = createUtxo(active_chainstate, key);
1117 auto immature10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1119 buildProofWithSequence(key, {conflictingOutpoint, matureOutpoint}, 20);
1129 auto proof30 = buildProofWithOutpoints(key, {matureOutpoint},
1158 createUtxo(chainman.ActiveChainstate(), key);
1160 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1161 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1162 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1189 auto now = GetTime<std::chrono::seconds>();
1193 for (
size_t i = 0; i < 10; i++) {
1195 PeerId(GetRand<int>(1000)), now));
1200 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
1202 auto checkNextPossibleConflictTime = [&](std::chrono::seconds expected) {
1204 return p.nextPossibleConflictTime == expected;
1208 checkNextPossibleConflictTime(now);
1212 peerid, now - std::chrono::seconds{1}));
1213 checkNextPossibleConflictTime(now);
1216 peerid, now + std::chrono::seconds{1}));
1217 checkNextPossibleConflictTime(now + std::chrono::seconds{1});
1227 createUtxo(chainman.ActiveChainstate(), key);
1229 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1230 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1231 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1260 for (
size_t i = 0; i < 10; i++) {
1263 !pm.
registerProof(proofSeq10, RegistrationMode::FORCE_ACCEPT));
1271 for (
size_t i = 0; i < 10; i++) {
1273 pm.
registerProof(proofSeq30, RegistrationMode::FORCE_ACCEPT));
1279 pm.
registerProof(proofSeq10, RegistrationMode::FORCE_ACCEPT));
1293 createUtxo(chainman.ActiveChainstate(), key);
1295 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1296 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1297 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1325 createUtxo(chainman.ActiveChainstate(), key);
1327 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1328 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1329 auto proofSeq40 = buildProofWithSequence(key, {conflictingOutpoint}, 40);
1331 int64_t conflictingProofCooldown = 100;
1333 strprintf(
"%d", conflictingProofCooldown));
1337 auto increaseMockTime = [&](int64_t s) {
1341 increaseMockTime(0);
1346 auto checkRegistrationFailure = [&](
const ProofRef &proof,
1355 checkRegistrationFailure(proofSeq20,
1360 checkRegistrationFailure(proofSeq40,
1365 increaseMockTime(conflictingProofCooldown);
1372 checkRegistrationFailure(proofSeq40,
1378 increaseMockTime(conflictingProofCooldown);
1397 Chainstate &active_chainstate = chainman.ActiveChainstate();
1401 const COutPoint immatureOutpoint = createUtxo(active_chainstate, key);
1404 auto proofSeq10 = buildProofWithOutpoints(
1406 auto proofSeq20 = buildProofWithOutpoints(
1408 auto immature30 = buildProofWithSequence(
1409 key, {conflictingOutpoint, immatureOutpoint}, 30);
1420 for (
size_t i = 0; i < 10; i++) {
1429 auto checkRejectDefault = [&](
const ProofId &proofid) {
1431 const bool isImmature = pm.
isImmature(proofid);
1438 auto checkRejectInvalidate = [&](
const ProofId &proofid) {
1445 checkRejectDefault(immature30->getId());
1448 checkRejectInvalidate(immature30->getId());
1451 checkRejectDefault(proofSeq10->getId());
1452 checkRejectInvalidate(proofSeq10->getId());
1459 checkRejectDefault(proofSeq20->getId());
1466 checkRejectInvalidate(proofSeq10->getId());
1493 for (
size_t i = 0; i < 10; i++) {
1500 for (
size_t i = 0; i < 10; i++) {
1506 auto cooldownTimepoint = Now<SteadyMilliseconds>() + 10s;
1509 for (
size_t i = 0; i < 10; i++) {
1511 BOOST_CHECK_NE(selectedId,
NO_NODE);
1521 for (
size_t i = 0; i < 10; i++) {
1536 TestPeerManager::cleanupDanglingProofs(pm);
1543 TestPeerManager::cleanupDanglingProofs(pm);
1547 for (
size_t i = 0; i < 10; i++) {
1561 for (
size_t i = 0; i < 10; i++) {
1571 TestPeerManager::cleanupDanglingProofs(pm);
1577 TestPeerManager::cleanupDanglingProofs(pm);
1595 std::vector<uint32_t> expectedScores(10);
1597 std::generate(expectedScores.rbegin(), expectedScores.rend(),
1598 [n = 1]()
mutable { return n++ * MIN_VALID_PROOF_SCORE; });
1600 std::vector<ProofRef> proofs;
1601 proofs.reserve(expectedScores.size());
1602 for (uint32_t score : expectedScores) {
1608 for (
auto &proof : proofs) {
1612 auto peersScores = TestPeerManager::getOrderedScores(pm);
1613 BOOST_CHECK_EQUAL_COLLECTIONS(peersScores.begin(), peersScores.end(),
1614 expectedScores.begin(), expectedScores.end());
1627 Chainstate &active_chainstate = chainman.ActiveChainstate();
1629 const COutPoint peer1ConflictingOutput =
1630 createUtxo(active_chainstate, key, amount1, 99);
1631 const COutPoint peer1SecondaryOutpoint =
1632 createUtxo(active_chainstate, key, amount2, 99);
1634 auto peer1Proof1 = buildProof(
1636 {{peer1ConflictingOutput, amount1}, {peer1SecondaryOutpoint, amount2}},
1639 buildProof(key, {{peer1ConflictingOutput, amount1}}, key, 20, 99);
1644 {{peer1ConflictingOutput, amount1},
1645 {createUtxo(active_chainstate, key, amount1), amount1}},
1667 auto checkRejectDefault = [&](
const ProofId &proofid) {
1669 const bool isImmature = pm.
isImmature(proofid);
1676 auto checkRejectInvalidate = [&](
const ProofId &proofid) {
1683 checkRejectDefault(peer1Proof3->getId());
1687 checkRejectInvalidate(peer1Proof3->getId());
1691 checkRejectDefault(peer1Proof1->getId());
1692 checkRejectInvalidate(peer1Proof1->getId());
1701 checkRejectDefault(peer1Proof2->getId());
1708 checkRejectInvalidate(peer1Proof1->getId());
1718 PeerId peerid2 = TestPeerManager::registerAndGetPeerId(pm, peer2Proof1);
1729 TestPeerManager::getPeerIdForProofId(pm, peer1Proof2->getId());
1738 const auto checkScores = [&pm](uint32_t known, uint32_t connected) {
1746 Chainstate &active_chainstate = chainman.ActiveChainstate();
1752 PeerId peerid1 = TestPeerManager::registerAndGetPeerId(pm, proof1);
1753 checkScores(score1, 0);
1757 const ProofId &proofid1 = proof1->getId();
1758 const uint8_t nodesToAdd = 10;
1759 for (
int i = 0; i < nodesToAdd; i++) {
1761 checkScores(score1, score1);
1765 for (
int i = 0; i < nodesToAdd - 1; i++) {
1767 checkScores(score1, score1);
1772 checkScores(score1, 0);
1778 checkScores(score1, score1);
1782 PeerId peerid2 = TestPeerManager::registerAndGetPeerId(pm, proof2);
1783 checkScores(score1 + score2, score1);
1785 checkScores(score1 + score2, score1 + score2);
1790 checkScores(score1 + score2, score1 + score2);
1792 checkScores(score1 + score2, score2);
1796 checkScores(score2, score2);
1800 checkScores(score2, 0);
1809 peerid1 = TestPeerManager::registerAndGetPeerId(pm, proof1);
1810 checkScores(score1, 0);
1811 peerid2 = TestPeerManager::registerAndGetPeerId(pm, proof2);
1812 checkScores(score1 + score2, 0);
1814 checkScores(score1 + score2, score1);
1816 checkScores(score1 + score2, score1 + score2);
1819 checkScores(score1, score1);
1829 struct ProofComparatorById {
1834 using ProofSetById = std::set<ProofRef, ProofComparatorById>;
1836 ProofSetById expectedProofs;
1838 auto matchExpectedContent = [&](
const auto &tree) {
1839 auto it = expectedProofs.
begin();
1840 return tree.forEachLeaf([&](
auto pLeaf) {
1841 return it != expectedProofs.end() &&
1842 pLeaf->getId() == (*it++)->getId();
1847 const int64_t sequence = 10;
1849 Chainstate &active_chainstate = chainman.ActiveChainstate();
1852 for (
size_t i = 0; i < 10; i++) {
1853 auto outpoint = createUtxo(active_chainstate, key);
1854 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
1856 expectedProofs.insert(std::move(proof));
1866 ProofSetById addedProofs;
1867 std::vector<COutPoint> outpointsToSpend;
1868 for (
size_t i = 0; i < 10; i++) {
1869 auto outpoint = createUtxo(active_chainstate, key);
1870 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
1872 addedProofs.insert(std::move(proof));
1873 outpointsToSpend.push_back(std::move(outpoint));
1880 expectedProofs.
insert(addedProofs.begin(), addedProofs.end());
1887 for (
const auto &outpoint : outpointsToSpend) {
1899 for (
const auto &proof : addedProofs) {
1905 std::vector<ProofRef> conflictingProofs;
1906 std::vector<COutPoint> conflictingOutpoints;
1907 for (
size_t i = 0; i < 10; i++) {
1908 auto outpoint = createUtxo(active_chainstate, key);
1909 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
1911 conflictingProofs.push_back(std::move(proof));
1912 conflictingOutpoints.push_back(std::move(outpoint));
1916 expectedProofs.
insert(conflictingProofs.begin(), conflictingProofs.end());
1920 for (
size_t i = 0; i < 10; i += 2) {
1923 key, {{conflictingOutpoints[i]}}, sequence - 1)));
1926 auto replacementProof = buildProofWithSequence(
1927 key, {{conflictingOutpoints[i + 1]}}, sequence + 1);
1930 BOOST_CHECK(expectedProofs.insert(replacementProof).second);
1944 auto addNode = [&](
NodeId nodeid) {
1951 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
1968 const auto now = GetTime<std::chrono::seconds>();
1969 auto mocktime = now;
1971 auto elapseTime = [&](std::chrono::seconds seconds) {
1972 mocktime += seconds;
1979 const size_t numProofs = 10;
1981 std::vector<COutPoint> outpoints(numProofs);
1982 std::vector<ProofRef> proofs(numProofs);
1983 std::vector<ProofRef> conflictingProofs(numProofs);
1984 for (
size_t i = 0; i < numProofs; i++) {
1985 outpoints[i] = createUtxo(chainman.ActiveChainstate(), key);
1986 proofs[i] = buildProofWithSequence(key, {outpoints[i]}, 2);
1987 conflictingProofs[i] = buildProofWithSequence(key, {outpoints[i]}, 1);
2001 return peer.node_count;
2009 TestPeerManager::cleanupDanglingProofs(pm);
2010 for (
size_t i = 0; i < numProofs; i++) {
2017 TestPeerManager::cleanupDanglingProofs(pm);
2018 for (
size_t i = 0; i < numProofs; i++) {
2019 const bool hasNodeAttached = i % 2;
2036 conflictingProofs[0]->getId(),
2041 TestPeerManager::cleanupDanglingProofs(pm);
2042 for (
size_t i = 0; i < numProofs; i++) {
2043 const bool hasNodeAttached = i % 2;
2053 hasNodeAttached || i == 0);
2061 for (
size_t i = 1; i < numProofs; i += 2) {
2065 return peer.node_count == 0;
2070 conflictingProofs[0]->getId(),
2073 TestPeerManager::cleanupDanglingProofs(pm);
2074 for (
size_t i = 0; i < numProofs; i++) {
2075 const bool hadNodeAttached = i % 2;
2092 TestPeerManager::cleanupDanglingProofs(pm);
2094 for (
size_t i = 0; i < numProofs; i++) {
2120 const int64_t tipTime =
2126 auto utxo = createUtxo(chainman.ActiveChainstate(), key);
2128 100,
false, tipTime + 1);
2130 1, 100,
false, tipTime + 2);
2142 for (int64_t i = 0; i < 6; i++) {
2143 SetMockTime(proofToExpire->getExpirationTime() + i);
2144 CreateAndProcessBlock({},
CScript());
2148 ->GetMedianTimePast(),
2149 proofToExpire->getExpirationTime());
2165 Chainstate &active_chainstate = chainman.ActiveChainstate();
2167 const std::vector<std::tuple<uint32_t, uint32_t, double>> testCases = {
2169 {10, 100, 1. - std::exp(-1. * 10 / 100)},
2176 for (
const auto &[step,
tau, decayFactor] : testCases) {
2180 auto proofid = proof->
getId();
2183 const int numNodesPerPeer = 5;
2184 for (
auto nodeid = 0; nodeid < numNodesPerPeer; nodeid++) {
2188 auto getNodeAvailabilityScore = [&](
double avgScore,
2189 NodeId nodeid) ->
double {
2192 return (nodeid - numNodesPerPeer / 2) * 2 + avgScore;
2195 auto getAvailabilityScore = [&]() {
2197 pm.
forPeer(proofid, [&](
auto &peer) {
2198 score = peer.availabilityScore;
2204 double previousScore = getAvailabilityScore();
2205 BOOST_CHECK_SMALL(previousScore, 1e-6);
2208 for (
size_t i = 1; i <= 10; i++) {
2209 for (uint32_t j = 0; j <
tau; j += step) {
2212 return getNodeAvailabilityScore(1.0, nodeid);
2216 double currentScore = getAvailabilityScore();
2217 BOOST_CHECK_GE(currentScore, previousScore);
2218 previousScore = currentScore;
2224 BOOST_CHECK_CLOSE(previousScore,
2225 -1 * std::expm1(-1. * i) * numNodesPerPeer,
2230 BOOST_CHECK_CLOSE(previousScore, numNodesPerPeer, 0.01);
2240 pm.
forPeer(proofid, [&](
auto &peer) {
2248 previousScore = getAvailabilityScore();
2249 BOOST_CHECK_SMALL(previousScore, 1e-6);
2252 for (
size_t i = 1; i <= 10; i++) {
2253 for (uint32_t j = 0; j <
tau; j += step) {
2255 return getNodeAvailabilityScore(1.0, nodeid);
2259 previousScore = getAvailabilityScore();
2260 BOOST_CHECK_CLOSE(previousScore, numNodesPerPeer, 0.01);
2262 for (
size_t i = 1; i <= 3; i++) {
2263 for (uint32_t j = 0; j <
tau; j += step) {
2266 return getNodeAvailabilityScore(0.0, nodeid);
2270 double currentScore = getAvailabilityScore();
2271 BOOST_CHECK_LE(currentScore, previousScore);
2272 previousScore = currentScore;
2279 BOOST_CHECK_CLOSE(previousScore,
2280 (1. + std::expm1(-1. * i)) * numNodesPerPeer,
2285 BOOST_CHECK_LT(previousScore, .05 * numNodesPerPeer);
2287 for (
size_t i = 1; i <= 100; i++) {
2290 return getNodeAvailabilityScore(-10.0, nodeid);
2294 double currentScore = getAvailabilityScore();
2295 BOOST_CHECK_LE(currentScore, previousScore);
2296 BOOST_CHECK_LE(currentScore, 0.);
2297 previousScore = currentScore;
2305 Chainstate &active_chainstate = chainman.ActiveChainstate();
2307 auto buildProofWithAmountAndPayout = [&](
Amount amount,
2308 const CScript &payoutScript) {
2310 COutPoint utxo = createUtxo(active_chainstate, key, amount);
2311 return buildProof(key, {{std::move(utxo), amount}},
2317 std::vector<CScript> winners;
2323 auto now = GetTime<std::chrono::seconds>();
2325 prevBlock.
nTime = now.count();
2334 size_t numProofs = 8;
2335 std::vector<ProofRef> proofs;
2336 proofs.reserve(numProofs);
2337 for (
size_t i = 0; i < numProofs; i++) {
2343 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2344 BOOST_CHECK_NE(peerid,
NO_PEER);
2349 proofs.emplace_back(std::move(proof));
2356 prevBlock.
nTime = now.count();
2362 BOOST_CHECK_LE(winners.size(), numProofs);
2365 for (
size_t i = 0; i < numProofs; i++) {
2366 BOOST_CHECK(TestPeerManager::isFlaky(pm, proofs[i]->getId()));
2368 BOOST_CHECK_LE(winners.size(), numProofs);
2372 BOOST_CHECK(!TestPeerManager::isFlaky(pm, proofs[i]->getId()));
2374 BOOST_CHECK_LE(winners.size(), numProofs - i);
2379 BOOST_CHECK_LE(winners.size(), 1);
2385 const size_t loop_iters =
2386 size_t(-1.0 * std::log(100000.0) /
2387 std::log((
double(numProofs) - 1) / numProofs)) +
2389 BOOST_CHECK_GT(loop_iters, numProofs);
2390 std::unordered_map<std::string, size_t> winningCounts;
2391 for (
size_t i = 0; i < loop_iters; i++) {
2402 for (
size_t i = 0; i < numProofs; i++) {
2403 for (
size_t j = 0; j < numProofs; j++) {
2411 BOOST_CHECK_GT(3. / numProofs, 0.3);
2412 for (
size_t i = 0; i < numProofs; i++) {
2416 proofs[(i - 1 + numProofs) % numProofs]->getId(), nodeid,
false));
2418 proofs[(i + numProofs) % numProofs]->getId(), nodeid,
false));
2420 proofs[(i + 1 + numProofs) % numProofs]->getId(), nodeid,
false));
2425 for (
const auto &proof : proofs) {
2431 for (
const auto &proof : proofs) {
2432 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2441 for (
size_t numWinner = 1; numWinner < 4; numWinner++) {
2443 CScript lastWinner = winners[numWinner - 1];
2447 for (
const auto &proof : proofs) {
2449 winnerProofId = proof->
getId();
2455 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2458 BOOST_CHECK(TestPeerManager::isFlaky(pm, winnerProofId));
2468 CScript lastWinner = winners[3];
2471 for (
const auto &proof : proofs) {
2473 winnerProofId = proof->
getId();
2479 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2488 for (
auto &proof : proofs) {
2503 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2504 BOOST_CHECK_NE(peerid,
NO_PEER);
2530 prevBlock.
nTime = now.count();
2542 for (
size_t i = 0; i < 2; i++) {
2549 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2550 BOOST_CHECK_NE(peerid,
NO_PEER);
2556 proofs.push_back(proof);
2563 prevBlock.
nTime = now.count();
2572 prevBlock.
nTime = now.count();
2579 for (
auto &proof : proofs) {
2592 std::array<CBlockIndex, 12> blocks;
2593 for (
size_t i = 1; i < blocks.size(); ++i) {
2594 blocks[i].pprev = &blocks[i - 1];
2596 SetMTP(blocks, now.count());
2597 prevBlock.
pprev = &blocks.back();
2602 for (
size_t i = 0; i < 4; i++) {
2611 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2612 BOOST_CHECK_NE(peerid,
NO_PEER);
2614 return peer.registration_time == now + i * 30min;
2621 proofs.push_back(proof);
2626 prevBlock.
nTime = now.count();
2634 prevBlock.
nTime = now.count();
2637 auto checkRegistrationTime = [&](
const CScript &payout) {
2641 (now - 60min).count());
2652 prevBlock.
nTime = now.count();
2655 checkRegistrationTime(winners[0]);
2663 prevBlock.
nTime = now.count();
2665 BOOST_CHECK_LE(winners.size(), 3);
2666 checkRegistrationTime(winners[0]);
2674 prevBlock.
nTime = now.count();
2676 BOOST_CHECK_LE(winners.size(), 3);
2677 checkRegistrationTime(winners[0]);
2684 prevBlock.
nTime = now.count();
2686 BOOST_CHECK_LE(winners.size(), 2);
2687 checkRegistrationTime(winners[0]);
2693 prevBlock.
nTime = now.count();
2696 checkRegistrationTime(winners[0]);
2706 auto mockTime = GetTime<std::chrono::seconds>();
2714 auto checkRemoteProof =
2716 const bool expectedPresent,
2717 const std::chrono::seconds &expectedlastUpdate) {
2719 TestPeerManager::getRemoteProof(pm, proofid, nodeid);
2725 expectedlastUpdate.count());
2747 Chainstate &active_chainstate = chainman.ActiveChainstate();
2781 checkRemoteProof(proofid, 0,
true, mockTime);
2797 checkRemoteProof(proofid, 0,
true, mockTime);
2807 std::vector<ProofRef> proofs;
2812 proofs.push_back(proof);
2825 checkRemoteProof(proofid, 0,
true, mockTime);
2853 Chainstate &active_chainstate = chainman.ActiveChainstate();
2855 auto mockTime = GetTime<std::chrono::seconds>();
2864 for (
NodeId nodeid = 0; nodeid < 12; nodeid++) {
2877 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
2880 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
2890 TestPeerManager::setLocalProof(pm, localProof);
2898 TestPeerManager::setLocalProof(pm,
ProofRef());
2904 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
2907 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
2922 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
2925 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
2933 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
2936 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
2943 TestPeerManager::clearPeers(pm);
2953 for (
NodeId nodeid = 1; nodeid < 6; nodeid++) {
2959 for (
NodeId nodeid = 1; nodeid < 6; nodeid++) {
2974 Chainstate &active_chainstate = chainman.ActiveChainstate();
2976 auto mockTime = GetTime<std::chrono::seconds>();
2980 std::vector<ProofRef> proofs;
2981 for (
size_t i = 0; i < 10; i++) {
2984 proofs.push_back(proof);
2988 TestPeerManager::cleanupDanglingProofs(pm);
2989 for (
const auto &proof : proofs) {
2999 TestPeerManager::cleanupDanglingProofs(pm);
3000 for (
const auto &proof : proofs) {
3006 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
3012 for (
const auto &proof : proofs) {
3018 for (
const auto &proof : proofs) {
3024 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
3025 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3026 for (
const auto &proof : proofs) {
3034 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
3035 for (
const auto &proof : proofs) {
3041 for (
const auto &proof : proofs) {
3043 !TestPeerManager::getRemotePresenceStatus(pm, proof->
getId())
3048 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3050 for (
const auto &proof : proofs) {
3059 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3061 for (
const auto &proof : proofs) {
3067 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
3068 for (
const auto &proof : proofs) {
3073 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3074 for (
const auto &proof : proofs) {
3085 Chainstate &active_chainstate = chainman.ActiveChainstate();
3087 auto mockTime = GetTime<std::chrono::seconds>();
3090 std::vector<ProofRef> proofs;
3091 for (
size_t i = 0; i < 10; i++) {
3098 auto peerid = TestPeerManager::getPeerIdForProofId(pm, proof->getId());
3102 peerid, mockTime + std::chrono::seconds{100 + i}));
3109 proofs.push_back(proof);
3114 const fs::path testDumpPath =
"test_avapeers_dump.dat";
3117 TestPeerManager::clearPeers(pm);
3119 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
3123 auto findProofIndex = [&proofs](
const ProofId &proofid) {
3124 for (
size_t i = 0; i < proofs.size(); i++) {
3125 if (proofs[i]->getId() == proofid) {
3135 for (
const auto &proof : registeredProofs) {
3137 size_t i = findProofIndex(proofid);
3139 BOOST_CHECK_EQUAL(peer.hasFinalized, i < 5);
3140 BOOST_CHECK_EQUAL(peer.registration_time.count(),
3141 (mockTime + std::chrono::seconds{i}).count());
3143 peer.nextPossibleConflictTime.count(),
3144 (mockTime + std::chrono::seconds{100 + i}).count());
3150 TestPeerManager::clearPeers(pm);
3163 registeredProofs.insert(proofs[0]);
3173 file << static_cast<uint64_t>(-1);
3174 file << uint64_t{0};
3179 registeredProofs.insert(proofs[0]);
3190 const uint64_t now =
GetTime();
3192 file << static_cast<uint64_t>(1);
3193 file << uint64_t{2};
3210 proofs[0]->getId());
bool IsLeeKuanYewEnabled(const Consensus::Params ¶ms, int64_t nMedianTimePast)
Check if May 15th, 2024 protocol upgrade has activated.
static constexpr PeerId NO_PEER
const CChainParams & Params()
Return the currently selected parameters.
#define Assert(val)
Identity function.
void ForceSetArg(const std::string &strArg, const std::string &strValue)
void ClearForcedArg(const std::string &strArg)
Remove a forced arg setting, used only in testing.
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
const BlockHash * phashBlock
pointer to the hash of the block, if any.
CCoinsView that adds a memory cache for transactions to another CCoinsView.
void AddCoin(const COutPoint &outpoint, Coin coin, bool possible_overwrite)
Add a coin.
bool SpendCoin(const COutPoint &outpoint, Coin *moveto=nullptr)
Spend a coin.
An encapsulated secp256k1 private key.
static CKey MakeCompressedKey()
Produce a valid compressed key.
CPubKey GetPubKey() const
Compute the public key from a private key.
An outpoint - a combination of a transaction hash and an index n into its vout.
Serialized script, used inside transaction inputs and outputs.
An output of a transaction.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
bool InvalidateBlock(BlockValidationState &state, CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex
Mark a block as invalid.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
static RCUPtr make(Args &&...args)
Construct a new object that is owned by the pointer.
bool removeNode(NodeId nodeid)
bool selectStakingRewardWinner(const CBlockIndex *pprev, std::vector< CScript > &winners)
Deterministically select a list of payout scripts based on the proof set and the previous block hash.
bool setFinalized(PeerId peerid)
Latch on that this peer has a finalized proof.
bool dumpPeersToFile(const fs::path &dumpPath) const
RemoteProofSet remoteProofs
Remember which node sent which proof so we have an image of the proof set of our peers.
uint64_t getFragmentation() const
uint32_t getConnectedPeersScore() const
bool isDangling(const ProofId &proofid) const
bool updateNextRequestTime(NodeId nodeid, SteadyMilliseconds timeout)
std::optional< bool > getRemotePresenceStatus(const ProofId &proofid) const
Get the presence remote status of a proof.
bool shouldRequestMoreNodes()
Returns true if we encountered a lack of node since the last call.
bool exists(const ProofId &proofid) const
size_t getNodeCount() const
PendingNodeSet pendingNodes
bool verify() const
Perform consistency check on internal data structures.
bool forNode(NodeId nodeid, Callable &&func) const
bool forPeer(const ProofId &proofid, Callable &&func) const
uint32_t getTotalPeersScore() const
bool latchAvaproofsSent(NodeId nodeid)
Flag that a node did send its compact proofs.
bool addNode(NodeId nodeid, const ProofId &proofid)
Node API.
uint64_t getSlotCount() const
bool loadPeersFromFile(const fs::path &dumpPath, std::unordered_set< ProofRef, SaltedProofHasher > ®isteredProofs)
std::unordered_set< ProofRef, SaltedProofHasher > updatedBlockTip()
Update the peer set when a new block is connected.
bool isBoundToPeer(const ProofId &proofid) const
size_t getPendingNodeCount() const
bool saveRemoteProof(const ProofId &proofid, const NodeId nodeid, const bool present)
uint64_t compact()
Trigger maintenance of internal data structures.
void forEachPeer(Callable &&func) const
void forEachNode(const Peer &peer, Callable &&func) const
bool isFlaky(const ProofId &proofid) const
bool removePeer(const PeerId peerid)
Remove an existing peer.
bool isImmature(const ProofId &proofid) const
bool rejectProof(const ProofId &proofid, RejectionMode mode=RejectionMode::DEFAULT)
RegistrationMode
Registration mode.
static constexpr size_t MAX_REMOTE_PROOFS
PeerId selectPeer() const
Randomly select a peer to poll.
const ProofRadixTree & getShareableProofsSnapshot() const
void updateAvailabilityScores(const double decayFactor, Callable &&getNodeAvailabilityScore)
bool isInConflictingPool(const ProofId &proofid) const
void cleanupDanglingProofs(std::unordered_set< ProofRef, SaltedProofHasher > ®isteredProofs)
ProofRef getProof(const ProofId &proofid) const
bool registerProof(const ProofRef &proof, ProofRegistrationState ®istrationState, RegistrationMode mode=RegistrationMode::DEFAULT)
bool updateNextPossibleConflictTime(PeerId peerid, const std::chrono::seconds &nextTime)
Proof and Peer related API.
bool addUTXO(COutPoint utxo, Amount amount, uint32_t height, bool is_coinbase, CKey key)
static bool FromHex(Proof &proof, const std::string &hexProof, bilingual_str &errorOut)
const ProofId & getId() const
const CScript & getPayoutScript() const
static uint32_t amountToScore(Amount amount)
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
static const uint256 ZERO
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
static void addCoin(const Amount nValue, const CWallet &wallet, std::vector< std::unique_ptr< CWalletTx >> &wtxs)
std::string FormatScript(const CScript &script)
static const uint8_t tau[]
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
static RPCHelpMan generate()
static constexpr Amount PROOF_DUST_THRESHOLD
Minimum amount per utxo.
static constexpr uint32_t AVALANCHE_MAX_IMMATURE_PROOFS
Maximum number of immature proofs the peer manager will accept from the network.
const CScript UNSPENDABLE_ECREG_PAYOUT_SCRIPT
ProofRef buildRandomProof(Chainstate &active_chainstate, uint32_t score, int height, const CKey &masterKey)
constexpr uint32_t MIN_VALID_PROOF_SCORE
PeerId selectPeerImpl(const std::vector< Slot > &slots, const uint64_t slot, const uint64_t max)
Internal methods that are exposed for testing purposes.
RCUPtr< const Proof > ProofRef
FILE * fopen(const fs::path &p, const char *mode)
static constexpr NodeId NO_NODE
Special NodeId that represent no node.
#define BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static void addNodeWithScore(Chainstate &active_chainstate, avalanche::PeerManager &pm, NodeId node, uint32_t score)
BOOST_AUTO_TEST_CASE(select_peer_linear)
BOOST_FIXTURE_TEST_CASE(conflicting_proof_rescan, NoCoolDownFixture)
uint256 GetRandHash() noexcept
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
BOOST_FIXTURE_TEST_SUITE(stakingrewards_tests, StakingRewardsActivationTestingSetup) BOOST_AUTO_TEST_CASE(isstakingrewardsactivated)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static const double AVALANCHE_STATISTICS_DECAY_FACTOR
Pre-computed decay factor for the avalanche statistics computation.
static constexpr std::chrono::minutes AVALANCHE_STATISTICS_TIME_CONSTANT
Time constant for the avalanche statistics computation.
static constexpr std::chrono::minutes AVALANCHE_STATISTICS_REFRESH_PERIOD
Refresh period for the avalanche statistics computation.
A BlockHash is a unqiue identifier for a block.
bool insert(const RCUPtr< T > &value)
Insert a value into the tree.
A TxId is the identifier of a transaction.
Compare conflicting proofs.
std::chrono::seconds registration_time
static constexpr auto DANGLING_TIMEOUT
Consider dropping the peer if no node is attached after this timeout expired.
static ProofRef buildDuplicatedStakes(ProofBuilder &pb)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
bool FileCommit(FILE *file)
bool error(const char *fmt, const Args &...args)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
std::chrono::time_point< std::chrono::steady_clock, std::chrono::milliseconds > SteadyMilliseconds