diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -1018,7 +1018,9 @@ }; // m_avalanche_state == nullptr if we're not using avalanche with this peer - std::unique_ptr m_avalanche_state; + std::unique_ptr + m_avalanche_state GUARDED_BY(cs_avalanche_state); + Mutex cs_avalanche_state; // Used for headers announcements - unfiltered blocks to relay std::vector vBlockHashesToAnnounce GUARDED_BY(cs_inventory); diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4141,21 +4141,10 @@ } if (msg_type == NetMsgType::AVAHELLO) { - if (!pfrom.m_avalanche_state) { - pfrom.m_avalanche_state = std::make_unique(); - } - CHashVerifier verifier(&vRecv); avalanche::Delegation delegation; verifier >> delegation; - avalanche::DelegationState state; - CPubKey &pubkey = pfrom.m_avalanche_state->pubkey; - if (!delegation.verify(state, pubkey)) { - Misbehaving(pfrom, 100, "invalid-delegation"); - return; - } - CHashWriter sighasher(SER_GETHASH, 0); sighasher << delegation.getId(); sighasher << pfrom.nRemoteHostNonce; @@ -4165,9 +4154,25 @@ SchnorrSig sig; verifier >> sig; - if (!pubkey.VerifySchnorr(sighasher.GetHash(), sig)) { - Misbehaving(pfrom, 100, "invalid-avahello-signature"); - return; + + { + LOCK(pfrom.cs_avalanche_state); + if (!pfrom.m_avalanche_state) { + pfrom.m_avalanche_state = + std::make_unique(); + } + + avalanche::DelegationState state; + CPubKey &pubkey = pfrom.m_avalanche_state->pubkey; + if (!delegation.verify(state, pubkey)) { + Misbehaving(pfrom, 100, "invalid-delegation"); + return; + } + + if (!pubkey.VerifySchnorr(sighasher.GetHash(), sig)) { + Misbehaving(pfrom, 100, "invalid-avahello-signature"); + return; + } } // If we don't know this proof already, add it to the tracker so it can @@ -4301,11 +4306,14 @@ 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; + { + LOCK(pfrom.cs_avalanche_state); + if (!pfrom.m_avalanche_state || + !pfrom.m_avalanche_state->pubkey.VerifySchnorr( + verifier.GetHash(), sig)) { + Misbehaving(pfrom, 100, "invalid-ava-response-signature"); + return; + } } std::vector updates; diff --git a/src/rpc/avalanche.cpp b/src/rpc/avalanche.cpp --- a/src/rpc/avalanche.cpp +++ b/src/rpc/avalanche.cpp @@ -101,9 +101,7 @@ 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. + LOCK(pnode->cs_avalanche_state); if (!pnode->m_avalanche_state) { pnode->m_avalanche_state = std::make_unique();