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;
87 ProofPool::AddProofStatus::SUCCEED;
90 static std::optional<RemoteProof> getRemoteProof(
const PeerManager &pm,
93 auto it = pm.
remoteProofs.find(boost::make_tuple(proofid, nodeid));
97 return std::make_optional(*it);
100 static size_t getPeerCount(
const PeerManager &pm) {
101 return pm.
peers.size();
104 static std::optional<bool>
110 std::vector<PeerId> peerIds;
111 for (
auto &peer : pm.
peers) {
112 peerIds.push_back(peer.peerid);
114 for (
const PeerId &peerid : peerIds) {
136 uint32_t height = 100,
bool is_coinbase =
false) {
145 static COutPoint createUtxo(
Chainstate &chainstate,
const CKey &key,
147 uint32_t height = 100,
148 bool is_coinbase =
false) {
150 addCoin(chainstate, outpoint, key, amount, height, is_coinbase);
155 buildProof(
const CKey &key,
156 const std::vector<std::tuple<COutPoint, Amount>> &outpoints,
158 int64_t sequence = 1, uint32_t height = 100,
159 bool is_coinbase =
false, int64_t expirationTime = 0,
161 ProofBuilder pb(sequence, expirationTime, master, payoutScript);
162 for (
const auto &[outpoint, amount] : outpoints) {
163 BOOST_CHECK(pb.addUTXO(outpoint, amount, height, is_coinbase, key));
175 const std::vector<std::tuple<COutPoint, Amount, uint32_t>> &outpoints,
177 bool is_coinbase =
false, int64_t expirationTime = 0,
179 ProofBuilder pb(sequence, expirationTime, master, payoutScript);
180 for (
const auto &[outpoint, amount, height] : outpoints) {
181 BOOST_CHECK(pb.addUTXO(outpoint, amount, height, is_coinbase, key));
186 template <
typename... Args>
188 buildProofWithOutpoints(
const CKey &key,
189 const std::vector<COutPoint> &outpoints,
190 Amount amount, Args &&...args) {
191 std::vector<std::tuple<COutPoint, Amount>> outpointsWithAmount;
193 outpoints.begin(), outpoints.end(),
194 std::back_inserter(outpointsWithAmount),
195 [amount](
const auto &o) { return std::make_tuple(o, amount); });
196 return buildProof(key, outpointsWithAmount,
197 std::forward<Args>(args)...);
201 buildProofWithSequence(
const CKey &key,
202 const std::vector<COutPoint> &outpoints,
211struct PeerManagerFixture :
public TestChain100Setup {
212 PeerManagerFixture() {
215 ~PeerManagerFixture() {
222struct NoCoolDownFixture :
public PeerManagerFixture {
223 NoCoolDownFixture() {
226 ~NoCoolDownFixture() {
232BOOST_FIXTURE_TEST_SUITE(peermanager_tests, PeerManagerFixture)
240 const std::vector<Slot> oneslot = {{100, 100, 23}};
258 const std::vector<Slot> twoslots = {{100, 100, 69}, {300, 100, 42}};
287 std::vector<Slot> slots;
291 for (
int i = 0; i < 100; i++) {
292 slots.emplace_back(max, 1, i);
299 for (
int i = 0; i < 100; i++) {
307 slots[99] = slots[99].withScore(101);
308 max = slots[99].getStop();
311 for (
int i = 0; i < 100; i++) {
322 for (
int i = 0; i < 100; i++) {
323 slots[i] = slots[i].withStart(slots[i].getStart() + 100);
326 slots[0] =
Slot(1, slots[0].getStop() - 1, slots[0].getPeerId());
327 slots[99] = slots[99].withScore(1);
328 max = slots[99].getStop();
335 for (
int i = 0; i < 100; i++) {
342 for (
int c = 0; c < 1000; c++) {
343 size_t size = m_rng.randbits(10) + 1;
344 std::vector<Slot> slots;
347 uint64_t max = m_rng.randbits(3);
350 max += m_rng.randbits(3);
354 for (
size_t i = 0; i < size; i++) {
355 const uint64_t start = next();
356 const uint32_t score = m_rng.randbits(3);
358 slots.emplace_back(start, score, i);
361 for (
int k = 0; k < 100; k++) {
362 uint64_t s = max > 0 ? m_rng.randrange(max) : 0;
386 const NodeId node0 = 42, node1 = 69, node2 = 37;
396 std::unordered_map<PeerId, int> results = {};
397 for (
int i = 0; i < 10000; i++) {
403 BOOST_CHECK(abs(2 * results[0] - results[1]) < 500);
409 for (
int i = 0; i < 10000; i++) {
411 BOOST_CHECK(n == node0 || n == node1 || n == node2);
415 BOOST_CHECK(abs(results[0] - results[1] + results[2]) < 500);
426 std::array<PeerId, 8> peerids;
427 for (
int i = 0; i < 4; i++) {
429 peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p);
437 for (
int i = 0; i < 100; i++) {
439 BOOST_CHECK(p == peerids[0] || p == peerids[1] || p == peerids[2] ||
454 for (
int i = 0; i < 100; i++) {
456 BOOST_CHECK(p == peerids[0] || p == peerids[1] || p == peerids[3]);
460 for (
int i = 0; i < 4; i++) {
462 peerids[i + 4] = TestPeerManager::registerAndGetPeerId(pm, p);
485 for (
int i = 0; i < 100; i++) {
487 BOOST_CHECK(p == peerids[1] || p == peerids[3] || p == peerids[4] ||
488 p == peerids[5] || p == peerids[6]);
503 std::array<PeerId, 4> peerids;
504 for (
int i = 0; i < 4; i++) {
507 peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p);
513 for (
auto p : peerids) {
520 for (
int i = 0; i < 100; i++) {
535 const std::array<uint32_t, 4> scores{{10000, 20000, 30000, 40000}};
536 std::array<PeerId, 4> peerids;
537 for (
int i = 0; i < 4; i++) {
539 peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p);
563 for (uint64_t slot = 0; slot < pm.
getSlotCount(); slot++) {
564 PeerId p = TestPeerManager::selectPeerFromSlot(pm, slot);
567 }
else if (slot < 40000) {
589 for (
int i = 0; i < 4; i++) {
594 for (
int i = 0; i < 100; i++) {
598 n, Now<SteadyMilliseconds>(), round++));
604 for (
int i = 0; i < 100; i++) {
608 n, Now<SteadyMilliseconds>(), round++));
613 1, Now<SteadyMilliseconds>() + std::chrono::hours(24), round++));
615 for (
int i = 0; i < 100; i++) {
619 n, Now<SteadyMilliseconds>(), round++));
626 int node3selected = 0;
627 for (
int i = 0; i < 100; i++) {
636 n, Now<SteadyMilliseconds>(), round++));
640 for (
int i = 0; i < 100; i++) {
667 for (
int i = 0; i < 10; i++) {
670 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
676 const PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
677 BOOST_CHECK_NE(peerid,
NO_PEER);
678 for (
int i = 0; i < 10; i++) {
679 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
680 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
687 for (
int i = 0; i < 5; i++) {
689 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
690 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
696 for (
int i = 0; i < 5; i++) {
698 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
699 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
705 const ProofId &alt_proofid = alt_proof->getId();
708 for (
int i = 0; i < 5; i++) {
711 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
712 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
719 const ProofId &alt2_proofid = alt2_proof->getId();
722 for (
int i = 0; i < 5; i++) {
725 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
731 for (
int i = 0; i < 5; i++) {
733 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
734 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
742 for (
int i = 0; i < 10; i++) {
743 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
744 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
751 for (
int i = 0; i < 10; i++) {
753 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
754 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
770 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
771 BOOST_CHECK_NE(peerid,
NO_PEER);
775 for (
int i = 0; i < 10; i++) {
777 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
778 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
793 for (
int i = 0; i < 10; i++) {
794 BOOST_CHECK(TestPeerManager::isNodePending(pm, i));
795 BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid));
815 peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
816 BOOST_CHECK_NE(peerid,
NO_PEER);
817 for (
int i = 0; i < 10; i++) {
818 BOOST_CHECK(!TestPeerManager::isNodePending(pm, i));
819 BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid));
832 const int height = 100;
835 for (uint32_t i = 0; i < 10; i++) {
842 const auto getPeerId = [&](
const std::vector<COutPoint> &outpoints) {
843 return TestPeerManager::registerAndGetPeerId(
844 pm, buildProofWithOutpoints(key, outpoints, v, masterKey, 0, height,
849 const PeerId peer1 = getPeerId({COutPoint(txid1, 0)});
856 const PeerId peer2 = getPeerId({COutPoint(txid2, 0)});
860 const PeerId peer3 = getPeerId({COutPoint(txid1, 1)});
867 const PeerId peer4 = getPeerId({COutPoint(txid1, 2), COutPoint(txid2, 2)});
874 COutPoint o(txid1, 3);
877 !pm.
registerProof(TestProofBuilder::buildDuplicatedStakes(pb)));
899 int immatureHeight = 100;
901 auto registerImmature = [&](
const ProofRef &proof) {
907 auto checkImmature = [&](
const ProofRef &proof,
bool expectedImmature) {
924 std::vector<ProofRef> immatureProofs;
929 auto proof = buildProofWithOutpoints(
933 registerImmature(proof);
934 checkImmature(proof,
true);
935 immatureProofs.push_back(proof);
939 for (
auto i = 0; i < 100; i++) {
943 key, 0, immatureHeight);
946 registerImmature(proof);
947 checkImmature(proof,
true);
948 immatureProofs.push_back(proof);
950 immatureProofs.erase(immatureProofs.begin());
955 const COutPoint &outpoint =
956 immatureProofs.front()->getStakes()[0].getStake().getUTXO();
959 key, 1, immatureHeight);
960 registerImmature(proof);
961 checkImmature(proof,
true);
962 immatureProofs.push_back(proof);
964 immatureProofs.erase(immatureProofs.begin());
971 for (
const auto &proof : immatureProofs) {
972 checkImmature(proof,
false);
983 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
984 BOOST_CHECK_NE(peerid,
NO_PEER);
987 std::chrono::hours(24));
990 for (
int i = 0; i < 10; i++) {
1000 for (
int i = 0; i < 10; i++) {
1006 peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
1007 BOOST_CHECK_NE(peerid,
NO_PEER);
1010 for (
int i = 0; i < 10; i++) {
1014 i, [&](
const Node &n) { return n.nextRequestTime == theFuture; }));
1021 for (
int i = 0; i < 10; i++) {
1030 constexpr int numProofs = 10;
1032 std::vector<ProofRef> proofs;
1033 proofs.reserve(numProofs);
1034 for (
int i = 0; i < numProofs; i++) {
1039 for (
int i = 0; i < numProofs; i++) {
1047 ProofRegistrationResult::ALREADY_REGISTERED);
1050 for (
int added = 0; added <= i; added++) {
1051 auto proof = pm.
getProof(proofs[added]->getId());
1060 const std::string badProofHex(
1061 "96527eae083f1f24625f049d9e54bb9a21023beefdde700a6bc02036335b4df141c8b"
1062 "c67bb05a971f5ac2745fd683797dde3002321023beefdde700a6bc02036335b4df141"
1063 "c8bc67bb05a971f5ac2745fd683797dde3ac135da984db510334abe41134e3d4ef09a"
1064 "d006b1152be8bc413182bf6f947eac1f8580fe265a382195aa2d73935cabf86d90a8f"
1065 "666d0a62385ae24732eca51575");
1083 const COutPoint conflictingOutpoint = createUtxo(active_chainstate, key);
1084 const COutPoint outpointToSend = createUtxo(active_chainstate, key);
1087 buildProofWithSequence(key, {conflictingOutpoint, outpointToSend}, 20);
1091 buildProofWithSequence(key, {conflictingOutpoint}, 10);
1094 BOOST_CHECK(state.GetResult() == ProofRegistrationResult::CONFLICTING);
1116 const uint32_t height = 100;
1117 const bool is_coinbase =
false;
1123 auto conflictingOutpoint = createUtxo(active_chainstate, key, amount);
1125 auto proof_base = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1128 auto checkPreferred = [&](
const ProofRef &candidate,
1129 const ProofRef &reference,
bool expectAccepted) {
1141 ProofRegistrationResult::CONFLICTING,
1155 checkPreferred(buildProofWithSequence(key, {conflictingOutpoint}, 9),
1158 checkPreferred(buildProofWithSequence(key, {conflictingOutpoint}, 11),
1161 auto buildProofFromAmounts = [&](
const CKey &master,
1162 std::vector<Amount> &&amounts) {
1163 std::vector<std::tuple<COutPoint, Amount>> outpointsWithAmount{
1164 {conflictingOutpoint, amount}};
1165 std::transform(amounts.begin(), amounts.end(),
1166 std::back_inserter(outpointsWithAmount),
1167 [&key, &active_chainstate](
const Amount amount) {
1168 return std::make_tuple(
1169 createUtxo(active_chainstate, key, amount),
1172 return buildProof(key, outpointsWithAmount, master, 0, height,
1176 auto proof_multiUtxo = buildProofFromAmounts(
1183 checkPreferred(buildProofFromAmounts(
1185 proof_multiUtxo,
false);
1189 proof_multiUtxo,
true);
1192 proof_multiUtxo,
true);
1197 proof_multiUtxo,
false);
1199 auto proofSimilar = buildProofFromAmounts(
1201 checkPreferred(proofSimilar, proof_multiUtxo,
1202 proofSimilar->getId() < proof_multiUtxo->getId());
1215 const COutPoint conflictingOutpoint = createUtxo(active_chainstate, key);
1216 const COutPoint matureOutpoint =
1219 auto immature10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1234 auto proof30 = buildProofWithOutpoints(key, {matureOutpoint},
1262 const COutPoint conflictingOutpoint =
1265 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1266 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1267 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1294 auto now = GetTime<std::chrono::seconds>();
1298 for (
size_t i = 0; i < 10; i++) {
1305 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
1307 auto checkNextPossibleConflictTime = [&](std::chrono::seconds expected) {
1309 return p.nextPossibleConflictTime == expected;
1313 checkNextPossibleConflictTime(now);
1317 peerid, now - std::chrono::seconds{1}));
1318 checkNextPossibleConflictTime(now);
1321 peerid, now + std::chrono::seconds{1}));
1322 checkNextPossibleConflictTime(now + std::chrono::seconds{1});
1331 const COutPoint conflictingOutpoint =
1334 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1335 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1336 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1365 for (
size_t i = 0; i < 10; i++) {
1368 !pm.
registerProof(proofSeq10, RegistrationMode::FORCE_ACCEPT));
1376 for (
size_t i = 0; i < 10; i++) {
1378 pm.
registerProof(proofSeq30, RegistrationMode::FORCE_ACCEPT));
1384 pm.
registerProof(proofSeq10, RegistrationMode::FORCE_ACCEPT));
1397 const COutPoint conflictingOutpoint =
1400 auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10);
1401 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1402 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1429 const COutPoint conflictingOutpoint =
1432 auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20);
1433 auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30);
1434 auto proofSeq40 = buildProofWithSequence(key, {conflictingOutpoint}, 40);
1436 int64_t conflictingProofCooldown = 100;
1438 strprintf(
"%d", conflictingProofCooldown));
1442 auto increaseMockTime = [&](int64_t s) {
1446 increaseMockTime(0);
1451 auto checkRegistrationFailure = [&](
const ProofRef &proof,
1460 checkRegistrationFailure(proofSeq20,
1461 ProofRegistrationResult::COOLDOWN_NOT_ELAPSED);
1465 checkRegistrationFailure(proofSeq40,
1466 ProofRegistrationResult::COOLDOWN_NOT_ELAPSED);
1470 increaseMockTime(conflictingProofCooldown);
1473 checkRegistrationFailure(proofSeq20, ProofRegistrationResult::CONFLICTING);
1477 checkRegistrationFailure(proofSeq40,
1478 ProofRegistrationResult::COOLDOWN_NOT_ELAPSED);
1483 increaseMockTime(conflictingProofCooldown);
1504 const COutPoint conflictingOutpoint =
1506 const COutPoint immatureOutpoint = createUtxo(active_chainstate, key);
1509 auto proofSeq10 = buildProofWithOutpoints(
1511 auto proofSeq20 = buildProofWithOutpoints(
1528 for (
size_t i = 0; i < 10; i++) {
1537 auto checkRejectDefault = [&](
const ProofId &proofid) {
1539 const bool isImmature = pm.
isImmature(proofid);
1546 auto checkRejectInvalidate = [&](
const ProofId &proofid) {
1553 checkRejectDefault(immature30->getId());
1556 checkRejectInvalidate(immature30->getId());
1559 checkRejectDefault(proofSeq10->getId());
1560 checkRejectInvalidate(proofSeq10->getId());
1567 checkRejectDefault(proofSeq20->getId());
1574 checkRejectInvalidate(proofSeq10->getId());
1601 for (
size_t i = 0; i < 10; i++) {
1608 for (
size_t i = 0; i < 10; i++) {
1614 auto cooldownTimepoint = Now<SteadyMilliseconds>() + 10s;
1619 for (
size_t i = 0; i < 10; i++) {
1621 BOOST_CHECK_NE(selectedId,
NO_NODE);
1623 selectedId, cooldownTimepoint, round++));
1632 for (
size_t i = 0; i < 10; i++) {
1648 TestPeerManager::cleanupDanglingProofs(pm);
1655 TestPeerManager::cleanupDanglingProofs(pm);
1659 for (
size_t i = 0; i < 10; i++) {
1673 for (
size_t i = 0; i < 10; i++) {
1684 TestPeerManager::cleanupDanglingProofs(pm);
1690 TestPeerManager::cleanupDanglingProofs(pm);
1708 std::vector<uint32_t> expectedScores(10);
1710 std::generate(expectedScores.rbegin(), expectedScores.rend(),
1711 [n = 1]()
mutable { return n++ * MIN_VALID_PROOF_SCORE; });
1713 std::vector<ProofRef> proofs;
1714 proofs.reserve(expectedScores.size());
1715 for (uint32_t score : expectedScores) {
1721 for (
auto &proof : proofs) {
1725 auto peersScores = TestPeerManager::getOrderedScores(pm);
1726 BOOST_CHECK_EQUAL_COLLECTIONS(peersScores.begin(), peersScores.end(),
1727 expectedScores.begin(), expectedScores.end());
1742 const COutPoint peer1ConflictingOutput =
1743 createUtxo(active_chainstate, key, amount1, 99);
1744 const COutPoint peer1SecondaryOutpoint =
1745 createUtxo(active_chainstate, key, amount2, 99);
1747 auto peer1Proof1 = buildProof(
1749 {{peer1ConflictingOutput, amount1}, {peer1SecondaryOutpoint, amount2}},
1752 buildProof(key, {{peer1ConflictingOutput, amount1}}, key, 20, 99);
1755 const COutPoint immatureOutpoint =
1756 createUtxo(active_chainstate, key, amount1);
1759 {{peer1ConflictingOutput, amount1, uint32_t(99)},
1760 {immatureOutpoint, amount1, uint32_t(100)}},
1763 const uint32_t peer1Score1 = Proof::amountToScore(amount1 + amount2);
1764 const uint32_t peer1Score2 = Proof::amountToScore(amount1);
1782 auto checkRejectDefault = [&](
const ProofId &proofid) {
1784 const bool isImmature = pm.
isImmature(proofid);
1791 auto checkRejectInvalidate = [&](
const ProofId &proofid) {
1798 checkRejectDefault(peer1Proof3->getId());
1802 checkRejectInvalidate(peer1Proof3->getId());
1806 checkRejectDefault(peer1Proof1->getId());
1807 checkRejectInvalidate(peer1Proof1->getId());
1816 checkRejectDefault(peer1Proof2->getId());
1823 checkRejectInvalidate(peer1Proof1->getId());
1833 PeerId peerid2 = TestPeerManager::registerAndGetPeerId(pm, peer2Proof1);
1844 TestPeerManager::getPeerIdForProofId(pm, peer1Proof2->getId());
1853 const auto checkScores = [&pm](uint32_t known, uint32_t connected) {
1867 PeerId peerid1 = TestPeerManager::registerAndGetPeerId(pm, proof1);
1868 checkScores(score1, 0);
1872 const ProofId &proofid1 = proof1->getId();
1873 const uint8_t nodesToAdd = 10;
1874 for (
int i = 0; i < nodesToAdd; i++) {
1877 checkScores(score1, score1);
1881 for (
int i = 0; i < nodesToAdd - 1; i++) {
1883 checkScores(score1, score1);
1888 checkScores(score1, 0);
1894 checkScores(score1, score1);
1898 PeerId peerid2 = TestPeerManager::registerAndGetPeerId(pm, proof2);
1899 checkScores(score1 + score2, score1);
1902 checkScores(score1 + score2, score1 + score2);
1907 checkScores(score1 + score2, score1 + score2);
1909 checkScores(score1 + score2, score2);
1913 checkScores(score2, score2);
1917 checkScores(score2, 0);
1926 peerid1 = TestPeerManager::registerAndGetPeerId(pm, proof1);
1927 checkScores(score1, 0);
1928 peerid2 = TestPeerManager::registerAndGetPeerId(pm, proof2);
1929 checkScores(score1 + score2, 0);
1932 checkScores(score1 + score2, score1);
1935 checkScores(score1 + score2, score1 + score2);
1938 checkScores(score1, score1);
1948 struct ProofComparatorById {
1953 using ProofSetById = std::set<ProofRef, ProofComparatorById>;
1955 ProofSetById expectedProofs;
1957 auto matchExpectedContent = [&](
const auto &tree) {
1958 auto it = expectedProofs.
begin();
1959 return tree.forEachLeaf([&](
auto pLeaf) {
1960 return it != expectedProofs.end() &&
1961 pLeaf->getId() == (*it++)->getId();
1966 const int64_t sequence = 10;
1971 for (
size_t i = 0; i < 10; i++) {
1972 auto outpoint = createUtxo(active_chainstate, key);
1973 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
1975 expectedProofs.insert(std::move(proof));
1985 ProofSetById addedProofs;
1986 std::vector<COutPoint> outpointsToSpend;
1987 for (
size_t i = 0; i < 10; i++) {
1988 auto outpoint = createUtxo(active_chainstate, key);
1989 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
1991 addedProofs.insert(std::move(proof));
1992 outpointsToSpend.push_back(std::move(outpoint));
1999 expectedProofs.
insert(addedProofs.begin(), addedProofs.end());
2006 for (
const auto &outpoint : outpointsToSpend) {
2018 for (
const auto &proof : addedProofs) {
2024 std::vector<ProofRef> conflictingProofs;
2025 std::vector<COutPoint> conflictingOutpoints;
2026 for (
size_t i = 0; i < 10; i++) {
2027 auto outpoint = createUtxo(active_chainstate, key);
2028 auto proof = buildProofWithSequence(key, {{outpoint}}, sequence);
2030 conflictingProofs.push_back(std::move(proof));
2031 conflictingOutpoints.push_back(std::move(outpoint));
2035 expectedProofs.
insert(conflictingProofs.begin(), conflictingProofs.end());
2039 for (
size_t i = 0; i < 10; i += 2) {
2042 key, {{conflictingOutpoints[i]}}, sequence - 1)));
2045 auto replacementProof = buildProofWithSequence(
2046 key, {{conflictingOutpoints[i + 1]}}, sequence + 1);
2049 BOOST_CHECK(expectedProofs.insert(replacementProof).second);
2063 auto addNode = [&](
NodeId nodeid) {
2071 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
2088 const auto now = GetTime<std::chrono::seconds>();
2089 auto mocktime = now;
2091 auto elapseTime = [&](std::chrono::seconds seconds) {
2092 mocktime += seconds;
2099 const size_t numProofs = 10;
2101 std::vector<COutPoint> outpoints(numProofs);
2102 std::vector<ProofRef> proofs(numProofs);
2103 std::vector<ProofRef> conflictingProofs(numProofs);
2104 for (
size_t i = 0; i < numProofs; i++) {
2106 proofs[i] = buildProofWithSequence(key, {outpoints[i]}, 2);
2107 conflictingProofs[i] = buildProofWithSequence(key, {outpoints[i]}, 1);
2122 return peer.node_count;
2130 TestPeerManager::cleanupDanglingProofs(pm);
2131 for (
size_t i = 0; i < numProofs; i++) {
2138 TestPeerManager::cleanupDanglingProofs(pm);
2139 for (
size_t i = 0; i < numProofs; i++) {
2140 const bool hasNodeAttached = i % 2;
2158 conflictingProofs[0]->getId(),
2163 TestPeerManager::cleanupDanglingProofs(pm);
2164 for (
size_t i = 0; i < numProofs; i++) {
2165 const bool hasNodeAttached = i % 2;
2175 hasNodeAttached || i == 0);
2183 for (
size_t i = 1; i < numProofs; i += 2) {
2187 return peer.node_count == 0;
2192 conflictingProofs[0]->getId(),
2195 TestPeerManager::cleanupDanglingProofs(pm);
2196 for (
size_t i = 0; i < numProofs; i++) {
2197 const bool hadNodeAttached = i % 2;
2214 TestPeerManager::cleanupDanglingProofs(pm);
2216 for (
size_t i = 0; i < numProofs; i++) {
2233 BOOST_CHECK(state.GetResult() == ProofRegistrationResult::MISSING_UTXO);
2240 const int64_t tipTime =
2248 100,
false, tipTime + 1);
2250 1, 100,
false, tipTime + 2);
2262 for (int64_t i = 0; i < 6; i++) {
2263 SetMockTime(proofToExpire->getExpirationTime() + i);
2264 CreateAndProcessBlock({}, CScript());
2268 ->GetMedianTimePast(),
2269 proofToExpire->getExpirationTime());
2285 auto buildProofWithAmountAndPayout = [&](
Amount amount,
2286 const CScript &payoutScript) {
2288 COutPoint utxo = createUtxo(active_chainstate, key, amount);
2289 return buildProof(key, {{std::move(utxo), amount}},
2295 std::vector<std::pair<ProofId, CScript>> winners;
2301 auto now = GetTime<std::chrono::seconds>();
2303 prevBlock.
nTime = now.count();
2312 size_t numProofs = 8;
2313 std::vector<ProofRef> proofs;
2314 proofs.reserve(numProofs);
2315 for (
size_t i = 0; i < numProofs; i++) {
2321 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2322 BOOST_CHECK_NE(peerid,
NO_PEER);
2327 proofs.emplace_back(std::move(proof));
2334 prevBlock.
nTime = now.count();
2340 BOOST_CHECK_LE(winners.size(), numProofs);
2343 for (
size_t i = 0; i < numProofs; i++) {
2344 BOOST_CHECK(TestPeerManager::isFlaky(pm, proofs[i]->getId()));
2346 BOOST_CHECK_LE(winners.size(), numProofs);
2351 BOOST_CHECK(!TestPeerManager::isFlaky(pm, proofs[i]->getId()));
2353 BOOST_CHECK_LE(winners.size(), numProofs - i);
2358 BOOST_CHECK_LE(winners.size(), 1);
2364 const size_t loop_iters =
2365 size_t(-1.0 * std::log(100000.0) /
2366 std::log((
double(numProofs) - 1) / numProofs)) +
2368 BOOST_CHECK_GT(loop_iters, numProofs);
2369 std::unordered_map<std::string, size_t> winningCounts;
2370 for (
size_t i = 0; i < loop_iters; i++) {
2381 for (
size_t i = 0; i < numProofs; i++) {
2382 for (
size_t j = 0; j < numProofs; j++) {
2390 BOOST_CHECK_GT(3. / numProofs, 0.3);
2391 for (
size_t i = 0; i < numProofs; i++) {
2395 proofs[(i - 1 + numProofs) % numProofs]->getId(), nodeid,
false));
2397 proofs[(i + numProofs) % numProofs]->getId(), nodeid,
false));
2399 proofs[(i + 1 + numProofs) % numProofs]->getId(), nodeid,
false));
2404 for (
const auto &proof : proofs) {
2410 for (
const auto &proof : proofs) {
2411 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2420 for (
size_t numWinner = 1; numWinner < 4; numWinner++) {
2422 CScript lastWinner = winners[numWinner - 1].second;
2426 for (
const auto &proof : proofs) {
2428 winnerProofId = proof->
getId();
2434 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2437 BOOST_CHECK(TestPeerManager::isFlaky(pm, winnerProofId));
2447 CScript lastWinner = winners[3].second;
2450 for (
const auto &proof : proofs) {
2452 winnerProofId = proof->
getId();
2458 for (
NodeId nodeid = 0; nodeid <
NodeId(numProofs); nodeid++) {
2467 for (
auto &proof : proofs) {
2482 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2483 BOOST_CHECK_NE(peerid,
NO_PEER);
2509 prevBlock.
nTime = now.count();
2524 for (
size_t i = 0; i < 4; i++) {
2533 PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2534 BOOST_CHECK_NE(peerid,
NO_PEER);
2536 return peer.registration_time == now + i * 30min;
2544 proofs.push_back(proof);
2549 prevBlock.
nTime = now.count();
2557 prevBlock.
nTime = now.count();
2560 auto checkRegistrationTime =
2561 [&](
const std::pair<ProofId, CScript> &winner) {
2565 (now - 60min).count());
2576 prevBlock.
nTime = now.count();
2579 checkRegistrationTime(winners[0]);
2587 prevBlock.
nTime = now.count();
2589 BOOST_CHECK_LE(winners.size(), 3);
2590 checkRegistrationTime(winners[0]);
2598 prevBlock.
nTime = now.count();
2600 BOOST_CHECK_LE(winners.size(), 3);
2601 checkRegistrationTime(winners[0]);
2608 prevBlock.
nTime = now.count();
2610 BOOST_CHECK_LE(winners.size(), 2);
2611 checkRegistrationTime(winners[0]);
2617 prevBlock.
nTime = now.count();
2620 checkRegistrationTime(winners[0]);
2630 auto now = GetTime<std::chrono::seconds>();
2635 tip->
nTime = now.count();
2640 struct ContenderOption {
2642 bool invalid{
false};
2643 bool attachNode{
true};
2644 bool finalize{
true};
2645 bool knownForLongEnough{
true};
2649 auto makeEligibleContender = [&](
const ContenderOption &opt = {}) {
2658 opt.knownForLongEnough
2662 const PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof);
2666 if (opt.attachNode) {
2670 if (opt.knownForLongEnough) {
2682 return std::make_tuple(proof, contenderId, peerid);
2693 auto [proof, contenderId, peerid] = makeEligibleContender();
2699 auto [proof, contenderId, peerid] =
2700 makeEligibleContender({.accept =
false});
2706 auto [proof, contenderId, peerid] =
2707 makeEligibleContender({.accept =
false,
2709 .attachNode =
false,
2711 .knownForLongEnough =
false});
2717 auto [proof, contenderId, peerid] =
2718 makeEligibleContender({.invalid =
true});
2725 const COutPoint conflictingOutpoint =
2726 createUtxo(active_chainstate, key);
2727 auto preferredProof =
2728 buildProofWithSequence(key, {conflictingOutpoint}, 20);
2729 auto conflictingProof =
2730 buildProofWithSequence(key, {conflictingOutpoint}, 10);
2744 auto [proof, contenderId, peerid] =
2745 makeEligibleContender({.attachNode =
false});
2748 tip->
nTime = now.count();
2749 TestPeerManager::cleanupDanglingProofs(pm);
2764 !TestPeerManager::getRemotePresenceStatus(pm, proof->
getId())
2771 auto [proof, contenderId, peerid] =
2772 makeEligibleContender({.finalize =
false});
2778 auto [proof, contenderId, peerid] =
2779 makeEligibleContender({.knownForLongEnough =
false});
2794 std::vector<std::pair<ProofId, CScript>> winners;
2821 std::vector<std::pair<ProofId, CScript>> finalizedWinners;
2842 const CScript manualScript = CScript() <<
OP_TRUE;
2871 auto mockTime = GetTime<std::chrono::seconds>();
2879 auto checkRemoteProof =
2881 const bool expectedPresent,
2882 const std::chrono::seconds &expectedlastUpdate) {
2886 TestPeerManager::getRemoteProof(pm, proofid, nodeid);
2892 expectedlastUpdate.count());
2959 checkRemoteProof(proofid, 0,
true, mockTime);
2975 checkRemoteProof(proofid, 0,
true, mockTime);
2985 std::vector<ProofRef> proofs;
2990 proofs.push_back(proof);
3003 checkRemoteProof(proofid, 0,
true, mockTime);
3033 auto mockTime = GetTime<std::chrono::seconds>();
3042 for (
NodeId nodeid = 0; nodeid < 12; nodeid++) {
3056 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
3059 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
3069 TestPeerManager::setLocalProof(pm, localProof);
3077 TestPeerManager::setLocalProof(pm,
ProofRef());
3083 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
3086 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
3102 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
3105 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
3113 for (
NodeId nodeid = 0; nodeid < 5; nodeid++) {
3116 for (
NodeId nodeid = 5; nodeid < 12; nodeid++) {
3123 TestPeerManager::clearPeers(pm);
3134 for (
NodeId nodeid = 1; nodeid < 6; nodeid++) {
3141 for (
NodeId nodeid = 1; nodeid < 6; nodeid++) {
3158 auto mockTime = GetTime<std::chrono::seconds>();
3162 std::vector<ProofRef> proofs;
3163 for (
size_t i = 0; i < 10; i++) {
3166 proofs.push_back(proof);
3170 TestPeerManager::cleanupDanglingProofs(pm);
3171 for (
const auto &proof : proofs) {
3181 TestPeerManager::cleanupDanglingProofs(pm);
3182 for (
const auto &proof : proofs) {
3188 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
3195 for (
const auto &proof : proofs) {
3201 for (
const auto &proof : proofs) {
3207 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
3208 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3209 for (
const auto &proof : proofs) {
3217 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
3218 for (
const auto &proof : proofs) {
3224 for (
const auto &proof : proofs) {
3226 !TestPeerManager::getRemotePresenceStatus(pm, proof->
getId())
3231 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3233 for (
const auto &proof : proofs) {
3242 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3244 for (
const auto &proof : proofs) {
3250 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
3251 for (
const auto &proof : proofs) {
3256 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3257 for (
const auto &proof : proofs) {
3270 auto mockTime = GetTime<std::chrono::seconds>();
3273 std::vector<ProofRef> proofs;
3274 for (
size_t i = 0; i < 10; i++) {
3281 auto peerid = TestPeerManager::getPeerIdForProofId(pm, proof->getId());
3285 peerid, mockTime + std::chrono::seconds{100 + i}));
3292 proofs.push_back(proof);
3297 const fs::path testDumpPath =
"test_avapeers_dump.dat";
3300 TestPeerManager::clearPeers(pm);
3302 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
3306 auto findProofIndex = [&proofs](
const ProofId &proofid) {
3307 for (
size_t i = 0; i < proofs.size(); i++) {
3308 if (proofs[i]->getId() == proofid) {
3318 for (
const auto &proof : registeredProofs) {
3320 size_t i = findProofIndex(proofid);
3322 BOOST_CHECK_EQUAL(peer.hasFinalized, i < 5);
3323 BOOST_CHECK_EQUAL(peer.registration_time.count(),
3324 (mockTime + std::chrono::seconds{i}).count());
3326 peer.nextPossibleConflictTime.count(),
3327 (mockTime + std::chrono::seconds{100 + i}).count());
3333 TestPeerManager::clearPeers(pm);
3346 registeredProofs.insert(proofs[0]);
3356 file << static_cast<uint64_t>(-1);
3357 file << uint64_t{0};
3362 registeredProofs.insert(proofs[0]);
3373 const uint64_t now =
GetTime();
3375 file << static_cast<uint64_t>(1);
3376 file << uint64_t{2};
3393 proofs[0]->getId());
3405 auto utxo = createUtxo(active_chainstate, key);
3408 GetTime<std::chrono::seconds>().count() + 1000000);
3419 TestPeerManager::cleanupDanglingProofs(pm);
3457 TestPeerManager::cleanupDanglingProofs(pm);
3463 for (int64_t i = 0; i < 6; i++) {
3465 CreateAndProcessBlock({}, CScript());
3469 ->GetMedianTimePast(),
3487 auto danglingProof = buildProofWithSequence(key, {utxo}, 1);
3488 auto preferredProof = buildProofWithSequence(key, {utxo}, 2);
3496 TestPeerManager::cleanupDanglingProofs(pm);
3526 auto utxo = createUtxo(active_chainstate, key);
3527 auto lowSeqProof = buildProofWithSequence(key, {utxo}, 1);
3528 auto highSeqProof = buildProofWithSequence(key, {utxo}, 2);
3537 BOOST_CHECK(TestPeerManager::addDanglingProof(pm, highSeqProof));
3542 for (
NodeId nodeid = 0; nodeid < 10; nodeid++) {
3553 TestPeerManager::getRemotePresenceStatus(pm, highSeqProof->getId())
3556 !TestPeerManager::getRemotePresenceStatus(pm, lowSeqProof->getId())
3562 std::unordered_set<ProofRef, SaltedProofHasher> registeredProofs;
3563 TestPeerManager::cleanupDanglingProofs(pm, registeredProofs);
3575BOOST_AUTO_TEST_SUITE_END()
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
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.
Non-refcounted RAII wrapper for FILE*.
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.
BlockHash GetBlockHash() const
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...
SnapshotCompletionResult MaybeCompleteSnapshotValidation() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex *GetSnapshotBaseBlock() const EXCLUSIVE_LOCKS_REQUIRED(Chainstate ActiveChainstate)() const
Once the background validation chainstate has reached the height which is the base of the UTXO snapsh...
RecursiveMutex & GetMutex() const LOCK_RETURNED(
Alias for cs_main.
CBlockIndex * ActiveTip() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
int ActiveHeight() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
static RCUPtr make(Args &&...args)
Construct a new object that is owned by the pointer.
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
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 updateNextRequestTimeForResponse(NodeId nodeid, const Response &response)
bool isDangling(const ProofId &proofid) const
bool addNode(NodeId nodeid, const ProofId &proofid, size_t max_elements)
Node API.
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.
size_t getNodeCount() const
PendingNodeSet pendingNodes
bool verify() const
Perform consistency check on internal data structures.
bool forNode(NodeId nodeid, Callable &&func) const
bool hasRemoteProofStatus(const ProofId &proofid) const
bool forPeer(const ProofId &proofid, Callable &&func) const
void clearRemoteProofs(NodeId nodeid)
uint32_t getTotalPeersScore() const
void finalizeStakeContender(const StakeContenderId &contenderId, BlockHash &prevblockhash, std::vector< std::pair< ProofId, CScript > > &newWinners)
bool latchAvaproofsSent(NodeId nodeid)
Flag that a node did send its compact proofs.
bool updateNextRequestTimeForPoll(NodeId nodeid, SteadyMilliseconds timeout, uint64_t round)
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)
bool getStakeContenderWinners(const BlockHash &prevblockhash, std::vector< std::pair< ProofId, CScript > > &winners) const
uint64_t compact()
Trigger maintenance of internal data structures.
std::vector< Slot > slots
ProofPool danglingProofPool
void forEachPeer(Callable &&func) const
bool hasAcceptedStakeWinner(const BlockHash &prevblockhash) const
void setInvalid(const ProofId &proofid)
int getStakeContenderStatus(const StakeContenderId &contenderId, BlockHash &prevblockhashout) 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
void addStakeContender(const ProofRef &proof)
PeerId selectPeer() const
Randomly select a peer to poll.
bool isInConflictingPool(const ProofId &proofid) const
bool isRemotelyPresentProof(const ProofId &proofid) const
void cleanupDanglingProofs(std::unordered_set< ProofRef, SaltedProofHasher > ®isteredProofs)
void acceptStakeContender(const StakeContenderId &contenderId)
ProofRef getProof(const ProofId &proofid) const
bool registerProof(const ProofRef &proof, ProofRegistrationState ®istrationState, RegistrationMode mode=RegistrationMode::DEFAULT)
void rejectStakeContender(const StakeContenderId &contenderId)
bool updateNextPossibleConflictTime(PeerId peerid, const std::chrono::seconds &nextTime)
Proof and Peer related API.
bool setStakeContenderWinners(const CBlockIndex *pindex, const std::vector< CScript > &payoutScripts)
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
AddProofStatus addProofIfPreferred(const ProofRef &proof, ConflictingProofSet &conflictingProofs)
Attempt to add a proof to the pool.
constexpr uint8_t * begin()
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
static const uint256 ZERO
static void addCoin(const Amount nValue, const CWallet &wallet, std::vector< std::unique_ptr< CWalletTx > > &wtxs)
std::string FormatScript(const CScript &script)
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...
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
std::optional< uintN_t > FromHex(std::string_view str)
Writes the hex string (treated as little-endian) into a new uintN_t object and only returns a value i...
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)
static constexpr size_t DEFAULT_AVALANCHE_MAX_ELEMENT_POLL
Maximum item that can be polled at once.
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
uint256 GetRandHash() noexcept
========== CONVENIENCE FUNCTIONS FOR COMMONLY USED RANDOMNESS ==========
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
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.
StakeContenderIds are unique for each block to ensure that the peer polling for their acceptance has ...
#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