Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/test/peermanager_tests.cpp
Show First 20 Lines • Show All 284 Lines • ▼ Show 20 Lines | static void addNodeWithScore(avalanche::PeerManager &pm, NodeId node, | ||||
uint32_t score) { | uint32_t score) { | ||||
auto proof = buildRandomProof(score); | auto proof = buildRandomProof(score); | ||||
BOOST_CHECK(pm.registerProof(proof)); | BOOST_CHECK(pm.registerProof(proof)); | ||||
BOOST_CHECK(pm.addNode(node, proof->getId())); | BOOST_CHECK(pm.addNode(node, proof->getId())); | ||||
}; | }; | ||||
BOOST_AUTO_TEST_CASE(peer_probabilities) { | BOOST_AUTO_TEST_CASE(peer_probabilities) { | ||||
// No peers. | // No peers. | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
BOOST_CHECK_EQUAL(pm.selectNode(), NO_NODE); | BOOST_CHECK_EQUAL(pm.selectNode(), NO_NODE); | ||||
const NodeId node0 = 42, node1 = 69, node2 = 37; | const NodeId node0 = 42, node1 = 69, node2 = 37; | ||||
// One peer, we always return it. | // One peer, we always return it. | ||||
addNodeWithScore(pm, node0, MIN_VALID_PROOF_SCORE); | addNodeWithScore(pm, node0, MIN_VALID_PROOF_SCORE); | ||||
BOOST_CHECK_EQUAL(pm.selectNode(), node0); | BOOST_CHECK_EQUAL(pm.selectNode(), node0); | ||||
Show All 19 Lines | for (int i = 0; i < 10000; i++) { | ||||
results[n]++; | results[n]++; | ||||
} | } | ||||
BOOST_CHECK(abs(results[0] - results[1] + results[2]) < 500); | BOOST_CHECK(abs(results[0] - results[1] + results[2]) < 500); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(remove_peer) { | BOOST_AUTO_TEST_CASE(remove_peer) { | ||||
// No peers. | // No peers. | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
BOOST_CHECK_EQUAL(pm.selectPeer(), NO_PEER); | BOOST_CHECK_EQUAL(pm.selectPeer(), NO_PEER); | ||||
// Add 4 peers. | // Add 4 peers. | ||||
std::array<PeerId, 8> peerids; | std::array<PeerId, 8> peerids; | ||||
for (int i = 0; i < 4; i++) { | for (int i = 0; i < 4; i++) { | ||||
auto p = buildRandomProof(100); | auto p = buildRandomProof(100); | ||||
peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p); | peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p); | ||||
BOOST_CHECK(pm.addNode(InsecureRand32(), p->getId())); | BOOST_CHECK(pm.addNode(InsecureRand32(), p->getId())); | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(remove_peer) { | ||||
// Removing non existent peers fails. | // Removing non existent peers fails. | ||||
BOOST_CHECK(!pm.removePeer(peerids[0])); | BOOST_CHECK(!pm.removePeer(peerids[0])); | ||||
BOOST_CHECK(!pm.removePeer(peerids[2])); | BOOST_CHECK(!pm.removePeer(peerids[2])); | ||||
BOOST_CHECK(!pm.removePeer(peerids[7])); | BOOST_CHECK(!pm.removePeer(peerids[7])); | ||||
BOOST_CHECK(!pm.removePeer(NO_PEER)); | BOOST_CHECK(!pm.removePeer(NO_PEER)); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(compact_slots) { | BOOST_AUTO_TEST_CASE(compact_slots) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
// Add 4 peers. | // Add 4 peers. | ||||
std::array<PeerId, 4> peerids; | std::array<PeerId, 4> peerids; | ||||
for (int i = 0; i < 4; i++) { | for (int i = 0; i < 4; i++) { | ||||
auto p = buildRandomProof(100); | auto p = buildRandomProof(100); | ||||
peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p); | peerids[i] = TestPeerManager::registerAndGetPeerId(pm, p); | ||||
BOOST_CHECK(pm.addNode(InsecureRand32(), p->getId())); | BOOST_CHECK(pm.addNode(InsecureRand32(), p->getId())); | ||||
} | } | ||||
Show All 12 Lines | BOOST_AUTO_TEST_CASE(compact_slots) { | ||||
BOOST_CHECK_EQUAL(pm.compact(), 300); | BOOST_CHECK_EQUAL(pm.compact(), 300); | ||||
BOOST_CHECK(pm.verify()); | BOOST_CHECK(pm.verify()); | ||||
BOOST_CHECK_EQUAL(pm.getSlotCount(), 0); | BOOST_CHECK_EQUAL(pm.getSlotCount(), 0); | ||||
BOOST_CHECK_EQUAL(pm.getFragmentation(), 0); | BOOST_CHECK_EQUAL(pm.getFragmentation(), 0); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(node_crud) { | BOOST_AUTO_TEST_CASE(node_crud) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
// Create one peer. | // Create one peer. | ||||
auto proof = buildRandomProof(10000000 * MIN_VALID_PROOF_SCORE); | auto proof = buildRandomProof(10000000 * MIN_VALID_PROOF_SCORE); | ||||
BOOST_CHECK(pm.registerProof(proof)); | BOOST_CHECK(pm.registerProof(proof)); | ||||
BOOST_CHECK_EQUAL(pm.selectNode(), NO_NODE); | BOOST_CHECK_EQUAL(pm.selectNode(), NO_NODE); | ||||
// Add 4 nodes. | // Add 4 nodes. | ||||
const ProofId &proofid = proof->getId(); | const ProofId &proofid = proof->getId(); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | for (int i = 0; i < 100; i++) { | ||||
BOOST_CHECK_EQUAL(n, 0); | BOOST_CHECK_EQUAL(n, 0); | ||||
} | } | ||||
BOOST_CHECK( | BOOST_CHECK( | ||||
pm.updateNextRequestTime(n, std::chrono::steady_clock::now())); | pm.updateNextRequestTime(n, std::chrono::steady_clock::now())); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(node_binding) { | BOOST_AUTO_TEST_CASE(node_binding) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | ||||
const ProofId &proofid = proof->getId(); | const ProofId &proofid = proof->getId(); | ||||
BOOST_CHECK_EQUAL(pm.getNodeCount(), 0); | BOOST_CHECK_EQUAL(pm.getNodeCount(), 0); | ||||
BOOST_CHECK_EQUAL(pm.getPendingNodeCount(), 0); | BOOST_CHECK_EQUAL(pm.getPendingNodeCount(), 0); | ||||
// Add a bunch of nodes with no associated peer | // Add a bunch of nodes with no associated peer | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | 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_EQUAL(pm.getNodeCount(), 0); | BOOST_CHECK_EQUAL(pm.getNodeCount(), 0); | ||||
BOOST_CHECK_EQUAL(pm.getPendingNodeCount(), 10 - i - 1); | BOOST_CHECK_EQUAL(pm.getPendingNodeCount(), 10 - i - 1); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(node_binding_reorg) { | BOOST_AUTO_TEST_CASE(node_binding_reorg) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
auto key = CKey::MakeCompressedKey(); | auto key = CKey::MakeCompressedKey(); | ||||
COutPoint utxo = createUtxo(key); | COutPoint utxo = createUtxo(key); | ||||
auto proof = buildProofWithOutpoints(key, {utxo}, 10 * COIN); | auto proof = buildProofWithOutpoints(key, {utxo}, 10 * COIN); | ||||
const ProofId &proofid = proof->getId(); | const ProofId &proofid = proof->getId(); | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(proof_conflict) { | ||||
const Amount v = 10 * COIN; | const Amount v = 10 * COIN; | ||||
const int height = 100; | const int height = 100; | ||||
for (uint32_t i = 0; i < 10; i++) { | for (uint32_t i = 0; i < 10; i++) { | ||||
addCoin({txid1, i}, key); | addCoin({txid1, i}, key); | ||||
addCoin({txid2, i}, key); | addCoin({txid2, i}, key); | ||||
} | } | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
CKey masterKey = CKey::MakeCompressedKey(); | CKey masterKey = CKey::MakeCompressedKey(); | ||||
const auto getPeerId = [&](const std::vector<COutPoint> &outpoints) { | const auto getPeerId = [&](const std::vector<COutPoint> &outpoints) { | ||||
return TestPeerManager::registerAndGetPeerId( | return TestPeerManager::registerAndGetPeerId( | ||||
pm, buildProofWithOutpoints(key, outpoints, v, masterKey, 0, height, | pm, buildProofWithOutpoints(key, outpoints, v, masterKey, 0, height, | ||||
false, 0)); | false, 0)); | ||||
}; | }; | ||||
// Add one peer. | // Add one peer. | ||||
Show All 37 Lines | BOOST_AUTO_TEST_CASE(proof_conflict) { | ||||
// Mutliple inputs, collision on both inputs. | // Mutliple inputs, collision on both inputs. | ||||
BOOST_CHECK_EQUAL(getPeerId({COutPoint(txid1, 0), COutPoint(txid2, 2)}), | BOOST_CHECK_EQUAL(getPeerId({COutPoint(txid1, 0), COutPoint(txid2, 2)}), | ||||
NO_PEER); | NO_PEER); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(orphan_proofs) { | BOOST_AUTO_TEST_CASE(orphan_proofs) { | ||||
gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); | gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
auto key = CKey::MakeCompressedKey(); | auto key = CKey::MakeCompressedKey(); | ||||
COutPoint outpoint1 = COutPoint(TxId(GetRandHash()), 0); | COutPoint outpoint1 = COutPoint(TxId(GetRandHash()), 0); | ||||
COutPoint outpoint2 = COutPoint(TxId(GetRandHash()), 0); | COutPoint outpoint2 = COutPoint(TxId(GetRandHash()), 0); | ||||
COutPoint outpoint3 = COutPoint(TxId(GetRandHash()), 0); | COutPoint outpoint3 = COutPoint(TxId(GetRandHash()), 0); | ||||
COutPoint outpoint4 = COutPoint(TxId(GetRandHash()), 0); | COutPoint outpoint4 = COutPoint(TxId(GetRandHash()), 0); | ||||
▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | for (auto &proof : orphans) { | ||||
checkOrphan(proof, true); | checkOrphan(proof, true); | ||||
numOrphans++; | numOrphans++; | ||||
} | } | ||||
} | } | ||||
BOOST_CHECK_EQUAL(numOrphans, AVALANCHE_MAX_ORPHAN_PROOFS); | BOOST_CHECK_EQUAL(numOrphans, AVALANCHE_MAX_ORPHAN_PROOFS); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(dangling_node) { | BOOST_AUTO_TEST_CASE(dangling_node) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | ||||
PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof); | PeerId peerid = TestPeerManager::registerAndGetPeerId(pm, proof); | ||||
BOOST_CHECK_NE(peerid, NO_PEER); | BOOST_CHECK_NE(peerid, NO_PEER); | ||||
const TimePoint theFuture(std::chrono::steady_clock::now() + | const TimePoint theFuture(std::chrono::steady_clock::now() + | ||||
std::chrono::hours(24)); | std::chrono::hours(24)); | ||||
Show All 28 Lines | BOOST_AUTO_TEST_CASE(dangling_node) { | ||||
// Disconnect the nodes | // Disconnect the nodes | ||||
for (int i = 0; i < 10; i++) { | for (int i = 0; i < 10; i++) { | ||||
BOOST_CHECK(pm.removeNode(i)); | BOOST_CHECK(pm.removeNode(i)); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(proof_accessors) { | BOOST_AUTO_TEST_CASE(proof_accessors) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
constexpr int numProofs = 10; | constexpr int numProofs = 10; | ||||
std::vector<ProofRef> proofs; | std::vector<ProofRef> proofs; | ||||
proofs.reserve(numProofs); | proofs.reserve(numProofs); | ||||
for (int i = 0; i < numProofs; i++) { | for (int i = 0; i < numProofs; i++) { | ||||
proofs.push_back(buildRandomProof(MIN_VALID_PROOF_SCORE)); | proofs.push_back(buildRandomProof(MIN_VALID_PROOF_SCORE)); | ||||
} | } | ||||
Show All 27 Lines | BOOST_AUTO_TEST_CASE(proof_accessors) { | ||||
BOOST_CHECK(Proof::FromHex(*badProof, badProofHex, error)); | BOOST_CHECK(Proof::FromHex(*badProof, badProofHex, error)); | ||||
ProofRegistrationState state; | ProofRegistrationState state; | ||||
BOOST_CHECK(!pm.registerProof(badProof, state)); | BOOST_CHECK(!pm.registerProof(badProof, state)); | ||||
BOOST_CHECK(state.GetResult() == ProofRegistrationResult::INVALID); | BOOST_CHECK(state.GetResult() == ProofRegistrationResult::INVALID); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(conflicting_proof_rescan, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(conflicting_proof_rescan, NoCoolDownFixture) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const CKey key = CKey::MakeCompressedKey(); | const CKey key = CKey::MakeCompressedKey(); | ||||
const COutPoint conflictingOutpoint = createUtxo(key); | const COutPoint conflictingOutpoint = createUtxo(key); | ||||
const COutPoint outpointToSend = createUtxo(key); | const COutPoint outpointToSend = createUtxo(key); | ||||
const Amount amount = 10 * COIN; | const Amount amount = 10 * COIN; | ||||
Show All 38 Lines | BOOST_FIXTURE_TEST_CASE(conflicting_proof_selection, NoCoolDownFixture) { | ||||
gArgs.ForceSetArg("-enableavalancheproofreplacement", "1"); | gArgs.ForceSetArg("-enableavalancheproofreplacement", "1"); | ||||
ConflictingProofComparator comparator; | ConflictingProofComparator comparator; | ||||
auto checkPreferred = [&](const ProofRef &candidate, | auto checkPreferred = [&](const ProofRef &candidate, | ||||
const ProofRef &reference, bool expectAccepted) { | const ProofRef &reference, bool expectAccepted) { | ||||
BOOST_CHECK_EQUAL(comparator(candidate, reference), expectAccepted); | BOOST_CHECK_EQUAL(comparator(candidate, reference), expectAccepted); | ||||
BOOST_CHECK_EQUAL(comparator(reference, candidate), !expectAccepted); | BOOST_CHECK_EQUAL(comparator(reference, candidate), !expectAccepted); | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
BOOST_CHECK(pm.registerProof(reference)); | BOOST_CHECK(pm.registerProof(reference)); | ||||
BOOST_CHECK(pm.isBoundToPeer(reference->getId())); | BOOST_CHECK(pm.isBoundToPeer(reference->getId())); | ||||
ProofRegistrationState state; | ProofRegistrationState state; | ||||
BOOST_CHECK_EQUAL(pm.registerProof(candidate, state), expectAccepted); | BOOST_CHECK_EQUAL(pm.registerProof(candidate, state), expectAccepted); | ||||
BOOST_CHECK_EQUAL(state.IsValid(), expectAccepted); | BOOST_CHECK_EQUAL(state.IsValid(), expectAccepted); | ||||
BOOST_CHECK_EQUAL(state.GetResult() == | BOOST_CHECK_EQUAL(state.GetResult() == | ||||
ProofRegistrationResult::CONFLICTING, | ProofRegistrationResult::CONFLICTING, | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | for (const CKey &k : {key, CKey::MakeCompressedKey()}) { | ||||
checkPreferred(proofSimilar, proof_multiUtxo, | checkPreferred(proofSimilar, proof_multiUtxo, | ||||
proofSimilar->getId() < proof_multiUtxo->getId()); | proofSimilar->getId() < proof_multiUtxo->getId()); | ||||
} | } | ||||
gArgs.ClearForcedArg("-enableavalancheproofreplacement"); | gArgs.ClearForcedArg("-enableavalancheproofreplacement"); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(conflicting_orphans) { | BOOST_AUTO_TEST_CASE(conflicting_orphans) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const CKey key = CKey::MakeCompressedKey(); | const CKey key = CKey::MakeCompressedKey(); | ||||
const COutPoint conflictingOutpoint(TxId(GetRandHash()), 0); | const COutPoint conflictingOutpoint(TxId(GetRandHash()), 0); | ||||
const COutPoint randomOutpoint1(TxId(GetRandHash()), 0); | const COutPoint randomOutpoint1(TxId(GetRandHash()), 0); | ||||
auto orphan10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | auto orphan10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | ||||
auto orphan20 = | auto orphan20 = | ||||
Show All 30 Lines | BOOST_AUTO_TEST_CASE(conflicting_orphans) { | ||||
pm.updatedBlockTip(); | pm.updatedBlockTip(); | ||||
BOOST_CHECK(!pm.isBoundToPeer(proof30->getId())); | BOOST_CHECK(!pm.isBoundToPeer(proof30->getId())); | ||||
BOOST_CHECK(pm.isOrphan(proof30->getId())); | BOOST_CHECK(pm.isOrphan(proof30->getId())); | ||||
BOOST_CHECK(!pm.exists(orphan20->getId())); | BOOST_CHECK(!pm.exists(orphan20->getId())); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(preferred_conflicting_proof, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(preferred_conflicting_proof, NoCoolDownFixture) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const CKey key = CKey::MakeCompressedKey(); | const CKey key = CKey::MakeCompressedKey(); | ||||
const COutPoint conflictingOutpoint = createUtxo(key); | const COutPoint conflictingOutpoint = createUtxo(key); | ||||
auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | ||||
auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | ||||
auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30); | auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30); | ||||
Show All 14 Lines | BOOST_FIXTURE_TEST_CASE(preferred_conflicting_proof, NoCoolDownFixture) { | ||||
BOOST_CHECK(!pm.registerProof(proofSeq20)); | BOOST_CHECK(!pm.registerProof(proofSeq20)); | ||||
BOOST_CHECK(pm.isBoundToPeer(proofSeq30->getId())); | BOOST_CHECK(pm.isBoundToPeer(proofSeq30->getId())); | ||||
BOOST_CHECK(!pm.isBoundToPeer(proofSeq20->getId())); | BOOST_CHECK(!pm.isBoundToPeer(proofSeq20->getId())); | ||||
BOOST_CHECK(pm.isInConflictingPool(proofSeq20->getId())); | BOOST_CHECK(pm.isInConflictingPool(proofSeq20->getId())); | ||||
BOOST_CHECK(!pm.exists(proofSeq10->getId())); | BOOST_CHECK(!pm.exists(proofSeq10->getId())); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(update_next_conflict_time, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(update_next_conflict_time, NoCoolDownFixture) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
auto now = GetTime<std::chrono::seconds>(); | auto now = GetTime<std::chrono::seconds>(); | ||||
SetMockTime(now.count()); | SetMockTime(now.count()); | ||||
// Updating the time of an unknown peer should fail | // Updating the time of an unknown peer should fail | ||||
for (size_t i = 0; i < 10; i++) { | for (size_t i = 0; i < 10; i++) { | ||||
BOOST_CHECK( | BOOST_CHECK( | ||||
!pm.updateNextPossibleConflictTime(PeerId(GetRandInt(1000)), now)); | !pm.updateNextPossibleConflictTime(PeerId(GetRandInt(1000)), now)); | ||||
Show All 16 Lines | BOOST_FIXTURE_TEST_CASE(update_next_conflict_time, NoCoolDownFixture) { | ||||
checkNextPossibleConflictTime(now); | checkNextPossibleConflictTime(now); | ||||
BOOST_CHECK(pm.updateNextPossibleConflictTime( | BOOST_CHECK(pm.updateNextPossibleConflictTime( | ||||
peerid, now + std::chrono::seconds{1})); | peerid, now + std::chrono::seconds{1})); | ||||
checkNextPossibleConflictTime(now + std::chrono::seconds{1}); | checkNextPossibleConflictTime(now + std::chrono::seconds{1}); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(register_force_accept, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(register_force_accept, NoCoolDownFixture) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const CKey key = CKey::MakeCompressedKey(); | const CKey key = CKey::MakeCompressedKey(); | ||||
const COutPoint conflictingOutpoint = createUtxo(key); | const COutPoint conflictingOutpoint = createUtxo(key); | ||||
auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | ||||
auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | ||||
auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30); | auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | for (size_t i = 0; i < 10; i++) { | ||||
pm.registerProof(proofSeq10, RegistrationMode::FORCE_ACCEPT)); | pm.registerProof(proofSeq10, RegistrationMode::FORCE_ACCEPT)); | ||||
BOOST_CHECK(pm.isBoundToPeer(proofSeq10->getId())); | BOOST_CHECK(pm.isBoundToPeer(proofSeq10->getId())); | ||||
BOOST_CHECK(pm.isInConflictingPool(proofSeq30->getId())); | BOOST_CHECK(pm.isInConflictingPool(proofSeq30->getId())); | ||||
} | } | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(evicted_proof, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(evicted_proof, NoCoolDownFixture) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const CKey key = CKey::MakeCompressedKey(); | const CKey key = CKey::MakeCompressedKey(); | ||||
const COutPoint conflictingOutpoint = createUtxo(key); | const COutPoint conflictingOutpoint = createUtxo(key); | ||||
auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | ||||
auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | ||||
auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30); | auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30); | ||||
Show All 13 Lines | BOOST_FIXTURE_TEST_CASE(evicted_proof, NoCoolDownFixture) { | ||||
{ | { | ||||
ProofRegistrationState state; | ProofRegistrationState state; | ||||
BOOST_CHECK(!pm.registerProof(proofSeq10, state)); | BOOST_CHECK(!pm.registerProof(proofSeq10, state)); | ||||
BOOST_CHECK(state.GetResult() == ProofRegistrationResult::REJECTED); | BOOST_CHECK(state.GetResult() == ProofRegistrationResult::REJECTED); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(conflicting_proof_cooldown) { | BOOST_AUTO_TEST_CASE(conflicting_proof_cooldown) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const CKey key = CKey::MakeCompressedKey(); | const CKey key = CKey::MakeCompressedKey(); | ||||
const COutPoint conflictingOutpoint = createUtxo(key); | const COutPoint conflictingOutpoint = createUtxo(key); | ||||
auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | ||||
auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30); | auto proofSeq30 = buildProofWithSequence(key, {conflictingOutpoint}, 30); | ||||
auto proofSeq40 = buildProofWithSequence(key, {conflictingOutpoint}, 40); | auto proofSeq40 = buildProofWithSequence(key, {conflictingOutpoint}, 40); | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(conflicting_proof_cooldown) { | ||||
checkRegistrationFailure(proofSeq40, ProofRegistrationResult::CONFLICTING); | checkRegistrationFailure(proofSeq40, ProofRegistrationResult::CONFLICTING); | ||||
BOOST_CHECK(pm.isInConflictingPool(proofSeq40->getId())); | BOOST_CHECK(pm.isInConflictingPool(proofSeq40->getId())); | ||||
BOOST_CHECK(!pm.exists(proofSeq20->getId())); | BOOST_CHECK(!pm.exists(proofSeq20->getId())); | ||||
gArgs.ClearForcedArg("-avalancheconflictingproofcooldown"); | gArgs.ClearForcedArg("-avalancheconflictingproofcooldown"); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(reject_proof, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(reject_proof, NoCoolDownFixture) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const CKey key = CKey::MakeCompressedKey(); | const CKey key = CKey::MakeCompressedKey(); | ||||
const COutPoint conflictingOutpoint = createUtxo(key); | const COutPoint conflictingOutpoint = createUtxo(key); | ||||
// The good, the bad and the ugly | // The good, the bad and the ugly | ||||
auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | auto proofSeq10 = buildProofWithSequence(key, {conflictingOutpoint}, 10); | ||||
auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | auto proofSeq20 = buildProofWithSequence(key, {conflictingOutpoint}, 20); | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(reject_proof, NoCoolDownFixture) { | ||||
checkRejectInvalidate(proofSeq10->getId()); | checkRejectInvalidate(proofSeq10->getId()); | ||||
// The conflicting proof should also be promoted to a peer | // The conflicting proof should also be promoted to a peer | ||||
BOOST_CHECK(!pm.isInConflictingPool(proofSeq20->getId())); | BOOST_CHECK(!pm.isInConflictingPool(proofSeq20->getId())); | ||||
BOOST_CHECK(pm.isBoundToPeer(proofSeq20->getId())); | BOOST_CHECK(pm.isBoundToPeer(proofSeq20->getId())); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(should_request_more_nodes) { | BOOST_AUTO_TEST_CASE(should_request_more_nodes) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | ||||
BOOST_CHECK(pm.registerProof(proof)); | BOOST_CHECK(pm.registerProof(proof)); | ||||
// We have no nodes, so select node will fail and flag that we need more | // We have no nodes, so select node will fail and flag that we need more | ||||
// nodes | // nodes | ||||
BOOST_CHECK_EQUAL(pm.selectNode(), NO_NODE); | BOOST_CHECK_EQUAL(pm.selectNode(), NO_NODE); | ||||
BOOST_CHECK(pm.shouldRequestMoreNodes()); | BOOST_CHECK(pm.shouldRequestMoreNodes()); | ||||
Show All 31 Lines | BOOST_AUTO_TEST_CASE(should_request_more_nodes) { | ||||
// Make it possible to request a node again | // Make it possible to request a node again | ||||
BOOST_CHECK(pm.updateNextRequestTime(0, std::chrono::steady_clock::now())); | BOOST_CHECK(pm.updateNextRequestTime(0, std::chrono::steady_clock::now())); | ||||
BOOST_CHECK_NE(pm.selectNode(), NO_NODE); | BOOST_CHECK_NE(pm.selectNode(), NO_NODE); | ||||
BOOST_CHECK(!pm.shouldRequestMoreNodes()); | BOOST_CHECK(!pm.shouldRequestMoreNodes()); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(score_ordering) { | BOOST_AUTO_TEST_CASE(score_ordering) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
std::vector<uint32_t> expectedScores(10); | std::vector<uint32_t> expectedScores(10); | ||||
// Expect the peers to be ordered by descending score | // Expect the peers to be ordered by descending score | ||||
std::generate(expectedScores.rbegin(), expectedScores.rend(), | std::generate(expectedScores.rbegin(), expectedScores.rend(), | ||||
[n = 1]() mutable { return n++ * MIN_VALID_PROOF_SCORE; }); | [n = 1]() mutable { return n++ * MIN_VALID_PROOF_SCORE; }); | ||||
std::vector<ProofRef> proofs; | std::vector<ProofRef> proofs; | ||||
proofs.reserve(expectedScores.size()); | proofs.reserve(expectedScores.size()); | ||||
Show All 9 Lines | BOOST_AUTO_TEST_CASE(score_ordering) { | ||||
auto peersScores = TestPeerManager::getOrderedScores(pm); | auto peersScores = TestPeerManager::getOrderedScores(pm); | ||||
BOOST_CHECK_EQUAL_COLLECTIONS(peersScores.begin(), peersScores.end(), | BOOST_CHECK_EQUAL_COLLECTIONS(peersScores.begin(), peersScores.end(), | ||||
expectedScores.begin(), expectedScores.end()); | expectedScores.begin(), expectedScores.end()); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(known_score_tracking, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(known_score_tracking, NoCoolDownFixture) { | ||||
gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); | gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const CKey key = CKey::MakeCompressedKey(); | const CKey key = CKey::MakeCompressedKey(); | ||||
const Amount amount10(10 * COIN); | const Amount amount10(10 * COIN); | ||||
const Amount amount20(20 * COIN); | const Amount amount20(20 * COIN); | ||||
const COutPoint peer1ConflictingOutput = createUtxo(key, amount10, 99); | const COutPoint peer1ConflictingOutput = createUtxo(key, amount10, 99); | ||||
const COutPoint peer1SecondaryOutpoint = createUtxo(key, amount20, 99); | const COutPoint peer1SecondaryOutpoint = createUtxo(key, amount20, 99); | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(known_score_tracking, NoCoolDownFixture) { | ||||
BOOST_CHECK_EQUAL(pm.getTotalPeersScore(), peer1Score2); | BOOST_CHECK_EQUAL(pm.getTotalPeersScore(), peer1Score2); | ||||
PeerId peerid1 = | PeerId peerid1 = | ||||
TestPeerManager::getPeerIdForProofId(pm, peer1Proof2->getId()); | TestPeerManager::getPeerIdForProofId(pm, peer1Proof2->getId()); | ||||
BOOST_CHECK(pm.removePeer(peerid1)); | BOOST_CHECK(pm.removePeer(peerid1)); | ||||
BOOST_CHECK_EQUAL(pm.getTotalPeersScore(), 0); | BOOST_CHECK_EQUAL(pm.getTotalPeersScore(), 0); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(connected_score_tracking) { | BOOST_AUTO_TEST_CASE(connected_score_tracking) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const auto checkScores = [&pm](uint32_t known, uint32_t connected) { | const auto checkScores = [&pm](uint32_t known, uint32_t connected) { | ||||
BOOST_CHECK_EQUAL(pm.getTotalPeersScore(), known); | BOOST_CHECK_EQUAL(pm.getTotalPeersScore(), known); | ||||
BOOST_CHECK_EQUAL(pm.getConnectedPeersScore(), connected); | BOOST_CHECK_EQUAL(pm.getConnectedPeersScore(), connected); | ||||
}; | }; | ||||
// Start out with 0s | // Start out with 0s | ||||
checkScores(0, 0); | checkScores(0, 0); | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(connected_score_tracking) { | ||||
BOOST_CHECK(pm.removePeer(peerid2)); | BOOST_CHECK(pm.removePeer(peerid2)); | ||||
checkScores(score1, score1); | checkScores(score1, score1); | ||||
BOOST_CHECK(pm.removePeer(peerid1)); | BOOST_CHECK(pm.removePeer(peerid1)); | ||||
checkScores(0, 0); | checkScores(0, 0); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(proof_radix_tree, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(proof_radix_tree, NoCoolDownFixture) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
gArgs.ForceSetArg("-enableavalancheproofreplacement", "1"); | gArgs.ForceSetArg("-enableavalancheproofreplacement", "1"); | ||||
struct ProofComparatorById { | struct ProofComparatorById { | ||||
bool operator()(const ProofRef &lhs, const ProofRef &rhs) const { | bool operator()(const ProofRef &lhs, const ProofRef &rhs) const { | ||||
return lhs->getId() < rhs->getId(); | return lhs->getId() < rhs->getId(); | ||||
}; | }; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(proof_radix_tree, NoCoolDownFixture) { | ||||
// Check for consistency | // Check for consistency | ||||
pm.verify(); | pm.verify(); | ||||
gArgs.ClearForcedArg("-enableavalancheproofreplacement"); | gArgs.ClearForcedArg("-enableavalancheproofreplacement"); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(received_avaproofs) { | BOOST_AUTO_TEST_CASE(received_avaproofs) { | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
auto addNode = [&](NodeId nodeid) { | auto addNode = [&](NodeId nodeid) { | ||||
auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | ||||
BOOST_CHECK(pm.registerProof(proof)); | BOOST_CHECK(pm.registerProof(proof)); | ||||
BOOST_CHECK(pm.addNode(nodeid, proof->getId())); | BOOST_CHECK(pm.addNode(nodeid, proof->getId())); | ||||
}; | }; | ||||
for (NodeId nodeid = 0; nodeid < 10; nodeid++) { | for (NodeId nodeid = 0; nodeid < 10; nodeid++) { | ||||
// Node doesn't exist | // Node doesn't exist | ||||
BOOST_CHECK(!pm.latchAvaproofsSent(nodeid)); | BOOST_CHECK(!pm.latchAvaproofsSent(nodeid)); | ||||
addNode(nodeid); | addNode(nodeid); | ||||
BOOST_CHECK(pm.latchAvaproofsSent(nodeid)); | BOOST_CHECK(pm.latchAvaproofsSent(nodeid)); | ||||
// The flag is already set | // The flag is already set | ||||
BOOST_CHECK(!pm.latchAvaproofsSent(nodeid)); | BOOST_CHECK(!pm.latchAvaproofsSent(nodeid)); | ||||
} | } | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(cleanup_dangling_proof, NoCoolDownFixture) { | BOOST_FIXTURE_TEST_CASE(cleanup_dangling_proof, NoCoolDownFixture) { | ||||
gArgs.ForceSetArg("-enableavalancheproofreplacement", "1"); | gArgs.ForceSetArg("-enableavalancheproofreplacement", "1"); | ||||
avalanche::PeerManager pm; | avalanche::PeerManager pm(*m_node.scheduler); | ||||
const auto now = GetTime<std::chrono::seconds>(); | const auto now = GetTime<std::chrono::seconds>(); | ||||
auto mocktime = now; | auto mocktime = now; | ||||
auto elapseTime = [&](std::chrono::seconds seconds) { | auto elapseTime = [&](std::chrono::seconds seconds) { | ||||
mocktime += seconds; | mocktime += seconds; | ||||
SetMockTime(mocktime.count()); | SetMockTime(mocktime.count()); | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 126 Lines • Show Last 20 Lines |