diff --git a/src/avalanche.h b/src/avalanche.h --- a/src/avalanche.h +++ b/src/avalanche.h @@ -67,9 +67,9 @@ } public: - VoteRecord() : votes(0xaaaa), confidence(0) {} + VoteRecord(bool accepted) : votes(0xaaaa), confidence(accepted) {} - bool isValid() const { return confidence & 0x01; } + bool isAccepted() const { return confidence & 0x01; } uint16_t getConfidence() const { return confidence >> 1; } bool hasFinalized() const { @@ -87,7 +87,7 @@ return false; } - if (isValid() == yes) { + if (isAccepted() == yes) { // If the vote is in agreement with our internal status, increase // confidence. confidence += 2; diff --git a/src/avalanche.cpp b/src/avalanche.cpp --- a/src/avalanche.cpp +++ b/src/avalanche.cpp @@ -12,8 +12,15 @@ std::unique_ptr g_avalanche; bool AvalancheProcessor::addBlockToReconcile(const CBlockIndex *pindex) { + bool isAccepted; + + { + LOCK(cs_main); + isAccepted = chainActive.Contains(pindex); + } + return vote_records.getWriteView() - ->insert(std::make_pair(pindex, VoteRecord())) + ->insert(std::make_pair(pindex, VoteRecord(isAccepted))) .second; } @@ -31,7 +38,7 @@ bool AvalancheProcessor::isAccepted(const CBlockIndex *pindex) const { if (auto vr = GetRecord(vote_records, pindex)) { - return vr->isValid(); + return vr->isAccepted(); } return false; @@ -112,7 +119,7 @@ // We just finalized a vote. If it is valid, then let the caller // know. Either way, remove the item from the map. - if (vr.isValid()) { + if (vr.isAccepted()) { accepted.push_back(pindex); } else { rejected.push_back(pindex); diff --git a/src/test/avalanche_tests.cpp b/src/test/avalanche_tests.cpp --- a/src/test/avalanche_tests.cpp +++ b/src/test/avalanche_tests.cpp @@ -26,15 +26,22 @@ #define REGISTER_VOTE_AND_CHECK(vr, vote, state, finalized, confidence) \ vr.registerVote(vote); \ - BOOST_CHECK_EQUAL(vr.isValid(), state); \ + BOOST_CHECK_EQUAL(vr.isAccepted(), state); \ BOOST_CHECK_EQUAL(vr.hasFinalized(), finalized); \ BOOST_CHECK_EQUAL(vr.getConfidence(), confidence); BOOST_AUTO_TEST_CASE(vote_record) { - VoteRecord vr; + VoteRecord vraccpeter(true); // Check initial state. - BOOST_CHECK_EQUAL(vr.isValid(), false); + BOOST_CHECK_EQUAL(vraccpeter.isAccepted(), true); + BOOST_CHECK_EQUAL(vraccpeter.hasFinalized(), false); + BOOST_CHECK_EQUAL(vraccpeter.getConfidence(), 0); + + VoteRecord vr(false); + + // Check initial state. + BOOST_CHECK_EQUAL(vr.isAccepted(), false); BOOST_CHECK_EQUAL(vr.hasFinalized(), false); BOOST_CHECK_EQUAL(vr.getConfidence(), 0); @@ -131,14 +138,14 @@ BOOST_CHECK(invs[0].hash == blockHash); // Newly added blocks are also considered rejected. - BOOST_CHECK(!p.isAccepted(pindex)); + BOOST_CHECK(p.isAccepted(pindex)); // Let's vote for this block a few times. AvalancheResponse resp{0, {AvalancheVote(0, blockHash)}}; - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 4; i++) { AvalancheTest::runEventLoop(p); BOOST_CHECK(p.registerVotes(nodeid, resp, accepted, rejected)); - BOOST_CHECK(!p.isAccepted(pindex)); + BOOST_CHECK(p.isAccepted(pindex)); BOOST_CHECK_EQUAL(accepted.size(), 0); BOOST_CHECK_EQUAL(rejected.size(), 0); } @@ -183,10 +190,10 @@ // Only 3 here as we don't need to flip state. resp = {0, {AvalancheVote(1, blockHash)}}; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 4; i++) { AvalancheTest::runEventLoop(p); BOOST_CHECK(p.registerVotes(nodeid, resp, accepted, rejected)); - BOOST_CHECK(!p.isAccepted(pindex)); + BOOST_CHECK(p.isAccepted(pindex)); BOOST_CHECK_EQUAL(accepted.size(), 0); BOOST_CHECK_EQUAL(rejected.size(), 0); } @@ -226,7 +233,7 @@ // Adding the block twice does nothing. BOOST_CHECK(p.addBlockToReconcile(pindex)); BOOST_CHECK(!p.addBlockToReconcile(pindex)); - BOOST_CHECK(!p.isAccepted(pindex)); + BOOST_CHECK(p.isAccepted(pindex)); CConnmanTest::ClearNodes(); } @@ -282,7 +289,7 @@ BOOST_CHECK(invs[1].hash == blockHashB); // Now it is rejected, but we can vote for it numerous times. - for (int i = 0; i < AVALANCHE_FINALIZATION_SCORE + 4; i++) { + for (int i = 0; i < AVALANCHE_FINALIZATION_SCORE + 3; i++) { AvalancheTest::runEventLoop(p); BOOST_CHECK(p.registerVotes(node0->GetId(), resp, accepted, rejected)); BOOST_CHECK_EQUAL(accepted.size(), 0);