diff --git a/src/avalanche/peermanager.cpp b/src/avalanche/peermanager.cpp --- a/src/avalanche/peermanager.cpp +++ b/src/avalanche/peermanager.cpp @@ -409,18 +409,19 @@ // Check proof pool consistency for (const auto &ss : p.proof->getStakes()) { - auto it = validProofPool.pool.find(ss.getStake().getUTXO()); + const COutPoint &outpoint = ss.getStake().getUTXO(); + auto proof = validProofPool.getProof(outpoint); - if (it == validProofPool.pool.end()) { + if (!proof) { // Missing utxo return false; } - if (it->proof != p.proof) { + if (proof != p.proof) { // Wrong proof return false; } - if (!peersUtxos.emplace(it->getUTXO()).second) { + if (!peersUtxos.emplace(outpoint).second) { // Duplicated utxo return false; } @@ -462,11 +463,10 @@ } } - // Check there is no dangling utxo - for (const auto &entry : validProofPool.pool) { - if (!peersUtxos.count(entry.getUTXO())) { - return false; - } + // We checked the utxo consistency for all our peers utxos already, so if + // the pool size differs from the expected one there are dangling utxos. + if (validProofPool.size() != peersUtxos.size()) { + return false; } return true; diff --git a/src/avalanche/proofpool.h b/src/avalanche/proofpool.h --- a/src/avalanche/proofpool.h +++ b/src/avalanche/proofpool.h @@ -47,7 +47,7 @@ /** * Map a proof to each utxo. A proof can be mapped with several utxos. */ -struct ProofPool { +class ProofPool { boost::multi_index_container< ProofPoolEntry, bmi::indexed_by< @@ -63,6 +63,7 @@ SaltedProofIdHasher>>> pool; +public: enum AddProofStatus { REJECTED = 0, //!< Rejected due to conflicts SUCCEED = 1, //!< Added successfully @@ -75,6 +76,9 @@ void rescan(PeerManager &peerManager); ProofRef getProof(const ProofId &proofid) const; + ProofRef getProof(const COutPoint &outpoint) const; + + size_t size() const { return pool.size(); } }; } // namespace avalanche diff --git a/src/avalanche/proofpool.cpp b/src/avalanche/proofpool.cpp --- a/src/avalanche/proofpool.cpp +++ b/src/avalanche/proofpool.cpp @@ -70,4 +70,9 @@ return it == poolView.end() ? nullptr : it->proof; } +ProofRef ProofPool::getProof(const COutPoint &outpoint) const { + auto it = pool.find(outpoint); + return it == pool.end() ? nullptr : it->proof; +} + } // namespace avalanche diff --git a/src/avalanche/test/proofpool_tests.cpp b/src/avalanche/test/proofpool_tests.cpp --- a/src/avalanche/test/proofpool_tests.cpp +++ b/src/avalanche/test/proofpool_tests.cpp @@ -65,7 +65,7 @@ for (auto proof : proofs) { BOOST_CHECK(testPool.removeProof(proof)); } - BOOST_CHECK(testPool.pool.empty()); + BOOST_CHECK_EQUAL(testPool.size(), 0); } BOOST_AUTO_TEST_CASE(rescan) { @@ -73,7 +73,7 @@ avalanche::PeerManager pm; testPool.rescan(pm); - BOOST_CHECK(testPool.pool.empty()); + BOOST_CHECK_EQUAL(testPool.size(), 0); // No peer should be created bool hasPeer = false; @@ -95,7 +95,7 @@ pm.forEachPeer([&](const Peer &p) { pmProofs.insert(p.proof); }); BOOST_CHECK_EQUAL_COLLECTIONS(poolProofs.begin(), poolProofs.end(), pmProofs.begin(), pmProofs.end()); - BOOST_CHECK(testPool.pool.empty()); + BOOST_CHECK_EQUAL(testPool.size(), 0); } BOOST_AUTO_TEST_CASE(get_proof) {