diff --git a/src/avalanche/processor.h b/src/avalanche/processor.h --- a/src/avalanche/processor.h +++ b/src/avalanche/processor.h @@ -63,11 +63,6 @@ */ static constexpr int AVALANCHE_MAX_INFLIGHT_POLL = 10; -/** - * How many UTXOs can be used for a single proof. - */ -static constexpr int AVALANCHE_MAX_PROOF_STAKES = 1000; - namespace avalanche { class Delegation; diff --git a/src/avalanche/proof.h b/src/avalanche/proof.h --- a/src/avalanche/proof.h +++ b/src/avalanche/proof.h @@ -18,6 +18,11 @@ class CCoinsView; +/** + * How many UTXOs can be used for a single proof. + */ +static constexpr int AVALANCHE_MAX_PROOF_STAKES = 1000; + namespace avalanche { class ProofValidationState; diff --git a/src/avalanche/proof.cpp b/src/avalanche/proof.cpp --- a/src/avalanche/proof.cpp +++ b/src/avalanche/proof.cpp @@ -54,6 +54,10 @@ return state.Invalid(ProofValidationResult::NO_STAKE); } + if (stakes.size() > AVALANCHE_MAX_PROOF_STAKES) { + return state.Invalid(ProofValidationResult::TOO_MANY_UTXOS); + } + std::unordered_set utxos; for (const SignedStake &ss : stakes) { const Stake &s = ss.getStake(); diff --git a/src/avalanche/validation.h b/src/avalanche/validation.h --- a/src/avalanche/validation.h +++ b/src/avalanche/validation.h @@ -15,6 +15,7 @@ DUST_THRESOLD, DUPLICATE_STAKE, INVALID_SIGNATURE, + TOO_MANY_UTXOS, // UTXO based errors. MISSING_UTXO, diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -2461,6 +2461,11 @@ InitError(_("the avalanche proof has invalid stake " "signatures")); return false; + case avalanche::ProofValidationResult::TOO_MANY_UTXOS: + InitError(strprintf(_("the avalanche proof has too " + "many utxos (max: %u)"), + AVALANCHE_MAX_PROOF_STAKES)); + return false; default: InitError(_("the avalanche proof is invalid")); return false; diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3984,12 +3984,6 @@ verifier >> delegation; avalanche::Proof proof; - // TODO: read proof from message - if (proof.getStakes().size() > AVALANCHE_MAX_PROOF_STAKES) { - Misbehaving(pfrom, 100, "too-large-avalanche-proof"); - return; - } - avalanche::DelegationState state; CPubKey pubkey; if (!delegation.verify(state, proof, pubkey)) { diff --git a/src/rpc/avalanche.cpp b/src/rpc/avalanche.cpp --- a/src/rpc/avalanche.cpp +++ b/src/rpc/avalanche.cpp @@ -86,11 +86,6 @@ return false; } - if (proof.getStakes().size() > AVALANCHE_MAX_PROOF_STAKES) { - throw JSONRPCError(RPC_INVALID_PARAMS, - "Avalanche proof has too many UTXOs"); - } - return g_avalanche->addNode(nodeid, proof, avalanche::DelegationBuilder(proof).build()); } 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 @@ -6,13 +6,12 @@ from test_framework.avatools import get_stakes from test_framework.key import ECKey - from test_framework.mininode import P2PInterface - from test_framework.test_framework import BitcoinTestFramework +from test_framework.test_node import ErrorMatch from test_framework.util import ( + append_config, assert_equal, - assert_raises_rpc_error, ) AVALANCHE_MAX_PROOF_STAKES = 1000 @@ -83,18 +82,14 @@ proof_sequence, proof_expiration, proof_master, maximum_stakes) peerid1 = add_interface_node(node) - node.addavalanchenode( - peerid1, proof_master, good_proof) + assert node.addavalanchenode(peerid1, proof_master, good_proof) self.log.info("A proof using too many stakes should be rejected...") - bad_proof = node.buildavalancheproof( + too_many_utxos = node.buildavalancheproof( proof_sequence, proof_expiration, proof_master, too_many_stakes) - peerid2 = add_interface_node(node) - assert_raises_rpc_error(-32602, "Avalanche proof has too many UTXOs", - node.addavalanchenode, - peerid2, proof_master, bad_proof) + assert not node.addavalanchenode(peerid2, proof_master, too_many_utxos) # Test invalid proofs self.log.info("Bad proof should be rejected at startup") @@ -136,6 +131,16 @@ "the avalanche proof has duplicated stake") check_proof_init_error(bad_sig, "the avalanche proof has invalid stake signatures") + # The too many utxos case creates a proof which is that large that it + # cannot fit on the command line + append_config(node.datadir, ["avaproof={}".format(too_many_utxos)]) + node.assert_start_raises_init_error( + self.extra_args[0] + [ + "-avamasterkey=cND2ZvtabDbJ1gucx9GWH6XT9kgTAqfb6cotPt5Q5CyxVDhid2EN", + ], + expected_msg="Error: the avalanche proof has too many utxos", + match=ErrorMatch.PARTIAL_REGEX, + ) if __name__ == '__main__':