diff --git a/src/avalanche/peermanager.h b/src/avalanche/peermanager.h --- a/src/avalanche/peermanager.h +++ b/src/avalanche/peermanager.h @@ -260,7 +260,6 @@ bool isInConflictingPool(const ProofId &proofid) const; private: - bool createPeer(const ProofRef &proof); bool addOrUpdateNode(const PeerSet::iterator &it, NodeId nodeid); bool addNodeToPeer(const PeerSet::iterator &it); bool removeNodeFromPeer(const PeerSet::iterator &it, uint32_t count = 1); diff --git a/src/avalanche/peermanager.cpp b/src/avalanche/peermanager.cpp --- a/src/avalanche/peermanager.cpp +++ b/src/avalanche/peermanager.cpp @@ -148,6 +148,8 @@ } bool PeerManager::registerProof(const ProofRef &proof) { + assert(proof); + if (exists(proof->getId())) { // The proof is already registered, or orphaned. return false; @@ -168,7 +170,47 @@ return false; } - return createPeer(proof); + switch (validProofPool.addProofIfNoConflict(proof)) { + case ProofPool::AddProofStatus::REJECTED: + // The proof has conflicts, move it to the conflicting proof pool so + // it can be pulled back if the conflicting ones are invalidated. + conflictingProofPool.addProofIfPreferred(proof); + return false; + case ProofPool::AddProofStatus::DUPLICATED: + // If the proof was already in the pool, don't duplicate the peer. + return false; + case ProofPool::AddProofStatus::SUCCEED: + break; + + // No default case, so the compiler can warn about missing cases + } + + conflictingProofPool.removeProof(proof); + + // New peer means new peerid! + const PeerId peerid = nextPeerId++; + + // We have no peer for this proof, time to create it. + auto inserted = peers.emplace(peerid, proof); + assert(inserted.second); + + // If there are nodes waiting for this proof, add them + auto &pendingNodesView = pendingNodes.get<by_proofid>(); + auto range = pendingNodesView.equal_range(proof->getId()); + + // We want to update the nodes then remove them from the pending set. That + // will invalidate the range iterators, so we need to save the node ids + // first before we can loop over them. + std::vector<NodeId> nodeids; + nodeids.reserve(std::distance(range.first, range.second)); + std::transform(range.first, range.second, std::back_inserter(nodeids), + [](const PendingNode &n) { return n.nodeid; }); + + for (const NodeId &nodeid : nodeids) { + addOrUpdateNode(inserted.first, nodeid); + } + + return true; } NodeId PeerManager::selectNode() { @@ -276,52 +318,6 @@ return conflictingProofPool.getProof(proofid) != nullptr; } -bool PeerManager::createPeer(const ProofRef &proof) { - assert(proof); - - switch (validProofPool.addProofIfNoConflict(proof)) { - case ProofPool::AddProofStatus::REJECTED: - // The proof has conflicts, move it to the conflicting proof pool so - // it can be pulled back if the conflicting ones are invalidated. - conflictingProofPool.addProofIfPreferred(proof); - return false; - case ProofPool::AddProofStatus::DUPLICATED: - // If the proof was already in the pool, don't duplicate the peer. - return false; - case ProofPool::AddProofStatus::SUCCEED: - break; - - // No default case, so the compiler can warn about missing cases - } - - conflictingProofPool.removeProof(proof); - - // New peer means new peerid! - const PeerId peerid = nextPeerId++; - - // We have no peer for this proof, time to create it. - auto inserted = peers.emplace(peerid, proof); - assert(inserted.second); - - // If there are nodes waiting for this proof, add them - auto &pendingNodesView = pendingNodes.get<by_proofid>(); - auto range = pendingNodesView.equal_range(proof->getId()); - - // We want to update the nodes then remove them from the pending set. That - // will invalidate the range iterators, so we need to save the node ids - // first before we can loop over them. - std::vector<NodeId> nodeids; - nodeids.reserve(std::distance(range.first, range.second)); - std::transform(range.first, range.second, std::back_inserter(nodeids), - [](const PendingNode &n) { return n.nodeid; }); - - for (const NodeId &nodeid : nodeids) { - addOrUpdateNode(inserted.first, nodeid); - } - - return true; -} - bool PeerManager::removePeer(const PeerId peerid) { auto it = peers.find(peerid); if (it == peers.end()) { diff --git a/src/avalanche/proofpool.h b/src/avalanche/proofpool.h --- a/src/avalanche/proofpool.h +++ b/src/avalanche/proofpool.h @@ -83,6 +83,7 @@ ConflictingProofSet dummy; return addProofIfNoConflict(proof, dummy); } + /** * Attempt to add a proof to the pool. In case there is a conflict with one * or more UTXO, the proof is only added if it is the best candidate over