21#include <validation.h>
23#include <test/util/blockindex.h>
24#include <test/util/random.h>
25#include <test/util/setup_common.h>
27#include <boost/test/unit_test.hpp>
31#include <unordered_map>
37 struct TestPeerManager {
41 return node.peerid == peerid;
46 auto &pendingNodesView = pm.
pendingNodes.get<by_nodeid>();
47 return pendingNodesView.find(nodeid) != pendingNodesView.end();
52 auto &pview = pm.
peers.get<by_proofid>();
53 auto it = pview.find(proofid);
54 return it == pview.end() ?
NO_PEER : it->peerid;
60 return getPeerIdForProofId(pm, proof->
getId());
63 static std::vector<uint32_t> getOrderedScores(
const PeerManager &pm) {
64 std::vector<uint32_t> scores;
66 auto &peerView = pm.
peers.get<by_score>();
67 for (
const Peer &peer : peerView) {
68 scores.push_back(peer.getScore());
74 static void cleanupDanglingProofs(
76 std::unordered_set<ProofRef, SaltedProofHasher> ®isteredProofs) {
80 static void cleanupDanglingProofs(
PeerManager &pm) {
81 std::unordered_set<ProofRef, SaltedProofHasher> dummy;
85 static std::optional<RemoteProof> getRemoteProof(
const PeerManager &pm,
88 auto it = pm.
remoteProofs.find(boost::make_tuple(proofid, nodeid));
92 return std::make_optional(*it);
96 return pm.
peers.size();
99 static std::optional<bool>
105 std::vector<PeerId> peerIds;
106 for (
auto &peer : pm.
peers) {
107 peerIds.push_back(peer.peerid);
109 for (
const PeerId &peerid : peerIds) {
127 uint32_t height = 100,
bool is_coinbase =
false) {
133 Coin(
CTxOut(amount, script), height, is_coinbase),
false);
136 static COutPoint createUtxo(
Chainstate &chainstate,
const CKey &key,
138 uint32_t height = 100,
139 bool is_coinbase =
false) {
141 addCoin(chainstate, outpoint, key, amount, height, is_coinbase);
146 buildProof(
const CKey &key,
147 const std::vector<std::tuple<COutPoint, Amount>> &outpoints,
149 int64_t sequence = 1, uint32_t height = 100,
150 bool is_coinbase =
false, int64_t expirationTime = 0,
152 ProofBuilder pb(sequence, expirationTime, master, payoutScript);
153 for (
const auto &[outpoint, amount] : outpoints) {
154 BOOST_CHECK(pb.addUTXO(outpoint, amount, height, is_coinbase, key));
159 template <
typename... Args>
161 buildProofWithOutpoints(
const CKey &key,
162 const std::vector<COutPoint> &outpoints,
163 Amount amount, Args &&...args) {
164 std::vector<std::tuple<COutPoint, Amount>> outpointsWithAmount;
166 outpoints.begin(), outpoints.end(),
167 std::back_inserter(outpointsWithAmount),
168 [amount](
const auto &o) { return std::make_tuple(o, amount); });
169 return buildProof(key, outpointsWithAmount,
170 std::forward<Args>(args)...);
174 buildProofWithSequence(
const CKey &key,
175 const std::vector<COutPoint> &outpoints,
184struct PeerManagerFixture :
public TestChain100Setup {
185 PeerManagerFixture() {
188 ~PeerManagerFixture() {
195struct NoCoolDownFixture :
public PeerManagerFixture {
196 NoCoolDownFixture() {
199 ~NoCoolDownFixture() {
205BOOST_FIXTURE_TEST_SUITE(peermanager_tests, PeerManagerFixture)
213 const std::vector<Slot> oneslot = {{100, 100, 23}};
231 const std::vector<Slot> twoslots = {{100, 100, 69}, {300, 100, 42}};
260 std::vector<Slot> slots;
264 for (
int i = 0; i < 100; i++) {
265 slots.emplace_back(max, 1, i);
272 for (
int i = 0; i < 100; i++) {
280 slots[99] = slots[99].withScore(101);
281 max = slots[99].getStop();
284 for (
int i = 0; i < 100; i++) {
295 for (
int i = 0; i < 100; i++) {
296 slots[i] = slots[i].withStart(slots[i].getStart() + 100);
299 slots[0] =
Slot(1, slots[0].getStop() - 1, slots[0].getPeerId());
300 slots[99] = slots[99].withScore(1);
301 max = slots[99].getStop();
308 for (
int i = 0; i < 100; i++) {
315 for (
int c = 0; c < 1000; c++) {
316 size_t size = InsecureRandBits(10) + 1;
317 std::vector<Slot> slots;
320 uint64_t max = InsecureRandBits(3);
323 max += InsecureRandBits(3);
327 for (
size_t i = 0; i < size; i++) {
328 const uint64_t start = next();
329 const uint32_t score = InsecureRandBits(3);
331 slots.emplace_back(start, score, i);
334 for (
int k = 0; k < 100; k++) {
335 uint64_t s = max > 0 ? InsecureRandRange(max) : 0;
358 const NodeId node0 = 42, node1 = 69, node2 = 37;
368 std::unordered_map<PeerId, int> results = {};
369 for (
int i = 0; i < 10000; i++) {
375 BOOST_CHECK(abs(2 * results[0] - results[1]) < 500);
381 for (
int i = 0; i < 10000; i++) {
383 BOOST_CHECK(n == node0 || n == node1 || n == node2);
387 BOOST_CHECK(abs(results[0] - results[1] + results[2]) < 500);
398 std::array<PeerId, 8> peerids;
399 for (
int i = 0; i < 4; i++) {
401 peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p);
408 for (
int i = 0; i < 100; i++) {
410 BOOST_CHECK(p == peerids[0] || p == peerids[1] || p == peerids[2] ||
425 for (
int i = 0; i < 100; i++) {
427 BOOST_CHECK(p == peerids[0] || p == peerids[1] || p == peerids[3]);
431 for (
int i = 0; i < 4; i++) {
433 peerids[i + 4] = TestPeerManager::registerAndGetPeerId(pm, p);
455 for (
int i = 0; i < 100; i++) {
457 BOOST_CHECK(p == peerids[1] || p == peerids[3] || p == peerids[4] ||
458 p == peerids[5] || p == peerids[6]);
473 std::array<PeerId, 4> peerids;
474 for (
int i = 0; i < 4; i++) {
477 peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p);
482 for (
auto p : peerids) {
489 for (
int i = 0; i < 100; i++) {
513 for (
int i = 0; i < 4; i++) {
517 for (
int i = 0; i < 100; i++) {
526 for (
int i = 0; i < 100; i++) {
534 std::chrono::hours(24)));
536 for (
int i = 0; i < 100; i++) {
546 int node3selected = 0;
547 for (
int i = 0; i < 100; i++) {
572 for (
int i = 0; i < 10; i++) {
574 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
580 const PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
581 BOOST_CHECK_NE(peerid,
NO_PEER);
582 for (
int i = 0; i < 10; i++) {
583 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
584 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
591 for (
int i = 0; i < 5; i++) {
593 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
594 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
600 for (
int i = 0; i < 5; i++) {
602 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
603 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
609 const ProofId &alt_proofid = alt_proof->getId();
612 for (
int i = 0; i < 5; i++) {
614 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
615 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
622 const ProofId &alt2_proofid = alt2_proof->getId();
625 for (
int i = 0; i < 5; i++) {
627 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
633 for (
int i = 0; i < 5; i++) {
635 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
636 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
644 for (
int i = 0; i < 10; i++) {
645 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
646 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
653 for (
int i = 0; i < 10; i++) {
655 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
656 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
672 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
673 BOOST_CHECK_NE(peerid,
NO_PEER);
677 for (
int i = 0; i < 10; i++) {
679 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
680 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
695 for (
int i = 0; i < 10; i++) {
696 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
697 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
717 peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
718 BOOST_CHECK_NE(peerid,
NO_PEER);
719 for (
int i = 0; i < 10; i++) {
720 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
721 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
734 const int height = 100;
737 for (uint32_t i = 0; i < 10; i++) {
744 const auto getPeerId = [&](
const std::vector<COutPoint> &outpoints) {
745 return TestPeerManager::registerAndGetPeerId(
746 pm, buildProofWithOutpoints(key, outpoints, v, masterKey, 0, height,
751 const PeerId peer1 = getPeerId({COutPoint(txid1, 0)});
758 const PeerId peer2 = getPeerId({COutPoint(txid2, 0)});
762 const PeerId peer3 = getPeerId({COutPoint(txid1, 1)});
769 const PeerId peer4 = getPeerId({COutPoint(txid1, 2), COutPoint(txid2, 2)});
776 COutPoint o(txid1, 3);
779 !pm.
registerProof(TestProofBuilder::buildDuplicatedStakes(pb)));
801 int immatureHeight = 100;
803 auto registerImmature = [&](
const ProofRef &proof) {
809 auto checkImmature = [&](
const ProofRef &proof,
bool expectedImmature) {
826 std::vector<ProofRef> immatureProofs;
831 auto proof = buildProofWithOutpoints(
835 registerImmature(proof);
836 checkImmature(proof,
true);
837 immatureProofs.push_back(proof);
841 for (
auto i = 0; i < 100; i++) {
845 key, 0, immatureHeight);
848 registerImmature(proof);
849 checkImmature(proof,
true);
850 immatureProofs.push_back(proof);
852 immatureProofs.erase(immatureProofs.begin());
857 const COutPoint &outpoint =
858 immatureProofs.front()->getStakes()[0].getStake().getUTXO();
861 key, 1, immatureHeight);
862 registerImmature(proof);
863 checkImmature(proof,
true);
864 immatureProofs.push_back(proof);
866 immatureProofs.erase(immatureProofs.begin());
873 for (
const auto &proof : immatureProofs) {
874 checkImmature(proof,
false);
885 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
886 BOOST_CHECK_NE(peerid,
NO_PEER);
889 std::chrono::hours(24));
892 for (
int i = 0; i < 10; i++) {
901 for (
int i = 0; i < 10; i++) {
907 peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
908 BOOST_CHECK_NE(peerid,
NO_PEER);
911 for (
int i = 0; i < 10; i++) {
914 i, [&](
const Node &n) { return n.nextRequestTime == theFuture; }));
921 for (
int i = 0; i < 10; i++) {
930 constexpr int numProofs = 10;
932 std::vector<ProofRef> proofs;
933 proofs.reserve(numProofs);
934 for (
int i = 0; i < numProofs; i++) {
939 for (
int i = 0; i < numProofs; i++) {
947 ProofRegistrationResult::ALREADY_REGISTERED);
950 for (
int added = 0; added <= i; added++) {
951 auto proof = pm.
getProof(proofs[added]->getId());
960 const std::string badProofHex(
961 "96527eae083f1f24625f049d9e54bb9a21023beefdde700a6bc02036335b4df141c8b"
962 "c67bb05a971f5ac2745fd683797dde3002321023beefdde700a6bc02036335b4df141"
963 "c8bc67bb05a971f5ac2745fd683797dde3ac135da984db510334abe41134e3d4ef09a"
964 "d006b1152be8bc413182bf6f947eac1f8580fe265a382195aa2d73935cabf86d90a8f"
965 "666d0a62385ae24732eca51575");
983 const COutPoint conflictingOutpoint = createUtxo(active_chainstate, key);
984 const COutPoint outpointToSend = createUtxo(active_chainstate, key);
987 buildProofWithSequence(key, {conflictingOutpoint, outpointToSend}, 20);
991 buildProofWithSequence(key, {conflictingOutpoint}, 10);
994 BOOST_CHECK(state.GetResult() == ProofRegistrationResult::CONFLICTING);
1016 const uint32_t height = 100;
1017 const bool is_coinbase =
false;
1023 auto conflictingOutpoint = createUtxo(active_chainstate, key, amount);
1025 auto proof_base = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1028 auto checkPreferred = [&](
const ProofRef &candidate,
1029 const ProofRef &reference,
bool expectAccepted) {
1041 ProofRegistrationResult::CONFLICTING,
1055 checkPreferred(buildProofWithSequence(key, {conflictingOutpoint}, 9),
1058 checkPreferred(buildProofWithSequence(key, {conflictingOutpoint}, 11),
1061 auto buildProofFromAmounts = [&](
const CKey &master,
1062 std::vector<Amount> &&amounts) {
1063 std::vector<std::tuple<COutPoint, Amount>> outpointsWithAmount{
1064 {conflictingOutpoint, amount}};
1065 std::transform(amounts.begin(), amounts.end(),
1066 std::back_inserter(outpointsWithAmount),
1067 [&key, &active_chainstate](
const Amount amount) {
1068 return std::make_tuple(
1069 createUtxo(active_chainstate, key, amount),
1072 return buildProof(key, outpointsWithAmount, master, 0, height,
1076 auto proof_multiUtxo = buildProofFromAmounts(
1083 checkPreferred(buildProofFromAmounts(
1085 proof_multiUtxo,
false);
1089 proof_multiUtxo,
true);
1092 proof_multiUtxo,
true);
1097 proof_multiUtxo,
false);
1099 auto proofSimilar = buildProofFromAmounts(
1101 checkPreferred(proofSimilar, proof_multiUtxo,
1102 proofSimilar->getId() < proof_multiUtxo->getId());
1115 const COutPoint conflictingOutpoint = createUtxo(active_chainstate, key);
1116 const COutPoint matureOutpoint =
1119 auto immature10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1121 buildProofWithSequence(key, {conflictingOutpoint, matureOutpoint}, 20);
1131 auto proof30 = buildProofWithOutpoints(key, {matureOutpoint},
1159 const COutPoint conflictingOutpoint =
1162 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1163 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1164 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1191 auto now = GetTime<std::chrono::seconds>();
1195 for (
size_t i = 0; i < 10; i++) {
1197 PeerId(GetRand<int>(1000)), now));
1202 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
1204 auto checkNextPossibleConflictTime = [&](std::chrono::seconds expected) {
1206 return p.nextPossibleConflictTime == expected;
1210 checkNextPossibleConflictTime(now);
1214 peerid, now - std::chrono::seconds{1}));
1215 checkNextPossibleConflictTime(now);
1218 peerid, now + std::chrono::seconds{1}));
1219 checkNextPossibleConflictTime(now + std::chrono::seconds{1});
1228 const COutPoint conflictingOutpoint =
1231 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1232 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1233 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1262 for (
size_t i = 0; i < 10; i++) {
1265 !pm.
registerProof(proofSeq10, RegistrationMode::FORCE_ACCEPT));
1273 for (
size_t i = 0; i < 10; i++) {
1275 pm.
registerProof(proofSeq30, RegistrationMode::FORCE_ACCEPT));
1281 pm.
registerProof(proofSeq10, RegistrationMode::FORCE_ACCEPT));
1294 const COutPoint conflictingOutpoint =
1297 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1298 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1299 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1326 const COutPoint conflictingOutpoint =
1329 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1330 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1331 auto proofSeq40 = buildProofWithSequence(key, {conflictingOutpoint}, 40);
1333 int64_t conflictingProofCooldown = 100;
1335 strprintf(
"%d", conflictingProofCooldown));
1339 auto increaseMockTime = [&](int64_t s) {
1343 increaseMockTime(0);
1348 auto checkRegistrationFailure = [&](
const ProofRef &proof,
1357 checkRegistrationFailure(proofSeq20,
1358 ProofRegistrationResult::COOLDOWN_NOT_ELAPSED);
1362 checkRegistrationFailure(proofSeq40,
1363 ProofRegistrationResult::COOLDOWN_NOT_ELAPSED);
1367 increaseMockTime(conflictingProofCooldown);
1370 checkRegistrationFailure(proofSeq20, ProofRegistrationResult::CONFLICTING);
1374 checkRegistrationFailure(proofSeq40,
1375 ProofRegistrationResult::COOLDOWN_NOT_ELAPSED);
1380 increaseMockTime(conflictingProofCooldown);
1401 const COutPoint conflictingOutpoint =
1403 const COutPoint immatureOutpoint = createUtxo(active_chainstate, key);
1406 auto proofSeq10 = buildProofWithOutpoints(
1408 auto proofSeq20 = buildProofWithOutpoints(
1410 auto immature30 = buildProofWithSequence(
1411 key, {conflictingOutpoint, immatureOutpoint}, 30);
1422 for (
size_t i = 0; i < 10; i++) {
1431 auto checkRejectDefault = [&](
const ProofId &proofid) {
1433 const bool isImmature = pm.
isImmature(proofid);
1440 auto checkRejectInvalidate = [&](
const ProofId &proofid) {
1447 checkRejectDefault(immature30->getId());
1450 checkRejectInvalidate(immature30->getId());
1453 checkRejectDefault(proofSeq10->getId());
1454 checkRejectInvalidate(proofSeq10->getId());
1461 checkRejectDefault(proofSeq20->getId());
1468 checkRejectInvalidate(proofSeq10->getId());
1495 for (
size_t i = 0; i < 10; i++) {
1502 for (
size_t i = 0; i < 10; i++) {
1508 auto cooldownTimepoint = Now<SteadyMilliseconds>() + 10s;
1511 for (
size_t i = 0; i < 10; i++) {
1513 BOOST_CHECK_NE(selectedId,
NO_NODE);
1523 for (
size_t i = 0; i < 10; i++) {
1538 TestPeerManager::cleanupDanglingProofs(pm);
1545 TestPeerManager::cleanupDanglingProofs(pm);
1549 for (
size_t i = 0; i < 10; i++) {
1563 for (
size_t i = 0; i < 10; i++) {
1573 TestPeerManager::cleanupDanglingProofs(pm);
1579 TestPeerManager::cleanupDanglingProofs(pm);
1597 std::vector<uint32_t> expectedScores(10);
1599 std::generate(expectedScores.rbegin(), expectedScores.rend(),
1600 [n = 1]()
mutable { return n++ * MIN_VALID_PROOF_SCORE; });
1602 std::vector<ProofRef> proofs;
1603 proofs.reserve(expectedScores.size());
1604 for (uint32_t score : expectedScores) {
1610 for (
auto &proof : proofs) {
1614 auto peersScores = TestPeerManager::getOrderedScores(pm);
1615 BOOST_CHECK_EQUAL_COLLECTIONS(peersScores.begin(), peersScores.end(),
1616 expectedScores.begin(), expectedScores.end());
1631 const COutPoint peer1ConflictingOutput =
1632 createUtxo(active_chainstate, key, amount1, 99);
1633 const COutPoint peer1SecondaryOutpoint =
1634 createUtxo(active_chainstate, key, amount2, 99);
1636 auto peer1Proof1 = buildProof(
1638 {{peer1ConflictingOutput, amount1}, {peer1SecondaryOutpoint, amount2}},
1641 buildProof(key, {{peer1ConflictingOutput, amount1}}, key, 20, 99);
1646 {{peer1ConflictingOutput, amount1},
1647 {createUtxo(active_chainstate, key, amount1), amount1}},
1650 const uint32_t peer1Score1 = Proof::amountToScore(amount1 + amount2);
1651 const uint32_t peer1Score2 = Proof::amountToScore(amount1);
1669 auto checkRejectDefault = [&](
const ProofId &proofid) {
1671 const bool isImmature = pm.
isImmature(proofid);
1678 auto checkRejectInvalidate = [&](
const ProofId &proofid) {
1685 checkRejectDefault(peer1Proof3->getId());
1689 checkRejectInvalidate(peer1Proof3->getId());
1693 checkRejectDefault(peer1Proof1->getId());
1694 checkRejectInvalidate(peer1Proof1->getId());
1703 checkRejectDefault(peer1Proof2->getId());
1710 checkRejectInvalidate(peer1Proof1->getId());
1720 PeerId peerid2 = TestPeerManager::registerAndGetPeerId(pm, peer2Proof1);
1731 TestPeerManager::getPeerIdForProofId(pm, peer1Proof2->getId());
1740 const auto checkScores = [&pm](uint32_t known, uint32_t connected) {
1754 PeerId peerid1 = TestPeerManager::registerAndGetPeerId(pm, proof1);
1755 checkScores(score1, 0);
1759 const ProofId &proofid1 = proof1->getId();
1760 const uint8_t nodesToAdd = 10;
1761 for (
int i = 0; i < nodesToAdd; i++) {
1763 checkScores(score1, score1);
1767 for (
int i = 0; i < nodesToAdd - 1; i++) {
1769 checkScores(score1, score1);
1774 checkScores(score1, 0);
1780 checkScores(score1, score1);
1784 PeerId peerid2 = TestPeerManager::registerAndGetPeerId(pm, proof2);
1785 checkScores(score1 + score2, score1);
1787 checkScores(score1 + score2, score1 + score2);
1792 checkScores(score1 + score2, score1 + score2);
1794 checkScores(score1 + score2, score2);
1798 checkScores(score2, score2);
1802 checkScores(score2, 0);
1811 peerid1 = TestPeerManager::registerAndGetPeerId(pm, proof1);
1812 checkScores(score1, 0);
1813 peerid2 = TestPeerManager::registerAndGetPeerId(pm, proof2);
1814 checkScores(score1 + score2, 0);
1816 checkScores(score1 + score2, score1);
1818 checkScores(score1 + score2, score1 + score2);
1821 checkScores(score1, score1);
1831 struct ProofComparatorById {
1836 using ProofSetById = std::set<ProofRef, ProofComparatorById>;
1838 ProofSetById expectedProofs;
1840 auto matchExpectedContent = [&](
const auto &tree) {
1841 auto it = expectedProofs.
begin();
1842 return tree.forEachLeaf([&](
auto pLeaf) {
1843 return it != expectedProofs.end() &&
1844 pLeaf->getId() == (*it++)->getId();
1849 const int64_t sequence = 10;
1854 for (
size_t i = 0; i < 10; i++) {
1855 auto outpoint = createUtxo(active_chainstate, key);
1856 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
1858 expectedProofs.insert(std::move(proof));
1868 ProofSetById addedProofs;
1869 std::vector<COutPoint> outpointsToSpend;
1870 for (
size_t i = 0; i < 10; i++) {
1871 auto outpoint = createUtxo(active_chainstate, key);
1872 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
1874 addedProofs.insert(std::move(proof));
1875 outpointsToSpend.push_back(std::move(outpoint));
1882 expectedProofs.
insert(addedProofs.begin(), addedProofs.end());
1889 for (
const auto &outpoint : outpointsToSpend) {
1901 for (
const auto &proof : addedProofs) {
1907 std::vector<ProofRef> conflictingProofs;
1908 std::vector<COutPoint> conflictingOutpoints;
1909 for (
size_t i = 0; i < 10; i++) {
1910 auto outpoint = createUtxo(active_chainstate, key);
1911 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
1913 conflictingProofs.push_back(std::move(proof));
1914 conflictingOutpoints.push_back(std::move(outpoint));
1918 expectedProofs.
insert(conflictingProofs.begin(), conflictingProofs.end());
1922 for (
size_t i = 0; i < 10; i += 2) {
1925 key, {{conflictingOutpoints[i]}}, sequence - 1)));
1928 auto replacementProof = buildProofWithSequence(
1929 key, {{conflictingOutpoints[i + 1]}}, sequence + 1);
1932 BOOST_CHECK(expectedProofs.insert(replacementProof).second);
1946 auto addNode = [&](
NodeId nodeid) {
1953 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
1970 const auto now = GetTime<std::chrono::seconds>();
1971 auto mocktime = now;
1973 auto elapseTime = [&](std::chrono::seconds seconds) {
1974 mocktime += seconds;
1981 const size_t numProofs = 10;
1983 std::vector<COutPoint> outpoints(numProofs);
1984 std::vector<ProofRef> proofs(numProofs);
1985 std::vector<ProofRef> conflictingProofs(numProofs);
1986 for (
size_t i = 0; i < numProofs; i++) {
1988 proofs[i] = buildProofWithSequence(key, {outpoints[i]}, 2);
1989 conflictingProofs[i] = buildProofWithSequence(key, {outpoints[i]}, 1);
2003 return peer.node_count;
2011 TestPeerManager::cleanupDanglingProofs(pm);
2012 for (
size_t i = 0; i < numProofs; i++) {
2019 TestPeerManager::cleanupDanglingProofs(pm);
2020 for (
size_t i = 0; i < numProofs; i++) {
2021 const bool hasNodeAttached = i % 2;
2038 conflictingProofs[0]->getId(),
2043 TestPeerManager::cleanupDanglingProofs(pm);
2044 for (
size_t i = 0; i < numProofs; i++) {
2045 const bool hasNodeAttached = i % 2;
2055 hasNodeAttached || i == 0);
2063 for (
size_t i = 1; i < numProofs; i += 2) {
2067 return peer.node_count == 0;
2072 conflictingProofs[0]->getId(),
2075 TestPeerManager::cleanupDanglingProofs(pm);
2076 for (
size_t i = 0; i < numProofs; i++) {
2077 const bool hadNodeAttached = i % 2;
2094 TestPeerManager::cleanupDanglingProofs(pm);
2096 for (
size_t i = 0; i < numProofs; i++) {
2113 BOOST_CHECK(state.GetResult() == ProofRegistrationResult::MISSING_UTXO);
2120 const int64_t tipTime =
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 const std::vector<std::tuple<uint32_t, uint32_t, double>> testCases = {
2167 {10, 100, 1. - std::exp(-1. * 10 / 100)},
2174 for (
const auto &[step,
tau, decayFactor] : testCases) {
2178 auto proofid = proof->
getId();
2181 const int numNodesPerPeer = 5;
2182 for (
auto nodeid = 0; nodeid < numNodesPerPeer; nodeid++) {
2186 auto getNodeAvailabilityScore = [&](
double avgScore,
2187 NodeId nodeid) ->
double {
2190 return (nodeid - numNodesPerPeer / 2) * 2 + avgScore;
2193 auto getAvailabilityScore = [&]() {
2195 pm.
forPeer(proofid, [&](
auto &peer) {
2196 score = peer.availabilityScore;
2202 double previousScore = getAvailabilityScore();
2203 BOOST_CHECK_SMALL(previousScore, 1e-6);
2206 for (
size_t i = 1; i <= 10; i++) {
2207 for (uint32_t j = 0; j <
tau; j += step) {
2210 return getNodeAvailabilityScore(1.0, nodeid);
2214 double currentScore = getAvailabilityScore();
2215 BOOST_CHECK_GE(currentScore, previousScore);
2216 previousScore = currentScore;
2222 BOOST_CHECK_CLOSE(previousScore,
2223 -1 * std::expm1(-1. * i) * numNodesPerPeer,
2228 BOOST_CHECK_CLOSE(previousScore, numNodesPerPeer, 0.01);
2238 pm.
forPeer(proofid, [&](
auto &peer) {
2246 previousScore = getAvailabilityScore();
2247 BOOST_CHECK_SMALL(previousScore, 1e-6);
2250 for (
size_t i = 1; i <= 10; i++) {
2251 for (uint32_t j = 0; j <
tau; j += step) {
2253 return getNodeAvailabilityScore(1.0, nodeid);
2257 previousScore = getAvailabilityScore();
2258 BOOST_CHECK_CLOSE(previousScore, numNodesPerPeer, 0.01);
2260 for (
size_t i = 1; i <= 3; i++) {
2261 for (uint32_t j = 0; j <
tau; j += step) {
2264 return getNodeAvailabilityScore(0.0, nodeid);
2268 double currentScore = getAvailabilityScore();
2269 BOOST_CHECK_LE(currentScore, previousScore);
2270 previousScore = currentScore;
2277 BOOST_CHECK_CLOSE(previousScore,
2278 (1. + std::expm1(-1. * i)) * numNodesPerPeer,
2283 BOOST_CHECK_LT(previousScore, .05 * numNodesPerPeer);
2285 for (
size_t i = 1; i <= 100; i++) {
2288 return getNodeAvailabilityScore(-10.0, nodeid);
2292 double currentScore = getAvailabilityScore();
2293 BOOST_CHECK_LE(currentScore, previousScore);
2294 BOOST_CHECK_LE(currentScore, 0.);
2295 previousScore = currentScore;
2305 auto buildProofWithAmountAndPayout = [&](
Amount amount,
2306 const CScript &payoutScript) {
2308 COutPoint utxo = createUtxo(active_chainstate, key, amount);
2309 return buildProof(key, {{std::move(utxo), amount}},
2315 std::vector<std::pair<ProofId, CScript>> winners;
2321 auto now = GetTime<std::chrono::seconds>();
2323 prevBlock.
nTime = now.count();
2332 size_t numProofs = 8;
2333 std::vector<ProofRef> proofs;
2334 proofs.reserve(numProofs);
2335 for (
size_t i = 0; i < numProofs; i++) {
2341 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2342 BOOST_CHECK_NE(peerid,
NO_PEER);
2347 proofs.emplace_back(std::move(proof));
2354 prevBlock.
nTime = now.count();
2360 BOOST_CHECK_LE(winners.size(), numProofs);
2363 for (
size_t i = 0; i < numProofs; i++) {
2364 BOOST_CHECK(TestPeerManager::isFlaky(pm, proofs[i]->getId()));
2366 BOOST_CHECK_LE(winners.size(), numProofs);
2370 BOOST_CHECK(!TestPeerManager::isFlaky(pm, proofs[i]->getId()));
2372 BOOST_CHECK_LE(winners.size(), numProofs - i);
2377 BOOST_CHECK_LE(winners.size(), 1);
2383 const size_t loop_iters =
2384 size_t(-1.0 * std::log(100000.0) /
2385 std::log((
double(numProofs) - 1) / numProofs)) +
2387 BOOST_CHECK_GT(loop_iters, numProofs);
2388 std::unordered_map<std::string, size_t> winningCounts;
2389 for (
size_t i = 0; i < loop_iters; i++) {
2400 for (
size_t i = 0; i < numProofs; i++) {
2401 for (
size_t j = 0; j < numProofs; j++) {
2409 BOOST_CHECK_GT(3. / numProofs, 0.3);
2410 for (
size_t i = 0; i < numProofs; i++) {
2414 proofs[(i - 1 + numProofs) % numProofs]->getId(), nodeid,
false));
2416 proofs[(i + numProofs) % numProofs]->getId(), nodeid,
false));
2418 proofs[(i + 1 + numProofs) % numProofs]->getId(), nodeid,
false));
2423 for (
const auto &proof : proofs) {
2429 for (
const auto &proof : proofs) {
2430 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2439 for (
size_t numWinner = 1; numWinner < 4; numWinner++) {
2441 CScript lastWinner = winners[numWinner - 1].second;
2445 for (
const auto &proof : proofs) {
2447 winnerProofId = proof->
getId();
2453 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2456 BOOST_CHECK(TestPeerManager::isFlaky(pm, winnerProofId));
2466 CScript lastWinner = winners[3].second;
2469 for (
const auto &proof : proofs) {
2471 winnerProofId = proof->
getId();
2477 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2486 for (
auto &proof : proofs) {
2501 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2502 BOOST_CHECK_NE(peerid,
NO_PEER);
2528 prevBlock.
nTime = now.count();
2543 for (
size_t i = 0; i < 4; i++) {
2552 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2553 BOOST_CHECK_NE(peerid,
NO_PEER);
2555 return peer.registration_time == now + i * 30min;
2562 proofs.push_back(proof);
2567 prevBlock.
nTime = now.count();
2575 prevBlock.
nTime = now.count();
2578 auto checkRegistrationTime =
2579 [&](
const std::pair<ProofId, CScript> &winner) {
2583 (now - 60min).count());
2594 prevBlock.
nTime = now.count();
2597 checkRegistrationTime(winners[0]);
2605 prevBlock.
nTime = now.count();
2607 BOOST_CHECK_LE(winners.size(), 3);
2608 checkRegistrationTime(winners[0]);
2616 prevBlock.
nTime = now.count();
2618 BOOST_CHECK_LE(winners.size(), 3);
2619 checkRegistrationTime(winners[0]);
2626 prevBlock.
nTime = now.count();
2628 BOOST_CHECK_LE(winners.size(), 2);
2629 checkRegistrationTime(winners[0]);
2635 prevBlock.
nTime = now.count();
2638 checkRegistrationTime(winners[0]);
2646 auto mockTime = GetTime<std::chrono::seconds>();
2654 auto checkRemoteProof =
2656 const bool expectedPresent,
2657 const std::chrono::seconds &expectedlastUpdate) {
2660 TestPeerManager::getRemoteProof(pm, proofid, nodeid);
2666 expectedlastUpdate.count());
2722 checkRemoteProof(proofid, 0,
true, mockTime);
2738 checkRemoteProof(proofid, 0,
true, mockTime);
2748 std::vector<ProofRef> proofs;
2753 proofs.push_back(proof);
2766 checkRemoteProof(proofid, 0,
true, mockTime);
2796 auto mockTime = GetTime<std::chrono::seconds>();
2805 for (
NodeId nodeid = 0; nodeid < 12; nodeid++) {
2818 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
2821 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
2831 TestPeerManager::setLocalProof(pm, localProof);
2839 TestPeerManager::setLocalProof(pm,
ProofRef());
2845 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
2848 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
2863 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
2866 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
2874 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
2877 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
2884 TestPeerManager::clearPeers(pm);
2894 for (
NodeId nodeid = 1; nodeid < 6; nodeid++) {
2900 for (
NodeId nodeid = 1; nodeid < 6; nodeid++) {
2917 auto mockTime = GetTime<std::chrono::seconds>();
2921 std::vector<ProofRef> proofs;
2922 for (
size_t i = 0; i < 10; i++) {
2925 proofs.push_back(proof);
2929 TestPeerManager::cleanupDanglingProofs(pm);
2930 for (
const auto &proof : proofs) {
2940 TestPeerManager::cleanupDanglingProofs(pm);
2941 for (
const auto &proof : proofs) {
2947 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
2953 for (
const auto &proof : proofs) {
2959 for (
const auto &proof : proofs) {
2965 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
2966 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
2967 for (
const auto &proof : proofs) {
2975 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
2976 for (
const auto &proof : proofs) {
2982 for (
const auto &proof : proofs) {
2984 !TestPeerManager::getRemotePresenceStatus(pm, proof->
getId())
2989 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
2991 for (
const auto &proof : proofs) {
3000 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3002 for (
const auto &proof : proofs) {
3008 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
3009 for (
const auto &proof : proofs) {
3014 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3015 for (
const auto &proof : proofs) {
3028 auto mockTime = GetTime<std::chrono::seconds>();
3031 std::vector<ProofRef> proofs;
3032 for (
size_t i = 0; i < 10; i++) {
3039 auto peerid = TestPeerManager::getPeerIdForProofId(pm, proof->getId());
3043 peerid, mockTime + std::chrono::seconds{100 + i}));
3050 proofs.push_back(proof);
3055 const fs::path testDumpPath =
"test_avapeers_dump.dat";
3058 TestPeerManager::clearPeers(pm);
3060 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
3064 auto findProofIndex = [&proofs](
const ProofId &proofid) {
3065 for (
size_t i = 0; i < proofs.size(); i++) {
3066 if (proofs[i]->getId() == proofid) {
3076 for (
const auto &proof : registeredProofs) {
3078 size_t i = findProofIndex(proofid);
3080 BOOST_CHECK_EQUAL(peer.hasFinalized, i < 5);
3081 BOOST_CHECK_EQUAL(peer.registration_time.count(),
3082 (mockTime + std::chrono::seconds{i}).count());
3084 peer.nextPossibleConflictTime.count(),
3085 (mockTime + std::chrono::seconds{100 + i}).count());
3091 TestPeerManager::clearPeers(pm);
3104 registeredProofs.insert(proofs[0]);
3114 file << static_cast<uint64_t>(-1);
3115 file << uint64_t{0};
3120 registeredProofs.insert(proofs[0]);
3131 const uint64_t now =
GetTime();
3133 file << static_cast<uint64_t>(1);
3134 file << uint64_t{2};
3151 proofs[0]->getId());
3163 auto utxo = createUtxo(active_chainstate, key);
3166 GetTime<std::chrono::seconds>().count() + 1000000);
3177 TestPeerManager::cleanupDanglingProofs(pm);
3215 TestPeerManager::cleanupDanglingProofs(pm);
3221 for (int64_t i = 0; i < 6; i++) {
3223 CreateAndProcessBlock({}, CScript());
3227 ->GetMedianTimePast(),
3237BOOST_AUTO_TEST_SUITE_END()
static constexpr PeerId NO_PEER
#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,...
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 output of a transaction.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
bool InvalidateBlock(BlockValidationState &state, CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex
Mark a block as invalid.
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.
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
SnapshotCompletionResult MaybeCompleteSnapshotValidation(std::function< void(bilingual_str)> shutdown_fnc=[](bilingual_str msg) { AbortNode(msg.original, msg);}) EXCLUSIVE_LOCKS_REQUIRED(Chainstate & ActiveChainstate() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
static RCUPtr make(Args &&...args)
Construct a new object that is owned by the pointer.
bool selectStakingRewardWinner(const CBlockIndex *pprev, std::vector< std::pair< ProofId, CScript > > &winners)
Deterministically select a list of payout scripts based on the proof set and the previous block hash.
bool removeNode(NodeId nodeid)
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
Return true if the (valid) proof exists, but only for non-dangling proofs.
bool isRemoteProof(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.
const ProofRadixTree & getShareableProofsSnapshot() const
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.
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)
int64_t getExpirationTime() const
const CScript & getPayoutScript() const
const ProofId & getId() const
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.
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
bool error(const char *fmt, const Args &...args)
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_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.
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.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
std::chrono::time_point< std::chrono::steady_clock, std::chrono::milliseconds > SteadyMilliseconds