Changeset View
Changeset View
Standalone View
Standalone View
src/test/avalanche_tests.cpp
// Copyright (c) 2010 The Bitcoin developers | // Copyright (c) 2010 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "avalanche.h" | #include "avalanche.h" | ||||
#include "test/test_bitcoin.h" | #include "test/test_bitcoin.h" | ||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
struct AvalancheTest { | |||||
static std::vector<CInv> getInvsForNextPoll(const AvalancheProcessor &p) { | |||||
return p.getInvsForNextPoll(); | |||||
} | |||||
}; | |||||
BOOST_FIXTURE_TEST_SUITE(avalanche_tests, TestChain100Setup) | BOOST_FIXTURE_TEST_SUITE(avalanche_tests, TestChain100Setup) | ||||
#define REGISTER_VOTE_AND_CHECK(vr, vote, state, finalized, confidence) \ | #define REGISTER_VOTE_AND_CHECK(vr, vote, state, finalized, confidence) \ | ||||
vr.registerVote(vote); \ | vr.registerVote(vote); \ | ||||
BOOST_CHECK_EQUAL(vr.isValid(), state); \ | BOOST_CHECK_EQUAL(vr.isValid(), state); \ | ||||
BOOST_CHECK_EQUAL(vr.hasFinalized(), finalized); \ | BOOST_CHECK_EQUAL(vr.hasFinalized(), finalized); \ | ||||
BOOST_CHECK_EQUAL(vr.getConfidence(), confidence); | BOOST_CHECK_EQUAL(vr.getConfidence(), confidence); | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(vote_record) { | ||||
REGISTER_VOTE_AND_CHECK(vr, true, false, true, | REGISTER_VOTE_AND_CHECK(vr, true, false, true, | ||||
AVALANCHE_FINALIZATION_SCORE); | AVALANCHE_FINALIZATION_SCORE); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(block_register) { | BOOST_AUTO_TEST_CASE(block_register) { | ||||
AvalancheProcessor p; | AvalancheProcessor p; | ||||
CBlock block = CreateAndProcessBlock({}, CScript()); | CBlock block = CreateAndProcessBlock({}, CScript()); | ||||
const uint256 hash = block.GetHash(); | const uint256 blockHash = block.GetHash(); | ||||
const CBlockIndex *pindex = mapBlockIndex[hash]; | const CBlockIndex *pindex = mapBlockIndex[blockHash]; | ||||
// Querying for random block returns false. | // Querying for random block returns false. | ||||
BOOST_CHECK(!p.isAccepted(pindex)); | BOOST_CHECK(!p.isAccepted(pindex)); | ||||
BOOST_CHECK(!p.hasFinalized(pindex)); | BOOST_CHECK(!p.hasFinalized(pindex)); | ||||
// Newly added blocks are also considered rejected. | // Add a new block. Check it is added to the polls. | ||||
BOOST_CHECK(p.addBlockToReconcile(pindex)); | BOOST_CHECK(p.addBlockToReconcile(pindex)); | ||||
auto invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 1); | |||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | |||||
BOOST_CHECK(invs[0].hash == blockHash); | |||||
// Newly added blocks are also considered rejected. | |||||
BOOST_CHECK(!p.isAccepted(pindex)); | BOOST_CHECK(!p.isAccepted(pindex)); | ||||
BOOST_CHECK(!p.hasFinalized(pindex)); | BOOST_CHECK(!p.hasFinalized(pindex)); | ||||
// Let's vote for this block a few times. | // Let's vote for this block a few times. | ||||
AvalancheResponse resp{0, {AvalancheVote(0, hash)}}; | AvalancheResponse resp{0, {AvalancheVote(0, blockHash)}}; | ||||
for (int i = 0; i < 5; i++) { | for (int i = 0; i < 5; i++) { | ||||
p.registerVotes(resp); | p.registerVotes(resp); | ||||
BOOST_CHECK(!p.isAccepted(pindex)); | BOOST_CHECK(!p.isAccepted(pindex)); | ||||
BOOST_CHECK(!p.hasFinalized(pindex)); | BOOST_CHECK(!p.hasFinalized(pindex)); | ||||
} | } | ||||
// Now it is accepted, but we can vote for it numerous times. | // Now it is accepted, but we can vote for it numerous times. | ||||
for (int i = 0; i < AVALANCHE_FINALIZATION_SCORE; i++) { | for (int i = 0; i < AVALANCHE_FINALIZATION_SCORE; i++) { | ||||
p.registerVotes(resp); | p.registerVotes(resp); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK(!p.hasFinalized(pindex)); | BOOST_CHECK(!p.hasFinalized(pindex)); | ||||
} | } | ||||
// As long as it is not finalized, we poll. | |||||
invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 1); | |||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | |||||
BOOST_CHECK(invs[0].hash == blockHash); | |||||
// Now finalize the decision. | // Now finalize the decision. | ||||
resp = {0, {AvalancheVote(1, hash)}}; | resp = {0, {AvalancheVote(1, blockHash)}}; | ||||
p.registerVotes(resp); | p.registerVotes(resp); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK(p.hasFinalized(pindex)); | BOOST_CHECK(p.hasFinalized(pindex)); | ||||
// Once the decision is finalized, there is no poll for it. | |||||
invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 0); | |||||
// Now let's undo this and finalize rejection. | // Now let's undo this and finalize rejection. | ||||
for (int i = 0; i < 5; i++) { | for (int i = 0; i < 5; i++) { | ||||
p.registerVotes(resp); | p.registerVotes(resp); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK(p.hasFinalized(pindex)); | BOOST_CHECK(p.hasFinalized(pindex)); | ||||
} | } | ||||
// Now it is rejected, but we can vote for it numerous times. | // Now it is rejected, but we can vote for it numerous times. | ||||
for (int i = 0; i < AVALANCHE_FINALIZATION_SCORE; i++) { | for (int i = 0; i < AVALANCHE_FINALIZATION_SCORE; i++) { | ||||
p.registerVotes(resp); | p.registerVotes(resp); | ||||
BOOST_CHECK(!p.isAccepted(pindex)); | BOOST_CHECK(!p.isAccepted(pindex)); | ||||
BOOST_CHECK(!p.hasFinalized(pindex)); | BOOST_CHECK(!p.hasFinalized(pindex)); | ||||
} | } | ||||
// As long as it is not finalized, we poll. | |||||
invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 1); | |||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | |||||
BOOST_CHECK(invs[0].hash == blockHash); | |||||
// Now finalize the decision. | // Now finalize the decision. | ||||
p.registerVotes(resp); | p.registerVotes(resp); | ||||
BOOST_CHECK(!p.isAccepted(pindex)); | BOOST_CHECK(!p.isAccepted(pindex)); | ||||
BOOST_CHECK(p.hasFinalized(pindex)); | BOOST_CHECK(p.hasFinalized(pindex)); | ||||
// Once the decision is finalized, there is no poll for it. | |||||
invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 0); | |||||
// Adding the block twice does nothing. | // 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)); | ||||
BOOST_CHECK(p.hasFinalized(pindex)); | BOOST_CHECK(p.hasFinalized(pindex)); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(event_loop) { | BOOST_AUTO_TEST_CASE(event_loop) { | ||||
AvalancheProcessor p; | AvalancheProcessor p; | ||||
▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines |