Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/test/proofpool_tests.cpp
// Copyright (c) 2021 The Bitcoin developers | // Copyright (c) 2021 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <avalanche/proofpool.h> | #include <avalanche/proofpool.h> | ||||
#include <avalanche/peermanager.h> | #include <avalanche/peermanager.h> | ||||
#include <key.h> | #include <key.h> | ||||
#include <primitives/transaction.h> | #include <primitives/transaction.h> | ||||
#include <primitives/txid.h> | #include <primitives/txid.h> | ||||
#include <random.h> | #include <random.h> | ||||
#include <util/time.h> | |||||
#include <avalanche/test/util.h> | #include <avalanche/test/util.h> | ||||
#include <test/util/setup_common.h> | #include <test/util/setup_common.h> | ||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
using namespace avalanche; | using namespace avalanche; | ||||
▲ Show 20 Lines • Show All 253 Lines • ▼ Show 20 Lines | for (size_t i = 0; i < 10; i++) { | ||||
ProofPool::AddProofStatus::SUCCEED); | ProofPool::AddProofStatus::SUCCEED); | ||||
auto retrievedProof = testPool.getProof(proof->getId()); | auto retrievedProof = testPool.getProof(proof->getId()); | ||||
BOOST_CHECK_NE(retrievedProof, nullptr); | BOOST_CHECK_NE(retrievedProof, nullptr); | ||||
BOOST_CHECK_EQUAL(retrievedProof->getId(), proof->getId()); | BOOST_CHECK_EQUAL(retrievedProof->getId(), proof->getId()); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(get_registration_time) { | |||||
ProofPool testPool; | |||||
// If not registered, the time is set to an unrealistic value | |||||
for (size_t i = 0; i < 10; i++) { | |||||
// FIXME Use BOOST_CHECK_EQUAL after C++20, which implements operator<< | |||||
// for std::chrono::duration. | |||||
BOOST_CHECK(testPool.getRegistrationTime(ProofId(GetRandHash())) == | |||||
std::chrono::seconds::max()); | |||||
} | |||||
SetMockTime(100); | |||||
std::vector<ProofRef> proofs100; | |||||
for (size_t i = 0; i < 10; i++) { | |||||
auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfNoConflict(proof), | |||||
ProofPool::AddProofStatus::SUCCEED); | |||||
proofs100.push_back(std::move(proof)); | |||||
} | |||||
SetMockTime(200); | |||||
std::vector<ProofRef> proofs200; | |||||
for (size_t i = 0; i < 10; i++) { | |||||
auto proof = buildRandomProof(MIN_VALID_PROOF_SCORE); | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfNoConflict(proof), | |||||
ProofPool::AddProofStatus::SUCCEED); | |||||
proofs200.push_back(std::move(proof)); | |||||
} | |||||
SetMockTime(300); | |||||
for (const auto &proof : proofs100) { | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof->getId()) == | |||||
std::chrono::seconds{100}); | |||||
// Attempting to register again (duplicated) does not update the time | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfNoConflict(proof), | |||||
ProofPool::AddProofStatus::DUPLICATED); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof->getId()) == | |||||
std::chrono::seconds{100}); | |||||
} | |||||
for (const auto &proof : proofs200) { | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof->getId()) == | |||||
std::chrono::seconds{200}); | |||||
// Attempting to register again (duplicated) does not update the time | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfNoConflict(proof), | |||||
ProofPool::AddProofStatus::DUPLICATED); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof->getId()) == | |||||
std::chrono::seconds{200}); | |||||
} | |||||
const CKey key = CKey::MakeCompressedKey(); | |||||
const COutPoint conflictingOutpoint{TxId(GetRandHash()), 0}; | |||||
auto buildProofWithSequence = [&](uint64_t sequence) { | |||||
ProofBuilder pb(sequence, 0, key); | |||||
BOOST_CHECK( | |||||
pb.addUTXO(conflictingOutpoint, 10 * COIN, 123456, false, key)); | |||||
return pb.build(); | |||||
}; | |||||
SetMockTime(400); | |||||
auto proof400 = buildProofWithSequence(10); | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfNoConflict(proof400), | |||||
ProofPool::AddProofStatus::SUCCEED); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof400->getId()) == | |||||
std::chrono::seconds{400}); | |||||
// Build a conflicting proof and check the registration time is updated as | |||||
// needed | |||||
SetMockTime(500); | |||||
auto proof500 = buildProofWithSequence(20); | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfNoConflict(proof500), | |||||
ProofPool::AddProofStatus::REJECTED); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof400->getId()) == | |||||
std::chrono::seconds{400}); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof500->getId()) == | |||||
std::chrono::seconds::max()); | |||||
BOOST_CHECK_EQUAL(testPool.addProofIfPreferred(proof500), | |||||
ProofPool::AddProofStatus::SUCCEED); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof400->getId()) == | |||||
std::chrono::seconds::max()); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof500->getId()) == | |||||
std::chrono::seconds{500}); | |||||
SetMockTime(600); | |||||
avalanche::PeerManager pm; | |||||
testPool.rescan(pm); | |||||
BOOST_CHECK(!testPool.getProof(proof500->getId())); | |||||
BOOST_CHECK(testPool.getRegistrationTime(proof500->getId()) == | |||||
std::chrono::seconds::max()); | |||||
} | |||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |