24 #include <test/util/setup_common.h>
26 #include <boost/mpl/list.hpp>
27 #include <boost/test/unit_test.hpp>
31 #include <type_traits>
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));
98 struct CConnmanTest :
public CConnman {
102 m_nodes.push_back(&
node);
119 struct 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");
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();
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);
278 struct 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);
324 struct 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) {}
389 TestMemPoolEntryHelper mempoolEntryHelper;
390 auto entry = mempoolEntryHelper.Fee(int64_t(rng.randrange(10)) *
COIN)
407 std::vector<Vote> buildVotesForItems(uint32_t
error,
408 std::vector<CTransactionRef> &&items) {
409 size_t numItems = items.
size();
411 std::vector<Vote> votes;
412 votes.reserve(numItems);
422 std::sort(items.begin(), items.end(),
426 auto lhsIter = mempool->GetIter(lhs->GetId());
427 auto rhsIter = mempool->GetIter(rhs->GetId());
428 BOOST_CHECK(lhsIter);
429 BOOST_CHECK(rhsIter);
431 return CompareTxMemPoolEntryByModifiedFeeRate{}(
432 **lhsIter, **rhsIter);
436 for (
auto &item : items) {
437 votes.emplace_back(
error, item->GetId());
453 return std::get<const CTransactionRef>(item);
463 boost::mpl::list<BlockProvider, ProofProvider, TxProvider>;
468 std::set<VoteStatus> status{
469 VoteStatus::Invalid, VoteStatus::Rejected, VoteStatus::Accepted,
470 VoteStatus::Finalized, VoteStatus::Stale,
473 auto item = provider.buildVoteItem();
475 for (
auto s : status) {
498 auto item = provider.buildVoteItem();
499 auto itemid = provider.getVoteItemId(item);
507 auto avanodes = ConnectNodes();
509 int nextNodeIndex = 0;
510 std::vector<avalanche::VoteItemUpdate> updates;
511 auto registerNewVote = [&](
const Response &resp) {
513 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
518 auto finalize = [&](
const auto finalizeItemId) {
519 Response resp = {getRound(), 0, {
Vote(0, finalizeItemId)}};
521 registerNewVote(next(resp));
522 if (updates.size() > 0) {
527 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
535 auto finalizeNewItem = [&]() {
536 auto anotherItem = provider.buildVoteItem();
538 auto anotherItemId = provider.getVoteItemId(anotherItem);
541 AvalancheTest::addVoteRecord(*m_processor, anotherVoteItem, voteRecord);
542 finalize(anotherItemId);
562 AvalancheTest::setFinalizationTip(*m_processor, chaintip);
574 auto item = decltype(provider.buildVoteItem())();
581 item = provider.buildVoteItem();
590 const uint32_t invType = provider.invType;
592 auto item = provider.buildVoteItem();
593 auto itemid = provider.getVoteItemId(item);
596 auto avanodes = ConnectNodes();
603 auto invs = getInvsForNextPoll();
610 int nextNodeIndex = 0;
611 std::vector<avalanche::VoteItemUpdate> updates;
612 auto registerNewVote = [&](
const Response &resp) {
614 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
620 for (
int i = 0; i < 6; i++) {
621 registerNewVote(next(resp));
628 resp = {getRound(), 0, {
Vote(-1, itemid)}};
629 registerNewVote(next(resp));
634 resp = {getRound(), 0, {
Vote(0, itemid)}};
635 for (
int i = 1; i < 7; i++) {
636 registerNewVote(next(resp));
643 resp = {getRound(), 0, {
Vote(-1, itemid)}};
644 registerNewVote(next(resp));
648 registerNewVote(next(resp));
653 resp = {getRound(), 0, {
Vote(0, itemid)}};
654 for (
int i = 2; i < 8; i++) {
655 registerNewVote(next(resp));
663 registerNewVote(next(resp));
670 invs = getInvsForNextPoll();
676 registerNewVote(next(resp));
678 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
679 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
683 invs = getInvsForNextPoll();
687 item = provider.buildVoteItem();
688 itemid = provider.getVoteItemId(item);
692 invs = getInvsForNextPoll();
697 resp = {getRound(), 0, {
Vote(1, itemid)}};
698 for (
int i = 0; i < 6; i++) {
699 registerNewVote(next(resp));
705 registerNewVote(next(resp));
708 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
709 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Rejected);
714 registerNewVote(next(resp));
720 invs = getInvsForNextPoll();
726 registerNewVote(next(resp));
729 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
730 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Invalid);
734 invs = getInvsForNextPoll();
740 const uint32_t invType = provider.invType;
742 auto itemA = provider.buildVoteItem();
743 auto itemidA = provider.getVoteItemId(itemA);
745 auto itemB = provider.buildVoteItem();
746 auto itemidB = provider.getVoteItemId(itemB);
749 auto avanodes = ConnectNodes();
757 auto invs = getInvsForNextPoll();
762 uint64_t round = getRound();
764 std::vector<avalanche::VoteItemUpdate> updates;
766 {round, 0, {
Vote(0, itemidA)}}, updates));
770 std::vector<Vote> votes = provider.buildVotesForItems(0, {itemA, itemB});
773 invs = getInvsForNextPoll();
777 for (
size_t i = 0; i < invs.size(); i++) {
783 for (
int i = 0; i < 4; i++) {
784 NodeId nodeid = getSuitableNodeToQuery();
786 BOOST_CHECK(registerVotes(nodeid, next(resp), updates));
792 NodeId nodeid = getSuitableNodeToQuery();
794 BOOST_CHECK(registerVotes(nodeid, next(resp), updates));
800 NodeId firstNodeid = getSuitableNodeToQuery();
802 NodeId secondNodeid = getSuitableNodeToQuery();
808 BOOST_CHECK(registerVotes(firstNodeid, next(resp), updates));
810 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == itemA);
811 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
815 invs = getInvsForNextPoll();
821 BOOST_CHECK(registerVotes(secondNodeid, resp, updates));
823 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == itemB);
824 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Finalized);
828 invs = getInvsForNextPoll();
834 const uint32_t invType = provider.invType;
836 auto item = provider.buildVoteItem();
837 auto itemid = provider.getVoteItemId(item);
844 std::set<NodeId> avanodeIds;
845 auto avanodes = ConnectNodes();
846 for (
auto avanode : avanodes) {
848 avanodeIds.insert(avanode->GetId());
851 auto getSelectedAvanodeId = [&]() {
852 NodeId avanodeid = getSuitableNodeToQuery();
853 BOOST_CHECK(avanodeIds.find(avanodeid) != avanodeIds.end());
858 NodeId avanodeid = getSelectedAvanodeId();
862 auto invs = getInvsForNextPoll();
867 std::set<NodeId> unselectedNodeids = avanodeIds;
868 unselectedNodeids.erase(avanodeid);
869 const size_t remainingNodeIds = unselectedNodeids.size();
871 uint64_t round = getRound();
872 for (
size_t i = 0; i < remainingNodeIds; i++) {
877 NodeId nodeid = getSuitableNodeToQuery();
878 BOOST_CHECK(unselectedNodeids.find(nodeid) != avanodeIds.end());
879 unselectedNodeids.erase(nodeid);
889 std::vector<avalanche::VoteItemUpdate> updates;
890 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
897 auto checkRegisterVotesError = [&](
NodeId nodeid,
899 const std::string &expectedError) {
907 checkRegisterVotesError(avanodeid, next(resp),
"unexpected-ava-response");
916 resp = {round, 0, {
Vote(0, itemid),
Vote(0, itemid)}};
918 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-size");
922 resp = {getRound(), 0, {}};
924 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-size");
928 resp = {getRound(), 0, {
Vote()}};
930 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-content");
937 invs = getInvsForNextPoll();
940 item = provider.buildVoteItem();
941 itemid = provider.getVoteItemId(item);
944 invs = getInvsForNextPoll();
948 uint64_t queryRound = getRound();
951 resp = {queryRound + 1, 0, {
Vote()}};
952 checkRegisterVotesError(avanodeid, resp,
"unexpected-ava-response");
954 resp = {queryRound - 1, 0, {
Vote()}};
955 checkRegisterVotesError(avanodeid, resp,
"unexpected-ava-response");
959 resp = {queryRound, 0, {
Vote(0, itemid)}};
960 checkRegisterVotesError(avanodeid + 1234, resp,
"unexpected-ava-response");
963 resp = {queryRound, 0, {
Vote(0, itemid)}};
964 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
969 const auto item2 = provider.buildVoteItem();
972 std::vector<Vote> votes = provider.buildVotesForItems(0, {item, item2});
973 resp = {getRound(), 0, {votes[1], votes[0]}};
975 checkRegisterVotesError(avanodeid, resp,
"invalid-ava-response-content");
979 resp = {getRound(), 0, votes};
981 BOOST_CHECK(registerVotes(avanodeid, resp, updates));
988 const uint32_t invType = provider.invType;
990 auto itemA = provider.buildVoteItem();
991 auto itemB = provider.buildVoteItem();
993 auto avanodes = ConnectNodes();
996 std::vector<Vote> votes = provider.buildVotesForItems(0, {itemA, itemB});
1002 auto invs = getInvsForNextPoll();
1004 for (
size_t i = 0; i < invs.size(); i++) {
1010 provider.invalidateItem(itemB);
1012 Response goodResp{getRound(), 0, {
Vote(0, provider.getVoteItemId(itemA))}};
1013 std::vector<avalanche::VoteItemUpdate> updates;
1015 BOOST_CHECK(registerVotes(avanodes[0]->GetId(), goodResp, updates));
1019 Response badResp{getRound(), 0, votes};
1022 BOOST_CHECK(!registerVotes(avanodes[1]->GetId(), badResp, updates,
error));
1026 BOOST_TEST_DECORATOR(*boost::unit_test::timeout(60))
1031 auto queryTimeDuration = std::chrono::milliseconds(10);
1032 setArg(
"-avatimeout",
ToString(queryTimeDuration.count()));
1035 m_processor = Processor::MakeProcessor(
1039 const auto item = provider.buildVoteItem();
1040 const auto itemid = provider.getVoteItemId(item);
1050 for (
int i = 0; i < 10; i++) {
1052 avanodeid = getSuitableNodeToQuery();
1054 auto start = Now<SteadyMilliseconds>();
1058 std::this_thread::sleep_for(std::chrono::milliseconds(1));
1061 std::vector<avalanche::VoteItemUpdate> updates;
1062 bool ret = registerVotes(avanodeid, next(resp), updates);
1063 if (Now<SteadyMilliseconds>() > start + queryTimeDuration) {
1074 avanodeid = getSuitableNodeToQuery();
1078 std::this_thread::sleep_for(queryTimeDuration);
1080 BOOST_CHECK(!registerVotes(avanodeid, next(resp), updates));
1086 const uint32_t invType = provider.invType;
1089 auto proof = GetProof();
1093 std::array<CNode *, AVALANCHE_MAX_INFLIGHT_POLL + 1> nodes;
1094 for (
auto &n : nodes) {
1100 const auto item = provider.buildVoteItem();
1101 const auto itemid = provider.getVoteItemId(item);
1105 std::map<NodeId, uint64_t> node_round_map;
1107 NodeId nodeid = getSuitableNodeToQuery();
1108 BOOST_CHECK(node_round_map.find(nodeid) == node_round_map.end());
1109 node_round_map.insert(std::pair<NodeId, uint64_t>(nodeid, getRound()));
1110 auto invs = getInvsForNextPoll();
1118 auto suitablenodeid = getSuitableNodeToQuery();
1120 auto invs = getInvsForNextPoll();
1126 auto it = node_round_map.begin();
1128 std::vector<avalanche::VoteItemUpdate> updates;
1129 BOOST_CHECK(registerVotes(it->first, resp, updates));
1130 node_round_map.erase(it);
1132 invs = getInvsForNextPoll();
1139 std::vector<VoteItemUpdate> updates;
1147 Assert(
m_node.chainman)->m_blockman.LookupBlockIndex(blockHash);
1151 auto avanodes = ConnectNodes();
1160 uint64_t round = getRound();
1164 for (
size_t i = 0; i < avanodes.size(); i++) {
1166 BOOST_CHECK(registerVotes(avanodes[i]->GetId(), next(resp), updates));
1170 const NodeId firstNodeId = getSuitableNodeToQuery();
1171 std::map<NodeId, uint64_t> node_round_map;
1173 for (
size_t i = 0; i < avanodes.size(); i++) {
1174 NodeId nodeid = getSuitableNodeToQuery();
1175 BOOST_CHECK(node_round_map.find(nodeid) == node_round_map.end());
1176 node_round_map[nodeid] = getRound();
1182 auto confidence = m_processor->getConfidence(pindex);
1183 BOOST_REQUIRE(confidence > 0);
1185 for (
auto &[nodeid, r] : node_round_map) {
1186 if (nodeid == firstNodeId) {
1193 registerVotes(nodeid, {r, 0, {
Vote(0, blockHash)}}, updates));
1198 registerVotes(firstNodeId, {round, 0, {
Vote(0, blockHash)}}, updates));
1211 Assert(
m_node.chainman)->m_blockman.LookupBlockIndex(blockHash);
1218 std::chrono::steady_clock::time_point start,
stop;
1228 auto avanodes = ConnectNodes();
1231 NodeId nodeid = getSuitableNodeToQuery();
1232 BOOST_CHECK_NE(nodeid,
NO_NODE);
1235 uint64_t queryRound = getRound();
1239 for (
int i = 0; i < 60 * 1000; i++) {
1243 if (getRound() == queryRound + avanodes.size()) {
1252 uint64_t responseRound = getRound();
1253 auto queryTime = Now<SteadyMilliseconds>() + std::chrono::milliseconds(100);
1255 std::vector<VoteItemUpdate> updates;
1257 BOOST_CHECK(registerVotes(nodeid, {queryRound, 100, {
Vote(0, blockHash)}},
1260 for (
int i = 0; i < 10000; i++) {
1263 if (getRound() != responseRound) {
1264 BOOST_CHECK(Now<SteadyMilliseconds>() >= queryTime);
1283 schedulerThread.join();
1288 std::chrono::steady_clock::time_point start,
stop;
1290 std::thread schedulerThread;
1300 m_processor.reset();
1307 schedulerThread.join();
1314 auto addProofToReconcile = [&](uint32_t proofScore) {
1324 auto proof = addProofToReconcile(++score);
1326 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1335 for (
size_t i = 0; i < 10; i++) {
1336 auto proof = addProofToReconcile(++score);
1338 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1343 lastProofId = proof->
getId();
1346 for (
size_t i = 0; i < 10; i++) {
1347 auto proof = addProofToReconcile(--score);
1349 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1357 auto proof = addProofToReconcile(--score);
1358 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
1359 for (
auto &inv : invs) {
1360 BOOST_CHECK_NE(inv.hash, proof->
getId());
1366 setArg(
"-avaproofstakeutxoconfirmations",
"2");
1367 setArg(
"-avalancheconflictingproofcooldown",
"0");
1381 Assert(
m_node.chainman)->ActiveChainstate().CoinsTip();
1382 coins.
AddCoin(conflictingOutpoint,
1385 coins.
AddCoin(immatureOutpoint,
1390 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence,
1391 uint32_t height = 10) {
1398 auto conflictingProof = buildProof(conflictingOutpoint, 1);
1399 auto validProof = buildProof(conflictingOutpoint, 2);
1400 auto immatureProof = buildProof(immatureOutpoint, 3, 100);
1402 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1403 BOOST_CHECK(!m_processor->isAccepted(validProof));
1404 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1410 BOOST_CHECK(!m_processor->addToReconcile(conflictingProof));
1411 BOOST_CHECK(!m_processor->addToReconcile(validProof));
1412 BOOST_CHECK(!m_processor->addToReconcile(immatureProof));
1424 BOOST_CHECK(m_processor->addToReconcile(conflictingProof));
1425 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1426 BOOST_CHECK(!m_processor->isAccepted(validProof));
1427 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1432 BOOST_CHECK(m_processor->addToReconcile(validProof));
1433 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1435 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1440 BOOST_CHECK(!m_processor->addToReconcile(immatureProof));
1441 BOOST_CHECK(!m_processor->isAccepted(conflictingProof));
1443 BOOST_CHECK(!m_processor->isAccepted(immatureProof));
1451 int minStake = 400'000'000;
1452 setArg(
"-avaminquorumstake",
ToString(minStake));
1453 setArg(
"-avaminquorumconnectedstakeratio",
"0.5");
1457 uint32_t minScore = Proof::amountToScore(minStake * currency.baseunit);
1465 setArg(
"-avaproof", localProof->ToHex());
1469 m_processor = Processor::MakeProcessor(
1474 BOOST_CHECK(m_processor->getLocalProof() !=
nullptr);
1476 localProof->getId());
1479 AvalancheTest::getMinQuorumConnectedScoreRatio(*m_processor), 0.5);
1500 for (
NodeId id = 0;
id < 8;
id++) {
1502 pm.
addNode(
id, m_processor->getLocalProof()->getId());
1518 const int64_t tipTime =
1522 const Amount amount = (int64_t(minScore / 4) *
COIN) / 100;
1523 const int height = 100;
1524 const bool isCoinbase =
false;
1531 height, isCoinbase),
1536 auto proof2 = pb.
build();
1547 pm.
addNode(8, proof2->getId());
1566 m_processor->withPeerManager(
1572 pm.
addNode(7, m_processor->getLocalProof()->getId());
1577 auto spendProofUtxo = [&](
ProofRef proof) {
1590 for (int64_t i = 0; i < 6; i++) {
1592 CreateAndProcessBlock({},
CScript());
1596 ->GetMedianTimePast(),
1597 proof2->getExpirationTime());
1608 spendProofUtxo(proof1);
1615 spendProofUtxo(m_processor->getLocalProof());
1627 const std::vector<std::tuple<std::string, std::string, std::string, bool>>
1630 {
"",
"",
"",
false},
1631 {
"-1",
"-1",
"-1",
false},
1634 {
"-1",
"0",
"0",
false},
1635 {
"-0.01",
"0",
"0",
false},
1636 {
"21000000000000.01",
"0",
"0",
false},
1639 {
"0",
"-1",
"0",
false},
1640 {
"0",
"1.1",
"0",
false},
1643 {
"0",
"0",
"-1",
false},
1646 {
"0",
"0",
"0",
true},
1647 {
"0.00",
"0",
"0",
true},
1648 {
"0.01",
"0",
"0",
true},
1649 {
"1",
"0.1",
"0",
true},
1650 {
"10",
"0.5",
"0",
true},
1651 {
"10",
"1",
"0",
true},
1652 {
"21000000000000.00",
"0",
"0",
true},
1653 {
"0",
"0",
"1",
true},
1654 {
"0",
"0",
"100",
true},
1659 for (
const auto &[stake, stakeRatio, numProofsMessages, success] :
1661 setArg(
"-avaminquorumstake", stake);
1662 setArg(
"-avaminquorumconnectedstakeratio", stakeRatio);
1663 setArg(
"-avaminavaproofsnodecount", numProofsMessages);
1666 std::unique_ptr<Processor> processor = Processor::MakeProcessor(
1686 auto checkMinAvaproofsMessages = [&](int64_t minAvaproofsMessages) {
1687 setArg(
"-avaminavaproofsnodecount",
ToString(minAvaproofsMessages));
1690 auto processor = Processor::MakeProcessor(
1694 auto addNode = [&](
NodeId nodeid) {
1707 for (
NodeId id = 100;
id < 108;
id++) {
1712 minAvaproofsMessages <= 0);
1714 for (int64_t i = 0; i < minAvaproofsMessages - 1; i++) {
1717 processor->avaproofsSent(i);
1721 processor->avaproofsSent(i);
1727 addNode(minAvaproofsMessages);
1728 processor->avaproofsSent(minAvaproofsMessages);
1732 AvalancheTest::clearavaproofsNodeCounter(*processor);
1736 checkMinAvaproofsMessages(0);
1737 checkMinAvaproofsMessages(1);
1738 checkMinAvaproofsMessages(10);
1739 checkMinAvaproofsMessages(100);
1744 setArg(
"-avastalevotethreshold",
1746 setArg(
"-avastalevotefactor",
"2");
1748 const std::vector<std::tuple<int, int>> testCases = {
1755 m_processor = Processor::MakeProcessor(
1764 const uint32_t invType = provider.invType;
1766 const auto item = provider.buildVoteItem();
1767 const auto itemid = provider.getVoteItemId(item);
1770 auto avanodes = ConnectNodes();
1771 int nextNodeIndex = 0;
1773 std::vector<avalanche::VoteItemUpdate> updates;
1774 for (
const auto &[numYesVotes, numNeutralVotes] : testCases) {
1777 auto invs = getInvsForNextPoll();
1784 auto registerNewVote = [&](
const Response &resp) {
1786 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
1787 BOOST_CHECK(registerVotes(nodeid, resp, updates));
1791 for (
int i = 0; i < numYesVotes; i++) {
1793 registerNewVote(next(resp));
1796 i >= 6 ? i - 5 : 0);
1801 for (
int i = 0; i < numNeutralVotes; i++) {
1803 registerNewVote(next(resp));
1808 invs = getInvsForNextPoll();
1815 registerNewVote(next(resp));
1817 BOOST_CHECK(provider.fromAnyVoteItem(updates[0].getVoteItem()) == item);
1818 BOOST_CHECK(updates[0].getStatus() == VoteStatus::Stale);
1822 invs = getInvsForNextPoll();
1828 BlockProvider provider(
this);
1830 std::vector<CBlockIndex *> blockIndexes;
1834 blockIndexes.push_back(pindex);
1837 auto invs = getInvsForNextPoll();
1849 std::vector<Vote> votes;
1852 BlockHash blockhash = blockIndexes[i - 1]->GetBlockHash();
1853 votes.emplace_back(blockhash == eleventhBlockHash ? 0 : -1, blockhash);
1856 auto avanodes = ConnectNodes();
1857 int nextNodeIndex = 0;
1859 std::vector<avalanche::VoteItemUpdate> updates;
1860 auto registerNewVote = [&]() {
1861 Response resp = {getRound(), 0, votes};
1863 auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId();
1864 BOOST_CHECK(registerVotes(nodeid, resp, updates));
1868 bool eleventhBlockFinalized =
false;
1869 for (
size_t i = 0; i < 10000 && !eleventhBlockFinalized; i++) {
1872 for (
auto &update : updates) {
1873 if (update.getStatus() == VoteStatus::Finalized &&
1874 provider.fromAnyVoteItem(update.getVoteItem())
1875 ->GetBlockHash() == eleventhBlockHash) {
1876 eleventhBlockFinalized =
true;
1883 invs = getInvsForNextPoll();
1885 for (
size_t i = 0; i < 10; i++) {
1899 auto &activeChainstate =
m_node.chainman->ActiveChainstate();
1901 activeChainstate.InvalidateBlock(state, tip);
1907 ->m_blockman.LookupBlockIndex(altblock.
GetHash()));
1915 activeChainstate.ResetBlockFailureFlags(tip);
1917 activeChainstate.ActivateBestChain(state);
1921 invs = getInvsForNextPoll();
1928 for (
auto &inv : invs) {
1929 votes.emplace_back(inv.hash == tiphash ? 0 : -1, inv.hash);
1932 bool tipFinalized =
false;
1933 for (
size_t i = 0; i < 10000 && !tipFinalized; i++) {
1936 for (
auto &update : updates) {
1937 if (update.getStatus() == VoteStatus::Finalized &&
1938 provider.fromAnyVoteItem(update.getVoteItem())
1939 ->GetBlockHash() == tiphash) {
1940 tipFinalized =
true;
1949 invs = getInvsForNextPoll();
1957 BlockHash alttiphash = alttip->GetBlockHash();
1958 votes = {{1, alttiphash}};
1960 bool alttipInvalidated =
false;
1961 for (
size_t i = 0; i < 10000 && !alttipInvalidated; i++) {
1964 for (
auto &update : updates) {
1965 if (update.getStatus() == VoteStatus::Invalid &&
1966 provider.fromAnyVoteItem(update.getVoteItem())
1967 ->GetBlockHash() == alttiphash) {
1968 alttipInvalidated =
true;
1973 invs = getInvsForNextPoll();
1982 Chainstate &activeChainState = chainman.ActiveChainstate();
1984 const int numberElementsEachType = 100;
1987 std::vector<ProofRef> proofs;
1988 for (
size_t i = 1; i <= numberElementsEachType; i++) {
1992 proofs.emplace_back(std::move(proof));
1994 Shuffle(proofs.begin(), proofs.end(), rng);
1996 std::vector<CBlockIndex> indexes;
1997 for (
size_t i = 1; i <= numberElementsEachType; i++) {
2000 indexes.emplace_back(std::move(index));
2002 Shuffle(indexes.begin(), indexes.end(), rng);
2005 TestMemPoolEntryHelper mempoolEntryHelper;
2006 std::vector<CTransactionRef> txs;
2007 for (
size_t i = 1; i <= numberElementsEachType; i++) {
2015 auto entry = mempoolEntryHelper.Fee(int64_t(i) *
COIN).FromTx(tx);
2022 txs.emplace_back(std::move(tx));
2026 std::make_tuple(std::move(proofs), std::move(indexes), std::move(txs));
2027 static const size_t numTypes = std::tuple_size<decltype(allItems)>::value;
2033 for (
size_t i = 0; i < numberElementsEachType; i++) {
2035 const size_t firstType = rng.
randrange(numTypes);
2037 for (
size_t j = 0; j < numTypes; j++) {
2038 switch ((firstType + j) % numTypes) {
2041 writeView->insert(std::make_pair(
2042 std::get<0>(allItems)[i],
VoteRecord(
true)));
2046 writeView->insert(std::make_pair(
2047 &std::get<1>(allItems)[i],
VoteRecord(
true)));
2051 writeView->insert(std::make_pair(
2052 std::get<2>(allItems)[i],
VoteRecord(
true)));
2064 auto it = readView.
begin();
2068 uint32_t lastScore = std::numeric_limits<uint32_t>::max();
2069 for (
size_t i = 0; i < numberElementsEachType; i++) {
2070 BOOST_CHECK(std::holds_alternative<const ProofRef>(it->first));
2072 uint32_t currentScore =
2073 std::get<const ProofRef>(it->first)->getScore();
2074 BOOST_CHECK_LT(currentScore, lastScore);
2075 lastScore = currentScore;
2083 for (
size_t i = 0; i < numberElementsEachType; i++) {
2084 BOOST_CHECK(std::holds_alternative<const CBlockIndex *>(it->first));
2087 std::get<const CBlockIndex *>(it->first)->nChainWork;
2089 lastWork = currentWork;
2099 for (
size_t i = 0; i < numberElementsEachType; i++) {
2101 std::holds_alternative<const CTransactionRef>(it->first));
2104 std::get<const CTransactionRef>(it->first)->GetId());
2107 CFeeRate currentFeeRate = (**iter)->GetModifiedFeeRate();
2110 lastFeeRate = currentFeeRate;
2122 TestMemPoolEntryHelper mempoolEntryHelper;
2123 TxProvider provider(
this);
2125 std::vector<CTransactionRef> txs;
2126 for (
size_t i = 0; i < 5; i++) {
2127 txs.emplace_back(provider.buildVoteItem());
2135 for (
const auto &tx : txs) {
2136 writeView->insert(std::make_pair(tx,
VoteRecord(
true)));
2142 for (
const auto &[item, vote] : readView) {
2143 auto tx = std::get<const CTransactionRef>(item);
2144 BOOST_CHECK_GT(tx->GetId(), lastTxId);
2145 lastTxId = tx->GetId();
2151 for (
size_t i = 0; i < 5; i++) {
2152 txs.emplace_back(provider.buildVoteItem());
2160 for (
const auto &tx : txs) {
2161 writeView->insert(std::make_pair(tx,
VoteRecord(
true)));
2166 auto it = readView.
begin();
2172 for (
size_t i = 0; i < 5; i++) {
2173 auto tx = std::get<const CTransactionRef>(it->first);
2175 auto iter = mempool->
GetIter(tx->GetId());
2178 BOOST_CHECK((**iter)->GetModifiedFeeRate() <= lastFeeRate);
2179 lastFeeRate = (**iter)->GetModifiedFeeRate();
2185 for (
size_t i = 0; i < 5; i++) {
2186 auto tx = std::get<const CTransactionRef>(it->first);
2190 BOOST_CHECK_GT(tx->GetId(), lastTxId);
2191 lastTxId = tx->GetId();
2199 Chainstate &chainstate = chainman->ActiveChainstate();
2201 const auto block = std::make_shared<const CBlock>(
2202 this->CreateBlock({},
CScript(), chainstate));
2214 blockindex = chainman->m_blockman.LookupBlockIndex(blockhash);
2219 BOOST_CHECK(AvalancheTest::getInvsForNextPoll(*m_processor).empty());
2220 BOOST_CHECK(!m_processor->isAccepted(blockindex));
2228 auto invs = AvalancheTest::getInvsForNextPoll(*m_processor);
2241 auto now = GetTime<std::chrono::seconds>();
2247 std::vector<CScript> winners;
2249 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2252 BOOST_CHECK(!m_processor->computeStakingReward(
nullptr));
2253 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2258 prevBlock.
nTime = now.count();
2261 BOOST_CHECK(!m_processor->computeStakingReward(&prevBlock));
2262 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2264 setArg(
"-avaminquorumstake",
"0");
2265 setArg(
"-avaminquorumconnectedstakeratio",
"0");
2266 setArg(
"-avaminavaproofsnodecount",
"0");
2269 size_t numProofs = 10;
2270 std::vector<ProofRef> proofs;
2271 proofs.reserve(numProofs);
2272 for (
size_t i = 0; i < numProofs; i++) {
2276 auto proof = GetProof(payoutScript);
2282 return pm.setFinalized(peer.peerid);
2286 proofs.emplace_back(std::move(proof));
2292 BOOST_CHECK(!m_processor->computeStakingReward(&prevBlock));
2293 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2296 auto winnerExists = [&](
const CScript &expectedWinner) {
2297 const std::string winnerString =
FormatScript(expectedWinner);
2299 for (
const ProofRef &proof : proofs) {
2310 prevBlock.
nTime = now.count();
2313 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2314 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2318 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2319 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2325 prevBlockHigh.
phashBlock = &prevBlockHashHigh;
2327 BOOST_CHECK(m_processor->computeStakingReward(&prevBlockHigh));
2329 m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2333 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2337 m_processor->cleanupStakingRewards(101);
2340 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2344 m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2348 BOOST_CHECK(m_processor->computeStakingReward(&prevBlock));
2349 BOOST_CHECK(m_processor->getStakingRewardWinners(prevBlockHash, winners));
2353 m_processor->cleanupStakingRewards(200);
2356 BOOST_CHECK(!m_processor->getStakingRewardWinners(prevBlockHash, winners));
2358 !m_processor->getStakingRewardWinners(prevBlockHashHigh, winners));
2370 Assert(
m_node.chainman)->ActiveChainstate().CoinsTip();
2376 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence,
2384 auto localProof = buildProof(outpoint, 1, 100);
2387 setArg(
"-avaproof", localProof->ToHex());
2388 setArg(
"-avalancheconflictingproofcooldown",
"0");
2389 setArg(
"-avalanchepeerreplacementcooldown",
"0");
2390 setArg(
"-avaproofstakeutxoconfirmations",
"3");
2394 m_processor = Processor::MakeProcessor(
2399 localProof->getId());
2401 auto checkLocalProofState =
2402 [&](
const bool boundToPeer,
2406 return pm.isBoundToPeer(localProof->getId());
2409 BOOST_CHECK_MESSAGE(
2410 m_processor->getLocalProofRegistrationState().GetResult() ==
2412 m_processor->getLocalProofRegistrationState().ToString());
2419 AvalancheTest::updatedBlockTip(*m_processor);
2423 AvalancheTest::setLocalProofShareable(*m_processor,
true);
2425 AvalancheTest::updatedBlockTip(*m_processor);
2426 checkLocalProofState(
false, ProofRegistrationResult::IMMATURE);
2430 AvalancheTest::updatedBlockTip(*m_processor);
2431 checkLocalProofState(
false, ProofRegistrationResult::IMMATURE);
2435 AvalancheTest::updatedBlockTip(*m_processor);
2439 auto conflictingProof = buildProof(outpoint, 2, 100);
2445 AvalancheTest::updatedBlockTip(*m_processor);
2446 checkLocalProofState(
false, ProofRegistrationResult::CONFLICTING);
2450 setArg(
"-avalancheconflictingproofcooldown",
"0");
2451 setArg(
"-avalanchepeerreplacementcooldown",
"0");
2457 Chainstate &activeChainState = chainman.ActiveChainstate();
2471 auto buildProof = [&](
const COutPoint &outpoint, uint64_t sequence) {
2478 auto proof = buildProof(outpoint, 1);
2482 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2492 BOOST_CHECK(m_processor->reconcileOrFinalize(proof));
2494 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2497 AvalancheTest::addProofToRecentfinalized(*m_processor, proof->
getId());
2499 BOOST_CHECK(m_processor->reconcileOrFinalize(proof));
2504 return peer.hasFinalized;
2511 auto betterProof = buildProof(outpoint, 2);
2515 BOOST_CHECK(!m_processor->reconcileOrFinalize(betterProof));
2527 BOOST_CHECK(!m_processor->reconcileOrFinalize(proof));
2529 BOOST_CHECK(m_processor->reconcileOrFinalize(betterProof));
2532 BOOST_AUTO_TEST_SUITE_END()
static constexpr Amount MAX_MONEY
No amount larger than this (in satoshi) is valid.
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)
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.
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())
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, avalanche::Processor *const avalanche, Options opts)
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)
bool error(const char *fmt, const Args &...args)
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_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.
#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.