diff --git a/src/avalanche/peermanager.h b/src/avalanche/peermanager.h --- a/src/avalanche/peermanager.h +++ b/src/avalanche/peermanager.h @@ -240,9 +240,11 @@ uint32_t connectedPeersScore = 0; ChainstateManager &chainman; + ProofParams &proofParams; public: - PeerManager(ChainstateManager &chainmanIn) : chainman(chainmanIn){}; + PeerManager(ChainstateManager &chainmanIn, ProofParams &proofParamsIn) + : chainman(chainmanIn), proofParams(proofParamsIn){}; /** * Node API. diff --git a/src/avalanche/peermanager.cpp b/src/avalanche/peermanager.cpp --- a/src/avalanche/peermanager.cpp +++ b/src/avalanche/peermanager.cpp @@ -242,7 +242,8 @@ // Check the proof's validity. ProofValidationState validationState; - if (!WITH_LOCK(cs_main, return proof->verify(validationState, chainman))) { + if (!WITH_LOCK(cs_main, return proof->verify(proofParams, validationState, + chainman))) { if (isOrphanState(validationState)) { orphanProofPool.addProofIfPreferred(proof); if (orphanProofPool.countProofs() > AVALANCHE_MAX_ORPHAN_PROOFS) { @@ -487,7 +488,7 @@ for (const auto &p : peers) { ProofValidationState state; - if (!p.proof->verify(state, chainman)) { + if (!p.proof->verify(proofParams, state, chainman)) { if (isOrphanState(state)) { newOrphans.push_back(p.proof); } diff --git a/src/avalanche/processor.h b/src/avalanche/processor.h --- a/src/avalanche/processor.h +++ b/src/avalanche/processor.h @@ -96,6 +96,7 @@ // of implementing the whole NetEventsInterface for a single interesting event. class Processor final : public NetEventsInterface { Config avaconfig; + ProofParams proofParams; CConnman *connman; ChainstateManager &chainman; @@ -175,7 +176,8 @@ class NotificationsHandler; std::unique_ptr chainNotificationsHandler; - Processor(Config avaconfig, interfaces::Chain &chain, CConnman *connmanIn, + Processor(Config avaconfig, ProofParams proofParams, + interfaces::Chain &chain, CConnman *connmanIn, ChainstateManager &chainman, CScheduler &scheduler, std::unique_ptr peerDataIn, CKey sessionKeyIn, uint32_t minQuorumTotalScoreIn, @@ -215,6 +217,8 @@ ProofRef getLocalProof() const; + const ProofParams getProofParams() const { return proofParams; } + /* * Return whether the avalanche service flag should be set. */ diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -35,10 +35,11 @@ std::unique_ptr g_avalanche; namespace avalanche { -static bool VerifyProof(const Proof &proof, bilingual_str &error) { +static bool VerifyProof(const ProofParams &proofParams, const Proof &proof, + bilingual_str &error) { ProofValidationState proof_state; - if (!proof.verify(proof_state)) { + if (!proof.verify(proofParams, proof_state)) { switch (proof_state.GetResult()) { case ProofValidationResult::NO_STAKE: error = _("The avalanche proof has no stake."); @@ -127,17 +128,17 @@ } }; -Processor::Processor(Config avaconfigIn, interfaces::Chain &chain, - CConnman *connmanIn, ChainstateManager &chainmanIn, - CScheduler &scheduler, +Processor::Processor(Config avaconfigIn, ProofParams proofParamsIn, + interfaces::Chain &chain, CConnman *connmanIn, + ChainstateManager &chainmanIn, CScheduler &scheduler, std::unique_ptr peerDataIn, CKey sessionKeyIn, uint32_t minQuorumTotalScoreIn, double minQuorumConnectedScoreRatioIn, int64_t minAvaproofsNodeCountIn, uint32_t staleVoteThresholdIn, uint32_t staleVoteFactorIn) - : avaconfig(std::move(avaconfigIn)), connman(connmanIn), - chainman(chainmanIn), round(0), - peerManager(std::make_unique(chainman)), + : avaconfig(std::move(avaconfigIn)), proofParams(std::move(proofParamsIn)), + connman(connmanIn), chainman(chainmanIn), round(0), + peerManager(std::make_unique(chainman, proofParams)), peerData(std::move(peerDataIn)), sessionKey(std::move(sessionKeyIn)), minQuorumScore(minQuorumTotalScoreIn), minQuorumConnectedScoreRatio(minQuorumConnectedScoreRatioIn), @@ -171,6 +172,8 @@ CKey masterKey; CKey sessionKey; + ProofParams proofParams; + if (argsman.IsArgSet("-avasessionkey")) { sessionKey = DecodeSecret(argsman.GetArg("-avasessionkey", "")); if (!sessionKey.IsValid()) { @@ -203,7 +206,7 @@ peerData = std::make_unique(); peerData->proof = std::move(proof); - if (!VerifyProof(*peerData->proof, error)) { + if (!VerifyProof(proofParams, *peerData->proof, error)) { // error is set by VerifyProof return nullptr; } @@ -330,8 +333,8 @@ // We can't use std::make_unique with a private constructor return std::unique_ptr(new Processor( - std::move(avaconfig), chain, connman, chainman, scheduler, - std::move(peerData), std::move(sessionKey), + std::move(avaconfig), std::move(proofParams), chain, connman, chainman, + scheduler, std::move(peerData), std::move(sessionKey), Proof::amountToScore(minQuorumStake), minQuorumConnectedStakeRatio, minAvaproofsNodeCount, staleVoteThreshold, staleVoteFactor)); } diff --git a/src/avalanche/proof.h b/src/avalanche/proof.h --- a/src/avalanche/proof.h +++ b/src/avalanche/proof.h @@ -45,6 +45,12 @@ class ProofValidationState; +struct ProofParams { + Amount stakeUtxoDustThreshold; + + ProofParams() : stakeUtxoDustThreshold(PROOF_DUST_THRESHOLD) {} +}; + using StakeId = uint256; struct StakeCommitment : public uint256 { @@ -188,8 +194,8 @@ uint32_t getScore() const { return score; } Amount getStakedAmount() const; - bool verify(ProofValidationState &state) const; - bool verify(ProofValidationState &state, + bool verify(const ProofParams ¶ms, ProofValidationState &state) const; + bool verify(const ProofParams ¶ms, ProofValidationState &state, const ChainstateManager &chainman) const EXCLUSIVE_LOCKS_REQUIRED(cs_main); }; diff --git a/src/avalanche/proof.cpp b/src/avalanche/proof.cpp --- a/src/avalanche/proof.cpp +++ b/src/avalanche/proof.cpp @@ -122,7 +122,8 @@ }); } -bool Proof::verify(ProofValidationState &state) const { +bool Proof::verify(const ProofParams ¶ms, + ProofValidationState &state) const { if (stakes.empty()) { return state.Invalid(ProofValidationResult::NO_STAKE, "no-stake"); } @@ -150,11 +151,12 @@ std::unordered_set utxos; for (const SignedStake &ss : stakes) { const Stake &s = ss.getStake(); - if (s.getAmount() < PROOF_DUST_THRESHOLD) { - return state.Invalid(ProofValidationResult::DUST_THRESHOLD, - "amount-below-dust-threshold", - strprintf("%s < %s", s.getAmount().ToString(), - PROOF_DUST_THRESHOLD.ToString())); + if (s.getAmount() < params.stakeUtxoDustThreshold) { + return state.Invalid( + ProofValidationResult::DUST_THRESHOLD, + "amount-below-dust-threshold", + strprintf("%s < %s", s.getAmount().ToString(), + params.stakeUtxoDustThreshold.ToString())); } if (s.getId() < prevId) { @@ -179,10 +181,10 @@ return true; } -bool Proof::verify(ProofValidationState &state, +bool Proof::verify(const ProofParams ¶ms, ProofValidationState &state, const ChainstateManager &chainman) const { AssertLockHeld(cs_main); - if (!verify(state)) { + if (!verify(params, state)) { // state is set by verify. return false; } 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 @@ -295,8 +295,9 @@ BOOST_AUTO_TEST_CASE(peer_probabilities) { ChainstateManager &chainman = *Assert(m_node.chainman); + ProofParams proofParams; // No peers. - avalanche::PeerManager pm(chainman); + avalanche::PeerManager pm(chainman, proofParams); BOOST_CHECK_EQUAL(pm.selectNode(), NO_NODE); const NodeId node0 = 42, node1 = 69, node2 = 37; @@ -333,8 +334,9 @@ BOOST_AUTO_TEST_CASE(remove_peer) { ChainstateManager &chainman = *Assert(m_node.chainman); + ProofParams proofParams; // No peers. - avalanche::PeerManager pm(chainman); + avalanche::PeerManager pm(chainman, proofParams); BOOST_CHECK_EQUAL(pm.selectPeer(), NO_PEER); CChainState &active_chainstate = chainman.ActiveChainstate(); @@ -411,7 +413,8 @@ BOOST_AUTO_TEST_CASE(compact_slots) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); // Add 4 peers. std::array peerids; @@ -442,7 +445,8 @@ BOOST_AUTO_TEST_CASE(node_crud) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); CChainState &active_chainstate = chainman.ActiveChainstate(); @@ -506,7 +510,8 @@ BOOST_AUTO_TEST_CASE(node_binding) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); CChainState &active_chainstate = chainman.ActiveChainstate(); @@ -610,8 +615,9 @@ BOOST_AUTO_TEST_CASE(node_binding_reorg) { gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); ChainstateManager &chainman = *Assert(m_node.chainman); + ProofParams proofParams; - avalanche::PeerManager pm(chainman); + avalanche::PeerManager pm(chainman, proofParams); auto proof = buildRandomProof(chainman.ActiveChainstate(), MIN_VALID_PROOF_SCORE, 99); @@ -687,7 +693,8 @@ addCoin(chainman.ActiveChainstate(), {txid2, i}, key); } - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); CKey masterKey = CKey::MakeCompressedKey(); const auto getPeerId = [&](const std::vector &outpoints) { return TestPeerManager::registerAndGetPeerId( @@ -742,7 +749,8 @@ BOOST_AUTO_TEST_CASE(orphan_proofs) { ChainstateManager &chainman = *Assert(m_node.chainman); gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); auto key = CKey::MakeCompressedKey(); int immatureHeight = 100; @@ -823,7 +831,8 @@ BOOST_AUTO_TEST_CASE(dangling_node) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); CChainState &active_chainstate = chainman.ActiveChainstate(); @@ -871,7 +880,8 @@ BOOST_AUTO_TEST_CASE(proof_accessors) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); constexpr int numProofs = 10; @@ -917,7 +927,8 @@ BOOST_FIXTURE_TEST_CASE(conflicting_proof_rescan, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const CKey key = CKey::MakeCompressedKey(); @@ -957,6 +968,7 @@ BOOST_FIXTURE_TEST_CASE(conflicting_proof_selection, NoCoolDownFixture) { const CKey key = CKey::MakeCompressedKey(); + ProofParams proofParams; const Amount amount(PROOF_DUST_THRESHOLD); const uint32_t height = 100; const bool is_coinbase = false; @@ -977,7 +989,7 @@ BOOST_CHECK_EQUAL(comparator(candidate, reference), expectAccepted); BOOST_CHECK_EQUAL(comparator(reference, candidate), !expectAccepted); - avalanche::PeerManager pm(chainman); + avalanche::PeerManager pm(chainman, proofParams); BOOST_CHECK(pm.registerProof(reference)); BOOST_CHECK(pm.isBoundToPeer(reference->getId())); @@ -1055,7 +1067,8 @@ BOOST_AUTO_TEST_CASE(conflicting_orphans) { ChainstateManager &chainman = *Assert(m_node.chainman); gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const CKey key = CKey::MakeCompressedKey(); @@ -1101,7 +1114,8 @@ BOOST_FIXTURE_TEST_CASE(preferred_conflicting_proof, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const CKey key = CKey::MakeCompressedKey(); const COutPoint conflictingOutpoint = @@ -1134,7 +1148,8 @@ BOOST_FIXTURE_TEST_CASE(update_next_conflict_time, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); auto now = GetTime(); SetMockTime(now.count()); @@ -1169,7 +1184,8 @@ BOOST_FIXTURE_TEST_CASE(register_force_accept, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const CKey key = CKey::MakeCompressedKey(); @@ -1235,7 +1251,8 @@ BOOST_FIXTURE_TEST_CASE(evicted_proof, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const CKey key = CKey::MakeCompressedKey(); @@ -1267,7 +1284,8 @@ BOOST_AUTO_TEST_CASE(conflicting_proof_cooldown) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const CKey key = CKey::MakeCompressedKey(); @@ -1338,7 +1356,8 @@ BOOST_FIXTURE_TEST_CASE(reject_proof, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const CKey key = CKey::MakeCompressedKey(); @@ -1420,7 +1439,8 @@ BOOST_AUTO_TEST_CASE(should_request_more_nodes) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); // Set mock time so that proof registration time is predictable and // testable. @@ -1516,7 +1536,8 @@ BOOST_AUTO_TEST_CASE(score_ordering) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); std::vector expectedScores(10); // Expect the peers to be ordered by descending score @@ -1543,7 +1564,8 @@ BOOST_FIXTURE_TEST_CASE(known_score_tracking, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "2"); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const CKey key = CKey::MakeCompressedKey(); @@ -1659,7 +1681,8 @@ BOOST_AUTO_TEST_CASE(connected_score_tracking) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); const auto checkScores = [&pm](uint32_t known, uint32_t connected) { BOOST_CHECK_EQUAL(pm.getTotalPeersScore(), known); @@ -1750,7 +1773,8 @@ BOOST_FIXTURE_TEST_CASE(proof_radix_tree, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); gArgs.ForceSetArg("-enableavalancheproofreplacement", "1"); @@ -1869,7 +1893,8 @@ BOOST_AUTO_TEST_CASE(received_avaproofs) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); auto addNode = [&](NodeId nodeid) { auto proof = buildRandomProof(chainman.ActiveChainstate(), @@ -1893,8 +1918,9 @@ BOOST_FIXTURE_TEST_CASE(cleanup_dangling_proof, NoCoolDownFixture) { ChainstateManager &chainman = *Assert(m_node.chainman); gArgs.ForceSetArg("-enableavalancheproofreplacement", "1"); + ProofParams proofParams; - avalanche::PeerManager pm(chainman); + avalanche::PeerManager pm(chainman, proofParams); const auto now = GetTime(); auto mocktime = now; @@ -2042,7 +2068,8 @@ BOOST_AUTO_TEST_CASE(register_proof_missing_utxo) { ChainstateManager &chainman = *Assert(m_node.chainman); - avalanche::PeerManager pm(chainman); + ProofParams proofParams; + avalanche::PeerManager pm(chainman, proofParams); CKey key = CKey::MakeCompressedKey(); auto proof = buildProofWithOutpoints(key, {{TxId(GetRandHash()), 0}}, diff --git a/src/avalanche/test/proof_tests.cpp b/src/avalanche/test/proof_tests.cpp --- a/src/avalanche/test/proof_tests.cpp +++ b/src/avalanche/test/proof_tests.cpp @@ -24,6 +24,7 @@ BOOST_AUTO_TEST_CASE(proof_random) { CChainState &active_chainstate = Assert(m_node.chainman)->ActiveChainstate(); + ProofParams proofParams; for (int i = 0; i < 1000; i++) { const uint32_t score = InsecureRand32(); @@ -35,14 +36,15 @@ : ProofValidationResult::NONE; ProofValidationState state; - BOOST_CHECK_EQUAL(p->verify(state), + BOOST_CHECK_EQUAL(p->verify(proofParams, state), state.GetResult() == ProofValidationResult::NONE); BOOST_CHECK(state.GetResult() == expected_state); } } BOOST_AUTO_TEST_CASE(proofbuilder) { - // Master key. + ProofParams proofParams; + auto key = CKey::MakeCompressedKey(); const CPubKey master = key.GetPubKey(); @@ -61,7 +63,7 @@ ProofRef p = pb.build(); ProofValidationState state; - BOOST_CHECK(p->verify(state)); + BOOST_CHECK(p->verify(proofParams, state)); BOOST_CHECK_EQUAL(p->getSequence(), sequence); BOOST_CHECK_EQUAL(p->getExpirationTime(), expiration); @@ -862,6 +864,8 @@ 2 * 444638638, ProofValidationResult::NONE}, }; + ProofParams proofParams; + auto checkCases = [&](const std::vector &testcases) { for (auto &c : testcases) { Proof p; @@ -871,7 +875,7 @@ BOOST_CHECK_EQUAL(p.getScore(), c.score); ProofValidationState state; - BOOST_CHECK_EQUAL(p.verify(state), + BOOST_CHECK_EQUAL(p.verify(proofParams, state), c.result == ProofValidationResult::NONE); BOOST_CHECK(state.GetResult() == c.result); BOOST_TEST_MESSAGE(c.proofid); @@ -891,6 +895,7 @@ BOOST_AUTO_TEST_CASE(verify) { gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "1"); + ProofParams proofParams; auto key = CKey::MakeCompressedKey(); const CPubKey pubkey = key.GetPubKey(); @@ -925,9 +930,9 @@ ProofRef p = pb.build(); ProofValidationState state; - BOOST_CHECK(p->verify(state)); + BOOST_CHECK(p->verify(proofParams, state)); LOCK(cs_main); - BOOST_CHECK(p->verify(state, chainman) == + BOOST_CHECK(p->verify(proofParams, state, chainman) == (result == ProofValidationResult::NONE)); BOOST_CHECK(state.GetResult() == result); }; @@ -975,7 +980,7 @@ ProofRef p = ProofBuilder(0, 0, key).build(); ProofValidationState state; - BOOST_CHECK(!p->verify(state, chainman)); + BOOST_CHECK(!p->verify(proofParams, state, chainman)); BOOST_CHECK(state.GetResult() == ProofValidationResult::NO_STAKE); } @@ -987,7 +992,7 @@ ProofRef p = pb.build(); ProofValidationState state; - BOOST_CHECK(!p->verify(state, chainman)); + BOOST_CHECK(!p->verify(proofParams, state, chainman)); BOOST_CHECK(state.GetResult() == ProofValidationResult::DUST_THRESHOLD); } @@ -998,7 +1003,7 @@ ProofRef p = pb.build(); ProofValidationState state; - BOOST_CHECK(!p->verify(state, chainman)); + BOOST_CHECK(!p->verify(proofParams, state, chainman)); BOOST_CHECK(state.GetResult() == ProofValidationResult::DUST_THRESHOLD); } @@ -1009,7 +1014,7 @@ ProofRef p = TestProofBuilder::buildDuplicatedStakes(pb); ProofValidationState state; - BOOST_CHECK(!p->verify(state, chainman)); + BOOST_CHECK(!p->verify(proofParams, state, chainman)); BOOST_CHECK(state.GetResult() == ProofValidationResult::DUPLICATE_STAKE); } @@ -1027,7 +1032,7 @@ ProofRef p = TestProofBuilder::buildWithReversedOrderStakes(pb); ProofValidationState state; - BOOST_CHECK(!p->verify(state, chainman)); + BOOST_CHECK(!p->verify(proofParams, state, chainman)); BOOST_CHECK(state.GetResult() == ProofValidationResult::WRONG_STAKE_ORDERING); } diff --git a/src/avalanche/test/proofpool_tests.cpp b/src/avalanche/test/proofpool_tests.cpp --- a/src/avalanche/test/proofpool_tests.cpp +++ b/src/avalanche/test/proofpool_tests.cpp @@ -80,7 +80,8 @@ BOOST_AUTO_TEST_CASE(rescan) { gArgs.ForceSetArg("-avaproofstakeutxoconfirmations", "1"); ProofPool testPool; - avalanche::PeerManager pm(*Assert(m_node.chainman)); + ProofParams proofParams; + avalanche::PeerManager pm(*Assert(m_node.chainman), proofParams); testPool.rescan(pm); BOOST_CHECK_EQUAL(testPool.size(), 0); diff --git a/src/rpc/avalanche.cpp b/src/rpc/avalanche.cpp --- a/src/rpc/avalanche.cpp +++ b/src/rpc/avalanche.cpp @@ -82,10 +82,16 @@ throw JSONRPCError(RPC_DESERIALIZATION_ERROR, error.original); } + avalanche::ProofParams proofParams; + if (g_avalanche) { + // If Avalanche is enabled, use the configured params + proofParams = g_avalanche->getProofParams(); + } + avalanche::ProofValidationState state; { LOCK(cs_main); - if (!proof.verify(state, *Assert(node.chainman))) { + if (!proof.verify(proofParams, state, *Assert(node.chainman))) { throw JSONRPCError(RPC_INVALID_PARAMETER, "The proof is invalid: " + state.ToString()); }