diff --git a/src/avalanche/peermanager.h b/src/avalanche/peermanager.h --- a/src/avalanche/peermanager.h +++ b/src/avalanche/peermanager.h @@ -296,6 +296,9 @@ bool isOrphan(const ProofId &proofid) const; private: + bool addToPool(ProofPool &pool, const ProofRef &proof); + bool removeFromPool(ProofPool &pool, const ProofRef &proof); + bool createPeer(const ProofRef &proof); bool addOrUpdateNode(const PeerSet::iterator &it, NodeId nodeid); 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 @@ -170,6 +170,14 @@ return false; } + if (!addToPool(validProofPool, proof)) { + // Orphan the proof so it can be pulled back if the conflicting ones are + // invalidated. + orphanProofs.addProof(proof); + + return false; + } + return createPeer(proof); } @@ -253,22 +261,11 @@ return orphanProofs.getProof(proofid) != nullptr; } -bool PeerManager::createPeer(const ProofRef &proof) { - assert(proof); - - const ProofId &proofid = proof->getId(); - - if (isValid(proofid)) { - return false; - } - - // New peer means new peerid! - const PeerId peerid = nextPeerId++; - +bool PeerManager::addToPool(ProofPool &pool, const ProofRef &proof) { // Attach UTXOs to this proof. std::unordered_set conflicting_proofs; for (const auto &s : proof->getStakes()) { - auto p = validProofPool.emplace(s.getStake().getUTXO(), proof); + auto p = pool.emplace(s.getStake().getUTXO(), proof); if (!p.second) { // We have a collision with an existing proof. conflicting_proofs.insert(p.first->proof); @@ -278,22 +275,36 @@ // For now, if there is a conflict, just cleanup the mess. if (conflicting_proofs.size() > 0) { for (const auto &s : proof->getStakes()) { - auto it = validProofPool.find(s.getStake().getUTXO()); - assert(it != validProofPool.end()); + auto it = pool.find(s.getStake().getUTXO()); + assert(it != pool.end()); // We need to delete that one. - if (it->proof->getId() == proofid) { - validProofPool.erase(it); + if (it->proof->getId() == proof->getId()) { + pool.erase(it); } } + } - // Orphan the proof so it can be pulled back if the conflicting ones are - // invalidated. - orphanProofs.addProof(proof); + return conflicting_proofs.size() == 0; +} + +bool PeerManager::removeFromPool(ProofPool &pool, const ProofRef &proof) { + auto &poolView = pool.get(); + return poolView.erase(proof->getId()); +} + +bool PeerManager::createPeer(const ProofRef &proof) { + assert(proof); + const ProofId &proofid = proof->getId(); + + if (isValid(proofid)) { return false; } + // 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); @@ -342,10 +353,7 @@ peerid, std::chrono::steady_clock::now()))); // Release UTXOs attached to this proof. - for (const auto &s : it->proof->getStakes()) { - bool deleted = validProofPool.erase(s.getStake().getUTXO()) > 0; - assert(deleted); - } + removeFromPool(validProofPool, it->proof); m_unbroadcast_proofids.erase(it->proof->getId());