diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -195,7 +195,7 @@ // error is set by FromHex return nullptr; } - peerData->proof = std::make_shared(std::move(proof)); + peerData->proof = ProofRef::make(std::move(proof)); if (!VerifyProof(*peerData->proof, error)) { // error is set by VerifyProof diff --git a/src/avalanche/proof.h b/src/avalanche/proof.h --- a/src/avalanche/proof.h +++ b/src/avalanche/proof.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -114,6 +115,8 @@ uint32_t score; void computeScore(); + IMPLEMENT_RCU_REFCOUNT(uint64_t); + public: Proof() : sequence(0), expirationTime(0), master(), stakes(), @@ -129,6 +132,13 @@ computeProofId(); computeScore(); } + Proof(Proof &&other) + : sequence(other.sequence), expirationTime(other.expirationTime), + master(std::move(other.master)), stakes(std::move(other.stakes)), + payoutScriptPubKey(std::move(other.payoutScriptPubKey)), + signature(std::move(other.signature)), + limitedProofId(std::move(other.limitedProofId)), + proofid(std::move(other.proofid)), score(other.score) {} SERIALIZE_METHODS(Proof, obj) { READWRITE(obj.sequence, obj.expirationTime, obj.master, obj.stakes); @@ -169,7 +179,7 @@ bool verify(ProofValidationState &state, const CCoinsView &view) const; }; -using ProofRef = std::shared_ptr; +using ProofRef = RCUPtr; } // namespace avalanche diff --git a/src/avalanche/proofbuilder.cpp b/src/avalanche/proofbuilder.cpp --- a/src/avalanche/proofbuilder.cpp +++ b/src/avalanche/proofbuilder.cpp @@ -53,9 +53,9 @@ signedStakes.push_back(handle.value().sign(commitment)); } - return std::make_shared( - sequence, expirationTime, masterKey.GetPubKey(), - std::move(signedStakes), payoutScriptPubKey, std::move(proofSignature)); + return ProofRef::make(sequence, expirationTime, masterKey.GetPubKey(), + std::move(signedStakes), payoutScriptPubKey, + std::move(proofSignature)); } LimitedProofId ProofBuilder::getLimitedProofId() const { 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 @@ -878,8 +878,7 @@ BOOST_CHECK(Proof::FromHex(badProof, badProofHex, error)); ProofRegistrationState state; - BOOST_CHECK( - !pm.registerProof(std::make_shared(std::move(badProof)), state)); + BOOST_CHECK(!pm.registerProof(ProofRef::make(std::move(badProof)), state)); BOOST_CHECK(state.GetResult() == ProofRegistrationResult::INVALID); } diff --git a/src/avalanche/test/util.cpp b/src/avalanche/test/util.cpp --- a/src/avalanche/test/util.cpp +++ b/src/avalanche/test/util.cpp @@ -78,9 +78,9 @@ signedStakes.push_back(handle.value().sign(commitment)); } - return std::make_shared( - pb.sequence, pb.expirationTime, pb.masterKey.GetPubKey(), - std::move(signedStakes), pb.payoutScriptPubKey, SchnorrSig()); + return ProofRef::make(pb.sequence, pb.expirationTime, + pb.masterKey.GetPubKey(), std::move(signedStakes), + pb.payoutScriptPubKey, SchnorrSig()); } ProofId TestProofBuilder::getDuplicatedStakeProofId(ProofBuilder &pb) { @@ -115,9 +115,9 @@ signedStakes.push_back(signedStake); } - return std::make_shared( - pb.sequence, pb.expirationTime, pb.masterKey.GetPubKey(), - std::move(signedStakes), pb.payoutScriptPubKey, SchnorrSig()); + return ProofRef::make(pb.sequence, pb.expirationTime, + pb.masterKey.GetPubKey(), std::move(signedStakes), + pb.payoutScriptPubKey, SchnorrSig()); } } // namespace avalanche diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -5284,9 +5284,9 @@ } if (msg_type == NetMsgType::AVAPROOF) { - auto proof = std::make_shared(); - vRecv >> *proof; - const avalanche::ProofId &proofid = proof->getId(); + avalanche::Proof p; + vRecv >> p; + const avalanche::ProofId &proofid = p.getId(); pfrom.AddKnownProof(proofid); @@ -5305,6 +5305,7 @@ // registerProof should not be called while cs_proofrequest because it // holds cs_main and that creates a potential deadlock during shutdown + auto proof = avalanche::ProofRef::make(std::move(p)); avalanche::ProofRegistrationState state; if (g_avalanche->withPeerManager([&](avalanche::PeerManager &pm) { return pm.registerProof(proof, state); diff --git a/src/rpc/avalanche.cpp b/src/rpc/avalanche.cpp --- a/src/rpc/avalanche.cpp +++ b/src/rpc/avalanche.cpp @@ -124,9 +124,10 @@ const NodeId nodeid = request.params[0].get_int64(); CPubKey key = ParsePubKey(request.params[1]); - auto proof = std::make_shared(); + avalanche::Proof p; NodeContext &node = EnsureNodeContext(request.context); - verifyProofOrThrow(node, *proof, request.params[2].get_str()); + verifyProofOrThrow(node, p, request.params[2].get_str()); + auto proof = avalanche::ProofRef::make(std::move(p)); const avalanche::ProofId &proofid = proof->getId(); if (key != proof->getMaster()) { @@ -938,13 +939,14 @@ "Avalanche is not initialized"); } - auto proof = std::make_shared(); NodeContext &node = EnsureNodeContext(request.context); // Verify the proof. Note that this is redundant with the // verification done when adding the proof to the pool, but we get a // chance to give a better error message. - verifyProofOrThrow(node, *proof, request.params[0].get_str()); + avalanche::Proof p; + verifyProofOrThrow(node, p, request.params[0].get_str()); + auto proof = avalanche::ProofRef::make(std::move(p)); // Add the proof to the pool if we don't have it already. Since the // proof verification has already been done, a failure likely