mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-19 01:42:58 +01:00
testnet: Introduce Testnet4
This commit is contained in:
parent
902dd14382
commit
74a04f9e7a
@ -9,7 +9,7 @@ _bitcoin_rpc() {
|
||||
local rpcargs=()
|
||||
for i in ${COMP_LINE}; do
|
||||
case "$i" in
|
||||
-conf=*|-datadir=*|-regtest|-rpc*|-testnet)
|
||||
-conf=*|-datadir=*|-regtest|-rpc*|-testnet|-testnet4)
|
||||
rpcargs=( "${rpcargs[@]}" "$i" )
|
||||
;;
|
||||
esac
|
||||
|
@ -5,11 +5,12 @@
|
||||
'''
|
||||
Script to generate list of seed nodes for kernel/chainparams.cpp.
|
||||
|
||||
This script expects two text files in the directory that is passed as an
|
||||
This script expects three text files in the directory that is passed as an
|
||||
argument:
|
||||
|
||||
nodes_main.txt
|
||||
nodes_test.txt
|
||||
nodes_testnet4.txt
|
||||
|
||||
These files must consist of lines in the format
|
||||
|
||||
@ -171,6 +172,9 @@ def main():
|
||||
g.write('\n')
|
||||
with open(os.path.join(indir,'nodes_test.txt'), 'r', encoding="utf8") as f:
|
||||
process_nodes(g, f, 'chainparams_seed_test')
|
||||
g.write('\n')
|
||||
with open(os.path.join(indir,'nodes_testnet4.txt'), 'r', encoding="utf8") as f:
|
||||
process_nodes(g, f, 'chainparams_seed_testnet4')
|
||||
g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -4,7 +4,7 @@ Unauthenticated REST Interface
|
||||
The REST API can be enabled with the `-rest` option.
|
||||
|
||||
The interface runs on the same port as the JSON-RPC interface, by default port 8332 for mainnet, port 18332 for testnet,
|
||||
port 38332 for signet, and port 18443 for regtest.
|
||||
port 48332 for testnet4, port 38332 for signet, and port 18443 for regtest.
|
||||
|
||||
REST Interface consistency guarantees
|
||||
-------------------------------------
|
||||
|
13
doc/files.md
13
doc/files.md
@ -34,12 +34,13 @@ Windows | `%LOCALAPPDATA%\Bitcoin\` <sup>[\[1\]](#note1)</sup>
|
||||
|
||||
3. All content of the data directory, except for `bitcoin.conf` file, is chain-specific. This means the actual data directory paths for non-mainnet cases differ:
|
||||
|
||||
Chain option | Data directory path
|
||||
-------------------------------|------------------------------
|
||||
`-chain=main` (default) | *path_to_datadir*`/`
|
||||
`-chain=test` or `-testnet` | *path_to_datadir*`/testnet3/`
|
||||
`-chain=signet` or `-signet` | *path_to_datadir*`/signet/`
|
||||
`-chain=regtest` or `-regtest` | *path_to_datadir*`/regtest/`
|
||||
Chain option | Data directory path
|
||||
---------------------------------|------------------------------
|
||||
`-chain=main` (default) | *path_to_datadir*`/`
|
||||
`-chain=test` or `-testnet` | *path_to_datadir*`/testnet3/`
|
||||
`-chain=testnet4` or `-testnet4` | *path_to_datadir*`/testnet4/`
|
||||
`-chain=signet` or `-signet` | *path_to_datadir*`/signet/`
|
||||
`-chain=regtest` or `-regtest` | *path_to_datadir*`/regtest/`
|
||||
|
||||
## Data directory layout
|
||||
|
||||
|
@ -311,13 +311,15 @@ Both variables are used as a guideline for how much space the user needs on thei
|
||||
Note that all values should be taken from a **fully synced** node and have an overhead of 5-10% added on top of its base value.
|
||||
|
||||
To calculate `m_assumed_blockchain_size`, take the size in GiB of these directories:
|
||||
- For `mainnet` -> the data directory, excluding the `/testnet3`, `/signet`, and `/regtest` directories and any overly large files, e.g. a huge `debug.log`
|
||||
- For `mainnet` -> the data directory, excluding the `/testnet3`, `/testnet4`, `/signet`, and `/regtest` directories and any overly large files, e.g. a huge `debug.log`
|
||||
- For `testnet` -> `/testnet3`
|
||||
- For `testnet4` -> `/testnet4`
|
||||
- For `signet` -> `/signet`
|
||||
|
||||
To calculate `m_assumed_chain_state_size`, take the size in GiB of these directories:
|
||||
- For `mainnet` -> `/chainstate`
|
||||
- For `testnet` -> `/testnet3/chainstate`
|
||||
- For `testnet4` -> `/testnet4/chainstate`
|
||||
- For `signet` -> `/signet/chainstate`
|
||||
|
||||
Notes:
|
||||
|
@ -75,6 +75,7 @@ static void SetupCliArgs(ArgsManager& argsman)
|
||||
|
||||
const auto defaultBaseParams = CreateBaseChainParams(ChainType::MAIN);
|
||||
const auto testnetBaseParams = CreateBaseChainParams(ChainType::TESTNET);
|
||||
const auto testnet4BaseParams = CreateBaseChainParams(ChainType::TESTNET4);
|
||||
const auto signetBaseParams = CreateBaseChainParams(ChainType::SIGNET);
|
||||
const auto regtestBaseParams = CreateBaseChainParams(ChainType::REGTEST);
|
||||
|
||||
@ -98,7 +99,7 @@ static void SetupCliArgs(ArgsManager& argsman)
|
||||
argsman.AddArg("-rpcconnect=<ip>", strprintf("Send commands to node running on <ip> (default: %s)", DEFAULT_RPCCONNECT), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-rpcport=<port>", strprintf("Connect to JSON-RPC on <port> (default: %u, testnet: %u, signet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), signetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-rpcport=<port>", strprintf("Connect to JSON-RPC on <port> (default: %u, testnet: %u, testnet4: %u, signet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), testnet4BaseParams->RPCPort(), signetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-rpcwait", "Wait for RPC server to start", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-rpcwaittimeout=<n>", strprintf("Timeout in seconds to wait for the RPC server to start, or 0 for no timeout. (default: %d)", DEFAULT_WAIT_CLIENT_TIMEOUT), ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);
|
||||
@ -428,6 +429,8 @@ private:
|
||||
std::string ChainToString() const
|
||||
{
|
||||
switch (gArgs.GetChainType()) {
|
||||
case ChainType::TESTNET4:
|
||||
return " testnet4";
|
||||
case ChainType::TESTNET:
|
||||
return " testnet";
|
||||
case ChainType::SIGNET:
|
||||
|
@ -69,7 +69,7 @@ static std::optional<int> WalletAppInit(ArgsManager& args, int argc, char* argv[
|
||||
strUsage += "\n"
|
||||
"bitcoin-wallet is an offline tool for creating and interacting with " PACKAGE_NAME " wallet files.\n"
|
||||
"By default bitcoin-wallet will act on wallets in the default mainnet wallet directory in the datadir.\n"
|
||||
"To change the target wallet, use the -datadir, -wallet and -regtest/-signet/-testnet arguments.\n\n"
|
||||
"To change the target wallet, use the -datadir, -wallet and -regtest/-signet/-testnet/-testnet4 arguments.\n\n"
|
||||
"Usage:\n"
|
||||
" bitcoin-wallet [options] <command>\n";
|
||||
strUsage += "\n" + args.GetHelpMessage();
|
||||
|
@ -115,6 +115,8 @@ std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, c
|
||||
return CChainParams::Main();
|
||||
case ChainType::TESTNET:
|
||||
return CChainParams::TestNet();
|
||||
case ChainType::TESTNET4:
|
||||
return CChainParams::TestNet4();
|
||||
case ChainType::SIGNET: {
|
||||
auto opts = CChainParams::SigNetOptions{};
|
||||
ReadSigNetArgs(args, opts);
|
||||
|
@ -17,7 +17,8 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
|
||||
argsman.AddArg("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. "
|
||||
"This is intended for regression testing tools and app development. Equivalent to -chain=regtest.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (segwit, bip34, dersig, cltv, csv). (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||
argsman.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-testnet", "Use the testnet3 chain. Equivalent to -chain=test. Support for testnet3 is deprecated and will be removed with the next release. Consider moving to testnet4 now by using -testnet4.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-testnet4", "Use the testnet4 chain. Equivalent to -chain=testnet4.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-vbparams=deployment:start:end[:min_activation_height]", "Use given start/end times and min_activation_height for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-signet", "Use the signet chain. Equivalent to -chain=signet. Note that the network is defined by the -signetchallenge parameter", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-signetchallenge", "Blocks must satisfy the given script to be considered valid (only for signet networks; defaults to the global default signet test network challenge)", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::CHAINPARAMS);
|
||||
@ -33,7 +34,7 @@ const CBaseChainParams& BaseParams()
|
||||
}
|
||||
|
||||
/**
|
||||
* Port numbers for incoming Tor connections (8334, 18334, 38334, 18445) have
|
||||
* Port numbers for incoming Tor connections (8334, 18334, 38334, 48334, 18445) have
|
||||
* been chosen arbitrarily to keep ranges of used ports tight.
|
||||
*/
|
||||
std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const ChainType chain)
|
||||
@ -43,6 +44,8 @@ std::unique_ptr<CBaseChainParams> CreateBaseChainParams(const ChainType chain)
|
||||
return std::make_unique<CBaseChainParams>("", 8332, 8334);
|
||||
case ChainType::TESTNET:
|
||||
return std::make_unique<CBaseChainParams>("testnet3", 18332, 18334);
|
||||
case ChainType::TESTNET4:
|
||||
return std::make_unique<CBaseChainParams>("testnet4", 48332, 48334);
|
||||
case ChainType::SIGNET:
|
||||
return std::make_unique<CBaseChainParams>("signet", 38332, 38334);
|
||||
case ChainType::REGTEST:
|
||||
|
@ -1786,4 +1786,16 @@ static const uint8_t chainparams_seed_test[] = {
|
||||
0x04,0x20,0xbd,0x0e,0xc8,0x73,0x43,0xa7,0xc6,0x25,0x15,0xcf,0x3e,0x23,0xa8,0xb0,0xbf,0xe8,0x20,0xa7,0xec,0x2a,0xf6,0x37,0x6c,0x60,0x5e,0x4d,0xed,0xf4,0xb1,0xef,0xf7,0xb2,0x47,0x9d,
|
||||
0x04,0x20,0xc8,0x88,0xfe,0x71,0x5f,0xa3,0x6c,0x96,0x6a,0xd7,0x9e,0x38,0x84,0x9f,0x44,0xe1,0x6b,0xdc,0x98,0x31,0xad,0x96,0x29,0xe7,0x00,0x83,0x63,0x03,0xae,0x69,0x2e,0x63,0x47,0x9d,
|
||||
};
|
||||
|
||||
static const uint8_t chainparams_seed_testnet4[] = {
|
||||
0x01,0x04,0x39,0x80,0xb0,0xa3,0xbc,0xcd,
|
||||
0x01,0x04,0x33,0x9e,0xf8,0x08,0xbc,0xcd,
|
||||
0x01,0x04,0x5f,0xd9,0x49,0xa2,0xbc,0xcd,
|
||||
0x01,0x04,0x12,0xbd,0x9c,0x66,0xbc,0xcd,
|
||||
0x01,0x04,0x67,0x63,0xab,0xd4,0xbc,0xcd,
|
||||
0x01,0x04,0x52,0x43,0x66,0x0f,0xbc,0xcd,
|
||||
0x01,0x04,0x58,0x63,0xf8,0x32,0xbc,0xcd,
|
||||
0x01,0x04,0x67,0xa5,0xc0,0xd2,0xbc,0xcd,
|
||||
0x01,0x04,0x12,0xc9,0xcf,0x37,0xbc,0xcd,
|
||||
};
|
||||
#endif // BITCOIN_CHAINPARAMSSEEDS_H
|
||||
|
@ -159,6 +159,7 @@ std::list<SectionInfo> ArgsManager::GetUnrecognizedSections() const
|
||||
ChainTypeToString(ChainType::REGTEST),
|
||||
ChainTypeToString(ChainType::SIGNET),
|
||||
ChainTypeToString(ChainType::TESTNET),
|
||||
ChainTypeToString(ChainType::TESTNET4),
|
||||
ChainTypeToString(ChainType::MAIN),
|
||||
};
|
||||
|
||||
@ -773,10 +774,11 @@ std::variant<ChainType, std::string> ArgsManager::GetChainArg() const
|
||||
const bool fRegTest = get_net("-regtest");
|
||||
const bool fSigNet = get_net("-signet");
|
||||
const bool fTestNet = get_net("-testnet");
|
||||
const bool fTestNet4 = get_net("-testnet4");
|
||||
const auto chain_arg = GetArg("-chain");
|
||||
|
||||
if ((int)chain_arg.has_value() + (int)fRegTest + (int)fSigNet + (int)fTestNet > 1) {
|
||||
throw std::runtime_error("Invalid combination of -regtest, -signet, -testnet and -chain. Can use at most one.");
|
||||
if ((int)chain_arg.has_value() + (int)fRegTest + (int)fSigNet + (int)fTestNet + (int)fTestNet4 > 1) {
|
||||
throw std::runtime_error("Invalid combination of -regtest, -signet, -testnet, -testnet4 and -chain. Can use at most one.");
|
||||
}
|
||||
if (chain_arg) {
|
||||
if (auto parsed = ChainTypeFromString(*chain_arg)) return *parsed;
|
||||
@ -786,6 +788,7 @@ std::variant<ChainType, std::string> ArgsManager::GetChainArg() const
|
||||
if (fRegTest) return ChainType::REGTEST;
|
||||
if (fSigNet) return ChainType::SIGNET;
|
||||
if (fTestNet) return ChainType::TESTNET;
|
||||
if (fTestNet4) return ChainType::TESTNET4;
|
||||
return ChainType::MAIN;
|
||||
}
|
||||
|
||||
|
@ -423,7 +423,7 @@ private:
|
||||
fs::path GetDataDir(bool net_specific) const;
|
||||
|
||||
/**
|
||||
* Return -regtest/-signet/-testnet/-chain= setting as a ChainType enum if a
|
||||
* Return -regtest/-signet/-testnet/-testnet4/-chain= setting as a ChainType enum if a
|
||||
* recognized chain type was set, or as a string if an unrecognized chain
|
||||
* name was set. Raise an exception if an invalid combination of flags was
|
||||
* provided.
|
||||
|
@ -108,6 +108,7 @@ struct Params {
|
||||
/** Proof of work parameters */
|
||||
uint256 powLimit;
|
||||
bool fPowAllowMinDifficultyBlocks;
|
||||
bool enforce_BIP94;
|
||||
bool fPowNoRetargeting;
|
||||
int64_t nPowTargetSpacing;
|
||||
int64_t nPowTargetTimespan;
|
||||
|
17
src/init.cpp
17
src/init.cpp
@ -450,10 +450,12 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
|
||||
const auto defaultBaseParams = CreateBaseChainParams(ChainType::MAIN);
|
||||
const auto testnetBaseParams = CreateBaseChainParams(ChainType::TESTNET);
|
||||
const auto testnet4BaseParams = CreateBaseChainParams(ChainType::TESTNET4);
|
||||
const auto signetBaseParams = CreateBaseChainParams(ChainType::SIGNET);
|
||||
const auto regtestBaseParams = CreateBaseChainParams(ChainType::REGTEST);
|
||||
const auto defaultChainParams = CreateChainParams(argsman, ChainType::MAIN);
|
||||
const auto testnetChainParams = CreateChainParams(argsman, ChainType::TESTNET);
|
||||
const auto testnet4ChainParams = CreateChainParams(argsman, ChainType::TESTNET4);
|
||||
const auto signetChainParams = CreateChainParams(argsman, ChainType::SIGNET);
|
||||
const auto regtestChainParams = CreateChainParams(argsman, ChainType::REGTEST);
|
||||
|
||||
@ -467,7 +469,7 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
#if HAVE_SYSTEM
|
||||
argsman.AddArg("-alertnotify=<cmd>", "Execute command when an alert is raised (%s in cmd is replaced by message)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
#endif
|
||||
argsman.AddArg("-assumevalid=<hex>", strprintf("If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s, signet: %s)", defaultChainParams->GetConsensus().defaultAssumeValid.GetHex(), testnetChainParams->GetConsensus().defaultAssumeValid.GetHex(), signetChainParams->GetConsensus().defaultAssumeValid.GetHex()), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-assumevalid=<hex>", strprintf("If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet3: %s, testnet4: %s, signet: %s)", defaultChainParams->GetConsensus().defaultAssumeValid.GetHex(), testnetChainParams->GetConsensus().defaultAssumeValid.GetHex(), testnet4ChainParams->GetConsensus().defaultAssumeValid.GetHex(), signetChainParams->GetConsensus().defaultAssumeValid.GetHex()), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-blocksdir=<dir>", "Specify directory to hold blocks subdirectory for *.dat files (default: <datadir>)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-fastprune", "Use smaller block files and lower minimum prune height for testing purposes", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||
#if HAVE_SYSTEM
|
||||
@ -486,7 +488,7 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
argsman.AddArg("-maxmempool=<n>", strprintf("Keep the transaction memory pool below <n> megabytes (default: %u)", DEFAULT_MAX_MEMPOOL_SIZE_MB), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-maxorphantx=<n>", strprintf("Keep at most <n> unconnectable transactions in memory (default: %u)", DEFAULT_MAX_ORPHAN_TRANSACTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-mempoolexpiry=<n>", strprintf("Do not keep transactions in the mempool longer than <n> hours (default: %u)", DEFAULT_MEMPOOL_EXPIRY_HOURS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-minimumchainwork=<hex>", strprintf("Minimum work assumed to exist on a valid chain in hex (default: %s, testnet: %s, signet: %s)", defaultChainParams->GetConsensus().nMinimumChainWork.GetHex(), testnetChainParams->GetConsensus().nMinimumChainWork.GetHex(), signetChainParams->GetConsensus().nMinimumChainWork.GetHex()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-minimumchainwork=<hex>", strprintf("Minimum work assumed to exist on a valid chain in hex (default: %s, testnet3: %s, testnet4: %s, signet: %s)", defaultChainParams->GetConsensus().nMinimumChainWork.GetHex(), testnetChainParams->GetConsensus().nMinimumChainWork.GetHex(), testnet4ChainParams->GetConsensus().nMinimumChainWork.GetHex(), signetChainParams->GetConsensus().nMinimumChainWork.GetHex()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-par=<n>", strprintf("Set the number of script verification threads (0 = auto, up to %d, <0 = leave that many cores free, default: %d)",
|
||||
MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
argsman.AddArg("-persistmempool", strprintf("Whether to save the mempool on shutdown and load on restart (default: %u)", DEFAULT_PERSIST_MEMPOOL), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
@ -515,7 +517,7 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
argsman.AddArg("-addnode=<ip>", strprintf("Add a node to connect to and attempt to keep the connection open (see the addnode RPC help for more info). This option can be specified multiple times to add multiple nodes; connections are limited to %u at a time and are counted separately from the -maxconnections limit.", MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-bind=<addr>[:<port>][=onion]", strprintf("Bind to given address and always listen on it (default: 0.0.0.0). Use [host]:port notation for IPv6. Append =onion to tag any incoming connections to that address and port as incoming Tor connections (default: 127.0.0.1:%u=onion, testnet3: 127.0.0.1:%u=onion, testnet4: 127.0.0.1:%u=onion, signet: 127.0.0.1:%u=onion, regtest: 127.0.0.1:%u=onion)", defaultBaseParams->OnionServiceTargetPort(), testnetBaseParams->OnionServiceTargetPort(), testnet4BaseParams->OnionServiceTargetPort(), signetBaseParams->OnionServiceTargetPort(), regtestBaseParams->OnionServiceTargetPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-cjdnsreachable", "If set, then this host is configured for CJDNS (connecting to fc00::/8 addresses would lead us to the CJDNS network, see doc/cjdns.md) (default: 0)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
@ -542,7 +544,7 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-txreconciliation", strprintf("Enable transaction reconciliations per BIP 330 (default: %d)", DEFAULT_TXRECONCILIATION_ENABLE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md).", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet3: %u, testnet4: %u, signet: %u, regtest: %u). Not relevant for I2P (see doc/i2p.md).", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), testnet4ChainParams->GetDefaultPort(), signetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
|
||||
#ifdef HAVE_SOCKADDR_UN
|
||||
argsman.AddArg("-proxy=<ip:port|path>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled). May be a local file path prefixed with 'unix:' if the proxy supports it.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_ELISION, OptionsCategory::CONNECTION);
|
||||
#else
|
||||
@ -659,7 +661,7 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||
argsman.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||
argsman.AddArg("-rpccookieperms=<readable-by>", strprintf("Set permissions on the RPC auth cookie file so that it is readable by [owner|group|all] (default: owner [via umask 0077])"), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||
argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
|
||||
argsman.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u, testnet: %u, signet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), signetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::RPC);
|
||||
argsman.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u, testnet3: %u, testnet4: %u, signet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), testnet4BaseParams->RPCPort(), signetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::RPC);
|
||||
argsman.AddArg("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
|
||||
argsman.AddArg("-rpcthreads=<n>", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||
argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
|
||||
@ -906,6 +908,11 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
||||
return InitError(errors);
|
||||
}
|
||||
|
||||
// Testnet3 deprecation warning
|
||||
if (chain == ChainType::TESTNET) {
|
||||
LogInfo("Warning: Support for testnet3 is deprecated and will be removed in an upcoming release. Consider switching to testnet4.\n");
|
||||
}
|
||||
|
||||
// Warn if unrecognized section name are present in the config file.
|
||||
bilingual_str warnings;
|
||||
for (const auto& section : args.GetUnrecognizedSections()) {
|
||||
|
@ -100,6 +100,7 @@ public:
|
||||
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
|
||||
consensus.nPowTargetSpacing = 10 * 60;
|
||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||
consensus.enforce_BIP94 = false;
|
||||
consensus.fPowNoRetargeting = false;
|
||||
consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
|
||||
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
@ -219,6 +220,7 @@ public:
|
||||
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
|
||||
consensus.nPowTargetSpacing = 10 * 60;
|
||||
consensus.fPowAllowMinDifficultyBlocks = true;
|
||||
consensus.enforce_BIP94 = false;
|
||||
consensus.fPowNoRetargeting = false;
|
||||
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
|
||||
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
@ -296,6 +298,104 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Testnet (v4): public test network which is reset from time to time.
|
||||
*/
|
||||
class CTestNet4Params : public CChainParams {
|
||||
public:
|
||||
CTestNet4Params() {
|
||||
m_chain_type = ChainType::TESTNET4;
|
||||
consensus.signet_blocks = false;
|
||||
consensus.signet_challenge.clear();
|
||||
consensus.nSubsidyHalvingInterval = 210000;
|
||||
consensus.BIP34Height = 1;
|
||||
consensus.BIP34Hash = uint256{};
|
||||
consensus.BIP65Height = 1;
|
||||
consensus.BIP66Height = 1;
|
||||
consensus.CSVHeight = 1;
|
||||
consensus.SegwitHeight = 1;
|
||||
consensus.MinBIP9WarningHeight = 0;
|
||||
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
|
||||
consensus.nPowTargetSpacing = 10 * 60;
|
||||
consensus.fPowAllowMinDifficultyBlocks = true;
|
||||
consensus.enforce_BIP94 = true;
|
||||
consensus.fPowNoRetargeting = false;
|
||||
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
|
||||
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
||||
|
||||
// Deployment of Taproot (BIPs 340-342)
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
||||
|
||||
consensus.nMinimumChainWork = uint256{};
|
||||
consensus.defaultAssumeValid = uint256{};
|
||||
|
||||
pchMessageStart[0] = 0x1c;
|
||||
pchMessageStart[1] = 0x16;
|
||||
pchMessageStart[2] = 0x3f;
|
||||
pchMessageStart[3] = 0x28;
|
||||
nDefaultPort = 48333;
|
||||
nPruneAfterHeight = 1000;
|
||||
m_assumed_blockchain_size = 0;
|
||||
m_assumed_chain_state_size = 0;
|
||||
|
||||
const char* testnet4_genesis_msg = "03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e";
|
||||
const CScript testnet4_genesis_script = CScript() << ParseHex("000000000000000000000000000000000000000000000000000000000000000000") << OP_CHECKSIG;
|
||||
genesis = CreateGenesisBlock(testnet4_genesis_msg,
|
||||
testnet4_genesis_script,
|
||||
1714777860,
|
||||
393743547,
|
||||
0x1d00ffff,
|
||||
1,
|
||||
50 * COIN);
|
||||
consensus.hashGenesisBlock = genesis.GetHash();
|
||||
assert(consensus.hashGenesisBlock == uint256S("0x00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043"));
|
||||
assert(genesis.hashMerkleRoot == uint256S("0x7aa0a7ae1e223414cb807e40cd57e667b718e42aaf9306db9102fe28912b7b4e"));
|
||||
|
||||
vFixedSeeds.clear();
|
||||
vSeeds.clear();
|
||||
// nodes with support for servicebits filtering should be at the top
|
||||
vSeeds.emplace_back("seed.testnet4.bitcoin.sprovoost.nl."); // Sjors Provoost
|
||||
vSeeds.emplace_back("seed.testnet4.wiz.biz."); // Jason Maurice
|
||||
|
||||
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
|
||||
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
|
||||
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
|
||||
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
|
||||
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
|
||||
|
||||
bech32_hrp = "tb";
|
||||
|
||||
vFixedSeeds = std::vector<uint8_t>(std::begin(chainparams_seed_testnet4), std::end(chainparams_seed_testnet4));
|
||||
|
||||
fDefaultConsistencyChecks = false;
|
||||
m_is_mockable_chain = false;
|
||||
|
||||
checkpointData = {
|
||||
{
|
||||
{},
|
||||
}
|
||||
};
|
||||
|
||||
m_assumeutxo_data = {
|
||||
{}
|
||||
};
|
||||
|
||||
chainTxData = ChainTxData{
|
||||
.nTime = 0,
|
||||
.tx_count = 0,
|
||||
.dTxRate = 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Signet: test network with an additional consensus parameter (see BIP325).
|
||||
*/
|
||||
@ -356,6 +456,7 @@ public:
|
||||
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
|
||||
consensus.nPowTargetSpacing = 10 * 60;
|
||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||
consensus.enforce_BIP94 = false;
|
||||
consensus.fPowNoRetargeting = false;
|
||||
consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
|
||||
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
|
||||
@ -434,6 +535,7 @@ public:
|
||||
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
|
||||
consensus.nPowTargetSpacing = 10 * 60;
|
||||
consensus.fPowAllowMinDifficultyBlocks = true;
|
||||
consensus.enforce_BIP94 = false;
|
||||
consensus.fPowNoRetargeting = true;
|
||||
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
|
||||
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
|
||||
@ -563,6 +665,11 @@ std::unique_ptr<const CChainParams> CChainParams::TestNet()
|
||||
return std::make_unique<const CTestNetParams>();
|
||||
}
|
||||
|
||||
std::unique_ptr<const CChainParams> CChainParams::TestNet4()
|
||||
{
|
||||
return std::make_unique<const CTestNet4Params>();
|
||||
}
|
||||
|
||||
std::vector<int> CChainParams::GetAvailableSnapshotHeights() const
|
||||
{
|
||||
std::vector<int> heights;
|
||||
|
@ -161,6 +161,7 @@ public:
|
||||
static std::unique_ptr<const CChainParams> SigNet(const SigNetOptions& options);
|
||||
static std::unique_ptr<const CChainParams> Main();
|
||||
static std::unique_ptr<const CChainParams> TestNet();
|
||||
static std::unique_ptr<const CChainParams> TestNet4();
|
||||
|
||||
protected:
|
||||
CChainParams() = default;
|
||||
|
@ -50,6 +50,7 @@ static const int TOOLTIP_WRAP_THRESHOLD = 80;
|
||||
#define QAPP_ORG_DOMAIN "bitcoin.org"
|
||||
#define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt"
|
||||
#define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet"
|
||||
#define QAPP_APP_NAME_TESTNET4 "Bitcoin-Qt-testnet4"
|
||||
#define QAPP_APP_NAME_SIGNET "Bitcoin-Qt-signet"
|
||||
#define QAPP_APP_NAME_REGTEST "Bitcoin-Qt-regtest"
|
||||
|
||||
|
@ -115,6 +115,7 @@ static std::string DummyAddress(const CChainParams ¶ms)
|
||||
break;
|
||||
case ChainType::SIGNET:
|
||||
case ChainType::TESTNET:
|
||||
case ChainType::TESTNET4:
|
||||
addr = "tb1p35yvjel7srp783ztf8v6jdra7dhfzk5jaun8xz2qp6ws7z80n4tqa6qnlg";
|
||||
break;
|
||||
case ChainType::REGTEST:
|
||||
|
@ -19,6 +19,7 @@ static const struct {
|
||||
} network_styles[] = {
|
||||
{ChainType::MAIN, QAPP_APP_NAME_DEFAULT, 0, 0},
|
||||
{ChainType::TESTNET, QAPP_APP_NAME_TESTNET, 70, 30},
|
||||
{ChainType::TESTNET4, QAPP_APP_NAME_TESTNET4, 70, 30},
|
||||
{ChainType::SIGNET, QAPP_APP_NAME_SIGNET, 35, 15},
|
||||
{ChainType::REGTEST, QAPP_APP_NAME_REGTEST, 160, 30},
|
||||
};
|
||||
|
@ -644,10 +644,12 @@ BOOST_AUTO_TEST_CASE(util_GetChainTypeString)
|
||||
{
|
||||
TestArgsManager test_args;
|
||||
const auto testnet = std::make_pair("-testnet", ArgsManager::ALLOW_ANY);
|
||||
const auto testnet4 = std::make_pair("-testnet4", ArgsManager::ALLOW_ANY);
|
||||
const auto regtest = std::make_pair("-regtest", ArgsManager::ALLOW_ANY);
|
||||
test_args.SetupArgs({testnet, regtest});
|
||||
test_args.SetupArgs({testnet, testnet4, regtest});
|
||||
|
||||
const char* argv_testnet[] = {"cmd", "-testnet"};
|
||||
const char* argv_testnet4[] = {"cmd", "-testnet4"};
|
||||
const char* argv_regtest[] = {"cmd", "-regtest"};
|
||||
const char* argv_test_no_reg[] = {"cmd", "-testnet", "-noregtest"};
|
||||
const char* argv_both[] = {"cmd", "-testnet", "-regtest"};
|
||||
@ -663,6 +665,12 @@ BOOST_AUTO_TEST_CASE(util_GetChainTypeString)
|
||||
BOOST_CHECK(test_args.ParseParameters(2, argv_testnet, error));
|
||||
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "test");
|
||||
|
||||
BOOST_CHECK(test_args.ParseParameters(0, argv_testnet4, error));
|
||||
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "main");
|
||||
|
||||
BOOST_CHECK(test_args.ParseParameters(2, argv_testnet4, error));
|
||||
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "testnet4");
|
||||
|
||||
BOOST_CHECK(test_args.ParseParameters(2, argv_regtest, error));
|
||||
BOOST_CHECK_EQUAL(test_args.GetChainTypeString(), "regtest");
|
||||
|
||||
@ -758,8 +766,8 @@ struct ArgsMergeTestingSetup : public BasicTestingSetup {
|
||||
ForEachNoDup(conf_actions, SET, SECTION_NEGATE, [&] {
|
||||
for (bool soft_set : {false, true}) {
|
||||
for (bool force_set : {false, true}) {
|
||||
for (const std::string& section : {ChainTypeToString(ChainType::MAIN), ChainTypeToString(ChainType::TESTNET), ChainTypeToString(ChainType::SIGNET)}) {
|
||||
for (const std::string& network : {ChainTypeToString(ChainType::MAIN), ChainTypeToString(ChainType::TESTNET), ChainTypeToString(ChainType::SIGNET)}) {
|
||||
for (const std::string& section : {ChainTypeToString(ChainType::MAIN), ChainTypeToString(ChainType::TESTNET), ChainTypeToString(ChainType::TESTNET4), ChainTypeToString(ChainType::SIGNET)}) {
|
||||
for (const std::string& network : {ChainTypeToString(ChainType::MAIN), ChainTypeToString(ChainType::TESTNET), ChainTypeToString(ChainType::TESTNET4), ChainTypeToString(ChainType::SIGNET)}) {
|
||||
for (bool net_specific : {false, true}) {
|
||||
fn(arg_actions, conf_actions, soft_set, force_set, section, network, net_specific);
|
||||
}
|
||||
@ -913,7 +921,7 @@ BOOST_FIXTURE_TEST_CASE(util_ArgsMerge, ArgsMergeTestingSetup)
|
||||
// Results file is formatted like:
|
||||
//
|
||||
// <input> || <IsArgSet/IsArgNegated/GetArg output> | <GetArgs output> | <GetUnsuitable output>
|
||||
BOOST_CHECK_EQUAL(out_sha_hex, "d1e436c1cd510d0ec44d5205d4b4e3bee6387d316e0075c58206cb16603f3d82");
|
||||
BOOST_CHECK_EQUAL(out_sha_hex, "f1ee5ab094cc43d16a6086fa7f2c10389e0f99902616b31bbf29189972ad1473");
|
||||
}
|
||||
|
||||
// Similar test as above, but for ArgsManager::GetChainTypeString function.
|
||||
@ -1016,7 +1024,7 @@ BOOST_FIXTURE_TEST_CASE(util_ChainMerge, ChainMergeTestingSetup)
|
||||
// Results file is formatted like:
|
||||
//
|
||||
// <input> || <output>
|
||||
BOOST_CHECK_EQUAL(out_sha_hex, "f263493e300023b6509963887444c41386f44b63bc30047eb8402e8c1144854c");
|
||||
BOOST_CHECK_EQUAL(out_sha_hex, "9e60306e1363528bbc19a47f22bcede88e5d6815212f18ec8e6cdc4638dddab4");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(util_ReadWriteSettings)
|
||||
|
@ -198,6 +198,11 @@ BOOST_AUTO_TEST_CASE(ChainParams_TESTNET_sanity)
|
||||
sanity_check_chainparams(*m_node.args, ChainType::TESTNET);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ChainParams_TESTNET4_sanity)
|
||||
{
|
||||
sanity_check_chainparams(*m_node.args, ChainType::TESTNET4);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ChainParams_SIGNET_sanity)
|
||||
{
|
||||
sanity_check_chainparams(*m_node.args, ChainType::SIGNET);
|
||||
|
@ -419,7 +419,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
|
||||
|
||||
// check that any deployment on any chain can conceivably reach both
|
||||
// ACTIVE and FAILED states in roughly the way we expect
|
||||
for (const auto& chain_type: {ChainType::MAIN, ChainType::TESTNET, ChainType::SIGNET, ChainType::REGTEST}) {
|
||||
for (const auto& chain_type: {ChainType::MAIN, ChainType::TESTNET, ChainType::TESTNET4, ChainType::SIGNET, ChainType::REGTEST}) {
|
||||
const auto chainParams = CreateChainParams(*m_node.args, chain_type);
|
||||
uint32_t chain_all_vbits{0};
|
||||
for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
|
||||
|
@ -15,6 +15,8 @@ std::string ChainTypeToString(ChainType chain)
|
||||
return "main";
|
||||
case ChainType::TESTNET:
|
||||
return "test";
|
||||
case ChainType::TESTNET4:
|
||||
return "testnet4";
|
||||
case ChainType::SIGNET:
|
||||
return "signet";
|
||||
case ChainType::REGTEST:
|
||||
@ -29,6 +31,8 @@ std::optional<ChainType> ChainTypeFromString(std::string_view chain)
|
||||
return ChainType::MAIN;
|
||||
} else if (chain == "test") {
|
||||
return ChainType::TESTNET;
|
||||
} else if (chain == "testnet4") {
|
||||
return ChainType::TESTNET4;
|
||||
} else if (chain == "signet") {
|
||||
return ChainType::SIGNET;
|
||||
} else if (chain == "regtest") {
|
||||
|
@ -13,6 +13,7 @@ enum class ChainType {
|
||||
TESTNET,
|
||||
SIGNET,
|
||||
REGTEST,
|
||||
TESTNET4,
|
||||
};
|
||||
|
||||
std::string ChainTypeToString(ChainType chain);
|
||||
|
@ -371,11 +371,44 @@ class ConfArgsTest(BitcoinTestFramework):
|
||||
def test_acceptstalefeeestimates_arg_support(self):
|
||||
self.log.info("Test -acceptstalefeeestimates option support")
|
||||
conf_file = self.nodes[0].datadir_path / "bitcoin.conf"
|
||||
for chain, chain_name in {("main", ""), ("test", "testnet3"), ("signet", "signet")}:
|
||||
for chain, chain_name in {("main", ""), ("test", "testnet3"), ("signet", "signet"), ("testnet4", "testnet4")}:
|
||||
util.write_config(conf_file, n=0, chain=chain_name, extra_config='acceptstalefeeestimates=1\n')
|
||||
self.nodes[0].assert_start_raises_init_error(expected_msg=f'Error: acceptstalefeeestimates is not supported on {chain} chain.')
|
||||
util.write_config(conf_file, n=0, chain="regtest") # Reset to regtest
|
||||
|
||||
def test_testnet3_deprecation_msg(self):
|
||||
self.log.info("Test testnet3 deprecation warning")
|
||||
t3_warning_log = "Warning: Support for testnet3 is deprecated and will be removed in an upcoming release. Consider switching to testnet4."
|
||||
|
||||
def warning_msg(node, approx_size):
|
||||
return f'Warning: Disk space for "{node.datadir_path / node.chain / "blocks" }" may not accommodate the block files. Approximately {approx_size} GB of data will be stored in this directory.'
|
||||
|
||||
# Testnet3 node will log the warning
|
||||
self.nodes[0].chain = 'testnet3'
|
||||
self.nodes[0].replace_in_config([('regtest=', 'testnet='), ('[regtest]', '[test]')])
|
||||
with self.nodes[0].assert_debug_log([t3_warning_log]):
|
||||
self.start_node(0)
|
||||
# Some CI environments will have limited space and some others won't
|
||||
# so we need to handle both cases as a valid result.
|
||||
self.nodes[0].stderr.seek(0)
|
||||
err = self.nodes[0].stdout.read()
|
||||
self.nodes[0].stderr.seek(0)
|
||||
self.nodes[0].stderr.truncate()
|
||||
if err != b'' and err != warning_msg(self.nodes[0], 42):
|
||||
raise AssertionError("Unexpected stderr after shutdown of Testnet3 node")
|
||||
self.stop_node(0)
|
||||
|
||||
# Testnet4 node will not log the warning
|
||||
self.nodes[0].chain = 'testnet4'
|
||||
self.nodes[0].replace_in_config([('testnet=', 'testnet4='), ('[test]', '[testnet4]')])
|
||||
with self.nodes[0].assert_debug_log([], unexpected_msgs=[t3_warning_log]):
|
||||
self.start_node(0)
|
||||
self.stop_node(0)
|
||||
|
||||
# Reset to regtest
|
||||
self.nodes[0].chain = 'regtest'
|
||||
self.nodes[0].replace_in_config([('testnet4=', 'regtest='), ('[testnet4]', '[regtest]')])
|
||||
|
||||
def run_test(self):
|
||||
self.test_log_buffer()
|
||||
self.test_args_log()
|
||||
@ -389,6 +422,7 @@ class ConfArgsTest(BitcoinTestFramework):
|
||||
self.test_ignored_conf()
|
||||
self.test_ignored_default_conf()
|
||||
self.test_acceptstalefeeestimates_arg_support()
|
||||
self.test_testnet3_deprecation_msg()
|
||||
|
||||
# Remove the -datadir argument so it doesn't override the config file
|
||||
self.nodes[0].args = [arg for arg in self.nodes[0].args if not arg.startswith("-datadir")]
|
||||
|
@ -11,7 +11,7 @@ class WalletCrossChain(BitcoinTestFramework):
|
||||
self.add_wallet_options(parser)
|
||||
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
self.num_nodes = 3
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
@ -24,6 +24,12 @@ class WalletCrossChain(BitcoinTestFramework):
|
||||
self.nodes[1].chain = 'testnet3'
|
||||
self.nodes[1].extra_args = ['-maxconnections=0', '-prune=550'] # disable testnet sync
|
||||
self.nodes[1].replace_in_config([('regtest=', 'testnet='), ('[regtest]', '[test]')])
|
||||
|
||||
# Switch node 2 to testnet4 before starting it.
|
||||
self.nodes[2].chain = 'testnet4'
|
||||
self.nodes[2].extra_args = ['-maxconnections=0', '-prune=550'] # disable testnet4 sync
|
||||
self.nodes[2].replace_in_config([('regtest=', 'testnet4='), ('[regtest]', '[testnet4]')])
|
||||
|
||||
self.start_nodes()
|
||||
|
||||
def run_test(self):
|
||||
@ -39,19 +45,40 @@ class WalletCrossChain(BitcoinTestFramework):
|
||||
self.nodes[1].createwallet(node1_wallet)
|
||||
self.nodes[1].backupwallet(node1_wallet_backup)
|
||||
self.nodes[1].unloadwallet(node1_wallet)
|
||||
node2_wallet = self.nodes[2].datadir_path / 'node2_wallet'
|
||||
node2_wallet_backup = self.nodes[0].datadir_path / 'node2_wallet.bak'
|
||||
self.nodes[2].createwallet(node2_wallet)
|
||||
self.nodes[2].backupwallet(node2_wallet_backup)
|
||||
self.nodes[2].unloadwallet(node2_wallet)
|
||||
|
||||
self.log.info("Loading/restoring wallets into nodes with a different genesis block")
|
||||
|
||||
if self.options.descriptors:
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[0].loadwallet, node1_wallet)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[0].loadwallet, node2_wallet)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[1].loadwallet, node0_wallet)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[2].loadwallet, node0_wallet)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[1].loadwallet, node2_wallet)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[2].loadwallet, node1_wallet)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[0].restorewallet, 'w', node1_wallet_backup)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[0].restorewallet, 'w', node2_wallet_backup)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[1].restorewallet, 'w', node0_wallet_backup)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[2].restorewallet, 'w', node0_wallet_backup)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[1].restorewallet, 'w', node2_wallet_backup)
|
||||
assert_raises_rpc_error(-18, 'Wallet file verification failed.', self.nodes[2].restorewallet, 'w', node1_wallet_backup)
|
||||
else:
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[0].loadwallet, node1_wallet)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[0].loadwallet, node2_wallet)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[1].loadwallet, node0_wallet)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[2].loadwallet, node0_wallet)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[1].loadwallet, node2_wallet)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[2].loadwallet, node1_wallet)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[0].restorewallet, 'w', node1_wallet_backup)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[0].restorewallet, 'w', node2_wallet_backup)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[1].restorewallet, 'w', node0_wallet_backup)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[2].restorewallet, 'w', node0_wallet_backup)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[1].restorewallet, 'w', node2_wallet_backup)
|
||||
assert_raises_rpc_error(-4, 'Wallet files should not be reused across chains.', self.nodes[2].restorewallet, 'w', node1_wallet_backup)
|
||||
|
||||
if not self.options.descriptors:
|
||||
self.log.info("Override cross-chain wallet load protection")
|
||||
|
Loading…
Reference in New Issue
Block a user