Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/test/proofpool_tests.cpp
Show First 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | BOOST_CHECK_EQUAL_COLLECTIONS( | ||||
conflictingProofs.begin(), conflictingProofs.end(), | conflictingProofs.begin(), conflictingProofs.end(), | ||||
expectedConflictingProofs.begin(), expectedConflictingProofs.end()); | expectedConflictingProofs.begin(), expectedConflictingProofs.end()); | ||||
BOOST_CHECK(testPool.getProof(proof_seq123->getId())); | BOOST_CHECK(testPool.getProof(proof_seq123->getId())); | ||||
BOOST_CHECK(!testPool.getProof(proof_seq10->getId())); | BOOST_CHECK(!testPool.getProof(proof_seq10->getId())); | ||||
BOOST_CHECK(!testPool.getProof(proof_seq20->getId())); | BOOST_CHECK(!testPool.getProof(proof_seq20->getId())); | ||||
BOOST_CHECK(!testPool.getProof(proof_seq30->getId())); | BOOST_CHECK(!testPool.getProof(proof_seq30->getId())); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(proof_override_cooldown) { | |||||
ProofPool testPool; | |||||
const CKey key = CKey::MakeCompressedKey(); | |||||
auto buildProofWithSequenceAndOutpoints = | |||||
[&](uint64_t sequence, const std::vector<COutPoint> &outpoints) { | |||||
ProofBuilder pb(sequence, 0, key); | |||||
for (const COutPoint &outpoint : outpoints) { | |||||
BOOST_CHECK( | |||||
pb.addUTXO(outpoint, 10 * COIN, 123456, false, key)); | |||||
} | |||||
return pb.build(); | |||||
}; | |||||
auto buildAndRegister = [&](uint64_t sequence, | |||||
const std::vector<COutPoint> &outpoints, | |||||
std::chrono::seconds registrationTime) { | |||||
auto proof = buildProofWithSequenceAndOutpoints(sequence, outpoints); | |||||
SetMockTime(registrationTime.count()); | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfPreferred(proof), | |||||
ProofPool::AddProofStatus::SUCCEED); | |||||
BOOST_CHECK(testPool.getProof(proof->getId())); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof->getId()) == | |||||
registrationTime); | |||||
return proof; | |||||
}; | |||||
const COutPoint outpoint1{TxId(GetRandHash()), 0}; | |||||
const COutPoint outpoint2{TxId(GetRandHash()), 0}; | |||||
const COutPoint outpoint3{TxId(GetRandHash()), 0}; | |||||
// Build and register 3 proofs with a single utxo each, and a different | |||||
// registration time. | |||||
auto proof1 = buildAndRegister(10, {outpoint1}, std::chrono::seconds{100}); | |||||
auto proof2 = buildAndRegister(20, {outpoint2}, std::chrono::seconds{200}); | |||||
auto proof3 = buildAndRegister(30, {outpoint3}, std::chrono::seconds{300}); | |||||
// Build a proof that conflicts with the above 3, but has a higher sequence | |||||
auto proof4 = buildProofWithSequenceAndOutpoints( | |||||
400, {outpoint1, outpoint2, outpoint3}); | |||||
ProofPool::ConflictingProofSet expectedConflictingProofs{proof1, proof2, | |||||
proof3}; | |||||
SetMockTime(400); | |||||
auto checkRejected = [&](std::chrono::seconds cooldown) { | |||||
ProofPool::ConflictingProofSet conflictingProofs; | |||||
BOOST_CHECK_EQUAL( | |||||
testPool.addProofIfPreferred(proof4, conflictingProofs, cooldown), | |||||
ProofPool::AddProofStatus::REJECTED); | |||||
BOOST_CHECK_EQUAL_COLLECTIONS( | |||||
conflictingProofs.begin(), conflictingProofs.end(), | |||||
expectedConflictingProofs.begin(), expectedConflictingProofs.end()); | |||||
BOOST_CHECK(!testPool.getProof(proof4->getId())); | |||||
BOOST_CHECK(testPool.getProof(proof1->getId())); | |||||
BOOST_CHECK(testPool.getProof(proof2->getId())); | |||||
BOOST_CHECK(testPool.getProof(proof3->getId())); | |||||
}; | |||||
// Cooldown is not enough for any conflicting proof | |||||
checkRejected(std::chrono::seconds{400}); | |||||
// Cooldown is not enough for proof2 and proof3 | |||||
checkRejected(std::chrono::seconds{300}); | |||||
// Cooldown is not enough for proof3 | |||||
checkRejected(std::chrono::seconds{200}); | |||||
// Cooldown is not enough for proof3 | |||||
checkRejected(std::chrono::seconds{101}); | |||||
// Cooldown has elaped for each conflicting proof | |||||
ProofPool::ConflictingProofSet conflictingProofs; | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfPreferred(proof4, conflictingProofs, | |||||
std::chrono::seconds{100}), | |||||
ProofPool::AddProofStatus::SUCCEED); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof4->getId()) == | |||||
std::chrono::seconds{400}); | |||||
BOOST_CHECK_EQUAL_COLLECTIONS( | |||||
conflictingProofs.begin(), conflictingProofs.end(), | |||||
expectedConflictingProofs.begin(), expectedConflictingProofs.end()); | |||||
BOOST_CHECK(testPool.getProof(proof4->getId())); | |||||
BOOST_CHECK(!testPool.getProof(proof1->getId())); | |||||
BOOST_CHECK(!testPool.getProof(proof2->getId())); | |||||
BOOST_CHECK(!testPool.getProof(proof3->getId())); | |||||
// Cooldown is irrelevant if there is no conflict | |||||
conflictingProofs.clear(); | |||||
auto proofNoConflict = buildProofWithSequenceAndOutpoints( | |||||
0, {COutPoint{TxId(GetRandHash()), 0}}); | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfPreferred(proofNoConflict, | |||||
conflictingProofs, | |||||
std::chrono::seconds::max()), | |||||
ProofPool::AddProofStatus::SUCCEED); | |||||
BOOST_CHECK(conflictingProofs.empty()); | |||||
BOOST_CHECK(testPool.getProof(proofNoConflict->getId())); | |||||
} | |||||
BOOST_AUTO_TEST_CASE(get_proof) { | BOOST_AUTO_TEST_CASE(get_proof) { | ||||
ProofPool testPool; | ProofPool testPool; | ||||
for (size_t i = 0; i < 10; i++) { | for (size_t i = 0; i < 10; i++) { | ||||
BOOST_CHECK(!testPool.getProof(ProofId(GetRandHash()))); | BOOST_CHECK(!testPool.getProof(ProofId(GetRandHash()))); | ||||
} | } | ||||
for (size_t i = 0; i < 10; i++) { | for (size_t i = 0; i < 10; i++) { | ||||
▲ Show 20 Lines • Show All 99 Lines • Show Last 20 Lines |