Changeset View
Changeset View
Standalone View
Standalone View
src/test/avalanche_tests.cpp
Show First 20 Lines • Show All 71 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; | ||||
CBlockIndex index; | CBlockIndex index; | ||||
std::vector<uint256> accepted, rejected; | |||||
jasonbcox: This is much better. thank you | |||||
// Make sure the block has a hash. | // Make sure the block has a hash. | ||||
static const uint256 blockHash(uint256S( | static const uint256 blockHash(uint256S( | ||||
"abcdef0000000000000000000000000000000000000000000000000000000001")); | "abcdef0000000000000000000000000000000000000000000000000000000001")); | ||||
index.phashBlock = &blockHash; | index.phashBlock = &blockHash; | ||||
// Querying for random block returns false. | // Querying for random block returns false. | ||||
BOOST_CHECK(!p.isAccepted(&index)); | BOOST_CHECK(!p.isAccepted(&index)); | ||||
BOOST_CHECK(!p.hasFinalized(&index)); | |||||
// Add a new block. Check it is added to the polls. | // Add a new block. Check it is added to the polls. | ||||
BOOST_CHECK(p.addBlockToReconcile(&index)); | BOOST_CHECK(p.addBlockToReconcile(&index)); | ||||
auto invs = AvalancheTest::getInvsForNextPoll(p); | auto invs = AvalancheTest::getInvsForNextPoll(p); | ||||
BOOST_CHECK_EQUAL(invs.size(), 1); | BOOST_CHECK_EQUAL(invs.size(), 1); | ||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | ||||
BOOST_CHECK(invs[0].hash == blockHash); | BOOST_CHECK(invs[0].hash == blockHash); | ||||
// Newly added blocks are also considered rejected. | // Newly added blocks are also considered rejected. | ||||
BOOST_CHECK(!p.isAccepted(&index)); | BOOST_CHECK(!p.isAccepted(&index)); | ||||
BOOST_CHECK(!p.hasFinalized(&index)); | |||||
// Let's vote for this block a few times. | // Let's vote for this block a few times. | ||||
AvalancheResponse resp{{AvalancheVote(blockHash, 0)}}; | AvalancheResponse resp{{AvalancheVote(blockHash, 0)}}; | ||||
for (int i = 0; i < 5; i++) { | for (int i = 0; i < 5; i++) { | ||||
p.registerVotes(resp); | p.registerVotes(resp, accepted, rejected); | ||||
BOOST_CHECK(!p.isAccepted(&index)); | BOOST_CHECK(!p.isAccepted(&index)); | ||||
BOOST_CHECK(!p.hasFinalized(&index)); | BOOST_CHECK_EQUAL(accepted.size(), 0); | ||||
BOOST_CHECK_EQUAL(rejected.size(), 0); | |||||
} | } | ||||
// Now it is accepeted, but we can vote for it numerous times. | // Now it is accepeted, 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, accepted, rejected); | ||||
BOOST_CHECK(p.isAccepted(&index)); | BOOST_CHECK(p.isAccepted(&index)); | ||||
BOOST_CHECK(!p.hasFinalized(&index)); | BOOST_CHECK_EQUAL(accepted.size(), 0); | ||||
BOOST_CHECK_EQUAL(rejected.size(), 0); | |||||
} | } | ||||
// As long as it is not finalized, we poll. | // As long as it is not finalized, we poll. | ||||
invs = AvalancheTest::getInvsForNextPoll(p); | invs = AvalancheTest::getInvsForNextPoll(p); | ||||
BOOST_CHECK_EQUAL(invs.size(), 1); | BOOST_CHECK_EQUAL(invs.size(), 1); | ||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | ||||
BOOST_CHECK(invs[0].hash == blockHash); | BOOST_CHECK(invs[0].hash == blockHash); | ||||
// Now finalize the decision. | // Now finalize the decision. | ||||
resp = {{AvalancheVote(blockHash, 1)}}; | p.registerVotes(resp, accepted, rejected); | ||||
p.registerVotes(resp); | BOOST_CHECK_EQUAL(accepted.size(), 1); | ||||
BOOST_CHECK(p.isAccepted(&index)); | BOOST_CHECK_EQUAL(rejected.size(), 0); | ||||
BOOST_CHECK(p.hasFinalized(&index)); | BOOST_CHECK(accepted[0] == blockHash); | ||||
accepted = {}; | |||||
// Once the decision is finalized, there is no poll for it. | // Once the decision is finalized, there is no poll for it. | ||||
invs = AvalancheTest::getInvsForNextPoll(p); | invs = AvalancheTest::getInvsForNextPoll(p); | ||||
BOOST_CHECK_EQUAL(invs.size(), 0); | 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++) { | BOOST_CHECK(p.addBlockToReconcile(&index)); | ||||
p.registerVotes(resp); | invs = AvalancheTest::getInvsForNextPoll(p); | ||||
BOOST_CHECK(p.isAccepted(&index)); | BOOST_CHECK_EQUAL(invs.size(), 1); | ||||
BOOST_CHECK(p.hasFinalized(&index)); | BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | ||||
BOOST_CHECK(invs[0].hash == blockHash); | |||||
// Only 3 here as we don't need to flip state. | |||||
resp = {{AvalancheVote(blockHash, 1)}}; | |||||
for (int i = 0; i < 3; i++) { | |||||
p.registerVotes(resp, accepted, rejected); | |||||
BOOST_CHECK(!p.isAccepted(&index)); | |||||
BOOST_CHECK_EQUAL(accepted.size(), 0); | |||||
BOOST_CHECK_EQUAL(rejected.size(), 0); | |||||
} | } | ||||
// 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, accepted, rejected); | ||||
BOOST_CHECK(!p.isAccepted(&index)); | BOOST_CHECK(!p.isAccepted(&index)); | ||||
BOOST_CHECK(!p.hasFinalized(&index)); | BOOST_CHECK_EQUAL(accepted.size(), 0); | ||||
BOOST_CHECK_EQUAL(rejected.size(), 0); | |||||
} | } | ||||
// As long as it is not finalized, we poll. | // As long as it is not finalized, we poll. | ||||
invs = AvalancheTest::getInvsForNextPoll(p); | invs = AvalancheTest::getInvsForNextPoll(p); | ||||
BOOST_CHECK_EQUAL(invs.size(), 1); | BOOST_CHECK_EQUAL(invs.size(), 1); | ||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | ||||
BOOST_CHECK(invs[0].hash == blockHash); | BOOST_CHECK(invs[0].hash == blockHash); | ||||
// Now finalize the decision. | // Now finalize the decision. | ||||
p.registerVotes(resp); | p.registerVotes(resp, accepted, rejected); | ||||
BOOST_CHECK(!p.isAccepted(&index)); | BOOST_CHECK(!p.isAccepted(&index)); | ||||
BOOST_CHECK(p.hasFinalized(&index)); | BOOST_CHECK_EQUAL(accepted.size(), 0); | ||||
BOOST_CHECK_EQUAL(rejected.size(), 1); | |||||
BOOST_CHECK(rejected[0] == blockHash); | |||||
rejected = {}; | |||||
// Once the decision is finalized, there is no poll for it. | // Once the decision is finalized, there is no poll for it. | ||||
invs = AvalancheTest::getInvsForNextPoll(p); | invs = AvalancheTest::getInvsForNextPoll(p); | ||||
BOOST_CHECK_EQUAL(invs.size(), 0); | BOOST_CHECK_EQUAL(invs.size(), 0); | ||||
// Adding the block twice does nothing. | // Adding the block twice does nothing. | ||||
BOOST_CHECK(p.addBlockToReconcile(&index)); | |||||
BOOST_CHECK(!p.addBlockToReconcile(&index)); | BOOST_CHECK(!p.addBlockToReconcile(&index)); | ||||
BOOST_CHECK(!p.isAccepted(&index)); | BOOST_CHECK(!p.isAccepted(&index)); | ||||
BOOST_CHECK(p.hasFinalized(&index)); | } | ||||
BOOST_AUTO_TEST_CASE(multi_block_register) { | |||||
AvalancheProcessor p; | |||||
CBlockIndex indexA, indexB; | |||||
std::vector<uint256> accepted, rejected; | |||||
// Make sure the block has a hash. | |||||
static const uint256 blockHashA(uint256S( | |||||
"abcdef0000000000000000000000000000000000000000000000000000000001")); | |||||
indexA.phashBlock = &blockHashA; | |||||
static const uint256 blockHashB(uint256S( | |||||
"abcdef0000000000000000000000000000000000000000000000000987654321")); | |||||
indexB.phashBlock = &blockHashB; | |||||
// Querying for random block returns false. | |||||
BOOST_CHECK(!p.isAccepted(&indexA)); | |||||
BOOST_CHECK(!p.isAccepted(&indexB)); | |||||
// Start voting on block A. | |||||
BOOST_CHECK(p.addBlockToReconcile(&indexA)); | |||||
auto invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 1); | |||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | |||||
BOOST_CHECK(invs[0].hash == blockHashA); | |||||
AvalancheResponse resp{ | |||||
{AvalancheVote(blockHashA, 0), AvalancheVote(blockHashB, 0)}}; | |||||
p.registerVotes(resp, accepted, rejected); | |||||
BOOST_CHECK_EQUAL(accepted.size(), 0); | |||||
BOOST_CHECK_EQUAL(rejected.size(), 0); | |||||
// Start voing on block B after one vote. | |||||
BOOST_CHECK(p.addBlockToReconcile(&indexB)); | |||||
invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 2); | |||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | |||||
BOOST_CHECK(invs[0].hash == blockHashA); | |||||
BOOST_CHECK_EQUAL(invs[1].type, MSG_BLOCK); | |||||
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++) { | |||||
p.registerVotes(resp, accepted, rejected); | |||||
BOOST_CHECK_EQUAL(accepted.size(), 0); | |||||
BOOST_CHECK_EQUAL(rejected.size(), 0); | |||||
} | |||||
// Next vote will finalize block A. | |||||
p.registerVotes(resp, accepted, rejected); | |||||
BOOST_CHECK_EQUAL(accepted.size(), 1); | |||||
BOOST_CHECK_EQUAL(rejected.size(), 0); | |||||
BOOST_CHECK(accepted[0] == blockHashA); | |||||
accepted = {}; | |||||
// We do not vote on A anymore. | |||||
invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 1); | |||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | |||||
BOOST_CHECK(invs[0].hash == blockHashB); | |||||
// Next vote will finalize block B. | |||||
p.registerVotes(resp, accepted, rejected); | |||||
BOOST_CHECK_EQUAL(accepted.size(), 1); | |||||
BOOST_CHECK_EQUAL(rejected.size(), 0); | |||||
BOOST_CHECK(accepted[0] == blockHashB); | |||||
accepted = {}; | |||||
// There is nothing left to vote on. | |||||
invs = AvalancheTest::getInvsForNextPoll(p); | |||||
BOOST_CHECK_EQUAL(invs.size(), 0); | |||||
} | } | ||||
BOOST_AUTO_TEST_CASE(event_loop) { | BOOST_AUTO_TEST_CASE(event_loop) { | ||||
AvalancheProcessor p; | AvalancheProcessor p; | ||||
CScheduler scheduler; | CScheduler scheduler; | ||||
// Starting the event loop. | // Starting the event loop. | ||||
BOOST_CHECK(p.startEventLoop(scheduler)); | BOOST_CHECK(p.startEventLoop(scheduler)); | ||||
▲ Show 20 Lines • Show All 49 Lines • Show Last 20 Lines |
This is much better. thank you