mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-12 18:44:59 +01:00
Use distinct data dirs for each signet
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.
This commit is contained in:
parent
c773618886
commit
f1b40b4de4
7 changed files with 56 additions and 10 deletions
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <common/args.h>
|
#include <common/args.h>
|
||||||
|
|
||||||
|
#include <hash.h>
|
||||||
#include <chainparamsbase.h>
|
#include <chainparamsbase.h>
|
||||||
#include <common/settings.h>
|
#include <common/settings.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
@ -279,6 +280,18 @@ fs::path ArgsManager::GetPathArg(std::string arg, const fs::path& default_value)
|
||||||
return result.has_filename() ? result : result.parent_path();
|
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
|
fs::path ArgsManager::GetBlocksDirPath() const
|
||||||
{
|
{
|
||||||
LOCK(cs_args);
|
LOCK(cs_args);
|
||||||
|
@ -298,7 +311,12 @@ fs::path ArgsManager::GetBlocksDirPath() const
|
||||||
path = GetDataDirBase();
|
path = GetDataDirBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetChainType() == ChainType::SIGNET) {
|
||||||
|
path /= GetSignetDataDir();
|
||||||
|
} else {
|
||||||
path /= fs::PathFromString(BaseParams().DataDir());
|
path /= fs::PathFromString(BaseParams().DataDir());
|
||||||
|
}
|
||||||
|
|
||||||
path /= "blocks";
|
path /= "blocks";
|
||||||
fs::create_directories(path);
|
fs::create_directories(path);
|
||||||
return path;
|
return path;
|
||||||
|
@ -324,8 +342,12 @@ fs::path ArgsManager::GetDataDir(bool net_specific) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (net_specific && !BaseParams().DataDir().empty()) {
|
if (net_specific && !BaseParams().DataDir().empty()) {
|
||||||
|
if (GetChainType() == ChainType::SIGNET) {
|
||||||
|
path /= GetSignetDataDir();
|
||||||
|
} else {
|
||||||
path /= fs::PathFromString(BaseParams().DataDir());
|
path /= fs::PathFromString(BaseParams().DataDir());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,6 +212,14 @@ protected:
|
||||||
*/
|
*/
|
||||||
std::optional<const Command> GetCommand() const;
|
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
|
* Get blocks directory path
|
||||||
*
|
*
|
||||||
|
|
|
@ -96,7 +96,7 @@ class TestBitcoinCli(BitcoinTestFramework):
|
||||||
assert_equal(self.nodes[0].cli("-named", "echo", "arg0=0", "arg1=1", "arg2=2", "arg1=3").send_cli(), ['0', '3', '2'])
|
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)
|
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")
|
self.log.info("Test -stdinrpcpass option")
|
||||||
assert_equal(BLOCKS, self.nodes[0].cli(f'-rpcuser={user}', '-stdinrpcpass', input=password).getblockcount())
|
assert_equal(BLOCKS, self.nodes[0].cli(f'-rpcuser={user}', '-stdinrpcpass', input=password).getblockcount())
|
||||||
|
|
|
@ -58,7 +58,7 @@ class RPCBindTest(BitcoinTestFramework):
|
||||||
self.nodes[0].rpchost = None
|
self.nodes[0].rpchost = None
|
||||||
self.start_nodes([node_args])
|
self.start_nodes([node_args])
|
||||||
# connect to node through non-loopback interface
|
# 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()
|
node.getnetworkinfo()
|
||||||
self.stop_nodes()
|
self.stop_nodes()
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ from .util import (
|
||||||
p2p_port,
|
p2p_port,
|
||||||
wait_until_helper_internal,
|
wait_until_helper_internal,
|
||||||
)
|
)
|
||||||
|
from .script import hash160
|
||||||
|
|
||||||
|
|
||||||
class TestStatus(Enum):
|
class TestStatus(Enum):
|
||||||
|
@ -540,11 +541,21 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
||||||
descriptors=self.options.descriptors,
|
descriptors=self.options.descriptors,
|
||||||
v2transport=self.options.v2transport,
|
v2transport=self.options.v2transport,
|
||||||
)
|
)
|
||||||
|
if self.chain == "signet":
|
||||||
|
test_node_i.signet_chain = self.get_signet_chain(args)
|
||||||
self.nodes.append(test_node_i)
|
self.nodes.append(test_node_i)
|
||||||
if not test_node_i.version_is_at_least(170000):
|
if not test_node_i.version_is_at_least(170000):
|
||||||
# adjust conf for pre 17
|
# adjust conf for pre 17
|
||||||
test_node_i.replace_in_config([('[regtest]', '')])
|
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):
|
def start_node(self, i, *args, **kwargs):
|
||||||
"""Start a bitcoind"""
|
"""Start a bitcoind"""
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,7 @@ class TestNode():
|
||||||
self.stdout_dir = self.datadir_path / "stdout"
|
self.stdout_dir = self.datadir_path / "stdout"
|
||||||
self.stderr_dir = self.datadir_path / "stderr"
|
self.stderr_dir = self.datadir_path / "stderr"
|
||||||
self.chain = chain
|
self.chain = chain
|
||||||
|
self.signet_chain = ""
|
||||||
self.rpchost = rpchost
|
self.rpchost = rpchost
|
||||||
self.rpc_timeout = timewait
|
self.rpc_timeout = timewait
|
||||||
self.binary = bitcoind
|
self.binary = bitcoind
|
||||||
|
@ -183,6 +184,9 @@ class TestNode():
|
||||||
AddressKeyPair('mzRe8QZMfGi58KyWCse2exxEFry2sfF2Y7', 'cPiRWE8KMjTRxH1MWkPerhfoHFn5iHPWVK5aPqjW8NxmdwenFinJ'),
|
AddressKeyPair('mzRe8QZMfGi58KyWCse2exxEFry2sfF2Y7', 'cPiRWE8KMjTRxH1MWkPerhfoHFn5iHPWVK5aPqjW8NxmdwenFinJ'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_chain(self):
|
||||||
|
return self.signet_chain if self.chain == 'signet' else self.chain
|
||||||
|
|
||||||
def get_deterministic_priv_key(self):
|
def get_deterministic_priv_key(self):
|
||||||
"""Return a deterministic priv key in base58, that only depends on the node's index"""
|
"""Return a deterministic priv key in base58, that only depends on the node's index"""
|
||||||
assert len(self.PRIV_KEYS) == MAX_NODES
|
assert len(self.PRIV_KEYS) == MAX_NODES
|
||||||
|
@ -276,7 +280,7 @@ class TestNode():
|
||||||
f'bitcoind exited with status {self.process.returncode} during initialization. {str_error}'))
|
f'bitcoind exited with status {self.process.returncode} during initialization. {str_error}'))
|
||||||
try:
|
try:
|
||||||
rpc = get_rpc_proxy(
|
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,
|
self.index,
|
||||||
timeout=self.rpc_timeout // 2, # Shorter timeout to allow for one retry in case of ETIMEDOUT
|
timeout=self.rpc_timeout // 2, # Shorter timeout to allow for one retry in case of ETIMEDOUT
|
||||||
coveragedir=self.coverage_dir,
|
coveragedir=self.coverage_dir,
|
||||||
|
@ -340,7 +344,7 @@ class TestNode():
|
||||||
poll_per_s = 4
|
poll_per_s = 4
|
||||||
for _ in range(poll_per_s * self.rpc_timeout):
|
for _ in range(poll_per_s * self.rpc_timeout):
|
||||||
try:
|
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")
|
self.log.debug("Cookie credentials successfully retrieved")
|
||||||
return
|
return
|
||||||
except ValueError: # cookie file not found and no rpcuser or rpcpassword; bitcoind is still starting
|
except ValueError: # cookie file not found and no rpcuser or rpcpassword; bitcoind is still starting
|
||||||
|
@ -460,7 +464,7 @@ class TestNode():
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def chain_path(self) -> Path:
|
def chain_path(self) -> Path:
|
||||||
return self.datadir_path / self.chain
|
return self.datadir_path / self.get_chain()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def debug_log_path(self) -> Path:
|
def debug_log_path(self) -> Path:
|
||||||
|
|
|
@ -32,8 +32,8 @@ class SignetMinerTest(BitcoinTestFramework):
|
||||||
privkey = ECKey()
|
privkey = ECKey()
|
||||||
privkey.set(CHALLENGE_PRIVATE_KEY, True)
|
privkey.set(CHALLENGE_PRIVATE_KEY, True)
|
||||||
pubkey = privkey.get_pubkey().get_bytes()
|
pubkey = privkey.get_pubkey().get_bytes()
|
||||||
challenge = key_to_p2wpkh_script(pubkey)
|
self.challenge = key_to_p2wpkh_script(pubkey)
|
||||||
self.extra_args = [[f'-signetchallenge={challenge.hex()}']]
|
self.extra_args = [[f'-signetchallenge={self.challenge.hex()}']]
|
||||||
|
|
||||||
def skip_test_if_missing_module(self):
|
def skip_test_if_missing_module(self):
|
||||||
self.skip_if_no_cli()
|
self.skip_if_no_cli()
|
||||||
|
@ -48,10 +48,11 @@ class SignetMinerTest(BitcoinTestFramework):
|
||||||
# generate block with signet miner tool
|
# generate block with signet miner tool
|
||||||
base_dir = self.config["environment"]["SRCDIR"]
|
base_dir = self.config["environment"]["SRCDIR"]
|
||||||
signet_miner_path = os.path.join(base_dir, "contrib", "signet", "miner")
|
signet_miner_path = os.path.join(base_dir, "contrib", "signet", "miner")
|
||||||
|
# breakpoint()
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
sys.executable,
|
sys.executable,
|
||||||
signet_miner_path,
|
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',
|
'generate',
|
||||||
f'--address={node.getnewaddress()}',
|
f'--address={node.getnewaddress()}',
|
||||||
f'--grind-cmd={self.options.bitcoinutil} grind',
|
f'--grind-cmd={self.options.bitcoinutil} grind',
|
||||||
|
|
Loading…
Add table
Reference in a new issue