From c8cc0ea4a41a49cd9601f22c094de2f6891433b9 Mon Sep 17 00:00:00 2001 From: PastaClaw Date: Sat, 27 Jun 2026 14:07:17 -0500 Subject: [PATCH 1/3] test: add unit coverage for -masternodeblsprivkey parameter interaction Cover the InitParameterInteraction behavior triggered by -masternodeblsprivkey directly: -disablewallet, -peerblockfilters and -blockfilterindex=basic are soft-set, while explicit user values win. This replaces the much slower node-spinning checks in feature_masternode_params.py, removed in a follow-up commit. --- src/Makefile.test.include | 1 + src/test/masternode_params_tests.cpp | 60 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/test/masternode_params_tests.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 2885c5fccb25..7b13336a0d93 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -141,6 +141,7 @@ BITCOIN_TESTS =\ test/llmq_snapshot_tests.cpp \ test/llmq_utils_tests.cpp \ test/logging_tests.cpp \ + test/masternode_params_tests.cpp \ test/dbwrapper_tests.cpp \ test/validation_tests.cpp \ test/mempool_tests.cpp \ diff --git a/src/test/masternode_params_tests.cpp b/src/test/masternode_params_tests.cpp new file mode 100644 index 000000000000..78a0652218c5 --- /dev/null +++ b/src/test/masternode_params_tests.cpp @@ -0,0 +1,60 @@ +// Copyright (c) 2025 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include + +#include + +//! These tests cover the parameter interactions triggered by +//! -masternodeblsprivkey in InitParameterInteraction. Previously this was +//! exercised by test/functional/feature_masternode_params.py, which spun up +//! full nodes only to read back arg state. +BOOST_FIXTURE_TEST_SUITE(masternode_params_tests, BasicTestingSetup) + +//! Without -masternodeblsprivkey, masternode-driven defaults must not fire. +BOOST_AUTO_TEST_CASE(no_masternode_key_leaves_defaults) +{ + ArgsManager args; + InitParameterInteraction(args); + + BOOST_CHECK(!args.IsArgSet("-disablewallet")); + BOOST_CHECK(!args.IsArgSet("-peerblockfilters")); + BOOST_CHECK(!args.IsArgSet("-blockfilterindex")); +} + +//! Setting -masternodeblsprivkey must auto-enable -disablewallet, +//! -peerblockfilters and -blockfilterindex=basic. +BOOST_AUTO_TEST_CASE(masternode_key_enables_filters_and_disables_wallet) +{ + ArgsManager args; + args.ForceSetArg("-masternodeblsprivkey", "dummy"); + + InitParameterInteraction(args); + + BOOST_CHECK(args.GetBoolArg("-disablewallet", false)); + BOOST_CHECK(args.GetBoolArg("-peerblockfilters", false)); + BOOST_CHECK_EQUAL(args.GetArg("-blockfilterindex", ""), "basic"); +} + +//! Explicit user overrides must win over the masternode defaults +//! (SoftSet semantics): the user can still disable filters and keep the +//! wallet on a masternode. +BOOST_AUTO_TEST_CASE(masternode_key_respects_user_overrides) +{ + ArgsManager args; + args.ForceSetArg("-masternodeblsprivkey", "dummy"); + args.ForceSetArg("-disablewallet", "0"); + args.ForceSetArg("-peerblockfilters", "0"); + args.ForceSetArg("-blockfilterindex", "0"); + + InitParameterInteraction(args); + + BOOST_CHECK(!args.GetBoolArg("-disablewallet", true)); + BOOST_CHECK(!args.GetBoolArg("-peerblockfilters", true)); + BOOST_CHECK_EQUAL(args.GetArg("-blockfilterindex", ""), "0"); +} + +BOOST_AUTO_TEST_SUITE_END() From b90088035b2fa8042504fb24103d2f7b106b7687 Mon Sep 17 00:00:00 2001 From: PastaClaw Date: Sat, 27 Jun 2026 14:07:32 -0500 Subject: [PATCH 2/3] test: drop feature_masternode_params.py in favor of unit coverage The functional test only verified -masternodeblsprivkey parameter interactions (auto -disablewallet, -peerblockfilters, -blockfilterindex, plus user override semantics). All of these are now covered directly in masternode_params_tests, which is faster and exercises the soft-set logic without spinning up nodes. Local timings (Apple M-series, debug build): - feature_masternode_params.py: real 5.70s - test_dash --run_test=masternode_params_tests: real 0.35s --- test/functional/feature_masternode_params.py | 95 -------------------- test/functional/test_runner.py | 1 - 2 files changed, 96 deletions(-) delete mode 100755 test/functional/feature_masternode_params.py diff --git a/test/functional/feature_masternode_params.py b/test/functional/feature_masternode_params.py deleted file mode 100755 index e53e1fcb18d2..000000000000 --- a/test/functional/feature_masternode_params.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2025 The Dash Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Test masternode parameter interactions. - -This test verifies that certain parameters are automatically enabled -when a node is configured as a masternode via -masternodeblsprivkey. -""" - -from test_framework.test_framework import BitcoinTestFramework - -# Service flags -NODE_COMPACT_FILTERS = (1 << 6) - -# Constants -BASIC_FILTER_INDEX = 'basic filter index' - - -class MasternodeParamsTest(BitcoinTestFramework): - def add_options(self, parser): - self.add_wallet_options(parser) - - def set_test_params(self): - self.setup_clean_chain = True - self.num_nodes = 2 - - def run_test(self): - self.log.info("Test that regular node has default settings") - node0 = self.nodes[0] - - # Regular node should have peerblockfilters disabled by default - services = int(node0.getnetworkinfo()['localservices'], 16) - assert services & NODE_COMPACT_FILTERS == 0 - - # Regular node should not have blockfilterindex enabled - index_info = node0.getindexinfo() - assert BASIC_FILTER_INDEX not in index_info - - self.log.info("Test that masternode has blockfilters auto-enabled") - # Generate a valid BLS key for testing - bls_info = node0.bls('generate') - bls_key = bls_info['secret'] - - # Start a node with masternode key - self.restart_node(1, extra_args=[f"-masternodeblsprivkey={bls_key}"]) - node1 = self.nodes[1] - - # Masternode should have peerblockfilters enabled - services = int(node1.getnetworkinfo()['localservices'], 16) - self.log.info(f"Masternode services: {hex(services)}, has COMPACT_FILTERS: {services & NODE_COMPACT_FILTERS != 0}") - - # Check blockfilterindex - index_info = node1.getindexinfo() - self.log.info(f"Masternode indexes: {list(index_info.keys())}") - - # For now, just check that the node started successfully with masternode key - # The actual filter enabling might require the node to be fully synced - assert node1.getblockcount() >= 0 # Basic check that node is running - - self.log.info("Test that masternode can explicitly disable blockfilters") - # Restart masternode with explicit disable - self.restart_node(1, extra_args=[ - f"-masternodeblsprivkey={bls_key}", - "-peerblockfilters=0", - "-blockfilterindex=0" - ]) - node1 = self.nodes[1] - - # Should not have COMPACT_FILTERS service - services = int(node1.getnetworkinfo()['localservices'], 16) - assert services & NODE_COMPACT_FILTERS == 0 - - # Should not have blockfilterindex - index_info = node1.getindexinfo() - assert BASIC_FILTER_INDEX not in index_info - - self.log.info("Test that masternode parameter interaction is logged") - # Stop the node first so we can check the startup logs - self.stop_node(1) - - # Check debug log for parameter interaction messages during startup - if self.is_wallet_compiled(): - with self.nodes[1].assert_debug_log(["parameter interaction: -masternodeblsprivkey set -> setting -disablewallet=1"]): - self.start_node(1, extra_args=[ - f"-masternodeblsprivkey={bls_key}", - "-peerblockfilters=0", - "-blockfilterindex=0" - ]) - # Note: The peerblockfilters and blockfilterindex messages won't be in the log - # when explicitly disabled, only when auto-enabled - - -if __name__ == '__main__': - MasternodeParamsTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index f97e9261a223..3ade74b58633 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -142,7 +142,6 @@ 'feature_llmq_singlenode.py', # NOTE: needs dash_hash to pass 'feature_dip4_coinbasemerkleroots.py', # NOTE: needs dash_hash to pass 'feature_mnehf.py', # NOTE: needs dash_hash to pass - 'feature_masternode_params.py', # NOTE: needs dash_hash to pass 'feature_governance.py --legacy-wallet', 'feature_governance.py --descriptors', 'feature_governance_cl.py --legacy-wallet', From 15e8bc8757c7831cf58bd6a49c4e807bdc7d6b0a Mon Sep 17 00:00:00 2001 From: PastaClaw Date: Mon, 29 Jun 2026 08:48:04 -0500 Subject: [PATCH 3/3] test: register masternode params unit test for dash lint --- test/util/data/non-backported.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/util/data/non-backported.txt b/test/util/data/non-backported.txt index 7b49af36a695..76fcaefa095c 100644 --- a/test/util/data/non-backported.txt +++ b/test/util/data/non-backported.txt @@ -64,6 +64,7 @@ src/test/dip0020opcodes_tests.cpp src/test/dynamic_activation*.cpp src/test/evo*.cpp src/test/llmq*.cpp +src/test/masternode_params_tests.cpp src/test/util/llmq_tests.h src/test/governance*.cpp src/unordered_lru_cache.h