diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -214,12 +215,21 @@ return nullptr; } + std::string avaproof = argsman.GetArg("-avaproof", ""); + if (!IsHexNumber(avaproof)) { + error = strprintf(_("invalid non-hexadecimal avalanche proof [%s]"), + avaproof); + return nullptr; + } + peerData = std::make_unique(); - { - // The proof. - CDataStream stream(ParseHex(argsman.GetArg("-avaproof", "")), - SER_NETWORK, 0); + try { + CDataStream stream(ParseHex(avaproof), SER_NETWORK, 0); stream >> peerData->proof; + } catch (const std::exception &e) { + error = strprintf(_("the avalanche proof is ill-formed [%s]: %s"), + avaproof, e.what()); + return nullptr; } ProofValidationState proof_state; @@ -249,6 +259,11 @@ } } + if (masterKey.GetPubKey() != peerData->proof.getMaster()) { + error = _("the master key does not match the proof public key"); + return nullptr; + } + // Generate the delegation to the session key. DelegationBuilder dgb(peerData->proof); if (sessionKey.GetPubKey() != peerData->proof.getMaster()) { diff --git a/test/functional/abc_rpc_avalancheproof.py b/test/functional/abc_rpc_avalancheproof.py --- a/test/functional/abc_rpc_avalancheproof.py +++ b/test/functional/abc_rpc_avalancheproof.py @@ -226,15 +226,28 @@ expected_msg="Error: the avalanche master key is invalid", ) - def check_proof_init_error(proof, message): + node.assert_start_raises_init_error( + self.extra_args[0] + [ + "-avaproof={}".format(proof), + "-avamasterkey=cN55daf1HotwBAgAKWVgDcoppmUNDtQSfb7XLutTLeAgVc3u8hik", + ], + expected_msg="Error: the master key does not match the proof public key", + ) + + def check_proof_init_error(proof, message, partial_match=False): node.assert_start_raises_init_error( self.extra_args[0] + [ "-avaproof={}".format(proof), "-avamasterkey=cND2ZvtabDbJ1gucx9GWH6XT9kgTAqfb6cotPt5Q5CyxVDhid2EN", ], expected_msg="Error: " + message, + match=ErrorMatch.PARTIAL_REGEX if partial_match else ErrorMatch.FULL_TEXT, ) + check_proof_init_error("This is not a serialized proof", + "invalid non-hexadecimal avalanche proof", partial_match=True) + check_proof_init_error("dead", + "the avalanche proof is ill-formed", partial_match=True) check_proof_init_error(no_stake, "the avalanche proof has no stake") check_proof_init_error(dust,