Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/test/peermanager_tests.cpp
Show First 20 Lines • Show All 438 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(node_binding) { | ||||
for (int i = 0; i < 5; i++) { | for (int i = 0; i < 5; i++) { | ||||
BOOST_CHECK(pm.addNode(i, proofid)); | BOOST_CHECK(pm.addNode(i, proofid)); | ||||
BOOST_CHECK(!TestPeerManager::isNodePending(pm, i)); | BOOST_CHECK(!TestPeerManager::isNodePending(pm, i)); | ||||
BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid)); | BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid)); | ||||
} | } | ||||
// Remove the peer, the nodes should be pending again | // Remove the peer, the nodes should be pending again | ||||
BOOST_CHECK(pm.removePeer(peerid)); | BOOST_CHECK(pm.removePeer(peerid)); | ||||
BOOST_CHECK(!pm.getProof(proof->getId())); | BOOST_CHECK(!pm.exists(proof->getId())); | ||||
for (int i = 0; i < 10; i++) { | for (int i = 0; i < 10; i++) { | ||||
BOOST_CHECK(TestPeerManager::isNodePending(pm, i)); | BOOST_CHECK(TestPeerManager::isNodePending(pm, i)); | ||||
BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid)); | BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid)); | ||||
} | } | ||||
BOOST_CHECK(pm.verify()); | BOOST_CHECK(pm.verify()); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(node_binding_reorg) { | BOOST_AUTO_TEST_CASE(node_binding_reorg) { | ||||
Show All 30 Lines | BOOST_AUTO_TEST_CASE(node_binding_reorg) { | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | ||||
coins.SpendCoin(utxo); | coins.SpendCoin(utxo); | ||||
} | } | ||||
pm.updatedBlockTip(); | pm.updatedBlockTip(); | ||||
BOOST_CHECK(pm.isOrphan(proofid)); | BOOST_CHECK(pm.isOrphan(proofid)); | ||||
BOOST_CHECK(!pm.getProof(proofid)); | BOOST_CHECK(!pm.isValid(proofid)); | ||||
for (int i = 0; i < 10; i++) { | for (int i = 0; i < 10; i++) { | ||||
BOOST_CHECK(TestPeerManager::isNodePending(pm, i)); | BOOST_CHECK(TestPeerManager::isNodePending(pm, i)); | ||||
BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid)); | BOOST_CHECK(!TestPeerManager::nodeBelongToPeer(pm, i, peerid)); | ||||
} | } | ||||
BOOST_CHECK(pm.verify()); | BOOST_CHECK(pm.verify()); | ||||
// Make the proof great again | // Make the proof great again | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | ||||
coins.AddCoin(utxo, Coin(CTxOut(amount, script), height, false), false); | coins.AddCoin(utxo, Coin(CTxOut(amount, script), height, false), false); | ||||
} | } | ||||
pm.updatedBlockTip(); | pm.updatedBlockTip(); | ||||
BOOST_CHECK(!pm.isOrphan(proofid)); | BOOST_CHECK(!pm.isOrphan(proofid)); | ||||
BOOST_CHECK(pm.getProof(proofid)); | BOOST_CHECK(pm.isValid(proofid)); | ||||
// The peerid has certainly been updated | // The peerid has certainly been updated | ||||
peerid = pm.getPeerId(proof); | peerid = pm.getPeerId(proof); | ||||
BOOST_CHECK_NE(peerid, NO_PEER); | BOOST_CHECK_NE(peerid, NO_PEER); | ||||
for (int i = 0; i < 10; i++) { | for (int i = 0; i < 10; i++) { | ||||
BOOST_CHECK(!TestPeerManager::isNodePending(pm, i)); | BOOST_CHECK(!TestPeerManager::isNodePending(pm, i)); | ||||
BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid)); | BOOST_CHECK(TestPeerManager::nodeBelongToPeer(pm, i, peerid)); | ||||
} | } | ||||
BOOST_CHECK(pm.verify()); | BOOST_CHECK(pm.verify()); | ||||
▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | // Add outpoints 1 and 3, not 2 | ||||
coins.AddCoin(outpoint3, coin, false); | coins.AddCoin(outpoint3, coin, false); | ||||
} | } | ||||
// Add the proofs | // Add the proofs | ||||
BOOST_CHECK(pm.getPeerId(proof1) != NO_PEER); | BOOST_CHECK(pm.getPeerId(proof1) != NO_PEER); | ||||
BOOST_CHECK(pm.getPeerId(proof2) == NO_PEER); | BOOST_CHECK(pm.getPeerId(proof2) == NO_PEER); | ||||
BOOST_CHECK(pm.getPeerId(proof3) == NO_PEER); | BOOST_CHECK(pm.getPeerId(proof3) == NO_PEER); | ||||
// Good | auto checkOrphan = [&](const ProofRef &proof, bool expectedOrphan) { | ||||
BOOST_CHECK(!pm.isOrphan(proof1->getId())); | const ProofId &proofid = proof->getId(); | ||||
// MISSING_UTXO | BOOST_CHECK(pm.exists(proofid)); | ||||
BOOST_CHECK(pm.isOrphan(proof2->getId())); | |||||
// HEIGHT_MISMATCH | BOOST_CHECK_EQUAL(pm.isOrphan(proofid), expectedOrphan); | ||||
BOOST_CHECK(pm.isOrphan(proof3->getId())); | BOOST_CHECK_EQUAL(pm.isValid(proofid), !expectedOrphan); | ||||
const auto isGoodPeer = [&pm](const ProofRef &p) { | |||||
bool ret = false; | bool ret = false; | ||||
pm.forEachPeer([&](const Peer &peer) { | pm.forEachPeer([&](const Peer &peer) { | ||||
if (p->getId() == peer.proof->getId()) { | if (proof->getId() == peer.proof->getId()) { | ||||
ret = true; | ret = true; | ||||
} | } | ||||
}); | }); | ||||
return ret; | BOOST_CHECK_EQUAL(ret, !expectedOrphan); | ||||
}; | }; | ||||
BOOST_CHECK(isGoodPeer(proof1)); | // Good | ||||
BOOST_CHECK(!isGoodPeer(proof2)); | checkOrphan(proof1, false); | ||||
BOOST_CHECK(!isGoodPeer(proof3)); | // MISSING_UTXO | ||||
checkOrphan(proof2, true); | |||||
// HEIGHT_MISMATCH | |||||
checkOrphan(proof3, true); | |||||
// Add outpoint2, proof2 is no longer considered orphan | // Add outpoint2, proof2 is no longer considered orphan | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | ||||
coins.AddCoin(outpoint2, coin, false); | coins.AddCoin(outpoint2, coin, false); | ||||
} | } | ||||
pm.updatedBlockTip(); | pm.updatedBlockTip(); | ||||
BOOST_CHECK(!pm.isOrphan(proof2->getId())); | checkOrphan(proof2, false); | ||||
BOOST_CHECK(isGoodPeer(proof2)); | |||||
// The status of proof1 and proof3 are unchanged | // The status of proof1 and proof3 are unchanged | ||||
BOOST_CHECK(!pm.isOrphan(proof1->getId())); | checkOrphan(proof1, false); | ||||
BOOST_CHECK(isGoodPeer(proof1)); | checkOrphan(proof3, true); | ||||
BOOST_CHECK(pm.isOrphan(proof3->getId())); | |||||
BOOST_CHECK(!isGoodPeer(proof3)); | |||||
// Spend outpoint1, proof1 becomes orphan | // Spend outpoint1, proof1 becomes orphan | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | ||||
coins.SpendCoin(outpoint1); | coins.SpendCoin(outpoint1); | ||||
} | } | ||||
pm.updatedBlockTip(); | pm.updatedBlockTip(); | ||||
BOOST_CHECK(pm.isOrphan(proof1->getId())); | checkOrphan(proof1, true); | ||||
BOOST_CHECK(!isGoodPeer(proof1)); | |||||
// The status of proof2 and proof3 are unchanged | // The status of proof2 and proof3 are unchanged | ||||
BOOST_CHECK(!pm.isOrphan(proof2->getId())); | checkOrphan(proof2, false); | ||||
BOOST_CHECK(isGoodPeer(proof2)); | checkOrphan(proof3, true); | ||||
BOOST_CHECK(pm.isOrphan(proof3->getId())); | |||||
BOOST_CHECK(!isGoodPeer(proof3)); | |||||
// A reorg could make a previous HEIGHT_MISMATCH become valid | // A reorg could make a previous HEIGHT_MISMATCH become valid | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | ||||
coins.SpendCoin(outpoint3); | coins.SpendCoin(outpoint3); | ||||
coins.AddCoin(outpoint3, Coin(CTxOut(v, script), wrongHeight, false), | coins.AddCoin(outpoint3, Coin(CTxOut(v, script), wrongHeight, false), | ||||
false); | false); | ||||
} | } | ||||
pm.updatedBlockTip(); | pm.updatedBlockTip(); | ||||
BOOST_CHECK(!pm.isOrphan(proof3->getId())); | checkOrphan(proof3, false); | ||||
BOOST_CHECK(isGoodPeer(proof3)); | |||||
// The status of proof 1 and proof2 are unchanged | // The status of proof 1 and proof2 are unchanged | ||||
BOOST_CHECK(pm.isOrphan(proof1->getId())); | checkOrphan(proof1, true); | ||||
BOOST_CHECK(!isGoodPeer(proof1)); | checkOrphan(proof2, false); | ||||
BOOST_CHECK(!pm.isOrphan(proof2->getId())); | |||||
BOOST_CHECK(isGoodPeer(proof2)); | |||||
} | } | ||||
BOOST_AUTO_TEST_CASE(dangling_node) { | BOOST_AUTO_TEST_CASE(dangling_node) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm; | ||||
auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | ||||
PeerId peerid = pm.getPeerId(proof); | PeerId peerid = pm.getPeerId(proof); | ||||
BOOST_CHECK_NE(peerid, NO_PEER); | BOOST_CHECK_NE(peerid, NO_PEER); | ||||
▲ Show 20 Lines • Show All 76 Lines • Show Last 20 Lines |