Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/test/processor_tests.cpp
Show First 20 Lines • Show All 213 Lines • ▼ Show 20 Lines | std::array<CNode *, 8> ConnectNodes(const Config &config, Processor &p, | ||||
for (CNode *&n : nodes) { | for (CNode *&n : nodes) { | ||||
n = ConnectNode(config, nServices, peerLogic, connman); | n = ConnectNode(config, nServices, peerLogic, connman); | ||||
BOOST_CHECK(pm.addNodeToPeer(pid, n->GetId(), CPubKey())); | BOOST_CHECK(pm.addNodeToPeer(pid, n->GetId(), CPubKey())); | ||||
} | } | ||||
return nodes; | return nodes; | ||||
} | } | ||||
static AvalancheResponse next(AvalancheResponse &r) { | static Response next(Response &r) { | ||||
auto copy = r; | auto copy = r; | ||||
r = {r.getRound() + 1, r.getCooldown(), r.GetVotes()}; | r = {r.getRound() + 1, r.getCooldown(), r.GetVotes()}; | ||||
return copy; | return copy; | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(block_register) { | BOOST_AUTO_TEST_CASE(block_register) { | ||||
const Config &config = GetConfig(); | const Config &config = GetConfig(); | ||||
Show All 25 Lines | BOOST_AUTO_TEST_CASE(block_register) { | ||||
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' state reflect the blockchain. | // Newly added blocks' state reflect the blockchain. | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
int nextNodeIndex = 0; | int nextNodeIndex = 0; | ||||
auto registerNewVote = [&](const AvalancheResponse &resp) { | auto registerNewVote = [&](const Response &resp) { | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId(); | auto nodeid = avanodes[nextNodeIndex++ % avanodes.size()]->GetId(); | ||||
BOOST_CHECK(p.registerVotes(nodeid, resp, updates)); | BOOST_CHECK(p.registerVotes(nodeid, resp, updates)); | ||||
}; | }; | ||||
// Let's vote for this block a few times. | // Let's vote for this block a few times. | ||||
AvalancheResponse resp{0, 0, {AvalancheVote(0, blockHash)}}; | Response resp{0, 0, {Vote(0, blockHash)}}; | ||||
for (int i = 0; i < 6; i++) { | for (int i = 0; i < 6; i++) { | ||||
registerNewVote(next(resp)); | registerNewVote(next(resp)); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK_EQUAL(p.getConfidence(pindex), 0); | BOOST_CHECK_EQUAL(p.getConfidence(pindex), 0); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
} | } | ||||
// A single neutral vote do not change anything. | // A single neutral vote do not change anything. | ||||
resp = {AvalancheTest::getRound(p), 0, {AvalancheVote(-1, blockHash)}}; | resp = {AvalancheTest::getRound(p), 0, {Vote(-1, blockHash)}}; | ||||
registerNewVote(next(resp)); | registerNewVote(next(resp)); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK_EQUAL(p.getConfidence(pindex), 0); | BOOST_CHECK_EQUAL(p.getConfidence(pindex), 0); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
resp = {AvalancheTest::getRound(p), 0, {AvalancheVote(0, blockHash)}}; | resp = {AvalancheTest::getRound(p), 0, {Vote(0, blockHash)}}; | ||||
for (int i = 1; i < 7; i++) { | for (int i = 1; i < 7; i++) { | ||||
registerNewVote(next(resp)); | registerNewVote(next(resp)); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK_EQUAL(p.getConfidence(pindex), i); | BOOST_CHECK_EQUAL(p.getConfidence(pindex), i); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
} | } | ||||
// Two neutral votes will stall progress. | // Two neutral votes will stall progress. | ||||
resp = {AvalancheTest::getRound(p), 0, {AvalancheVote(-1, blockHash)}}; | resp = {AvalancheTest::getRound(p), 0, {Vote(-1, blockHash)}}; | ||||
registerNewVote(next(resp)); | registerNewVote(next(resp)); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK_EQUAL(p.getConfidence(pindex), 6); | BOOST_CHECK_EQUAL(p.getConfidence(pindex), 6); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
registerNewVote(next(resp)); | registerNewVote(next(resp)); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK_EQUAL(p.getConfidence(pindex), 6); | BOOST_CHECK_EQUAL(p.getConfidence(pindex), 6); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
resp = {AvalancheTest::getRound(p), 0, {AvalancheVote(0, blockHash)}}; | resp = {AvalancheTest::getRound(p), 0, {Vote(0, blockHash)}}; | ||||
for (int i = 2; i < 8; i++) { | for (int i = 2; i < 8; i++) { | ||||
registerNewVote(next(resp)); | registerNewVote(next(resp)); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK_EQUAL(p.getConfidence(pindex), 6); | BOOST_CHECK_EQUAL(p.getConfidence(pindex), 6); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
} | } | ||||
// We vote for it numerous times to finalize it. | // We vote for it numerous times to finalize it. | ||||
Show All 23 Lines | BOOST_AUTO_TEST_CASE(block_register) { | ||||
// Now let's undo this and finalize rejection. | // Now let's undo this and finalize rejection. | ||||
BOOST_CHECK(p.addBlockToReconcile(pindex)); | BOOST_CHECK(p.addBlockToReconcile(pindex)); | ||||
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); | ||||
resp = {AvalancheTest::getRound(p), 0, {AvalancheVote(1, blockHash)}}; | resp = {AvalancheTest::getRound(p), 0, {Vote(1, blockHash)}}; | ||||
for (int i = 0; i < 6; i++) { | for (int i = 0; i < 6; i++) { | ||||
registerNewVote(next(resp)); | registerNewVote(next(resp)); | ||||
BOOST_CHECK(p.isAccepted(pindex)); | BOOST_CHECK(p.isAccepted(pindex)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
} | } | ||||
// Now the state will flip. | // Now the state will flip. | ||||
registerNewVote(next(resp)); | registerNewVote(next(resp)); | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(multi_block_register) { | ||||
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 == blockHashA); | BOOST_CHECK(invs[0].hash == blockHashA); | ||||
uint64_t round = AvalancheTest::getRound(p); | uint64_t round = AvalancheTest::getRound(p); | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK(p.registerVotes(avanodes[0]->GetId(), | BOOST_CHECK(p.registerVotes(avanodes[0]->GetId(), | ||||
{round, 0, {AvalancheVote(0, blockHashA)}}, | {round, 0, {Vote(0, blockHashA)}}, updates)); | ||||
updates)); | |||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
// Start voting on block B after one vote. | // Start voting on block B after one vote. | ||||
AvalancheResponse resp{ | Response resp{round + 1, 0, {Vote(0, blockHashB), Vote(0, blockHashA)}}; | ||||
round + 1, | |||||
0, | |||||
{AvalancheVote(0, blockHashB), AvalancheVote(0, blockHashA)}}; | |||||
BOOST_CHECK(p.addBlockToReconcile(pindexB)); | BOOST_CHECK(p.addBlockToReconcile(pindexB)); | ||||
invs = AvalancheTest::getInvsForNextPoll(p); | invs = AvalancheTest::getInvsForNextPoll(p); | ||||
BOOST_CHECK_EQUAL(invs.size(), 2); | BOOST_CHECK_EQUAL(invs.size(), 2); | ||||
// Ensure B comes before A because it has accumulated more PoW. | // Ensure B comes before A because it has accumulated more PoW. | ||||
BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | BOOST_CHECK_EQUAL(invs[0].type, MSG_BLOCK); | ||||
BOOST_CHECK(invs[0].hash == blockHashB); | BOOST_CHECK(invs[0].hash == blockHashB); | ||||
BOOST_CHECK_EQUAL(invs[1].type, MSG_BLOCK); | BOOST_CHECK_EQUAL(invs[1].type, MSG_BLOCK); | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(poll_and_response) { | ||||
// Trigger a poll on avanode. | // Trigger a poll on avanode. | ||||
uint64_t round = AvalancheTest::getRound(p); | uint64_t round = AvalancheTest::getRound(p); | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
// There is no more suitable peer available, so return nothing. | // There is no more suitable peer available, so return nothing. | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), NO_NODE); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), NO_NODE); | ||||
// Respond to the request. | // Respond to the request. | ||||
AvalancheResponse resp = {round, 0, {AvalancheVote(0, blockHash)}}; | Response resp = {round, 0, {Vote(0, blockHash)}}; | ||||
BOOST_CHECK(p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
// Now that avanode fullfilled his request, it is added back to the list of | // Now that avanode fullfilled his request, it is added back to the list of | ||||
// queriable nodes. | // queriable nodes. | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | ||||
// Sending a response when not polled fails. | // Sending a response when not polled fails. | ||||
BOOST_CHECK(!p.registerVotes(avanodeid, next(resp), updates)); | BOOST_CHECK(!p.registerVotes(avanodeid, next(resp), updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
// Trigger a poll on avanode. | // Trigger a poll on avanode. | ||||
round = AvalancheTest::getRound(p); | round = AvalancheTest::getRound(p); | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), NO_NODE); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), NO_NODE); | ||||
// Sending responses that do not match the request also fails. | // Sending responses that do not match the request also fails. | ||||
// 1. Too many results. | // 1. Too many results. | ||||
resp = { | resp = {round, 0, {Vote(0, blockHash), Vote(0, blockHash)}}; | ||||
round, 0, {AvalancheVote(0, blockHash), AvalancheVote(0, blockHash)}}; | |||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | ||||
// 2. Not enough results. | // 2. Not enough results. | ||||
resp = {AvalancheTest::getRound(p), 0, {}}; | resp = {AvalancheTest::getRound(p), 0, {}}; | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | ||||
// 3. Do not match the poll. | // 3. Do not match the poll. | ||||
resp = {AvalancheTest::getRound(p), 0, {AvalancheVote()}}; | resp = {AvalancheTest::getRound(p), 0, {Vote()}}; | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | ||||
// 4. Invalid round count. Request is not discarded. | // 4. Invalid round count. Request is not discarded. | ||||
uint64_t queryRound = AvalancheTest::getRound(p); | uint64_t queryRound = AvalancheTest::getRound(p); | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
resp = {queryRound + 1, 0, {AvalancheVote()}}; | resp = {queryRound + 1, 0, {Vote()}}; | ||||
BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
resp = {queryRound - 1, 0, {AvalancheVote()}}; | resp = {queryRound - 1, 0, {Vote()}}; | ||||
BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
// 5. Making request for invalid nodes do not work. Request is not | // 5. Making request for invalid nodes do not work. Request is not | ||||
// discarded. | // discarded. | ||||
resp = {queryRound, 0, {AvalancheVote(0, blockHash)}}; | resp = {queryRound, 0, {Vote(0, blockHash)}}; | ||||
BOOST_CHECK(!p.registerVotes(avanodeid + 1234, resp, updates)); | BOOST_CHECK(!p.registerVotes(avanodeid + 1234, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
// Proper response gets processed and avanode is available again. | // Proper response gets processed and avanode is available again. | ||||
resp = {queryRound, 0, {AvalancheVote(0, blockHash)}}; | resp = {queryRound, 0, {Vote(0, blockHash)}}; | ||||
BOOST_CHECK(p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | ||||
// Out of order response are rejected. | // Out of order response are rejected. | ||||
CBlock block2 = CreateAndProcessBlock({}, CScript()); | CBlock block2 = CreateAndProcessBlock({}, CScript()); | ||||
const BlockHash blockHash2 = block2.GetHash(); | const BlockHash blockHash2 = block2.GetHash(); | ||||
CBlockIndex *pindex2; | CBlockIndex *pindex2; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
pindex2 = LookupBlockIndex(blockHash2); | pindex2 = LookupBlockIndex(blockHash2); | ||||
} | } | ||||
BOOST_CHECK(p.addBlockToReconcile(pindex2)); | BOOST_CHECK(p.addBlockToReconcile(pindex2)); | ||||
resp = {AvalancheTest::getRound(p), | resp = {AvalancheTest::getRound(p), | ||||
0, | 0, | ||||
{AvalancheVote(0, blockHash), AvalancheVote(0, blockHash2)}}; | {Vote(0, blockHash), Vote(0, blockHash2)}}; | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(!p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | ||||
// But they are accepted in order. | // But they are accepted in order. | ||||
resp = {AvalancheTest::getRound(p), | resp = {AvalancheTest::getRound(p), | ||||
0, | 0, | ||||
{AvalancheVote(0, blockHash2), AvalancheVote(0, blockHash)}}; | {Vote(0, blockHash2), Vote(0, blockHash)}}; | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK(p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | ||||
// When a block is marked invalid, stop polling. | // When a block is marked invalid, stop polling. | ||||
pindex2->nStatus = pindex2->nStatus.withFailed(); | pindex2->nStatus = pindex2->nStatus.withFailed(); | ||||
resp = {AvalancheTest::getRound(p), 0, {AvalancheVote(0, blockHash)}}; | resp = {AvalancheTest::getRound(p), 0, {Vote(0, blockHash)}}; | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK(p.registerVotes(avanodeid, resp, updates)); | BOOST_CHECK(p.registerVotes(avanodeid, resp, updates)); | ||||
BOOST_CHECK_EQUAL(updates.size(), 0); | BOOST_CHECK_EQUAL(updates.size(), 0); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), avanodeid); | ||||
connman->ClearNodes(); | connman->ClearNodes(); | ||||
} | } | ||||
Show All 24 Lines | auto avanode = | ||||
ConnectNode(config, NODE_AVALANCHE, *peerLogic, connman.get()); | ConnectNode(config, NODE_AVALANCHE, *peerLogic, connman.get()); | ||||
NodeId avanodeid = avanode->GetId(); | NodeId avanodeid = avanode->GetId(); | ||||
BOOST_CHECK(p.addPeer(avanodeid, 100, CPubKey())); | BOOST_CHECK(p.addPeer(avanodeid, 100, CPubKey())); | ||||
// Expire requests after some time. | // Expire requests after some time. | ||||
auto queryTimeDuration = std::chrono::milliseconds(10); | auto queryTimeDuration = std::chrono::milliseconds(10); | ||||
p.setQueryTimeoutDuration(queryTimeDuration); | p.setQueryTimeoutDuration(queryTimeDuration); | ||||
for (int i = 0; i < 10; i++) { | for (int i = 0; i < 10; i++) { | ||||
AvalancheResponse resp = { | Response resp = {AvalancheTest::getRound(p), 0, {Vote(0, blockHash)}}; | ||||
AvalancheTest::getRound(p), 0, {AvalancheVote(0, blockHash)}}; | |||||
auto start = std::chrono::steady_clock::now(); | auto start = std::chrono::steady_clock::now(); | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
// We cannot guarantee that we'll wait for just 1ms, so we have to bail | // We cannot guarantee that we'll wait for just 1ms, so we have to bail | ||||
// if we aren't within the proper time range. | // if we aren't within the proper time range. | ||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); | std::this_thread::sleep_for(std::chrono::milliseconds(1)); | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(poll_inflight_count) { | ||||
BOOST_CHECK_EQUAL(invs.size(), 0); | BOOST_CHECK_EQUAL(invs.size(), 0); | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), suitablenodeid); | BOOST_CHECK_EQUAL(AvalancheTest::getSuitableNodeToQuery(p), suitablenodeid); | ||||
std::vector<BlockUpdate> updates; | std::vector<BlockUpdate> updates; | ||||
// Send one response, now we can poll again. | // Send one response, now we can poll again. | ||||
auto it = node_round_map.begin(); | auto it = node_round_map.begin(); | ||||
AvalancheResponse resp = {it->second, 0, {AvalancheVote(0, blockHash)}}; | Response resp = {it->second, 0, {Vote(0, blockHash)}}; | ||||
BOOST_CHECK(p.registerVotes(it->first, resp, updates)); | BOOST_CHECK(p.registerVotes(it->first, resp, updates)); | ||||
node_round_map.erase(it); | node_round_map.erase(it); | ||||
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); | ||||
Show All 25 Lines | BOOST_AUTO_TEST_CASE(quorum_diversity) { | ||||
// Querying for random block returns false. | // Querying for random block returns false. | ||||
BOOST_CHECK(!p.isAccepted(pindex)); | BOOST_CHECK(!p.isAccepted(pindex)); | ||||
// 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(pindex)); | BOOST_CHECK(p.addBlockToReconcile(pindex)); | ||||
// Do one valid round of voting. | // Do one valid round of voting. | ||||
uint64_t round = AvalancheTest::getRound(p); | uint64_t round = AvalancheTest::getRound(p); | ||||
AvalancheResponse resp{round, 0, {AvalancheVote(0, blockHash)}}; | Response resp{round, 0, {Vote(0, blockHash)}}; | ||||
// Check that all nodes can vote. | // Check that all nodes can vote. | ||||
for (size_t i = 0; i < avanodes.size(); i++) { | for (size_t i = 0; i < avanodes.size(); i++) { | ||||
AvalancheTest::runEventLoop(p); | AvalancheTest::runEventLoop(p); | ||||
BOOST_CHECK(p.registerVotes(avanodes[i]->GetId(), next(resp), updates)); | BOOST_CHECK(p.registerVotes(avanodes[i]->GetId(), next(resp), updates)); | ||||
} | } | ||||
// Generate a query for every single node. | // Generate a query for every single node. | ||||
Show All 17 Lines | for (auto &pair : node_round_map) { | ||||
uint64_t r = pair.second; | uint64_t r = pair.second; | ||||
if (nodeid == firstNodeId) { | if (nodeid == firstNodeId) { | ||||
// Node 0 is the only one which can vote at this stage. | // Node 0 is the only one which can vote at this stage. | ||||
round = r; | round = r; | ||||
continue; | continue; | ||||
} | } | ||||
BOOST_CHECK(p.registerVotes( | BOOST_CHECK( | ||||
nodeid, {r, 0, {AvalancheVote(0, blockHash)}}, updates)); | p.registerVotes(nodeid, {r, 0, {Vote(0, blockHash)}}, updates)); | ||||
BOOST_CHECK_EQUAL(p.getConfidence(pindex), confidence); | BOOST_CHECK_EQUAL(p.getConfidence(pindex), confidence); | ||||
} | } | ||||
BOOST_CHECK(p.registerVotes( | BOOST_CHECK(p.registerVotes(firstNodeId, {round, 0, {Vote(0, blockHash)}}, | ||||
firstNodeId, {round, 0, {AvalancheVote(0, blockHash)}}, updates)); | updates)); | ||||
BOOST_CHECK_EQUAL(p.getConfidence(pindex), confidence + 1); | BOOST_CHECK_EQUAL(p.getConfidence(pindex), confidence + 1); | ||||
connman->ClearNodes(); | connman->ClearNodes(); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(event_loop) { | BOOST_AUTO_TEST_CASE(event_loop) { | ||||
const Config &config = GetConfig(); | const Config &config = GetConfig(); | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(event_loop) { | ||||
BOOST_CHECK(AvalancheTest::getRound(p) > queryRound); | BOOST_CHECK(AvalancheTest::getRound(p) > queryRound); | ||||
// Respond and check the cooldown time is respected. | // Respond and check the cooldown time is respected. | ||||
uint64_t responseRound = AvalancheTest::getRound(p); | uint64_t responseRound = AvalancheTest::getRound(p); | ||||
auto queryTime = | auto queryTime = | ||||
std::chrono::steady_clock::now() + std::chrono::milliseconds(100); | std::chrono::steady_clock::now() + std::chrono::milliseconds(100); | ||||
std::vector<BlockUpdate> updates; | std::vector<BlockUpdate> updates; | ||||
p.registerVotes(nodeid, {queryRound, 100, {AvalancheVote(0, blockHash)}}, | p.registerVotes(nodeid, {queryRound, 100, {Vote(0, blockHash)}}, updates); | ||||
updates); | |||||
for (int i = 0; i < 10000; i++) { | for (int i = 0; i < 10000; i++) { | ||||
// We make sure that we do not get a request before queryTime. | // We make sure that we do not get a request before queryTime. | ||||
UninterruptibleSleep(std::chrono::milliseconds(1)); | UninterruptibleSleep(std::chrono::milliseconds(1)); | ||||
if (AvalancheTest::getRound(p) != responseRound) { | if (AvalancheTest::getRound(p) != responseRound) { | ||||
BOOST_CHECK(std::chrono::steady_clock::now() > queryTime); | BOOST_CHECK(std::chrono::steady_clock::now() > queryTime); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 42 Lines • Show Last 20 Lines |