24 #include <validation.h>
27 #include <test/util/setup_common.h>
29 #include <boost/mpl/list.hpp>
30 #include <boost/test/unit_test.hpp>
34 #include <type_traits>
41 struct AvalancheTest {
44 static std::vector<CInv> getInvsForNextPoll(
Processor &p) {
50 return p.peerManager->selectNode());
55 static uint32_t getMinQuorumScore(
const Processor &p) {
59 static double getMinQuorumConnectedScoreRatio(
const Processor &p) {
63 static void clearavaproofsNodeCounter(
Processor &p) {
70 std::make_pair(item, voteRecord));
73 static void setFinalizationTip(
Processor &p,
76 p.finalizationTip = pindex;
79 static void setLocalProofShareable(
Processor &p,
bool shareable) {
85 static void addProofToRecentfinalized(
Processor &p,
88 return p.finalizedItems.insert(proofid));
101 struct CConnmanTest :
public CConnman {
105 m_nodes.push_back(&
node);
122 struct AvalancheTestingSetup :
public TestChain100Setup {
123 const ::Config &config;
124 CConnmanTest *m_connman;
126 std::unique_ptr<Processor> m_processor;
131 std::unordered_set<std::string> m_overridden_args;
133 AvalancheTestingSetup()
134 : TestChain100Setup(), config(
GetConfig()),
135 masterpriv(
CKey::MakeCompressedKey()) {
137 auto connman = std::make_unique<CConnmanTest>(config, 0x1337, 0x1337,
139 m_connman = connman.get();
140 m_node.connman = std::move(connman);
147 setArg(
"-avaminquorumstake",
"0");
148 setArg(
"-avaminquorumconnectedstakeratio",
"0");
149 setArg(
"-avaminavaproofsnodecount",
"0");
150 setArg(
"-avaproofstakeutxoconfirmations",
"1");
159 ~AvalancheTestingSetup() {
160 m_connman->ClearNodes();
164 for (
const std::string &key : m_overridden_args) {
167 m_overridden_args.clear();
182 node->m_has_all_wanted_services =
186 node->fSuccessfullyConnected =
true;
188 m_connman->AddNode(*
node);
197 const uint32_t height = 100;
206 BOOST_CHECK(pb.addUTXO(outpoint, amount, height,
false, key));
212 return pm.
addNode(nodeid, proofid);
216 bool addNode(
NodeId nodeid) {
217 auto proof = GetProof();
220 pm.
addNode(nodeid, proof->getId());
224 std::array<CNode *, 8> ConnectNodes() {
225 auto proof = GetProof();
228 return pm.registerProof(proof);
230 const ProofId &proofid = proof->getId();
232 std::array<CNode *, 8> nodes;
233 for (
CNode *&n : nodes) {
241 void runEventLoop() { AvalancheTest::runEventLoop(*m_processor); }
243 NodeId getSuitableNodeToQuery() {
244 return AvalancheTest::getSuitableNodeToQuery(*m_processor);
247 std::vector<CInv> getInvsForNextPoll() {
248 return AvalancheTest::getInvsForNextPoll(*m_processor);
251 uint64_t getRound()
const {
return AvalancheTest::getRound(*m_processor); }
254 std::vector<avalanche::VoteItemUpdate> &updates,
255 std::string &
error) {
257 return m_processor->registerVotes(nodeid,
response, updates, banscore,
262 std::vector<avalanche::VoteItemUpdate> &updates) {
265 return m_processor->registerVotes(nodeid,
response, updates, banscore,
269 void setArg(std::string key, std::string value) {
272 m_overridden_args.emplace(std::move(key));
276 return m_processor->addToReconcile(item);
280 struct BlockProvider {
281 AvalancheTestingSetup *fixture;
284 BlockProvider(AvalancheTestingSetup *_fixture)
285 : fixture(_fixture), invType(
MSG_BLOCK) {}
288 CBlock block = fixture->CreateAndProcessBlock({},
CScript());
292 return Assert(fixture->m_node.chainman)
293 ->m_blockman.LookupBlockIndex(blockHash);
300 std::vector<Vote> buildVotesForItems(uint32_t
error,
301 std::vector<CBlockIndex *> &&items) {
302 size_t numItems = items.
size();
304 std::vector<Vote> votes;
305 votes.reserve(numItems);
310 votes.emplace_back(
error, item->GetBlockHash());
318 pindex->nStatus = pindex->nStatus.withFailed();
322 return std::get<const CBlockIndex *>(item);
326 struct ProofProvider {
327 AvalancheTestingSetup *fixture;
330 ProofProvider(AvalancheTestingSetup *_fixture)
334 const ProofRef proof = fixture->GetProof();
342 return proof->
getId();
345 std::vector<Vote> buildVotesForItems(uint32_t
error,
346 std::vector<ProofRef> &&items) {
347 size_t numItems = items.
size();
349 std::vector<Vote> votes;
350 votes.reserve(numItems);
354 for (
auto &item : items) {
355 votes.emplace_back(
error, item->getId());
361 void invalidateItem(
const ProofRef &proof) {
369 return std::get<const ProofRef>(item);
374 AvalancheTestingSetup *fixture;
376 std::vector<avalanche::VoteItemUpdate> updates;
379 TxProvider(AvalancheTestingSetup *_fixture)
380 : fixture(_fixture), invType(
MSG_TX) {}
391 TestMemPoolEntryHelper mempoolEntryHelper;
392 auto entry = mempoolEntryHelper.Fee(int64_t(rng.randrange(10)) *
COIN)
409 std::vector<Vote> buildVotesForItems(uint32_t
error,
410 std::vector<CTransactionRef> &&items) {
411 size_t numItems = items.
size();
413 std::vector<Vote> votes;
414 votes.reserve(numItems);
424 std::sort(items.begin(), items.end(),
428 auto lhsIter = mempool->GetIter(lhs->GetId());
429 auto rhsIter = mempool->GetIter(rhs->GetId());
430 BOOST_CHECK(lhsIter);
431 BOOST_CHECK(rhsIter);
433 return CompareTxMemPoolEntryByModifiedFeeRate{}(
434 **lhsIter, **rhsIter);
438 for (
auto &item : items) {
439 votes.emplace_back(
error, item->GetId());
455 return std::get<const CTransactionRef>(item);
465 boost::mpl::list<BlockProvider, ProofProvider, TxProvider>;
470 std::set<VoteStatus> status{
471 VoteStatus::Invalid, VoteStatus::Rejected, VoteStatus::Accepted,
472 VoteStatus::Finalized, VoteStatus::Stale,
475 auto item = provider.buildVoteItem();
477 for (
auto s : status) {
500 auto item = provider.buildVoteItem();
501 auto itemid = provider.getVoteItemId(item);
509 auto avanodes = ConnectNodes();
511 int nextNodeIndex = 0;
512 std::vector<avalanche::VoteItemUpdate> updates;
513 auto registerNewVote = [&](
const Response &resp) {
515 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
520 auto finalize = [&](
const auto finalizeItemId) {
521 Response resp = {getRound(), 0, {
Vote(0, finalizeItemId)}};
523 registerNewVote(next(resp));
524 if (updates.size() > 0) {
529 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
537 auto finalizeNewItem = [&]() {
538 auto anotherItem = provider.buildVoteItem();
540 auto anotherItemId = provider.getVoteItemId(anotherItem);
543 AvalancheTest::addVoteRecord(*m_processor, anotherVoteItem, voteRecord);
544 finalize(anotherItemId);
564 AvalancheTest::setFinalizationTip(*m_processor, chaintip);
576 auto item = decltype(provider.buildVoteItem())();
583 item = provider.buildVoteItem();
592 const uint32_t invType = provider.invType;
594 auto item = provider.buildVoteItem();
595 auto itemid = provider.getVoteItemId(item);
598 auto avanodes = ConnectNodes();
605 auto invs = getInvsForNextPoll();
612 int nextNodeIndex = 0;
613 std::vector<avalanche::VoteItemUpdate> updates;
614 auto registerNewVote = [&](
const Response &resp) {
616 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
622 for (
int i = 0; i < 6; i++) {
623 registerNewVote(next(resp));
630 resp = {getRound(), 0, {
Vote(-1, itemid)}};
631 registerNewVote(next(resp));
636 resp = {getRound(), 0, {
Vote(0, itemid)}};
637 for (
int i = 1; i < 7; i++) {
638 registerNewVote(next(resp));
645 resp = {getRound(), 0, {
Vote(-1, itemid)}};
646 registerNewVote(next(resp));
650 registerNewVote(next(resp));
655 resp = {getRound(), 0, {
Vote(0, itemid)}};
656 for (
int i = 2; i < 8; i++) {
657 registerNewVote(next(resp));
665 registerNewVote(next(resp));
672 invs = getInvsForNextPoll();
678 registerNewVote(next(resp));
680 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
681 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
685 invs = getInvsForNextPoll();
689 item = provider.buildVoteItem();
690 itemid = provider.getVoteItemId(item);
694 invs = getInvsForNextPoll();
699 resp = {getRound(), 0, {
Vote(1, itemid)}};
700 for (
int i = 0; i < 6; i++) {
701 registerNewVote(next(resp));
707 registerNewVote(next(resp));
710 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
711 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Rejected);
716 registerNewVote(next(resp));
722 invs = getInvsForNextPoll();
728 registerNewVote(next(resp));
731 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
732 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Invalid);
736 invs = getInvsForNextPoll();
742 const uint32_t invType = provider.invType;
744 auto itemA = provider.buildVoteItem();
745 auto itemidA = provider.getVoteItemId(itemA);
747 auto itemB = provider.buildVoteItem();
748 auto itemidB = provider.getVoteItemId(itemB);
751 auto avanodes = ConnectNodes();
759 auto invs = getInvsForNextPoll();
764 uint64_t round = getRound();
766 std::vector<avalanche::VoteItemUpdate> updates;
768 {round, 0, {
Vote(0, itemidA)}}, updates));
772 std::vector<Vote> votes = provider.buildVotesForItems(0, {itemA, itemB});
775 invs = getInvsForNextPoll();
779 for (
size_t i = 0; i < invs.size(); i++) {
785 for (
int i = 0; i < 4; i++) {
786 NodeId nodeid = getSuitableNodeToQuery();
788 BOOST_CHECK(registerVotes(nodeid, next(resp), updates));
794 NodeId nodeid = getSuitableNodeToQuery();
796 BOOST_CHECK(registerVotes(nodeid, next(resp), updates));
802 NodeId firstNodeid = getSuitableNodeToQuery();
804 NodeId secondNodeid = getSuitableNodeToQuery();
810 BOOST_CHECK(registerVotes(firstNodeid, next(resp), updates));
812 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == itemA);
813 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
817 invs = getInvsForNextPoll();
823 BOOST_CHECK(registerVotes(secondNodeid, resp, updates));
825 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == itemB);
826 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
830 invs = getInvsForNextPoll();
836 const uint32_t invType = provider.invType;
838 auto item = provider.buildVoteItem();
839 auto itemid = provider.getVoteItemId(item);
846 std::set<NodeId> avanodeIds;
847 auto avanodes = ConnectNodes();
848 for (
auto avanode : avanodes) {
850 avanodeIds.insert(avanode->GetId());
853 auto getSelectedAvanodeId = [&]() {
854 NodeId avanodeid = getSuitableNodeToQuery();
855 BOOST_CHECK(avanodeIds.find(avanodeid) != avanodeIds.end());
860 NodeId avanodeid = getSelectedAvanodeId();
864 auto invs = getInvsForNextPoll();
869 std::set<NodeId> unselectedNodeids = avanodeIds;
870 unselectedNodeids.erase(avanodeid);
871 const size_t remainingNodeIds = unselectedNodeids.size();
873 uint64_t round = getRound();
874 for (
size_t i = 0; i < remainingNodeIds; i++) {
879 NodeId nodeid = getSuitableNodeToQuery();
880 BOOST_CHECK(unselectedNodeids.find(nodeid) != avanodeIds.end());
881 unselectedNodeids.erase(nodeid);
891 std::vector<avalanche::VoteItemUpdate> updates;
892 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
899 auto checkRegisterVotesError = [&](
NodeId nodeid,
901 const std::string &expectedError) {
909 checkRegisterVotesError(avanodeid, next(resp),
"unexpected-ava-response");
918 resp = {round, 0, {
Vote(0, itemid),
Vote(0, itemid)}};
920 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-size");
924 resp = {getRound(), 0, {}};
926 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-size");
930 resp = {getRound(), 0, {
Vote()}};
932 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-content");
939 invs = getInvsForNextPoll();
942 item = provider.buildVoteItem();
943 itemid = provider.getVoteItemId(item);
946 invs = getInvsForNextPoll();
950 uint64_t queryRound = getRound();
953 resp = {queryRound + 1, 0, {
Vote()}};
954 checkRegisterVotesError(avanodeid, resp,
"unexpected-ava-response");
956 resp = {queryRound - 1, 0, {
Vote()}};
957 checkRegisterVotesError(avanodeid, resp,
"unexpected-ava-response");
961 resp = {queryRound, 0, {
Vote(0, itemid)}};
962 checkRegisterVotesError(avanodeid + 1234, resp,
"unexpected-ava-response");
965 resp = {queryRound, 0, {
Vote(0, itemid)}};
966 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
971 const auto item2 = provider.buildVoteItem();
974 std::vector<Vote> votes = provider.buildVotesForItems(0, {item, item2});
975 resp = {getRound(), 0, {votes[1], votes[0]}};
977 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-content");
981 resp = {getRound(), 0, votes};
983 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
990 const uint32_t invType = provider.invType;
992 auto itemA = provider.buildVoteItem();
993 auto itemB = provider.buildVoteItem();
995 auto avanodes = ConnectNodes();
998 std::vector<Vote> votes = provider.buildVotesForItems(0, {itemA, itemB});
1004 auto invs = getInvsForNextPoll();
1006 for (
size_t i = 0; i < invs.size(); i++) {
1012 provider.invalidateItem(itemB);
1014 Response goodResp{getRound(), 0, {
Vote(0, provider.getVoteItemId(itemA))}};
1015 std::vector<avalanche::VoteItemUpdate> updates;
1017 BOOST_CHECK(registerVotes(avanodes[0]->GetId(), goodResp, updates));
1021 Response badResp{getRound(), 0, votes};
1024 BOOST_CHECK(!registerVotes(avanodes[1]->GetId(), badResp, updates,
error));
1028 BOOST_TEST_DECORATOR(*boost::unit_test::timeout(60))
1033 auto queryTimeDuration = std::chrono::milliseconds(10);
1034 setArg(
"-avatimeout",
ToString(queryTimeDuration.count()));
1037 m_processor = Processor::MakeProcessor(
1041 const auto item = provider.buildVoteItem();
1042 const auto itemid = provider.getVoteItemId(item);
1052 for (
int i = 0; i < 10; i++) {
1054 avanodeid = getSuitableNodeToQuery();
1056 auto start = Now<SteadyMilliseconds>();
1060 std::this_thread::sleep_for(std::chrono::milliseconds(1));
1063 std::vector<avalanche::VoteItemUpdate> updates;
1064 bool ret = registerVotes(avanodeid, next(resp), updates);
1065 if (Now<SteadyMilliseconds>() > start + queryTimeDuration) {
1076 avanodeid = getSuitableNodeToQuery();
1080 std::this_thread::sleep_for(queryTimeDuration);
1082 BOOST_CHECK(!registerVotes(avanodeid, next(resp), updates));
1088 const uint32_t invType = provider.invType;
1091 auto proof = GetProof();
1095 std::array<CNode *, AVALANCHE_MAX_INFLIGHT_POLL + 1> nodes;
1096 for (
auto &n : nodes) {
1102 const auto item = provider.buildVoteItem();
1103 const auto itemid = provider.getVoteItemId(item);
1107 std::map<NodeId, uint64_t> node_round_map;
1109 NodeId nodeid = getSuitableNodeToQuery();
1110 BOOST_CHECK(node_round_map.find(nodeid) == node_round_map.end());
1111 node_round_map.insert(std::pair<NodeId, uint64_t>(nodeid, getRound()));
1112 auto invs = getInvsForNextPoll();
1120 auto suitablenodeid = getSuitableNodeToQuery();
1122 auto invs = getInvsForNextPoll();
1128 auto it = node_round_map.begin();
1130 std::vector<avalanche::VoteItemUpdate> updates;
1131 BOOST_CHECK(registerVotes(it->first, resp, updates));
1132 node_round_map.erase(it);
1134 invs = getInvsForNextPoll();
1141 std::vector<VoteItemUpdate> updates;
1149 Assert(
m_node.chainman)->m_blockman.LookupBlockIndex(blockHash);
1153 auto avanodes = ConnectNodes();
1162 uint64_t round = getRound();
1166 for (
size_t i = 0; i < avanodes.size(); i++) {
1168 BOOST_CHECK(registerVotes(avanodes[i]->GetId(), next(resp), updates));
1172 const NodeId firstNodeId = getSuitableNodeToQuery();
1173 std::map<NodeId, uint64_t> node_round_map;
1175 for (
size_t i = 0; i < avanodes.size(); i++) {
1176 NodeId nodeid = getSuitableNodeToQuery();
1177 BOOST_CHECK(node_round_map.find(nodeid) == node_round_map.end());
1178 node_round_map[nodeid] = getRound();
1184 auto confidence = m_processor->getConfidence(pindex);
1185 BOOST_REQUIRE(confidence > 0);
1187 for (
auto &[nodeid, r] : node_round_map) {
1188 if (nodeid == firstNodeId) {
1195 registerVotes(nodeid, {r, 0, {
Vote(0, blockHash)}}, updates));
1200 registerVotes(firstNodeId, {round, 0, {
Vote(0, blockHash)}}, updates));
1213 Assert(
m_node.chainman)->m_blockman.LookupBlockIndex(blockHash);
1220 std::chrono::steady_clock::time_point start,
stop;
1230 auto avanodes = ConnectNodes();
1233 NodeId nodeid = getSuitableNodeToQuery();
1234 BOOST_CHECK_NE(nodeid,
NO_NODE);
1237 uint64_t queryRound = getRound();
1241 for (
int i = 0; i < 60 * 1000; i++) {
1245 if (getRound() == queryRound + avanodes.size()) {
1254 uint64_t responseRound = getRound();
1255 auto queryTime = Now<SteadyMilliseconds>() + std::chrono::milliseconds(100);
1257 std::vector<VoteItemUpdate> updates;
1259 BOOST_CHECK(registerVotes(nodeid, {queryRound, 100, {
Vote(0, blockHash)}},
1262 for (
int i = 0; i < 10000; i++) {
1265 if (getRound() != responseRound) {
1266 BOOST_CHECK(Now<SteadyMilliseconds>() >= queryTime);
1285 schedulerThread.join();
1290 std::chrono::steady_clock::time_point start,
stop;
1292 std::thread schedulerThread;
1302 m_processor.reset();
1309 schedulerThread.join();
1316 auto addProofToReconcile = [&](uint32_t proofScore) {
1326 auto proof = addProofToReconcile(++score);
1328 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1337 for (
size_t i = 0; i < 10; i++) {
1338 auto proof = addProofToReconcile(++score);
1340 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1345 lastProofId = proof->
getId();
1348 for (
size_t i = 0; i < 10; i++) {
1349 auto proof = addProofToReconcile(--score);
1351 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1359 auto proof = addProofToReconcile(--score);
1360 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1361 for (
auto &inv : invs) {
1362 BOOST_CHECK_NE(inv.hash, proof->
getId());
1368 setArg(
"-avaproofstakeutxoconfirmations",
"2");
1369 setArg(
"-avalancheconflictingproofcooldown",
"0");
1383 Assert(
m_node.chainman)->ActiveChainstate().CoinsTip();
1384 coins.
AddCoin(conflictingOutpoint,
1387 coins.
AddCoin(immatureOutpoint,
1392 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence,
1393 uint32_t height = 10) {
1400 auto conflictingProof = buildProof(conflictingOutpoint, 1);
1401 auto validProof = buildProof(conflictingOutpoint, 2);
1402 auto immatureProof = buildProof(immatureOutpoint, 3, 100);
1404 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1405 BOOST_CHECK(!m_processor->isAccepted(validProof));
1406 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1412 BOOST_CHECK(!m_processor->addToReconcile(conflictingProof));
1413 BOOST_CHECK(!m_processor->addToReconcile(validProof));
1414 BOOST_CHECK(!m_processor->addToReconcile(immatureProof));
1426 BOOST_CHECK(m_processor->addToReconcile(conflictingProof));
1427 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1428 BOOST_CHECK(!m_processor->isAccepted(validProof));
1429 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1434 BOOST_CHECK(m_processor->addToReconcile(validProof));
1435 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1437 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1442 BOOST_CHECK(!m_processor->addToReconcile(immatureProof));
1443 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1445 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1453 int minStake = 400'000'000;
1454 setArg(
"-avaminquorumstake",
ToString(minStake));
1455 setArg(
"-avaminquorumconnectedstakeratio",
"0.5");
1459 uint32_t minScore = Proof::amountToScore(minStake * currency.baseunit);
1467 setArg(
"-avaproof", localProof->ToHex());
1471 m_processor = Processor::MakeProcessor(
1476 BOOST_CHECK(m_processor->getLocalProof() !=
nullptr);
1478 localProof->getId());
1481 AvalancheTest::getMinQuorumConnectedScoreRatio(*m_processor), 0.5);
1502 for (
NodeId id = 0;
id < 8;
id++) {
1504 pm.
addNode(
id, m_processor->getLocalProof()->getId());
1520 const int64_t tipTime =
1524 const Amount amount = (int64_t(minScore / 4) *
COIN) / 100;
1525 const int height = 100;
1526 const bool isCoinbase =
false;
1533 height, isCoinbase),
1538 auto proof2 = pb.
build();
1549 pm.
addNode(8, proof2->getId());
1568 m_processor->withPeerManager(
1574 pm.
addNode(7, m_processor->getLocalProof()->getId());
1579 auto spendProofUtxo = [&](
ProofRef proof) {
1592 for (int64_t i = 0; i < 6; i++) {
1594 CreateAndProcessBlock({},
CScript());
1598 ->GetMedianTimePast(),
1599 proof2->getExpirationTime());
1610 spendProofUtxo(proof1);
1617 spendProofUtxo(m_processor->getLocalProof());
1629 const std::vector<std::tuple<std::string, std::string, std::string, bool>>
1632 {
"",
"",
"",
false},
1633 {
"-1",
"-1",
"-1",
false},
1636 {
"-1",
"0",
"0",
false},
1637 {
"-0.01",
"0",
"0",
false},
1638 {
"21000000000000.01",
"0",
"0",
false},
1641 {
"0",
"-1",
"0",
false},
1642 {
"0",
"1.1",
"0",
false},
1645 {
"0",
"0",
"-1",
false},
1648 {
"0",
"0",
"0",
true},
1649 {
"0.00",
"0",
"0",
true},
1650 {
"0.01",
"0",
"0",
true},
1651 {
"1",
"0.1",
"0",
true},
1652 {
"10",
"0.5",
"0",
true},
1653 {
"10",
"1",
"0",
true},
1654 {
"21000000000000.00",
"0",
"0",
true},
1655 {
"0",
"0",
"1",
true},
1656 {
"0",
"0",
"100",
true},
1661 for (
const auto &[stake, stakeRatio, numProofsMessages, success] :
1663 setArg(
"-avaminquorumstake", stake);
1664 setArg(
"-avaminquorumconnectedstakeratio", stakeRatio);
1665 setArg(
"-avaminavaproofsnodecount", numProofsMessages);
1668 std::unique_ptr<Processor> processor = Processor::MakeProcessor(
1688 auto checkMinAvaproofsMessages = [&](int64_t minAvaproofsMessages) {
1689 setArg(
"-avaminavaproofsnodecount",
ToString(minAvaproofsMessages));
1692 auto processor = Processor::MakeProcessor(
1696 auto addNode = [&](
NodeId nodeid) {
1709 for (
NodeId id = 100;
id < 108;
id++) {
1714 minAvaproofsMessages <= 0);
1716 for (int64_t i = 0; i < minAvaproofsMessages - 1; i++) {
1719 processor->avaproofsSent(i);
1723 processor->avaproofsSent(i);
1729 addNode(minAvaproofsMessages);
1730 processor->avaproofsSent(minAvaproofsMessages);
1734 AvalancheTest::clearavaproofsNodeCounter(*processor);
1738 checkMinAvaproofsMessages(0);
1739 checkMinAvaproofsMessages(1);
1740 checkMinAvaproofsMessages(10);
1741 checkMinAvaproofsMessages(100);
1746 setArg(
"-avastalevotethreshold",
1748 setArg(
"-avastalevotefactor",
"2");
1750 const std::vector<std::tuple<int, int>> testCases = {
1757 m_processor = Processor::MakeProcessor(
1766 const uint32_t invType = provider.invType;
1768 const auto item = provider.buildVoteItem();
1769 const auto itemid = provider.getVoteItemId(item);
1772 auto avanodes = ConnectNodes();
1773 int nextNodeIndex = 0;
1775 std::vector<avalanche::VoteItemUpdate> updates;
1776 for (
const auto &[numYesVotes, numNeutralVotes] : testCases) {
1779 auto invs = getInvsForNextPoll();
1786 auto registerNewVote = [&](
const Response &resp) {
1788 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
1789 BOOST_CHECK(registerVotes(nodeid, resp, updates));
1793 for (
int i = 0; i < numYesVotes; i++) {
1795 registerNewVote(next(resp));
1798 i >= 6 ? i - 5 : 0);
1803 for (
int i = 0; i < numNeutralVotes; i++) {
1805 registerNewVote(next(resp));
1810 invs = getInvsForNextPoll();
1817 registerNewVote(next(resp));
1819 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
1820 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Stale);
1824 invs = getInvsForNextPoll();
1830 BlockProvider provider(
this);
1832 std::vector<CBlockIndex *> blockIndexes;
1836 blockIndexes.push_back(pindex);
1839 auto invs = getInvsForNextPoll();
1851 std::vector<Vote> votes;
1854 BlockHash blockhash = blockIndexes[i - 1]->GetBlockHash();
1855 votes.emplace_back(blockhash == eleventhBlockHash ? 0 : -1, blockhash);
1858 auto avanodes = ConnectNodes();
1859 int nextNodeIndex = 0;
1861 std::vector<avalanche::VoteItemUpdate> updates;
1862 auto registerNewVote = [&]() {
1863 Response resp = {getRound(), 0, votes};
1865 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
1866 BOOST_CHECK(registerVotes(nodeid, resp, updates));
1870 bool eleventhBlockFinalized =
false;
1871 for (
size_t i = 0; i < 10000 && !eleventhBlockFinalized; i++) {
1874 for (
auto &update : updates) {
1875 if (update.getStatus() == VoteStatus::Finalized &&
1876 provider.fromAnyVoteItem(update.getVoteItem())
1877 ->GetBlockHash() == eleventhBlockHash) {
1878 eleventhBlockFinalized =
true;
1885 invs = getInvsForNextPoll();
1887 for (
size_t i = 0; i < 10; i++) {
1901 auto &activeChainstate =
m_node.chainman->ActiveChainstate();
1903 activeChainstate.InvalidateBlock(state, tip);
1909 ->m_blockman.LookupBlockIndex(altblock.
GetHash()));
1917 activeChainstate.ResetBlockFailureFlags(tip);
1919 activeChainstate.ActivateBestChain(state);
1923 invs = getInvsForNextPoll();
1930 for (
auto &inv : invs) {
1931 votes.emplace_back(inv.hash == tiphash ? 0 : -1, inv.hash);
1934 bool tipFinalized =
false;
1935 for (
size_t i = 0; i < 10000 && !tipFinalized; i++) {
1938 for (
auto &update : updates) {
1939 if (update.getStatus() == VoteStatus::Finalized &&
1940 provider.fromAnyVoteItem(update.getVoteItem())
1941 ->GetBlockHash() == tiphash) {
1942 tipFinalized =
true;
1951 invs = getInvsForNextPoll();
1959 BlockHash alttiphash = alttip->GetBlockHash();
1960 votes = {{1, alttiphash}};
1962 bool alttipInvalidated =
false;
1963 for (
size_t i = 0; i < 10000 && !alttipInvalidated; i++) {
1966 for (
auto &update : updates) {
1967 if (update.getStatus() == VoteStatus::Invalid &&
1968 provider.fromAnyVoteItem(update.getVoteItem())
1969 ->GetBlockHash() == alttiphash) {
1970 alttipInvalidated =
true;
1975 invs = getInvsForNextPoll();
1984 Chainstate &activeChainState = chainman.ActiveChainstate();
1986 const int numberElementsEachType = 100;
1989 std::vector<ProofRef> proofs;
1990 for (
size_t i = 1; i <= numberElementsEachType; i++) {
1994 proofs.emplace_back(std::move(proof));
1996 Shuffle(proofs.begin(), proofs.end(), rng);
1998 std::vector<CBlockIndex> indexes;
1999 for (
size_t i = 1; i <= numberElementsEachType; i++) {
2002 indexes.emplace_back(std::move(index));
2004 Shuffle(indexes.begin(), indexes.end(), rng);
2007 TestMemPoolEntryHelper mempoolEntryHelper;
2008 std::vector<CTransactionRef> txs;
2009 for (
size_t i = 1; i <= numberElementsEachType; i++) {
2017 auto entry = mempoolEntryHelper.Fee(int64_t(i) *
COIN).FromTx(tx);
2024 txs.emplace_back(std::move(tx));
2028 std::make_tuple(std::move(proofs), std::move(indexes), std::move(txs));
2029 static const size_t numTypes = std::tuple_size<decltype(allItems)>::value;
2035 for (
size_t i = 0; i < numberElementsEachType; i++) {
2037 const size_t firstType = rng.
randrange(numTypes);
2039 for (
size_t j = 0; j < numTypes; j++) {
2040 switch ((firstType + j) % numTypes) {
2043 writeView->insert(std::make_pair(
2044 std::get<0>(allItems)[i],
VoteRecord(
true)));
2048 writeView->insert(std::make_pair(
2049 &std::get<1>(allItems)[i],
VoteRecord(
true)));
2053 writeView->insert(std::make_pair(
2054 std::get<2>(allItems)[i],
VoteRecord(
true)));
2066 auto it = readView.
begin();
2070 uint32_t lastScore = std::numeric_limits<uint32_t>::max();
2071 for (
size_t i = 0; i < numberElementsEachType; i++) {
2072 BOOST_CHECK(std::holds_alternative<const ProofRef>(it->first));
2074 uint32_t currentScore =
2075 std::get<const ProofRef>(it->first)->getScore();
2076 BOOST_CHECK_LT(currentScore, lastScore);
2077 lastScore = currentScore;
2085 for (
size_t i = 0; i < numberElementsEachType; i++) {
2086 BOOST_CHECK(std::holds_alternative<const CBlockIndex *>(it->first));
2089 std::get<const CBlockIndex *>(it->first)->nChainWork;
2091 lastWork = currentWork;
2101 for (
size_t i = 0; i < numberElementsEachType; i++) {
2103 std::holds_alternative<const CTransactionRef>(it->first));
2106 std::get<const CTransactionRef>(it->first)->GetId());
2109 CFeeRate currentFeeRate = (**iter)->GetModifiedFeeRate();
2112 lastFeeRate = currentFeeRate;
2124 TestMemPoolEntryHelper mempoolEntryHelper;
2125 TxProvider provider(
this);
2127 std::vector<CTransactionRef> txs;
2128 for (
size_t i = 0; i < 5; i++) {
2129 txs.emplace_back(provider.buildVoteItem());
2137 for (
const auto &tx : txs) {
2138 writeView->insert(std::make_pair(tx,
VoteRecord(
true)));
2144 for (
const auto &[item, vote] : readView) {
2145 auto tx = std::get<const CTransactionRef>(item);
2146 BOOST_CHECK_GT(tx->GetId(), lastTxId);
2147 lastTxId = tx->GetId();
2153 for (
size_t i = 0; i < 5; i++) {
2154 txs.emplace_back(provider.buildVoteItem());
2162 for (
const auto &tx : txs) {
2163 writeView->insert(std::make_pair(tx,
VoteRecord(
true)));
2168 auto it = readView.
begin();
2174 for (
size_t i = 0; i < 5; i++) {
2175 auto tx = std::get<const CTransactionRef>(it->first);
2177 auto iter = mempool->
GetIter(tx->GetId());
2180 BOOST_CHECK((**iter)->GetModifiedFeeRate() <= lastFeeRate);
2181 lastFeeRate = (**iter)->GetModifiedFeeRate();
2187 for (
size_t i = 0; i < 5; i++) {
2188 auto tx = std::get<const CTransactionRef>(it->first);
2192 BOOST_CHECK_GT(tx->GetId(), lastTxId);
2193 lastTxId = tx->GetId();
2201 Chainstate &chainstate = chainman->ActiveChainstate();
2203 const auto block = std::make_shared<const CBlock>(
2204 this->CreateBlock({},
CScript(), chainstate));
2216 blockindex = chainman->m_blockman.LookupBlockIndex(blockhash);
2224 BOOST_CHECK(AvalancheTest::getInvsForNextPoll(*g_avalanche).empty());
2233 auto invs = AvalancheTest::getInvsForNextPoll(*
g_avalanche);
2248 auto now = GetTime<std::chrono::seconds>();
2254 std::vector<CScript> winners;
2256 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2259 BOOST_CHECK(!m_processor->computeStakingReward(
nullptr));
2260 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2265 prevBlock.
nTime = now.count();
2268 BOOST_CHECK(!m_processor->computeStakingReward(&prevBlock));
2269 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2271 setArg(
"-avaminquorumstake",
"0");
2272 setArg(
"-avaminquorumconnectedstakeratio",
"0");
2273 setArg(
"-avaminavaproofsnodecount",
"0");
2276 size_t numProofs = 10;
2277 std::vector<ProofRef> proofs;
2278 proofs.reserve(numProofs);
2279 for (
size_t i = 0; i < numProofs; i++) {
2283 auto proof = GetProof(payoutScript);
2289 return pm.setFinalized(peer.peerid);
2293 proofs.emplace_back(std::move(proof));
2299 BOOST_CHECK(!m_processor->computeStakingReward(&prevBlock));
2300 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2303 auto winnerExists = [&](
const CScript &expectedWinner) {
2304 const std::string winnerString =
FormatScript(expectedWinner);
2306 for (
const ProofRef &proof : proofs) {
2317 prevBlock.
nTime = now.count();
2320 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2321 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2325 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2326 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2332 prevBlockHigh.
phashBlock = &prevBlockHashHigh;
2334 BOOST_CHECK(m_processor->computeStakingReward(&prevBlockHigh));
2336 m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2340 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2344 m_processor->cleanupStakingRewards(101);
2347 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2351 m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2355 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2356 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2360 m_processor->cleanupStakingRewards(200);
2363 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2365 !m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2377 Assert(
m_node.chainman)->ActiveChainstate().CoinsTip();
2383 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence,
2391 auto localProof = buildProof(outpoint, 1, 100);
2394 setArg(
"-avaproof", localProof->ToHex());
2395 setArg(
"-avalancheconflictingproofcooldown",
"0");
2396 setArg(
"-avalanchepeerreplacementcooldown",
"0");
2397 setArg(
"-avaproofstakeutxoconfirmations",
"3");
2401 m_processor = Processor::MakeProcessor(
2406 localProof->getId());
2408 auto checkLocalProofState =
2409 [&](
const bool boundToPeer,
2413 return pm.isBoundToPeer(localProof->getId());
2416 BOOST_CHECK_MESSAGE(
2417 m_processor->getLocalProofRegistrationState().GetResult() ==
2419 m_processor->getLocalProofRegistrationState().ToString());
2426 AvalancheTest::updatedBlockTip(*m_processor);
2430 AvalancheTest::setLocalProofShareable(*m_processor,
true);
2432 AvalancheTest::updatedBlockTip(*m_processor);
2433 checkLocalProofState(
false, ProofRegistrationResult::IMMATURE);
2437 AvalancheTest::updatedBlockTip(*m_processor);
2438 checkLocalProofState(
false, ProofRegistrationResult::IMMATURE);
2442 AvalancheTest::updatedBlockTip(*m_processor);
2446 auto conflictingProof = buildProof(outpoint, 2, 100);
2452 AvalancheTest::updatedBlockTip(*m_processor);
2453 checkLocalProofState(
false, ProofRegistrationResult::CONFLICTING);
2457 setArg(
"-avalancheconflictingproofcooldown",
"0");
2458 setArg(
"-avalanchepeerreplacementcooldown",
"0");
2464 Chainstate &activeChainState = chainman.ActiveChainstate();
2478 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence) {
2485 auto proof = buildProof(outpoint, 1);
2489 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2499 BOOST_CHECK(m_processor->reconcileOrFinalize(proof));
2501 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2504 AvalancheTest::addProofToRecentfinalized(*m_processor, proof->
getId());
2506 BOOST_CHECK(m_processor->reconcileOrFinalize(proof));
2511 return peer.hasFinalized;
2518 auto betterProof = buildProof(outpoint, 2);
2522 BOOST_CHECK(!m_processor->reconcileOrFinalize(betterProof));
2534 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2536 BOOST_CHECK(m_processor->reconcileOrFinalize(betterProof));
static constexpr Amount MAX_MONEY
No amount larger than this (in satoshi) is valid.
static constexpr Amount COIN
uint256 ArithToUint256(const arith_uint256 &a)
std::unique_ptr< avalanche::Processor > g_avalanche
Global avalanche instance.
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.
A CService with information about it as peer.
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
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
const BlockHash * phashBlock
pointer to the hash of the block, if any.
BlockHash GetBlockHash() const
int nHeight
height of the entry in the chain. The genesis block has height 0
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
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.
CConnman(const Config &configIn, uint64_t seed0, uint64_t seed1, AddrMan &addrmanIn, bool network_active=true)
Fee rate in satoshis per kilobyte: Amount / kB.
An encapsulated secp256k1 private key.
static CKey MakeCompressedKey()
Produce a valid compressed key.
CPubKey GetPubKey() const
Compute the public key from a private key.
A mutable version of CTransaction.
std::vector< CTxOut > vout
Information about a peer.
An outpoint - a combination of a transaction hash and an index n into its vout.
Simple class for background tasks that should be run periodically or once "after a while".
void serviceQueue() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Services the queue 'forever'.
size_t getQueueInfo(std::chrono::steady_clock::time_point &first, std::chrono::steady_clock::time_point &last) const EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Returns number of tasks waiting to be serviced, and first and last task times.
void StopWhenDrained() EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Tell any threads running serviceQueue to stop when there is no work left to be done.
Serialized script, used inside transaction inputs and outputs.
A combination of a network address (CNetAddr) and a (TCP) port.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
bool exists(const TxId &txid) const
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(CTxMemPoolEntryRef entry) EXCLUSIVE_LOCKS_REQUIRED(cs
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
std::optional< txiter > GetIter(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given txid, if found.
An output of a transaction.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
CChain m_chain
The current chain of blockheaders we consult and build on.
bool ActivateBestChain(BlockValidationState &state, std::shared_ptr< const CBlock > pblock=nullptr, bool skip_checkblockindex=false) EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex
Find the best known block, and make it the tip of the block chain.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
bool AcceptBlock(const std::shared_ptr< const CBlock > &pblock, BlockValidationState &state, bool fRequested, const FlatFilePos *dbp, bool *fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Store a block on disk.
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())
uint256 rand256() noexcept
generate a random uint256.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
static std::unique_ptr< PeerManager > make(CConnman &connman, AddrMan &addrman, BanMan *banman, ChainstateManager &chainman, CTxMemPool &pool, bool ignore_incoming_txs)
ReadView getReadView() const
256-bit unsigned big integer.
bool removeNode(NodeId nodeid)
uint32_t getConnectedPeersScore() const
bool exists(const ProofId &proofid) const
bool forPeer(const ProofId &proofid, Callable &&func) const
uint32_t getTotalPeersScore() const
bool addNode(NodeId nodeid, const ProofId &proofid)
Node API.
std::unordered_set< ProofRef, SaltedProofHasher > updatedBlockTip()
Update the peer set when a new block is connected.
bool isBoundToPeer(const ProofId &proofid) const
bool isImmature(const ProofId &proofid) const
bool rejectProof(const ProofId &proofid, RejectionMode mode=RejectionMode::DEFAULT)
bool isInConflictingPool(const ProofId &proofid) const
bool registerProof(const ProofRef &proof, ProofRegistrationState ®istrationState, RegistrationMode mode=RegistrationMode::DEFAULT)
Mutex cs_finalizedItems
Rolling bloom filter to track recently finalized inventory items of any type.
std::vector< CInv > getInvsForNextPoll(bool forPoll=true) EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
std::atomic< uint64_t > round
Keep track of peers and queries sent.
static std::unique_ptr< Processor > MakeProcessor(const ArgsManager &argsman, interfaces::Chain &chain, CConnman *connman, ChainstateManager &chainman, CTxMemPool *mempoolIn, CScheduler &scheduler, bilingual_str &error)
void runEventLoop() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
void updatedBlockTip() EXCLUSIVE_LOCKS_REQUIRED(!cs_peerManager
RWCollection< VoteMap > voteRecords
Items to run avalanche on.
uint32_t minQuorumScore
Quorum management.
std::atomic< bool > m_canShareLocalProof
std::atomic< int64_t > avaproofsNodeCounter
Mutex cs_peerManager
Keep track of the peers and associated infos.
double minQuorumConnectedScoreRatio
bool addUTXO(COutPoint utxo, Amount amount, uint32_t height, bool is_coinbase, CKey key)
const ProofId & getId() const
const std::vector< SignedStake > & getStakes() const
const CScript & getPayoutScript() const
uint32_t getCooldown() const
uint64_t getRound() const
const std::vector< Vote > & GetVotes() const
const VoteStatus & getStatus() const
const AnyVoteItem & getVoteItem() const
unsigned int size() const
static const uint256 ZERO
const Config & GetConfig()
std::string FormatScript(const CScript &script)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
std::string EncodeSecret(const CKey &key)
static constexpr Amount PROOF_DUST_THRESHOLD
Minimum amount per utxo.
std::map< AnyVoteItem, VoteRecord, VoteMapComparator > VoteMap
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
std::variant< const ProofRef, const CBlockIndex *, const CTransactionRef > AnyVoteItem
std::unique_ptr< Chain > MakeChain(node::NodeContext &node, const CChainParams ¶ms)
Return implementation of Chain interface.
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
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 CTransactionRef MakeTransactionRef()
std::shared_ptr< const CTransaction > CTransactionRef
static constexpr size_t AVALANCHE_MAX_ELEMENT_POLL
Maximum item that can be polled at once.
static constexpr uint32_t AVALANCHE_FINALIZED_ITEMS_FILTER_NUM_ELEMENTS
The size of the finalized items filter.
BOOST_AUTO_TEST_CASE_TEMPLATE(voteitemupdate, P, VoteItemProviders)
BOOST_AUTO_TEST_CASE(quorum_diversity)
boost::mpl::list< BlockProvider, ProofProvider, TxProvider > VoteItemProviders
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
ServiceFlags
nServices flags.
uint256 GetRandHash() noexcept
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
reverse_range< T > reverse_iterate(T &x)
static uint16_t GetDefaultPort()
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.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
A BlockHash is a unqiue identifier for a block.
static const Currency & get()
A TxId is the identifier of a transaction.
Compare proofs by score, then by id in case of equality.
TestVoteRecord(uint16_t conf)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
bool error(const char *fmt, const Args &...args)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
void UninterruptibleSleep(const std::chrono::microseconds &n)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
@ CONFLICT
Removed for conflict with in-block transaction.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
static const int PROTOCOL_VERSION
network protocol versioning
static constexpr int AVALANCHE_MAX_INFLIGHT_POLL
How many inflight requests can exist for one item.
static constexpr uint32_t AVALANCHE_VOTE_STALE_MIN_THRESHOLD
Lowest configurable staleness threshold (finalization score + necessary votes to increase confidence ...
static constexpr int AVALANCHE_FINALIZATION_SCORE
Finalization score.