diff --git a/src/avalanche/peermanager.h b/src/avalanche/peermanager.h --- a/src/avalanche/peermanager.h +++ b/src/avalanche/peermanager.h @@ -337,7 +337,7 @@ /** * Update the peer set when a new block is connected. */ - void updatedBlockTip(); + std::unordered_set updatedBlockTip(); /** * Proof broadcast API. diff --git a/src/avalanche/peermanager.cpp b/src/avalanche/peermanager.cpp --- a/src/avalanche/peermanager.cpp +++ b/src/avalanche/peermanager.cpp @@ -445,7 +445,7 @@ return NO_NODE; } -void PeerManager::updatedBlockTip() { +std::unordered_set PeerManager::updatedBlockTip() { std::vector invalidProofIds; std::vector newOrphans; @@ -471,11 +471,13 @@ rejectProof(invalidProofId, RejectionMode::INVALIDATE); } - orphanProofPool.rescan(*this); + auto registeredProofs = orphanProofPool.rescan(*this); for (auto &p : newOrphans) { orphanProofPool.addProofIfPreferred(p); } + + return registeredProofs; } ProofRef PeerManager::getProof(const ProofId &proofid) const { diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -109,14 +109,21 @@ NotificationsHandler(Processor *p) : m_processor(p) {} void updatedBlockTip() override { - LOCK(m_processor->cs_peerManager); + auto registerProofs = [&]() { + LOCK(m_processor->cs_peerManager); - if (m_processor->peerData && m_processor->peerData->proof) { - m_processor->peerManager->registerProof( - m_processor->peerData->proof); - } + if (m_processor->peerData && m_processor->peerData->proof) { + m_processor->peerManager->registerProof( + m_processor->peerData->proof); + } - m_processor->peerManager->updatedBlockTip(); + return m_processor->peerManager->updatedBlockTip(); + }; + + auto registeredProofs = registerProofs(); + for (const auto &proof : registeredProofs) { + m_processor->addProofToReconcile(proof); + } } }; diff --git a/src/avalanche/proofpool.h b/src/avalanche/proofpool.h --- a/src/avalanche/proofpool.h +++ b/src/avalanche/proofpool.h @@ -109,7 +109,8 @@ bool removeProof(ProofId proofid); - void rescan(PeerManager &peerManager); + std::unordered_set + rescan(PeerManager &peerManager); ProofRef getProof(const ProofId &proofid) const; ProofRef getProof(const COutPoint &outpoint) const; diff --git a/src/avalanche/proofpool.cpp b/src/avalanche/proofpool.cpp --- a/src/avalanche/proofpool.cpp +++ b/src/avalanche/proofpool.cpp @@ -84,7 +84,8 @@ return poolView.erase(proofid); } -void ProofPool::rescan(PeerManager &peerManager) { +std::unordered_set +ProofPool::rescan(PeerManager &peerManager) { auto previousPool = std::move(pool); pool.clear(); cacheClean = false; @@ -95,6 +96,8 @@ peerManager.registerProof(entry.proof); } } + + return registeredProofs; } ProofRef ProofPool::getProof(const ProofId &proofid) const { diff --git a/test/functional/abc_p2p_avalanche_proof_voting.py b/test/functional/abc_p2p_avalanche_proof_voting.py --- a/test/functional/abc_p2p_avalanche_proof_voting.py +++ b/test/functional/abc_p2p_avalanche_proof_voting.py @@ -117,6 +117,7 @@ self.update_tests(node) self.vote_tests(node) self.stale_proof_tests(node) + self.unorphan_poll_tests(node) def poll_tests(self, node): proof_seq10 = self.build_conflicting_proof(node, 10) @@ -478,6 +479,31 @@ AvalancheVote(AvalancheProofVoteResponse.UNKNOWN, proofid_seq1), AvalancheVote(AvalancheProofVoteResponse.ACTIVE, proofid_seq2)]) + def unorphan_poll_tests(self, node): + # Restart the node with appropriate flags for this test + self.restart_node(0, extra_args=[ + '-enableavalanche=1', + '-enableavalancheproofreplacement=1', + '-avaproofstakeutxoconfirmations=2', + '-avalancheconflictingproofcooldown=0', + '-avacooldown=0', + ]) + + self.quorum = self.get_quorum(node) + peer = get_ava_p2p_interface(node) + + _, immature_proof = gen_proof(node) + + self.log.info("Orphan proofs are not polled") + + with node.assert_debug_log(["Not polling the avalanche proof (orphan-proof)"]): + peer.send_avaproof(immature_proof) + + self.log.info("Unorphaned proofs are polled") + + node.generate(1) + self.send_and_check_for_polling(peer, immature_proof.serialize().hex()) + if __name__ == '__main__': AvalancheProofVotingTest().main()