diff --git a/src/avalanche/processor.h b/src/avalanche/processor.h --- a/src/avalanche/processor.h +++ b/src/avalanche/processor.h @@ -25,6 +25,7 @@ #include #include #include +#include #include class Config; @@ -245,8 +246,11 @@ RWCollection queries; /** Data required to participate. */ - struct PeerData; - std::unique_ptr peerData; + struct PeerData { + std::optional proof; + std::optional delegation; + }; + PeerData peerData; CKey sessionKey; /** Event loop machinery. */ @@ -296,10 +300,9 @@ /** * Get the local proof used by this node. * - * @returns Proof for this node. - * @throws a std::runtime_error if there is no proof set for this node + * @returns Optional containing the proof for this node if there is one. */ - const Proof getProof() const; + const std::optional &getLocalProof() const; std::vector getPeers() const; std::vector getNodeIdsForPeer(PeerId peerId) const; diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -136,11 +136,6 @@ return true; } -struct Processor::PeerData { - Proof proof; - Delegation delegation; -}; - class Processor::NotificationsHandler : public interfaces::Chain::Notifications { Processor *m_processor; @@ -153,7 +148,8 @@ if (m_processor->mustRegisterProof && !::ChainstateActive().IsInitialBlockDownload()) { - m_processor->peerManager->getPeerId(m_processor->peerData->proof); + m_processor->peerManager->getPeerId( + m_processor->peerData.proof.value()); m_processor->mustRegisterProof = false; } @@ -174,25 +170,25 @@ } if (gArgs.IsArgSet("-avaproof")) { - peerData = std::make_unique(); - { // The proof. CDataStream stream(ParseHex(gArgs.GetArg("-avaproof", "")), SER_NETWORK, 0); - stream >> peerData->proof; + Proof proof; + stream >> proof; + peerData.proof = proof; // Schedule proof registration at the first new block after IBD. mustRegisterProof = true; } // Generate the delegation to the session key. - DelegationBuilder dgb(peerData->proof); - if (sessionKey.GetPubKey() != peerData->proof.getMaster()) { + DelegationBuilder dgb(peerData.proof.value()); + if (sessionKey.GetPubKey() != peerData.proof->getMaster()) { dgb.addLevel(DecodeSecret(gArgs.GetArg("-avamasterkey", "")), sessionKey.GetPubKey()); } - peerData->delegation = dgb.build(); + peerData.delegation = dgb.build(); } // Make sure we get notified of chain state changes. @@ -402,7 +398,7 @@ uint256 Processor::buildLocalSighash(CNode *pfrom) const { CHashWriter hasher(SER_GETHASH, 0); - hasher << peerData->delegation.getId(); + hasher << peerData.delegation->getId(); hasher << pfrom->GetLocalNonce(); hasher << pfrom->nRemoteHostNonce; hasher << pfrom->GetLocalExtraEntropy(); @@ -421,7 +417,7 @@ } bool Processor::sendHello(CNode *pfrom) const { - if (!peerData) { + if (!peerData.delegation) { // We do not have a delegation to advertise. return false; } @@ -437,18 +433,16 @@ } } - connman->PushMessage(pfrom, CNetMsgMaker(pfrom->GetCommonVersion()) - .Make(NetMsgType::AVAHELLO, - Hello(peerData->delegation, sig))); + connman->PushMessage(pfrom, + CNetMsgMaker(pfrom->GetCommonVersion()) + .Make(NetMsgType::AVAHELLO, + Hello(peerData.delegation.value(), sig))); return true; } -const Proof Processor::getProof() const { - if (!peerData) { - throw std::runtime_error("proof not set"); - } - return peerData->proof; +const std::optional &Processor::getLocalProof() const { + return peerData.proof; } bool Processor::startEventLoop(CScheduler &scheduler) { diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -87,6 +87,7 @@ #include #include #include +#include #include static const bool DEFAULT_PROXYRANDOMIZE = true; @@ -2444,12 +2445,15 @@ // If avalanche is enabled and a proof is supplied, make sure it does // not contain garbage. At this point the validity of the utxos cannot // be checked, so only basic verification is performed. - try { - avalanche::Proof proof; - proof = g_avalanche->getProof(); + const std::optional &proof = + g_avalanche->getLocalProof(); + if (!proof) { + LogPrintf("Avalanche is enabled but no proof supplied, the node " + "will not be able to vote\n"); + } else { avalanche::ProofValidationState proof_state; - if (!proof.verify(proof_state)) { + if (!proof->verify(proof_state)) { switch (proof_state.GetResult()) { case avalanche::ProofValidationResult::NO_STAKE: InitError(_("the avalanche proof has no stake")); @@ -2475,9 +2479,6 @@ return false; } } - } catch (const std::runtime_error &e) { - LogPrintf("Avalanche is enabled but no proof supplied, the node " - "will not be able to vote\n"); } }