diff --git a/src/avalanche/peermanager.h b/src/avalanche/peermanager.h --- a/src/avalanche/peermanager.h +++ b/src/avalanche/peermanager.h @@ -182,6 +182,8 @@ std::vector getPeers() const; std::vector getNodeIdsForPeer(PeerId peerId) const; + std::shared_ptr getProof(const ProofId &proofid) const; + private: PeerSet::iterator fetchOrCreatePeer(const std::shared_ptr &proof); bool addNodeToPeer(const PeerSet::iterator &it); diff --git a/src/avalanche/peermanager.cpp b/src/avalanche/peermanager.cpp --- a/src/avalanche/peermanager.cpp +++ b/src/avalanche/peermanager.cpp @@ -185,6 +185,12 @@ return it == peers.end() ? NO_PEER : it->peerid; } +std::shared_ptr PeerManager::getProof(const ProofId &proofid) const { + auto &pview = peers.get(); + auto it = pview.find(proofid); + return it == pview.end() ? nullptr : it->proof; +} + PeerManager::PeerSet::iterator PeerManager::fetchOrCreatePeer(const std::shared_ptr &proof) { { diff --git a/src/avalanche/processor.h b/src/avalanche/processor.h --- a/src/avalanche/processor.h +++ b/src/avalanche/processor.h @@ -302,6 +302,9 @@ */ uint256 buildRemoteSighash(CNode *pfrom) const; + bool addProof(const std::shared_ptr &proof); + std::shared_ptr getProof(const ProofId &proofid) const; + /* * Return whether the avalanche service flag should be set. */ diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -502,6 +502,17 @@ return true; } +bool Processor::addProof(const std::shared_ptr &proof) { + LOCK(cs_peerManager); + return !peerManager->getProof(proof->getId()) && + peerManager->getPeerId(proof) != NO_PEER; +} + +std::shared_ptr Processor::getProof(const ProofId &proofid) const { + LOCK(cs_peerManager); + return peerManager->getProof(proofid); +} + bool Processor::startEventLoop(CScheduler &scheduler) { return eventLoop.startEventLoop( scheduler, [this]() { this->runEventLoop(); }, AVALANCHE_TIME_STEP); diff --git a/src/avalanche/test/processor_tests.cpp b/src/avalanche/test/processor_tests.cpp --- a/src/avalanche/test/processor_tests.cpp +++ b/src/avalanche/test/processor_tests.cpp @@ -971,4 +971,40 @@ schedulerThread.join(); } +BOOST_AUTO_TEST_CASE(proof_accessors) { + constexpr int numProofs = 10; + + std::vector> proofs; + proofs.reserve(numProofs); + for (int i = 0; i < numProofs; i++) { + proofs.push_back(GetProof()); + } + + for (int i = 0; i < numProofs; i++) { + BOOST_CHECK(m_processor->addProof(proofs[i])); + // Fail to add an existing proof + BOOST_CHECK(!m_processor->addProof(proofs[i])); + + for (int added = 0; added <= i; added++) { + auto proof = m_processor->getProof(proofs[added]->getId()); + BOOST_CHECK(proof != nullptr); + BOOST_CHECK_EQUAL(proof->getId(), proofs[added]->getId()); + } + + for (int missing = i + 1; missing < numProofs; missing++) { + BOOST_CHECK(!m_processor->getProof(proofs[missing]->getId())); + } + } + + // No stake, copied from proof_tests.cpp + const std::string badProofHex( + "96527eae083f1f24625f049d9e54bb9a2102a93d98bf42ab90cfc0bf9e7c634ed76a7" + "3e95b02cacfd357b64e4fb6c92e92dd00"); + bilingual_str error; + Proof badProof; + BOOST_CHECK(Proof::FromHex(badProof, badProofHex, error)); + BOOST_CHECK( + !m_processor->addProof(std::make_shared(std::move(badProof)))); +} + BOOST_AUTO_TEST_SUITE_END()