24#include <test/util/setup_common.h>
26#include <boost/mpl/list.hpp>
27#include <boost/test/unit_test.hpp>
38 struct AvalancheTest {
41 static std::vector<CInv> getInvsForNextPoll(
Processor &p) {
47 return p.peerManager->selectNode());
52 static uint32_t getMinQuorumScore(
const Processor &p) {
56 static double getMinQuorumConnectedScoreRatio(
const Processor &p) {
60 static void clearavaproofsNodeCounter(
Processor &p) {
67 std::make_pair(item, voteRecord));
70 static void setFinalizationTip(
Processor &p,
73 p.finalizationTip = pindex;
76 static void setLocalProofShareable(
Processor &p,
bool shareable) {
82 static void addProofToRecentfinalized(
Processor &p,
85 return p.finalizedItems.insert(proofid));
98struct CConnmanTest :
public CConnman {
102 m_nodes.push_back(&
node);
119struct AvalancheTestingSetup :
public TestChain100Setup {
120 const ::Config &config;
121 CConnmanTest *m_connman;
123 std::unique_ptr<Processor> m_processor;
128 std::unordered_set<std::string> m_overridden_args;
130 AvalancheTestingSetup()
131 : TestChain100Setup(), config(
GetConfig()),
132 masterpriv(
CKey::MakeCompressedKey()) {
134 auto connman = std::make_unique<CConnmanTest>(config, 0x1337, 0x1337,
136 m_connman = connman.get();
137 m_node.connman = std::move(connman);
140 setArg(
"-avaminquorumstake",
"0");
141 setArg(
"-avaminquorumconnectedstakeratio",
"0");
142 setArg(
"-avaminavaproofsnodecount",
"0");
143 setArg(
"-avaproofstakeutxoconfirmations",
"1");
145 m_processor = Processor::MakeProcessor(
153 *
m_node.mempool, m_processor.get(), {});
157 ~AvalancheTestingSetup() {
158 m_connman->ClearNodes();
162 for (
const std::string &key : m_overridden_args) {
165 m_overridden_args.clear();
173 new CNode(
id++,
nullptr, addr,
180 node->m_has_all_wanted_services =
184 node->fSuccessfullyConnected =
true;
186 m_connman->AddNode(*
node);
195 const uint32_t height = 100;
204 BOOST_CHECK(pb.addUTXO(outpoint, amount, height,
false, key));
210 return pm.
addNode(nodeid, proofid);
214 bool addNode(
NodeId nodeid) {
215 auto proof = GetProof();
218 pm.
addNode(nodeid, proof->getId());
222 std::array<CNode *, 8> ConnectNodes() {
223 auto proof = GetProof();
226 return pm.registerProof(proof);
228 const ProofId &proofid = proof->getId();
230 std::array<CNode *, 8> nodes;
231 for (
CNode *&n : nodes) {
239 void runEventLoop() { AvalancheTest::runEventLoop(*m_processor); }
241 NodeId getSuitableNodeToQuery() {
242 return AvalancheTest::getSuitableNodeToQuery(*m_processor);
245 std::vector<CInv> getInvsForNextPoll() {
246 return AvalancheTest::getInvsForNextPoll(*m_processor);
249 uint64_t getRound()
const {
return AvalancheTest::getRound(*m_processor); }
252 std::vector<avalanche::VoteItemUpdate> &updates,
253 std::string &
error) {
255 return m_processor->registerVotes(nodeid,
response, updates, banscore,
260 std::vector<avalanche::VoteItemUpdate> &updates) {
263 return m_processor->registerVotes(nodeid,
response, updates, banscore,
267 void setArg(std::string key,
const std::string &value) {
270 m_overridden_args.emplace(std::move(key));
274 return m_processor->addToReconcile(item);
278struct BlockProvider {
279 AvalancheTestingSetup *fixture;
282 BlockProvider(AvalancheTestingSetup *_fixture)
283 : fixture(_fixture), invType(
MSG_BLOCK) {}
286 CBlock block = fixture->CreateAndProcessBlock({}, CScript());
290 return Assert(fixture->m_node.chainman)
291 ->m_blockman.LookupBlockIndex(blockHash);
298 std::vector<Vote> buildVotesForItems(uint32_t
error,
299 std::vector<CBlockIndex *> &&items) {
300 size_t numItems = items.
size();
302 std::vector<Vote> votes;
303 votes.reserve(numItems);
308 votes.emplace_back(
error, item->GetBlockHash());
316 pindex->nStatus = pindex->nStatus.withFailed();
320 return std::get<const CBlockIndex *>(item);
324struct ProofProvider {
325 AvalancheTestingSetup *fixture;
328 ProofProvider(AvalancheTestingSetup *_fixture)
332 const ProofRef proof = fixture->GetProof();
340 return proof->
getId();
343 std::vector<Vote> buildVotesForItems(uint32_t
error,
344 std::vector<ProofRef> &&items) {
345 size_t numItems = items.
size();
347 std::vector<Vote> votes;
348 votes.reserve(numItems);
352 for (
auto &item : items) {
353 votes.emplace_back(
error, item->getId());
359 void invalidateItem(
const ProofRef &proof) {
367 return std::get<const ProofRef>(item);
372 AvalancheTestingSetup *fixture;
374 std::vector<avalanche::VoteItemUpdate> updates;
377 TxProvider(AvalancheTestingSetup *_fixture)
378 : fixture(_fixture), invType(
MSG_TX) {}
388 TestMemPoolEntryHelper mempoolEntryHelper;
389 auto entry = mempoolEntryHelper.FromTx(tx);
405 std::vector<Vote> buildVotesForItems(uint32_t
error,
406 std::vector<CTransactionRef> &&items) {
407 size_t numItems = items.
size();
409 std::vector<Vote> votes;
410 votes.reserve(numItems);
413 std::sort(items.begin(), items.end(),
415 return lhs->GetId() < rhs->GetId();
417 for (
auto &item : items) {
418 votes.emplace_back(
error, item->GetId());
434 return std::get<const CTransactionRef>(item);
440BOOST_FIXTURE_TEST_SUITE(processor_tests, AvalancheTestingSetup)
444 boost::mpl::list<BlockProvider, ProofProvider, TxProvider>;
449 std::set<VoteStatus> status{
450 VoteStatus::Invalid, VoteStatus::Rejected, VoteStatus::Accepted,
451 VoteStatus::Finalized, VoteStatus::Stale,
454 auto item = provider.buildVoteItem();
456 for (
auto s : status) {
479 auto item = provider.buildVoteItem();
480 auto itemid = provider.getVoteItemId(item);
488 auto avanodes = ConnectNodes();
490 int nextNodeIndex = 0;
491 std::vector<avalanche::VoteItemUpdate> updates;
492 auto registerNewVote = [&](
const Response &resp) {
494 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
499 auto finalize = [&](
const auto finalizeItemId) {
500 Response resp = {getRound(), 0, {
Vote(0, finalizeItemId)}};
502 registerNewVote(next(resp));
503 if (updates.size() > 0) {
508 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
516 auto finalizeNewItem = [&]() {
517 auto anotherItem = provider.buildVoteItem();
519 auto anotherItemId = provider.getVoteItemId(anotherItem);
522 AvalancheTest::addVoteRecord(*m_processor, anotherVoteItem, voteRecord);
523 finalize(anotherItemId);
543 AvalancheTest::setFinalizationTip(*m_processor, chaintip);
555 auto item =
decltype(provider.buildVoteItem())();
562 item = provider.buildVoteItem();
571 const uint32_t invType = provider.invType;
573 auto item = provider.buildVoteItem();
574 auto itemid = provider.getVoteItemId(item);
577 auto avanodes = ConnectNodes();
584 auto invs = getInvsForNextPoll();
591 int nextNodeIndex = 0;
592 std::vector<avalanche::VoteItemUpdate> updates;
593 auto registerNewVote = [&](
const Response &resp) {
595 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
601 for (
int i = 0; i < 6; i++) {
602 registerNewVote(next(resp));
609 resp = {getRound(), 0, {
Vote(-1, itemid)}};
610 registerNewVote(next(resp));
615 resp = {getRound(), 0, {
Vote(0, itemid)}};
616 for (
int i = 1; i < 7; i++) {
617 registerNewVote(next(resp));
624 resp = {getRound(), 0, {
Vote(-1, itemid)}};
625 registerNewVote(next(resp));
629 registerNewVote(next(resp));
634 resp = {getRound(), 0, {
Vote(0, itemid)}};
635 for (
int i = 2; i < 8; i++) {
636 registerNewVote(next(resp));
644 registerNewVote(next(resp));
651 invs = getInvsForNextPoll();
657 registerNewVote(next(resp));
659 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
660 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
664 invs = getInvsForNextPoll();
668 item = provider.buildVoteItem();
669 itemid = provider.getVoteItemId(item);
673 invs = getInvsForNextPoll();
678 resp = {getRound(), 0, {
Vote(1, itemid)}};
679 for (
int i = 0; i < 6; i++) {
680 registerNewVote(next(resp));
686 registerNewVote(next(resp));
689 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
690 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Rejected);
695 registerNewVote(next(resp));
701 invs = getInvsForNextPoll();
707 registerNewVote(next(resp));
710 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
711 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Invalid);
715 invs = getInvsForNextPoll();
721 const uint32_t invType = provider.invType;
723 auto itemA = provider.buildVoteItem();
724 auto itemidA = provider.getVoteItemId(itemA);
726 auto itemB = provider.buildVoteItem();
727 auto itemidB = provider.getVoteItemId(itemB);
730 auto avanodes = ConnectNodes();
738 auto invs = getInvsForNextPoll();
743 uint64_t round = getRound();
745 std::vector<avalanche::VoteItemUpdate> updates;
747 {round, 0, {
Vote(0, itemidA)}}, updates));
751 std::vector<Vote> votes = provider.buildVotesForItems(0, {itemA, itemB});
754 invs = getInvsForNextPoll();
758 for (
size_t i = 0; i < invs.size(); i++) {
764 for (
int i = 0; i < 4; i++) {
765 NodeId nodeid = getSuitableNodeToQuery();
767 BOOST_CHECK(registerVotes(nodeid, next(resp), updates));
773 NodeId nodeid = getSuitableNodeToQuery();
775 BOOST_CHECK(registerVotes(nodeid, next(resp), updates));
781 NodeId firstNodeid = getSuitableNodeToQuery();
783 NodeId secondNodeid = getSuitableNodeToQuery();
789 BOOST_CHECK(registerVotes(firstNodeid, next(resp), updates));
791 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == itemA);
792 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
796 invs = getInvsForNextPoll();
802 BOOST_CHECK(registerVotes(secondNodeid, resp, updates));
804 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == itemB);
805 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
809 invs = getInvsForNextPoll();
815 const uint32_t invType = provider.invType;
817 auto item = provider.buildVoteItem();
818 auto itemid = provider.getVoteItemId(item);
825 std::set<NodeId> avanodeIds;
826 auto avanodes = ConnectNodes();
827 for (
auto avanode : avanodes) {
829 avanodeIds.insert(avanode->GetId());
832 auto getSelectedAvanodeId = [&]() {
833 NodeId avanodeid = getSuitableNodeToQuery();
834 BOOST_CHECK(avanodeIds.find(avanodeid) != avanodeIds.end());
839 NodeId avanodeid = getSelectedAvanodeId();
843 auto invs = getInvsForNextPoll();
848 std::set<NodeId> unselectedNodeids = avanodeIds;
849 unselectedNodeids.erase(avanodeid);
850 const size_t remainingNodeIds = unselectedNodeids.size();
852 uint64_t round = getRound();
853 for (
size_t i = 0; i < remainingNodeIds; i++) {
858 NodeId nodeid = getSuitableNodeToQuery();
859 BOOST_CHECK(unselectedNodeids.find(nodeid) != avanodeIds.end());
860 unselectedNodeids.erase(nodeid);
870 std::vector<avalanche::VoteItemUpdate> updates;
871 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
878 auto checkRegisterVotesError = [&](
NodeId nodeid,
880 const std::string &expectedError) {
888 checkRegisterVotesError(avanodeid, next(resp),
"unexpected-ava-response");
897 resp = {round, 0, {
Vote(0, itemid),
Vote(0, itemid)}};
899 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-size");
903 resp = {getRound(), 0, {}};
905 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-size");
909 resp = {getRound(), 0, {
Vote()}};
911 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-content");
918 invs = getInvsForNextPoll();
921 item = provider.buildVoteItem();
922 itemid = provider.getVoteItemId(item);
925 invs = getInvsForNextPoll();
929 uint64_t queryRound = getRound();
932 resp = {queryRound + 1, 0, {
Vote()}};
933 checkRegisterVotesError(avanodeid, resp,
"unexpected-ava-response");
935 resp = {queryRound - 1, 0, {
Vote()}};
936 checkRegisterVotesError(avanodeid, resp,
"unexpected-ava-response");
940 resp = {queryRound, 0, {
Vote(0, itemid)}};
941 checkRegisterVotesError(avanodeid + 1234, resp,
"unexpected-ava-response");
944 resp = {queryRound, 0, {
Vote(0, itemid)}};
945 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
950 const auto item2 = provider.buildVoteItem();
953 std::vector<Vote> votes = provider.buildVotesForItems(0, {item, item2});
954 resp = {getRound(), 0, {votes[1], votes[0]}};
956 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-content");
960 resp = {getRound(), 0, votes};
962 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
969 const uint32_t invType = provider.invType;
971 auto itemA = provider.buildVoteItem();
972 auto itemB = provider.buildVoteItem();
974 auto avanodes = ConnectNodes();
977 std::vector<Vote> votes = provider.buildVotesForItems(0, {itemA, itemB});
983 auto invs = getInvsForNextPoll();
985 for (
size_t i = 0; i < invs.size(); i++) {
991 provider.invalidateItem(itemB);
993 Response goodResp{getRound(), 0, {
Vote(0, provider.getVoteItemId(itemA))}};
994 std::vector<avalanche::VoteItemUpdate> updates;
996 BOOST_CHECK(registerVotes(avanodes[0]->GetId(), goodResp, updates));
1000 Response badResp{getRound(), 0, votes};
1003 BOOST_CHECK(!registerVotes(avanodes[1]->GetId(), badResp, updates,
error));
1007BOOST_TEST_DECORATOR(*boost::unit_test::timeout(60))
1012 auto queryTimeDuration = std::chrono::milliseconds(10);
1013 setArg(
"-avatimeout",
ToString(queryTimeDuration.count()));
1016 m_processor = Processor::MakeProcessor(
1020 const auto item = provider.buildVoteItem();
1021 const auto itemid = provider.getVoteItemId(item);
1031 for (
int i = 0; i < 10; i++) {
1033 avanodeid = getSuitableNodeToQuery();
1035 auto start = Now<SteadyMilliseconds>();
1039 std::this_thread::sleep_for(std::chrono::milliseconds(1));
1042 std::vector<avalanche::VoteItemUpdate> updates;
1043 bool ret = registerVotes(avanodeid, next(resp), updates);
1044 if (Now<SteadyMilliseconds>() > start + queryTimeDuration) {
1055 avanodeid = getSuitableNodeToQuery();
1059 std::this_thread::sleep_for(queryTimeDuration);
1061 BOOST_CHECK(!registerVotes(avanodeid, next(resp), updates));
1067 const uint32_t invType = provider.invType;
1070 auto proof = GetProof();
1074 std::array<CNode *, AVALANCHE_MAX_INFLIGHT_POLL + 1> nodes;
1075 for (
auto &n : nodes) {
1081 const auto item = provider.buildVoteItem();
1082 const auto itemid = provider.getVoteItemId(item);
1086 std::map<NodeId, uint64_t> node_round_map;
1088 NodeId nodeid = getSuitableNodeToQuery();
1089 BOOST_CHECK(node_round_map.find(nodeid) == node_round_map.end());
1090 node_round_map.insert(std::pair<NodeId, uint64_t>(nodeid, getRound()));
1091 auto invs = getInvsForNextPoll();
1099 auto suitablenodeid = getSuitableNodeToQuery();
1101 auto invs = getInvsForNextPoll();
1107 auto it = node_round_map.begin();
1109 std::vector<avalanche::VoteItemUpdate> updates;
1110 BOOST_CHECK(registerVotes(it->first, resp, updates));
1111 node_round_map.erase(it);
1113 invs = getInvsForNextPoll();
1120 std::vector<VoteItemUpdate> updates;
1122 CBlock block = CreateAndProcessBlock({}, CScript());
1128 Assert(
m_node.chainman)->m_blockman.LookupBlockIndex(blockHash);
1132 auto avanodes = ConnectNodes();
1141 uint64_t round = getRound();
1145 for (
size_t i = 0; i < avanodes.size(); i++) {
1147 BOOST_CHECK(registerVotes(avanodes[i]->GetId(), next(resp), updates));
1151 const NodeId firstNodeId = getSuitableNodeToQuery();
1152 std::map<NodeId, uint64_t> node_round_map;
1154 for (
size_t i = 0; i < avanodes.size(); i++) {
1155 NodeId nodeid = getSuitableNodeToQuery();
1156 BOOST_CHECK(node_round_map.find(nodeid) == node_round_map.end());
1157 node_round_map[nodeid] = getRound();
1163 auto confidence = m_processor->getConfidence(pindex);
1164 BOOST_REQUIRE(confidence > 0);
1166 for (
auto &[nodeid, r] : node_round_map) {
1167 if (nodeid == firstNodeId) {
1174 registerVotes(nodeid, {r, 0, {
Vote(0, blockHash)}}, updates));
1179 registerVotes(firstNodeId, {round, 0, {
Vote(0, blockHash)}}, updates));
1186 CBlock block = CreateAndProcessBlock({}, CScript());
1192 Assert(
m_node.chainman)->m_blockman.LookupBlockIndex(blockHash);
1199 std::chrono::steady_clock::time_point start,
stop;
1209 auto avanodes = ConnectNodes();
1212 NodeId nodeid = getSuitableNodeToQuery();
1213 BOOST_CHECK_NE(nodeid,
NO_NODE);
1216 uint64_t queryRound = getRound();
1220 for (
int i = 0; i < 60 * 1000; i++) {
1224 if (getRound() == queryRound + avanodes.size()) {
1233 uint64_t responseRound = getRound();
1234 auto queryTime = Now<SteadyMilliseconds>() + std::chrono::milliseconds(100);
1236 std::vector<VoteItemUpdate> updates;
1238 BOOST_CHECK(registerVotes(nodeid, {queryRound, 100, {
Vote(0, blockHash)}},
1241 for (
int i = 0; i < 10000; i++) {
1244 if (getRound() != responseRound) {
1245 BOOST_CHECK(Now<SteadyMilliseconds>() >= queryTime);
1264 schedulerThread.join();
1269 std::chrono::steady_clock::time_point start,
stop;
1271 std::thread schedulerThread;
1281 m_processor.reset();
1288 schedulerThread.join();
1295 auto addProofToReconcile = [&](uint32_t proofScore) {
1305 auto proof = addProofToReconcile(++score);
1307 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1316 for (
size_t i = 0; i < 10; i++) {
1317 auto proof = addProofToReconcile(++score);
1319 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1324 lastProofId = proof->
getId();
1327 for (
size_t i = 0; i < 10; i++) {
1328 auto proof = addProofToReconcile(--score);
1330 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1338 auto proof = addProofToReconcile(--score);
1339 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1340 for (
auto &inv : invs) {
1341 BOOST_CHECK_NE(inv.hash, proof->
getId());
1347 setArg(
"-avaproofstakeutxoconfirmations",
"2");
1348 setArg(
"-avalancheconflictingproofcooldown",
"0");
1362 Assert(
m_node.chainman)->ActiveChainstate().CoinsTip();
1363 coins.
AddCoin(conflictingOutpoint,
1366 coins.
AddCoin(immatureOutpoint,
1371 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence,
1372 uint32_t height = 10) {
1379 auto conflictingProof = buildProof(conflictingOutpoint, 1);
1380 auto validProof = buildProof(conflictingOutpoint, 2);
1381 auto immatureProof = buildProof(immatureOutpoint, 3, 100);
1383 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1384 BOOST_CHECK(!m_processor->isAccepted(validProof));
1385 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1391 BOOST_CHECK(!m_processor->addToReconcile(conflictingProof));
1392 BOOST_CHECK(!m_processor->addToReconcile(validProof));
1393 BOOST_CHECK(!m_processor->addToReconcile(immatureProof));
1405 BOOST_CHECK(m_processor->addToReconcile(conflictingProof));
1406 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1407 BOOST_CHECK(!m_processor->isAccepted(validProof));
1408 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1413 BOOST_CHECK(m_processor->addToReconcile(validProof));
1414 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1416 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1421 BOOST_CHECK(!m_processor->addToReconcile(immatureProof));
1422 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1424 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1432 int minStake = 400'000'000;
1433 setArg(
"-avaminquorumstake",
ToString(minStake));
1434 setArg(
"-avaminquorumconnectedstakeratio",
"0.5");
1438 uint32_t minScore = Proof::amountToScore(minStake * currency.baseunit);
1446 setArg(
"-avaproof", localProof->ToHex());
1450 m_processor = Processor::MakeProcessor(
1455 BOOST_CHECK(m_processor->getLocalProof() !=
nullptr);
1457 localProof->getId());
1460 AvalancheTest::getMinQuorumConnectedScoreRatio(*m_processor), 0.5);
1481 for (
NodeId id = 0;
id < 8;
id++) {
1483 pm.
addNode(
id, m_processor->getLocalProof()->getId());
1499 const int64_t tipTime =
1503 const Amount amount = (int64_t(minScore / 4) *
COIN) / 100;
1504 const int height = 100;
1505 const bool isCoinbase =
false;
1512 height, isCoinbase),
1517 auto proof2 = pb.
build();
1528 pm.
addNode(8, proof2->getId());
1547 m_processor->withPeerManager(
1553 pm.
addNode(7, m_processor->getLocalProof()->getId());
1558 auto spendProofUtxo = [&](
ProofRef proof) {
1571 for (int64_t i = 0; i < 6; i++) {
1573 CreateAndProcessBlock({}, CScript());
1577 ->GetMedianTimePast(),
1578 proof2->getExpirationTime());
1589 spendProofUtxo(proof1);
1596 spendProofUtxo(m_processor->getLocalProof());
1608 const std::vector<std::tuple<std::string, std::string, std::string, bool>>
1611 {
"",
"",
"",
false},
1612 {
"-1",
"-1",
"-1",
false},
1615 {
"-1",
"0",
"0",
false},
1616 {
"-0.01",
"0",
"0",
false},
1617 {
"21000000000000.01",
"0",
"0",
false},
1620 {
"0",
"-1",
"0",
false},
1621 {
"0",
"1.1",
"0",
false},
1624 {
"0",
"0",
"-1",
false},
1627 {
"0",
"0",
"0",
true},
1628 {
"0.00",
"0",
"0",
true},
1629 {
"0.01",
"0",
"0",
true},
1630 {
"1",
"0.1",
"0",
true},
1631 {
"10",
"0.5",
"0",
true},
1632 {
"10",
"1",
"0",
true},
1633 {
"21000000000000.00",
"0",
"0",
true},
1634 {
"0",
"0",
"1",
true},
1635 {
"0",
"0",
"100",
true},
1640 for (
const auto &[stake, stakeRatio, numProofsMessages, success] :
1642 setArg(
"-avaminquorumstake", stake);
1643 setArg(
"-avaminquorumconnectedstakeratio", stakeRatio);
1644 setArg(
"-avaminavaproofsnodecount", numProofsMessages);
1647 std::unique_ptr<Processor> processor = Processor::MakeProcessor(
1667 auto checkMinAvaproofsMessages = [&](int64_t minAvaproofsMessages) {
1668 setArg(
"-avaminavaproofsnodecount",
ToString(minAvaproofsMessages));
1671 auto processor = Processor::MakeProcessor(
1675 auto addNode = [&](
NodeId nodeid) {
1688 for (
NodeId id = 100;
id < 108;
id++) {
1693 minAvaproofsMessages <= 0);
1695 for (int64_t i = 0; i < minAvaproofsMessages - 1; i++) {
1698 processor->avaproofsSent(i);
1702 processor->avaproofsSent(i);
1708 addNode(minAvaproofsMessages);
1709 processor->avaproofsSent(minAvaproofsMessages);
1713 AvalancheTest::clearavaproofsNodeCounter(*processor);
1717 checkMinAvaproofsMessages(0);
1718 checkMinAvaproofsMessages(1);
1719 checkMinAvaproofsMessages(10);
1720 checkMinAvaproofsMessages(100);
1725 setArg(
"-avastalevotethreshold",
1727 setArg(
"-avastalevotefactor",
"2");
1729 const std::vector<std::tuple<int, int>> testCases = {
1736 m_processor = Processor::MakeProcessor(
1745 const uint32_t invType = provider.invType;
1747 const auto item = provider.buildVoteItem();
1748 const auto itemid = provider.getVoteItemId(item);
1751 auto avanodes = ConnectNodes();
1752 int nextNodeIndex = 0;
1754 std::vector<avalanche::VoteItemUpdate> updates;
1755 for (
const auto &[numYesVotes, numNeutralVotes] : testCases) {
1758 auto invs = getInvsForNextPoll();
1765 auto registerNewVote = [&](
const Response &resp) {
1767 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
1768 BOOST_CHECK(registerVotes(nodeid, resp, updates));
1772 for (
int i = 0; i < numYesVotes; i++) {
1774 registerNewVote(next(resp));
1777 i >= 6 ? i - 5 : 0);
1782 for (
int i = 0; i < numNeutralVotes; i++) {
1784 registerNewVote(next(resp));
1789 invs = getInvsForNextPoll();
1796 registerNewVote(next(resp));
1798 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
1799 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Stale);
1803 invs = getInvsForNextPoll();
1809 BlockProvider provider(
this);
1813 std::vector<CBlockIndex *> blockIndexes;
1817 blockIndexes.push_back(pindex);
1820 auto invs = getInvsForNextPoll();
1832 std::vector<Vote> votes;
1835 BlockHash blockhash = blockIndexes[i - 1]->GetBlockHash();
1836 votes.emplace_back(blockhash == eleventhBlockHash ? 0 : -1, blockhash);
1839 auto avanodes = ConnectNodes();
1840 int nextNodeIndex = 0;
1842 std::vector<avalanche::VoteItemUpdate> updates;
1843 auto registerNewVote = [&]() {
1844 Response resp = {getRound(), 0, votes};
1846 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
1847 BOOST_CHECK(registerVotes(nodeid, resp, updates));
1853 bool eleventhBlockFinalized =
false;
1854 for (
size_t i = 0; i < 10000 && !eleventhBlockFinalized; i++) {
1857 for (
auto &update : updates) {
1858 if (update.getStatus() == VoteStatus::Finalized &&
1859 provider.fromAnyVoteItem(update.getVoteItem())
1860 ->GetBlockHash() == eleventhBlockHash) {
1861 eleventhBlockFinalized =
true;
1872 invs = getInvsForNextPoll();
1874 for (
size_t i = 0; i < 10; i++) {
1888 auto &activeChainstate =
m_node.chainman->ActiveChainstate();
1890 activeChainstate.InvalidateBlock(state, tip);
1893 CBlock altblock = CreateAndProcessBlock({}, CScript() <<
OP_TRUE);
1896 ->m_blockman.LookupBlockIndex(altblock.
GetHash()));
1904 activeChainstate.ResetBlockFailureFlags(tip);
1906 activeChainstate.ActivateBestChain(state);
1910 invs = getInvsForNextPoll();
1917 for (
auto &inv : invs) {
1918 votes.emplace_back(inv.hash == tiphash ? 0 : -1, inv.hash);
1921 bool tipFinalized =
false;
1922 for (
size_t i = 0; i < 10000 && !tipFinalized; i++) {
1925 for (
auto &update : updates) {
1926 if (update.getStatus() == VoteStatus::Finalized &&
1927 provider.fromAnyVoteItem(update.getVoteItem())
1928 ->GetBlockHash() == tiphash) {
1929 tipFinalized =
true;
1938 invs = getInvsForNextPoll();
1946 BlockHash alttiphash = alttip->GetBlockHash();
1947 votes = {{1, alttiphash}};
1949 bool alttipInvalidated =
false;
1950 for (
size_t i = 0; i < 10000 && !alttipInvalidated; i++) {
1953 for (
auto &update : updates) {
1954 if (update.getStatus() == VoteStatus::Invalid &&
1955 provider.fromAnyVoteItem(update.getVoteItem())
1956 ->GetBlockHash() == alttiphash) {
1957 alttipInvalidated =
true;
1962 invs = getInvsForNextPoll();
1973 const int numberElementsEachType = 100;
1976 std::vector<ProofRef> proofs;
1977 for (
size_t i = 1; i <= numberElementsEachType; i++) {
1981 proofs.emplace_back(std::move(proof));
1983 Shuffle(proofs.begin(), proofs.end(), rng);
1985 std::vector<CBlockIndex> indexes;
1986 for (
size_t i = 1; i <= numberElementsEachType; i++) {
1989 indexes.emplace_back(std::move(index));
1991 Shuffle(indexes.begin(), indexes.end(), rng);
1993 auto allItems = std::make_tuple(std::move(proofs), std::move(indexes));
1994 static const size_t numTypes = std::tuple_size<
decltype(allItems)>::value;
2000 for (
size_t i = 0; i < numberElementsEachType; i++) {
2002 const size_t firstType = rng.
randrange(numTypes);
2004 for (
size_t j = 0; j < numTypes; j++) {
2005 switch ((firstType + j) % numTypes) {
2008 writeView->insert(std::make_pair(
2009 std::get<0>(allItems)[i],
VoteRecord(
true)));
2013 writeView->insert(std::make_pair(
2014 &std::get<1>(allItems)[i],
VoteRecord(
true)));
2025 auto readView = voteMap.getReadView();
2026 auto it = readView.begin();
2029 uint32_t lastScore = std::numeric_limits<uint32_t>::max();
2030 for (
size_t i = 0; i < numberElementsEachType; i++) {
2031 BOOST_CHECK(std::holds_alternative<const ProofRef>(it->first));
2033 uint32_t currentScore =
2034 std::get<const ProofRef>(it->first)->getScore();
2035 BOOST_CHECK_LT(currentScore, lastScore);
2036 lastScore = currentScore;
2044 for (
size_t i = 0; i < numberElementsEachType; i++) {
2045 BOOST_CHECK(std::holds_alternative<const CBlockIndex *>(it->first));
2048 std::get<const CBlockIndex *>(it->first)->nChainWork;
2050 lastWork = currentWork;
2061 Chainstate &chainstate = chainman->ActiveChainstate();
2063 const auto block = std::make_shared<const CBlock>(
2064 this->CreateBlock({}, CScript(), chainstate));
2076 blockindex = chainman->m_blockman.LookupBlockIndex(blockhash);
2081 BOOST_CHECK(AvalancheTest::getInvsForNextPoll(*m_processor).empty());
2082 BOOST_CHECK(!m_processor->isAccepted(blockindex));
2090 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
2103 auto now = GetTime<std::chrono::seconds>();
2109 std::vector<CScript> winners;
2111 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2114 BOOST_CHECK(!m_processor->computeStakingReward(
nullptr));
2115 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2120 prevBlock.
nTime = now.count();
2123 BOOST_CHECK(!m_processor->computeStakingReward(&prevBlock));
2124 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2127 size_t numProofs = 10;
2128 std::vector<ProofRef> proofs;
2129 proofs.reserve(numProofs);
2130 for (
size_t i = 0; i < numProofs; i++) {
2134 auto proof = GetProof(payoutScript);
2140 return pm.setFinalized(peer.peerid);
2144 proofs.emplace_back(std::move(proof));
2150 BOOST_CHECK(!m_processor->computeStakingReward(&prevBlock));
2151 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2154 auto winnerExists = [&](
const CScript &expectedWinner) {
2155 const std::string winnerString =
FormatScript(expectedWinner);
2157 for (
const ProofRef &proof : proofs) {
2168 prevBlock.
nTime = now.count();
2171 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2172 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2176 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2177 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2183 prevBlockHigh.
phashBlock = &prevBlockHashHigh;
2185 BOOST_CHECK(m_processor->computeStakingReward(&prevBlockHigh));
2187 m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2191 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2195 m_processor->cleanupStakingRewards(101);
2198 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2202 m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2206 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2207 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2211 m_processor->cleanupStakingRewards(200);
2214 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2216 !m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2228 Assert(
m_node.chainman)->ActiveChainstate().CoinsTip();
2234 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence,
2242 auto localProof = buildProof(outpoint, 1, 100);
2245 setArg(
"-avaproof", localProof->ToHex());
2246 setArg(
"-avalancheconflictingproofcooldown",
"0");
2247 setArg(
"-avalanchepeerreplacementcooldown",
"0");
2248 setArg(
"-avaproofstakeutxoconfirmations",
"3");
2252 m_processor = Processor::MakeProcessor(
2257 localProof->getId());
2259 auto checkLocalProofState =
2260 [&](
const bool boundToPeer,
2264 return pm.isBoundToPeer(localProof->getId());
2267 BOOST_CHECK_MESSAGE(
2268 m_processor->getLocalProofRegistrationState().GetResult() ==
2270 m_processor->getLocalProofRegistrationState().ToString());
2277 AvalancheTest::updatedBlockTip(*m_processor);
2281 AvalancheTest::setLocalProofShareable(*m_processor,
true);
2283 AvalancheTest::updatedBlockTip(*m_processor);
2284 checkLocalProofState(
false, ProofRegistrationResult::IMMATURE);
2288 AvalancheTest::updatedBlockTip(*m_processor);
2289 checkLocalProofState(
false, ProofRegistrationResult::IMMATURE);
2293 AvalancheTest::updatedBlockTip(*m_processor);
2297 auto conflictingProof = buildProof(outpoint, 2, 100);
2303 AvalancheTest::updatedBlockTip(*m_processor);
2304 checkLocalProofState(
false, ProofRegistrationResult::CONFLICTING);
2308 setArg(
"-avalancheconflictingproofcooldown",
"0");
2309 setArg(
"-avalanchepeerreplacementcooldown",
"0");
2329 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence) {
2336 auto proof = buildProof(outpoint, 1);
2340 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2350 BOOST_CHECK(m_processor->reconcileOrFinalize(proof));
2352 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2355 AvalancheTest::addProofToRecentfinalized(*m_processor, proof->
getId());
2357 BOOST_CHECK(m_processor->reconcileOrFinalize(proof));
2362 return peer.hasFinalized;
2369 auto betterProof = buildProof(outpoint, 2);
2373 BOOST_CHECK(!m_processor->reconcileOrFinalize(betterProof));
2385 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2387 BOOST_CHECK(m_processor->reconcileOrFinalize(betterProof));
2391 setArg(
"-avalanchestakingpreconsensus",
"1");
2393 m_processor = Processor::MakeProcessor(
2399 auto now = GetTime<std::chrono::seconds>();
2408 const ProofId proofid1 = proof1->getId();
2413 const ProofId proofid2 = proof2->getId();
2421 m_processor->addStakeContender(proof1);
2422 m_processor->addStakeContender(proof2);
2439 for (
NodeId n = 0; n < 8; n++) {
2444 return pm.setFinalized(peer.peerid);
2449 AvalancheTest::setFinalizationTip(*m_processor, chaintip);
2456 CBlock block = CreateAndProcessBlock({}, CScript());
2459 ->m_blockman.LookupBlockIndex(block.
GetHash()));
2460 AvalancheTest::updatedBlockTip(*m_processor);
2464 BOOST_CHECK(m_processor->computeStakingReward(chaintip));
2466 std::vector<CScript> winners;
2470 BOOST_CHECK(winners[0] == proof2->getPayoutScript());
2499 AvalancheTest::setFinalizationTip(*m_processor, chaintip);
2504 m_processor->cleanupStakingRewards(chaintip->
nHeight);
2520 m_processor->setStakingRewardWinners(
2521 chaintip, {proof1->getPayoutScript(), proof2->getPayoutScript()});
2532 m_processor->withPeerManager(
2534 block = CreateAndProcessBlock({}, CScript());
2537 ->m_blockman.LookupBlockIndex(block.
GetHash()));
2538 AvalancheTest::updatedBlockTip(*m_processor);
2539 AvalancheTest::setFinalizationTip(*m_processor, chaintip);
2540 m_processor->cleanupStakingRewards(chaintip->
nHeight);
2563BOOST_AUTO_TEST_SUITE_END()
static constexpr Amount COIN
uint256 ArithToUint256(const arith_uint256 &a)
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)
bool AddNode(const std::string &node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
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.
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.
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...
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.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
bool ActivateBestChain(BlockValidationState &state, std::shared_ptr< const CBlock > pblock=nullptr, avalanche::Processor *const avalanche=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.
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())
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...
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, avalanche::Processor *const avalanche, Options opts)
256-bit unsigned big integer.
bool removeNode(NodeId nodeid)
uint32_t getConnectedPeersScore() const
bool exists(const ProofId &proofid) const
Return true if the (valid) proof exists, but only for non-dangling proofs.
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 saveRemoteProof(const ProofId &proofid, const NodeId nodeid, const bool present)
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.
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 CScript & getPayoutScript() const
const ProofId & getId() const
const std::vector< SignedStake > & getStakes() const
uint32_t getCooldown() const
const std::vector< Vote > & GetVotes() const
uint64_t getRound() const
const AnyVoteItem & getVoteItem() const
const VoteStatus & getStatus() 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)
bool error(const char *fmt, const Args &...args)
static constexpr Amount PROOF_DUST_THRESHOLD
Minimum amount per utxo.
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_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()
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.
StakeContenderIds are unique for each block to ensure that the peer polling for their acceptance has ...
TestVoteRecord(uint16_t conf)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
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.