From e151cada58e00f9e12df2fe36a2a99934bbac40f Mon Sep 17 00:00:00 2001 From: Byron Hambly Date: Thu, 2 Jul 2026 14:05:24 +0200 Subject: [PATCH] test: update and re-enable trim headers functional test The trim_headers test was previously moved to extended tests, and only worked with legacy wallets. Update it to work with descriptor wallets, and move it back to base scripts in functional tests. --- src/wallet/wallet.cpp | 7 +++++ test/functional/feature_trim_headers.py | 37 +++++++++++++------------ test/functional/test_runner.py | 4 +-- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c9371f5d2c..da8cd09931 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1654,6 +1654,13 @@ isminetype CWallet::IsMine(const CScript& script) const return spkm->IsMine(script); } + // ELEMENTS: OP_TRUE outputs aren't derived from any descriptor, so they never + // land in m_cached_spks above. Custom chains (e.g. elementsregtest) rely on + // -anyonecanspendaremine to treat them as wallet funds regardless of wallet type. + if (Params().anyonecanspend_aremine && script == CScript() << OP_TRUE) { + return ISMINE_SPENDABLE; + } + return ISMINE_NO; } diff --git a/test/functional/feature_trim_headers.py b/test/functional/feature_trim_headers.py index 386f59c918..6c3dc8771f 100755 --- a/test/functional/feature_trim_headers.py +++ b/test/functional/feature_trim_headers.py @@ -5,25 +5,20 @@ import codecs from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal from test_framework import ( - address, key, ) from test_framework.messages import ( CBlock, from_hex, + ser_uint256, ) from test_framework.script import ( OP_NOP, OP_RETURN, - CScript + CScript, + SIGHASH_ALL, ) -# Generate wallet import format from private key. -def wif(pk): - # Base58Check version for regtest WIF keys is 0xef = 239 - pk_compressed = pk + bytes([0x1]) - return address.byte_to_base58(pk_compressed, 239) - # The signblockscript is a Bitcoin Script k-of-n multisig script. def make_signblockscript(num_nodes, required_signers, keys): assert num_nodes >= required_signers @@ -39,7 +34,6 @@ def make_signblockscript(num_nodes, required_signers, keys): class TrimHeadersTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() - self.skip_if_no_bdb() def add_options(self, parser): self.add_wallet_options(parser) @@ -47,13 +41,10 @@ class TrimHeadersTest(BitcoinTestFramework): # Dynamically generate N keys to be used for block signing. def init_keys(self, num_keys): self.keys = [] - self.wifs = [] for i in range(num_keys): k = key.ECKey() k.generate() - w = wif(k.get_bytes()) self.keys.append(k) - self.wifs.append(w) def set_test_params(self): self.num_nodes = 3 @@ -92,6 +83,21 @@ class TrimHeadersTest(BitcoinTestFramework): else: assert_equal(self.nodes[0].getblockcount(), expected_height) + # The signblock RPC only works on legacy (BDB) wallets. + # Sign the block header hash directly with the key instead, + # then use combineblocksigs (a non-wallet RPC). + def sign_block(self, key, block): + block.rehash() + msg = ser_uint256(block.sha256) + sig = key.sign_ecdsa(msg) + if not block.m_dynafed_params.is_null(): + sig += bytes([SIGHASH_ALL]) + + return [{ + "pubkey": key.get_pubkey().get_bytes().hex(), + "sig": sig.hex(), + }] + def mine_block(self, make_transactions): # alternate mining between the signing nodes mineridx = self.nodes[0].getblockcount() % self.required_signers # assuming in sync @@ -141,7 +147,7 @@ class TrimHeadersTest(BitcoinTestFramework): sigs = [] for i in range(self.num_keys): result = miner.combineblocksigs(block, sigs, self.witnessScript) - sigs = sigs + self.nodes[i].signblock(block, self.witnessScript) + sigs = sigs + self.sign_block(self.keys[i], block_struct) assert_equal(result["complete"], i >= self.required_signers) # submitting should have no effect pre-threshhold if i < self.required_signers: @@ -171,7 +177,7 @@ class TrimHeadersTest(BitcoinTestFramework): block.solve() h = block.serialize().hex() - sigs = node.signblock(h, self.witnessScript) + sigs = self.sign_block(self.keys[0], block) result = node.combineblocksigs(h, sigs, self.witnessScript) assert_equal(result["complete"], True) @@ -180,9 +186,6 @@ class TrimHeadersTest(BitcoinTestFramework): def run_test(self): - for i in range(self.num_keys): - self.nodes[i].importprivkey(self.wifs[i]) - expected_height = 0 self.check_height(expected_height, all=True) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 757d045fc2..61940c3eb9 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -87,7 +87,6 @@ EXTENDED_SCRIPTS = [ # 'feature_dbcrash.py', ELEMENTS: long running test and uses excessive disk space on GHA # 'feature_fee_estimation.py', ELEMENTS: this is broken on v23 'feature_index_prune.py', - 'feature_trim_headers.py', 'wallet_pruning.py --legacy-wallet', ] @@ -95,6 +94,7 @@ BASE_SCRIPTS = [ # Scripts that are run by default. # vv First elements tests vv 'example_elements_code_tutorial.py', + 'feature_trim_headers.py', 'feature_fedpeg.py --legacy-wallet', 'feature_fedpeg.py --pre_transition --legacy-wallet', 'feature_fedpeg.py --post_transition --legacy-wallet', @@ -365,7 +365,7 @@ BASE_SCRIPTS = [ #'wallet_upgradewallet.py --legacy-wallet', 'wallet_crosschain.py', 'mining_basic.py', - # ELEMENTS: PoW test set-up disabled. + # ELEMENTS: PoW test set-up disabled. # 'mining_mainnet.py', 'feature_signet.py', 'p2p_mutated_blocks.py',