diff --git a/src/common/args.cpp b/src/common/args.cpp index c90eb0c6856d8..6a879fc070c04 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -5,6 +5,7 @@ #include +#include #include #include #include @@ -277,6 +278,18 @@ fs::path ArgsManager::GetPathArg(std::string arg, const fs::path& default_value) return result.has_filename() ? result : result.parent_path(); } +fs::path ArgsManager::GetSignetDataDir() const +{ + const std::string base_data_dir = BaseParams().DataDir(); + const std::string signet_challenge_str = GetArg("-signetchallenge", ""); + if (!signet_challenge_str.empty()) { + std::vector signet_challenge = ParseHex(signet_challenge_str); + const auto data_dir_suffix = HexStr(Hash160(signet_challenge)).substr(0, 8); + return fs::PathFromString(base_data_dir + "_" + data_dir_suffix); + } + return fs::PathFromString(base_data_dir); +} + fs::path ArgsManager::GetBlocksDirPath() const { LOCK(cs_args); @@ -296,7 +309,12 @@ fs::path ArgsManager::GetBlocksDirPath() const path = GetDataDirBase(); } - path /= fs::PathFromString(BaseParams().DataDir()); + if (GetChainType() == ChainType::SIGNET) { + path /= GetSignetDataDir(); + } else { + path /= fs::PathFromString(BaseParams().DataDir()); + } + path /= "blocks"; fs::create_directories(path); return path; @@ -322,7 +340,11 @@ fs::path ArgsManager::GetDataDir(bool net_specific) const } if (net_specific && !BaseParams().DataDir().empty()) { - path /= fs::PathFromString(BaseParams().DataDir()); + if (GetChainType() == ChainType::SIGNET) { + path /= GetSignetDataDir(); + } else { + path /= fs::PathFromString(BaseParams().DataDir()); + } } return path; diff --git a/src/common/args.h b/src/common/args.h index 78a61313b91df..d7099f956e67a 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -210,6 +210,14 @@ class ArgsManager */ std::optional GetCommand() const; + /** + * Get signet data directory path. + * If a signet-challange argument is provided, it is used in constructing the directory path. + * + * @return The path to the signet data directory. + */ + fs::path GetSignetDataDir() const; + /** * Get blocks directory path * diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py index 83bb5121e5b4a..0acf6eea75cf3 100755 --- a/test/functional/interface_bitcoin_cli.py +++ b/test/functional/interface_bitcoin_cli.py @@ -94,7 +94,7 @@ def run_test(self): assert_equal(self.nodes[0].cli("-named", "echo", "arg0=0", "arg1=1", "arg2=2", "arg1=3").send_cli(), ['0', '3', '2']) assert_raises_rpc_error(-8, "Parameter args specified multiple times", self.nodes[0].cli("-named", "echo", "args=[0,1,2,3]", "4", "5", "6", ).send_cli) - user, password = get_auth_cookie(self.nodes[0].datadir_path, self.chain) + user, password = get_auth_cookie(self.nodes[0].datadir_path, self.nodes[0].get_chain()) self.log.info("Test -stdinrpcpass option") assert_equal(BLOCKS, self.nodes[0].cli(f'-rpcuser={user}', '-stdinrpcpass', input=password).getblockcount()) diff --git a/test/functional/rpc_bind.py b/test/functional/rpc_bind.py index 3106419e5cd4c..7077beabf6071 100755 --- a/test/functional/rpc_bind.py +++ b/test/functional/rpc_bind.py @@ -58,7 +58,7 @@ def run_allowip_test(self, allow_ips, rpchost, rpcport): self.nodes[0].rpchost = None self.start_nodes([node_args]) # connect to node through non-loopback interface - node = get_rpc_proxy(rpc_url(self.nodes[0].datadir_path, 0, self.chain, "%s:%d" % (rpchost, rpcport)), 0, coveragedir=self.options.coveragedir) + node = get_rpc_proxy(rpc_url(self.nodes[0].datadir_path, 0, self.nodes[0].get_chain(), "%s:%d" % (rpchost, rpcport)), 0, coveragedir=self.options.coveragedir) node.getnetworkinfo() self.stop_nodes() diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index c3884270da685..4610243ba33a6 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -35,6 +35,7 @@ p2p_port, wait_until_helper_internal, ) +from .script import hash160 class TestStatus(Enum): @@ -536,11 +537,21 @@ def get_bin_from_version(version, bin_name, bin_default): descriptors=self.options.descriptors, v2transport=self.options.v2transport, ) + if self.chain == "signet": + test_node_i.signet_chain = self.get_signet_chain(args) self.nodes.append(test_node_i) if not test_node_i.version_is_at_least(170000): # adjust conf for pre 17 test_node_i.replace_in_config([('[regtest]', '')]) + def get_signet_chain(self, args): + for arg in args: + if arg.startswith('-signetchallenge'): + signetchallenge = arg.split('=')[1] + data_dir_suffix = hash160(bytes.fromhex(signetchallenge)).hex()[0:8] + return f"signet_{data_dir_suffix}" + return 'signet' + def start_node(self, i, *args, **kwargs): """Start a bitcoind""" diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 67e0be52801a7..a39136eca7501 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -82,6 +82,7 @@ def __init__(self, i, datadir_path, *, chain, rpchost, timewait, timeout_factor, self.stdout_dir = self.datadir_path / "stdout" self.stderr_dir = self.datadir_path / "stderr" self.chain = chain + self.signet_chain = "" self.rpchost = rpchost self.rpc_timeout = timewait self.binary = bitcoind @@ -174,6 +175,9 @@ def __init__(self, i, datadir_path, *, chain, rpchost, timewait, timeout_factor, AddressKeyPair('mzRe8QZMfGi58KyWCse2exxEFry2sfF2Y7', 'cPiRWE8KMjTRxH1MWkPerhfoHFn5iHPWVK5aPqjW8NxmdwenFinJ'), ] + def get_chain(self): + return self.signet_chain if self.chain == 'signet' else self.chain + def get_deterministic_priv_key(self): """Return a deterministic priv key in base58, that only depends on the node's index""" assert len(self.PRIV_KEYS) == MAX_NODES @@ -256,7 +260,7 @@ def wait_for_rpc_connection(self): f'bitcoind exited with status {self.process.returncode} during initialization. {str_error}')) try: rpc = get_rpc_proxy( - rpc_url(self.datadir_path, self.index, self.chain, self.rpchost), + rpc_url(self.datadir_path, self.index, self.get_chain(), self.rpchost), self.index, timeout=self.rpc_timeout // 2, # Shorter timeout to allow for one retry in case of ETIMEDOUT coveragedir=self.coverage_dir, @@ -320,7 +324,7 @@ def wait_for_cookie_credentials(self): poll_per_s = 4 for _ in range(poll_per_s * self.rpc_timeout): try: - get_auth_cookie(self.datadir_path, self.chain) + get_auth_cookie(self.datadir_path, self.get_chain()) self.log.debug("Cookie credentials successfully retrieved") return except ValueError: # cookie file not found and no rpcuser or rpcpassword; bitcoind is still starting @@ -439,7 +443,7 @@ def replace_in_config(self, replacements): @property def chain_path(self) -> Path: - return self.datadir_path / self.chain + return self.datadir_path / self.get_chain() @property def debug_log_path(self) -> Path: diff --git a/test/functional/tool_signet_miner.py b/test/functional/tool_signet_miner.py index 1ad2a579bfb9e..c6e2ba53f314b 100755 --- a/test/functional/tool_signet_miner.py +++ b/test/functional/tool_signet_miner.py @@ -32,8 +32,8 @@ def set_test_params(self): 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()}']] + self.challenge = key_to_p2wpkh_script(pubkey) + self.extra_args = [[f'-signetchallenge={self.challenge.hex()}']] def skip_test_if_missing_module(self): self.skip_if_no_cli() @@ -48,10 +48,11 @@ def run_test(self): # generate block with signet miner tool base_dir = self.config["environment"]["SRCDIR"] signet_miner_path = os.path.join(base_dir, "contrib", "signet", "miner") + # breakpoint() subprocess.run([ sys.executable, signet_miner_path, - f'--cli={node.cli.binary} -datadir={node.cli.datadir}', + f'--cli={node.cli.binary} -datadir={node.cli.datadir} -signetchallenge={self.challenge.hex()}', 'generate', f'--address={node.getnewaddress()}', f'--grind-cmd={self.options.bitcoinutil} grind',