diff --git a/src/avalanche/peermanager.h b/src/avalanche/peermanager.h --- a/src/avalanche/peermanager.h +++ b/src/avalanche/peermanager.h @@ -129,13 +129,18 @@ * Peer API. */ PeerId addPeer(uint32_t score) { return addPeer(nextPeerId++, score); } + + // Provide the peer associated toa proof. If the peer does not exists, then + // it is created. + PeerId getPeer(const Proof &proof); + bool removePeer(const PeerId peerid); bool rescorePeer(const PeerId peerid, uint32_t score); /** * Node API. */ - bool addNodeToPeer(PeerId peerid, NodeId nodeid, CPubKey pubkey); + bool addNode(const Proof &proof, NodeId nodeid, const CPubKey &pubkey); bool removeNode(NodeId nodeid); bool forNode(NodeId nodeid, std::function func) const; diff --git a/src/avalanche/peermanager.cpp b/src/avalanche/peermanager.cpp --- a/src/avalanche/peermanager.cpp +++ b/src/avalanche/peermanager.cpp @@ -20,6 +20,25 @@ return p; } +PeerId PeerManager::getPeer(const Proof &proof) { + auto &pview = peers.get(); + auto it = pview.find(proof.getId()); + if (it != pview.end()) { + return it->peerid; + } + + // We have no peer for this proof, time to create it. + const PeerId peerid = nextPeerId++; + auto inserted = peers.emplace(peerid, uint32_t(slots.size()), proof); + assert(inserted.second); + + const uint32_t score = proof.getScore(); + const uint64_t start = slotCount; + slots.emplace_back(start, score, peerid); + slotCount = start + score; + return peerid; +} + bool PeerManager::removePeer(const PeerId peerid) { auto it = peers.find(peerid); if (it == peers.end()) { @@ -92,7 +111,10 @@ return true; } -bool PeerManager::addNodeToPeer(PeerId peerid, NodeId nodeid, CPubKey pubkey) { +bool PeerManager::addNode(const Proof &proof, NodeId nodeid, + const CPubKey &pubkey) { + const PeerId peerid = getPeer(proof); + auto pit = peers.find(peerid); if (pit == peers.end()) { return false; @@ -100,13 +122,13 @@ auto nit = nodes.find(nodeid); if (nit == nodes.end()) { - return nodes.emplace(nodeid, peerid, std::move(pubkey)).second; + return nodes.emplace(nodeid, peerid, pubkey).second; } // We actually have this node already, we need to update it. return nodes.modify(nit, [&](Node &n) { n.peerid = peerid; - n.pubkey = std::move(pubkey); + n.pubkey = pubkey; }); } diff --git a/src/avalanche/processor.h b/src/avalanche/processor.h --- a/src/avalanche/processor.h +++ b/src/avalanche/processor.h @@ -257,7 +257,7 @@ bool registerVotes(NodeId nodeid, const Response &response, std::vector &updates); - bool addPeer(NodeId nodeid, int64_t score, CPubKey pubkey); + bool addPeer(NodeId nodeid, int64_t score, const CPubKey &pubkey); bool forNode(NodeId nodeid, std::function func) const; CPubKey getSessionPubKey() const { return sessionKey.GetPubKey(); } diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -333,16 +333,9 @@ return true; } -bool Processor::addPeer(NodeId nodeid, int64_t score, CPubKey pubkey) { +bool Processor::addPeer(NodeId nodeid, int64_t score, const CPubKey &pubkey) { LOCK(cs_peerManager); - - PeerId p = peerManager->addPeer(score); - bool inserted = peerManager->addNodeToPeer(p, nodeid, std::move(pubkey)); - if (!inserted) { - peerManager->removePeer(p); - } - - return inserted; + return peerManager->addNode(Proof(score), nodeid, pubkey); } bool Processor::forNode(NodeId nodeid, diff --git a/src/avalanche/test/peermanager_tests.cpp b/src/avalanche/test/peermanager_tests.cpp --- a/src/avalanche/test/peermanager_tests.cpp +++ b/src/avalanche/test/peermanager_tests.cpp @@ -356,12 +356,13 @@ PeerManager pm; // Create one peer. - PeerId peerid = pm.addPeer(100); + Proof proof(100); + PeerId peerid = pm.getPeer(proof); BOOST_CHECK_EQUAL(pm.selectNode(), NO_NODE); // Add 4 nodes. for (int i = 0; i < 4; i++) { - BOOST_CHECK(pm.addNodeToPeer(peerid, i, CPubKey())); + BOOST_CHECK(pm.addNode(proof, i, CPubKey())); } for (int i = 0; i < 100; i++) { @@ -393,8 +394,9 @@ } // Move a node from a peer to another. - PeerId altpeer = pm.addPeer(0); - BOOST_CHECK(pm.addNodeToPeer(altpeer, 3, CPubKey())); + Proof altproof(0); + PeerId altpeer = pm.getPeer(altproof); + BOOST_CHECK(pm.addNode(altproof, 3, CPubKey())); for (int i = 0; i < 100; i++) { NodeId n = pm.selectNode(); 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 @@ -210,12 +210,12 @@ PeerLogicValidation &peerLogic, CConnmanTest *connman) { PeerManager &pm = AvalancheTest::getPeerManager(p); - PeerId pid = pm.addPeer(100); + Proof proof(100); std::array nodes; for (CNode *&n : nodes) { n = ConnectNode(config, nServices, peerLogic, connman); - BOOST_CHECK(pm.addNodeToPeer(pid, n->GetId(), CPubKey())); + BOOST_CHECK(pm.addNode(proof, n->GetId(), CPubKey())); } return nodes; @@ -725,12 +725,12 @@ // Create enough nodes so that we run into the inflight request limit. PeerManager &pm = AvalancheTest::getPeerManager(p); - PeerId pid = pm.addPeer(100); + Proof proof(100); std::array nodes; for (auto &n : nodes) { n = ConnectNode(config, NODE_AVALANCHE, *peerLogic, connman.get()); - BOOST_CHECK(pm.addNodeToPeer(pid, n->GetId(), CPubKey())); + BOOST_CHECK(pm.addNode(proof, n->GetId(), CPubKey())); } // Add a block to poll