Skip to content

Commit

Permalink
Use distinct data dirs for each signet
Browse files Browse the repository at this point in the history
If the -signetchallenge argument is provided,
the hash-160 (first 8 characters) of the challenge is appended to the datadir name,
resulting in unique data directories for each signet, i.e., signet_XXXXXXX.
  • Loading branch information
BrandonOdiwuor committed May 17, 2024
1 parent 0f0e36d commit ac1ccd5
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 10 deletions.
26 changes: 24 additions & 2 deletions src/common/args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <common/args.h>

#include <hash.h>
#include <chainparamsbase.h>
#include <common/settings.h>
#include <logging.h>
Expand Down Expand Up @@ -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<uint8_t> 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);
Expand All @@ -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;
Expand All @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions src/common/args.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ class ArgsManager
*/
std::optional<const Command> 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
*
Expand Down
2 changes: 1 addition & 1 deletion test/functional/interface_bitcoin_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
2 changes: 1 addition & 1 deletion test/functional/rpc_bind.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
11 changes: 11 additions & 0 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
p2p_port,
wait_until_helper_internal,
)
from .script import hash160


class TestStatus(Enum):
Expand Down Expand Up @@ -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"""

Expand Down
10 changes: 7 additions & 3 deletions test/functional/test_framework/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
7 changes: 4 additions & 3 deletions test/functional/tool_signet_miner.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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',
Expand Down

0 comments on commit ac1ccd5

Please sign in to comment.