diff --git a/Makefile.am b/Makefile.am index 54e9a6865f9..60167e3b7e8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,7 +47,8 @@ DIST_CONTRIB = \ $(top_srcdir)/test/sanitizer_suppressions/tsan \ $(top_srcdir)/test/sanitizer_suppressions/ubsan \ $(top_srcdir)/contrib/linearize/linearize-data.py \ - $(top_srcdir)/contrib/linearize/linearize-hashes.py + $(top_srcdir)/contrib/linearize/linearize-hashes.py \ + $(top_srcdir)/contrib/signet/miner DIST_SHARE = \ $(top_srcdir)/share/genbuild.sh \ diff --git a/test/config.ini.in b/test/config.ini.in index d7105c419be..5888ef443b4 100644 --- a/test/config.ini.in +++ b/test/config.ini.in @@ -19,6 +19,7 @@ RPCAUTH=@abs_top_srcdir@/share/rpcauth/rpcauth.py @USE_SQLITE_TRUE@USE_SQLITE=true @USE_BDB_TRUE@USE_BDB=true @BUILD_BITCOIN_CLI_TRUE@ENABLE_CLI=true +@BUILD_BITCOIN_UTIL_TRUE@ENABLE_BITCOIN_UTIL=true @BUILD_BITCOIN_WALLET_TRUE@ENABLE_WALLET_TOOL=true @BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true @ENABLE_FUZZ_TRUE@ENABLE_FUZZ=true diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 2fb9ec09422..a39ee003eff 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -244,8 +244,14 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): "src", "bitcoin-cli" + config["environment"]["EXEEXT"], ) + fname_bitcoinutil = os.path.join( + config["environment"]["BUILDDIR"], + "src", + "bitcoin-util" + config["environment"]["EXEEXT"], + ) self.options.bitcoind = os.getenv("BITCOIND", default=fname_bitcoind) self.options.bitcoincli = os.getenv("BITCOINCLI", default=fname_bitcoincli) + self.options.bitcoinutil = os.getenv("BITCOINUTIL", default=fname_bitcoinutil) os.environ['PATH'] = os.pathsep.join([ os.path.join(config['environment']['BUILDDIR'], 'src'), @@ -880,6 +886,11 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): if not self.is_wallet_tool_compiled(): raise SkipTest("bitcoin-wallet has not been compiled") + def skip_if_no_bitcoin_util(self): + """Skip the running test if bitcoin-util has not been compiled.""" + if not self.is_bitcoin_util_compiled(): + raise SkipTest("bitcoin-util has not been compiled") + def skip_if_no_cli(self): """Skip the running test if bitcoin-cli has not been compiled.""" if not self.is_cli_compiled(): @@ -927,6 +938,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): """Checks whether bitcoin-wallet was compiled.""" return self.config["components"].getboolean("ENABLE_WALLET_TOOL") + def is_bitcoin_util_compiled(self): + """Checks whether bitcoin-util was compiled.""" + return self.config["components"].getboolean("ENABLE_BITCOIN_UTIL") + def is_zmq_compiled(self): """Checks whether the zmq module was compiled.""" return self.config["components"].getboolean("ENABLE_ZMQ") diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 1f0f806d919..a3c938ae261 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -145,6 +145,8 @@ BASE_SCRIPTS = [ 'wallet_txn_doublespend.py --mineblock', 'tool_wallet.py --legacy-wallet', 'tool_wallet.py --descriptors', + 'tool_signet_miner.py --legacy-wallet', + 'tool_signet_miner.py --descriptors', 'wallet_txn_clone.py', 'wallet_txn_clone.py --segwit', 'rpc_getchaintips.py', diff --git a/test/functional/tool_signet_miner.py b/test/functional/tool_signet_miner.py new file mode 100755 index 00000000000..e6fc9072abd --- /dev/null +++ b/test/functional/tool_signet_miner.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test signet miner tool""" + +import os.path +import subprocess +import sys +import time + +from test_framework.key import ECKey +from test_framework.script_util import key_to_p2wpkh_script +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal +from test_framework.wallet_util import bytes_to_wif + + +CHALLENGE_PRIVATE_KEY = (42).to_bytes(32, 'big') + + +class SignetMinerTest(BitcoinTestFramework): + def set_test_params(self): + self.chain = "signet" + self.setup_clean_chain = True + self.num_nodes = 1 + + # generate and specify signet challenge (simple p2wpkh script) + privkey = ECKey() + privkey.set(CHALLENGE_PRIVATE_KEY, True) + pubkey = privkey.get_pubkey().get_bytes() + challenge = key_to_p2wpkh_script(pubkey) + self.extra_args = [[f'-signetchallenge={challenge.hex()}']] + + def skip_test_if_missing_module(self): + self.skip_if_no_cli() + self.skip_if_no_wallet() + self.skip_if_no_bitcoin_util() + + def run_test(self): + node = self.nodes[0] + # import private key needed for signing block + node.importprivkey(bytes_to_wif(CHALLENGE_PRIVATE_KEY)) + + # generate block with signet miner tool + base_dir = self.config["environment"]["SRCDIR"] + signet_miner_path = os.path.join(base_dir, "contrib", "signet", "miner") + subprocess.run([ + sys.executable, + signet_miner_path, + f'--cli={node.cli.binary} -datadir={node.cli.datadir}', + 'generate', + f'--address={node.getnewaddress()}', + f'--grind-cmd={self.options.bitcoinutil} grind', + '--nbits=1d00ffff', + f'--set-block-time={int(time.time())}', + ], check=True, stderr=subprocess.STDOUT) + assert_equal(node.getblockcount(), 1) + + +if __name__ == "__main__": + SignetMinerTest().main()