diff --git a/src/avalanche/processor.h b/src/avalanche/processor.h --- a/src/avalanche/processor.h +++ b/src/avalanche/processor.h @@ -261,6 +261,12 @@ class NotificationsHandler; std::unique_ptr chainNotificationsHandler; + /** + * Flag indicating that the proof must be registered at first new block + * after IBD + */ + bool mustRegisterProof = false; + public: Processor(interfaces::Chain &chain, CConnman *connmanIn, NodePeerManager *nodePeerManagerIn); diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include // For DecodeSecret #include // For ::PeerManager @@ -149,6 +150,13 @@ void updatedBlockTip() override { LOCK(m_processor->cs_peerManager); + + if (m_processor->mustRegisterProof && + !::ChainstateActive().IsInitialBlockDownload()) { + m_processor->peerManager->getPeerId(m_processor->peerData->proof); + m_processor->mustRegisterProof = false; + } + m_processor->peerManager->updatedBlockTip(); } }; @@ -174,13 +182,8 @@ SER_NETWORK, 0); stream >> peerData->proof; - // Ensure the peer manager knows about it. - // FIXME: There is no way to register the proof at this time because - // we might not have the proper chainstate at the moment. We need to - // find a way to delay the registration of the proof until after IBD - // has finished and the chain state is settled. - // LOCK(cs_peerManager); - // peerManager->getPeerId(peerData->proof); + // Schedule proof registration at the first new block after IBD. + mustRegisterProof = true; } // Generate the delegation to the session key. diff --git a/test/functional/abc_p2p_avalanche.py b/test/functional/abc_p2p_avalanche.py --- a/test/functional/abc_p2p_avalanche.py +++ b/test/functional/abc_p2p_avalanche.py @@ -373,15 +373,29 @@ wait_until(has_parked_new_tip, timeout=15) assert_equal(node.getbestblockhash(), fork_tip) - # Restart the node and rebuild the quorum + # Restart the node + minchainwork = int(node.getblockchaininfo()["chainwork"], 16) + 1 self.restart_node(0, self.extra_args[0] + [ "-avaproof={}".format(proof), "-avamasterkey=cND2ZvtabDbJ1gucx9GWH6XT9kgTAqfb6cotPt5Q5CyxVDhid2EN", + "-minimumchainwork=0x{:x}".format(minchainwork), ]) + self.log.info( + "The proof verification should be delayed until IBD is complete") + assert node.getblockchaininfo()["initialblockdownload"] is True + # Our proof cannot be verified during IBD, so we should have no peer + assert not node.getavalanchepeerinfo() + # Mining a few more blocks should cause us to leave IBD + node.generate(2) + # Our proof is now verified and our node is added as a peer + assert node.getblockchaininfo()["initialblockdownload"] is False + assert_equal(len(node.getavalanchepeerinfo()), 1) + + # Rebuild the quorum + self.log.info("Test the avahello signature") quorum = get_quorum() poll_node = quorum[0] - # Check the avahello is consistent avahello = poll_node.wait_for_avahello().hello avakey.set(bytes.fromhex(node.getavalanchekey()))