diff --git a/src/avalanche/node.h b/src/avalanche/node.h --- a/src/avalanche/node.h +++ b/src/avalanche/node.h @@ -22,12 +22,10 @@ NodeId nodeid; PeerId peerid; TimePoint nextRequestTime; - CPubKey pubkey; - Node(NodeId nodeid_, PeerId peerid_, CPubKey pubkey_) + Node(NodeId nodeid_, PeerId peerid_) : nodeid(nodeid_), peerid(peerid_), - nextRequestTime(std::chrono::steady_clock::now()), - pubkey(std::move(pubkey_)) {} + nextRequestTime(std::chrono::steady_clock::now()) {} }; } // namespace avalanche diff --git a/src/avalanche/peermanager.h b/src/avalanche/peermanager.h --- a/src/avalanche/peermanager.h +++ b/src/avalanche/peermanager.h @@ -213,8 +213,7 @@ private: PeerSet::iterator fetchOrCreatePeer(const std::shared_ptr &proof); - bool addOrUpdateNode(const PeerSet::iterator &it, NodeId nodeid, - CPubKey pubkey); + 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 @@ -32,26 +32,22 @@ return false; } - return addOrUpdateNode(peers.project<0>(it), nodeid, std::move(pubkey)); + return addOrUpdateNode(peers.project<0>(it), nodeid); } -bool PeerManager::addOrUpdateNode(const PeerSet::iterator &it, NodeId nodeid, - CPubKey pubkey) { +bool PeerManager::addOrUpdateNode(const PeerSet::iterator &it, NodeId nodeid) { assert(it != peers.end()); const PeerId peerid = it->peerid; auto nit = nodes.find(nodeid); if (nit == nodes.end()) { - if (!nodes.emplace(nodeid, peerid, std::move(pubkey)).second) { + if (!nodes.emplace(nodeid, peerid).second) { return false; } } else { const PeerId oldpeerid = nit->peerid; - if (!nodes.modify(nit, [&](Node &n) { - n.peerid = peerid; - n.pubkey = std::move(pubkey); - })) { + if (!nodes.modify(nit, [&](Node &n) { n.peerid = peerid; })) { return false; } diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -1014,7 +1014,7 @@ struct AvalancheState { AvalancheState() {} - avalanche::Delegation delegation; + CPubKey pubkey; }; // m_avalanche_state == nullptr if we're not using avalanche with this peer diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4127,18 +4127,18 @@ } CHashVerifier verifier(&vRecv); - avalanche::Delegation &delegation = pfrom.m_avalanche_state->delegation; + avalanche::Delegation delegation; verifier >> delegation; avalanche::DelegationState state; - CPubKey pubkey; + CPubKey &pubkey = pfrom.m_avalanche_state->pubkey; if (!delegation.verify(state, pubkey)) { Misbehaving(pfrom, 100, "invalid-delegation"); return; } CHashWriter sighasher(SER_GETHASH, 0); - sighasher << pfrom.m_avalanche_state->delegation.getId(); + sighasher << delegation.getId(); sighasher << pfrom.nRemoteHostNonce; sighasher << pfrom.GetLocalNonce(); sighasher << pfrom.nRemoteExtraEntropy; @@ -4280,11 +4280,11 @@ avalanche::Response response; verifier >> response; - if (!g_avalanche->forNode(pfrom.GetId(), [&](const avalanche::Node &n) { - SchnorrSig sig; - vRecv >> sig; - return n.pubkey.VerifySchnorr(verifier.GetHash(), sig); - })) { + SchnorrSig sig; + vRecv >> sig; + if (!pfrom.m_avalanche_state || + !pfrom.m_avalanche_state->pubkey.VerifySchnorr(verifier.GetHash(), + sig)) { Misbehaving(pfrom, 100, "invalid-ava-response-signature"); return; } diff --git a/src/rpc/avalanche.cpp b/src/rpc/avalanche.cpp --- a/src/rpc/avalanche.cpp +++ b/src/rpc/avalanche.cpp @@ -80,7 +80,7 @@ } const NodeId nodeid = request.params[0].get_int64(); - const CPubKey key = ParsePubKey(request.params[1]); + CPubKey key = ParsePubKey(request.params[1]); auto proof = std::make_shared(); bilingual_str error; @@ -99,6 +99,21 @@ return false; } + NodeContext &node = EnsureNodeContext(request.context); + if (!node.connman->ForNode(nodeid, [&](CNode *pnode) { + // FIXME This is not thread safe, and might cause issues if the + // unlikely event the peer sends an avahello message at the same + // time. + if (!pnode->m_avalanche_state) { + pnode->m_avalanche_state = + std::make_unique(); + } + pnode->m_avalanche_state->pubkey = std::move(key); + return true; + })) { + return false; + } + if (!g_avalanche->addNode(nodeid, avalanche::DelegationBuilder(*proof).build())) { return false;