mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-01 09:35:52 -05:00
Merge 7416b18392
into 85f96b01b7
This commit is contained in:
commit
8697a256e2
10 changed files with 320 additions and 19 deletions
|
@ -223,12 +223,10 @@ def seconds_to_hms(s):
|
|||
return out
|
||||
|
||||
class Generate:
|
||||
INTERVAL = 600.0*2016/2015 # 10 minutes, adjusted for the off-by-one bug
|
||||
|
||||
|
||||
def __init__(self, multiminer=None, ultimate_target=None, poisson=False, max_interval=1800,
|
||||
standby_delay=0, backup_delay=0, set_block_time=None,
|
||||
poolid=None):
|
||||
poolid=None, target_spacing=600):
|
||||
if multiminer is None:
|
||||
multiminer = (0, 1, 1)
|
||||
(self.multi_low, self.multi_high, self.multi_period) = multiminer
|
||||
|
@ -240,6 +238,10 @@ class Generate:
|
|||
self.set_block_time = set_block_time
|
||||
self.poolid = poolid
|
||||
|
||||
# Set INTERVAL. If target_spacing=600 (the default), it is 10 minutes,
|
||||
# adjusted for the off-by-one bug.
|
||||
self.INTERVAL = target_spacing * 2016 / 2015
|
||||
|
||||
def next_block_delta(self, last_nbits, last_hash):
|
||||
# strategy:
|
||||
# 1) work out how far off our desired target we are
|
||||
|
@ -377,8 +379,9 @@ def do_generate(args):
|
|||
return 1
|
||||
my_blocks = (start-1, stop, total)
|
||||
|
||||
if args.max_interval < 960:
|
||||
logging.error("--max-interval must be at least 960 (16 minutes)")
|
||||
max_interval_limit = args.target_spacing * 16 / 10
|
||||
if args.max_interval < max_interval_limit:
|
||||
logging.error("--max-interval must be at least %d (%f minutes)" % (max_interval_limit, max_interval_limit/60))
|
||||
return 1
|
||||
|
||||
poolid = get_poolid(args)
|
||||
|
@ -386,7 +389,7 @@ def do_generate(args):
|
|||
ultimate_target = nbits_to_target(int(args.nbits,16))
|
||||
|
||||
gen = Generate(multiminer=my_blocks, ultimate_target=ultimate_target, poisson=args.poisson, max_interval=args.max_interval,
|
||||
standby_delay=args.standby_delay, backup_delay=args.backup_delay, set_block_time=args.set_block_time, poolid=poolid)
|
||||
standby_delay=args.standby_delay, backup_delay=args.backup_delay, set_block_time=args.set_block_time, poolid=poolid, target_spacing=args.target_spacing)
|
||||
|
||||
mined_blocks = 0
|
||||
bestheader = {"hash": None}
|
||||
|
@ -529,6 +532,7 @@ def main():
|
|||
generate.add_argument("--backup-delay", default=300, type=int, help="Seconds to delay before mining blocks reserved for other miners (default=300)")
|
||||
generate.add_argument("--standby-delay", default=0, type=int, help="Seconds to delay before mining blocks (default=0)")
|
||||
generate.add_argument("--max-interval", default=1800, type=int, help="Maximum interblock interval (seconds)")
|
||||
generate.add_argument("--target-spacing", default=600, type=int, help="Target interval between blocks (seconds), property of the network (default 600)")
|
||||
|
||||
calibrate = cmds.add_parser("calibrate", help="Calibrate difficulty")
|
||||
calibrate.set_defaults(fn=do_calibrate)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <consensus/params.h>
|
||||
#include <deploymentinfo.h>
|
||||
#include <logging.h>
|
||||
#include <script/script.h>
|
||||
#include <tinyformat.h>
|
||||
#include <util/chaintype.h>
|
||||
#include <util/strencodings.h>
|
||||
|
@ -21,8 +22,83 @@
|
|||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
|
||||
using util::SplitString;
|
||||
|
||||
void ParseWrappedSignetChallenge(const std::vector<uint8_t>& wrappedChallenge, std::vector<uint8_t>& outParams, std::vector<uint8_t>& outChallenge) {
|
||||
if (wrappedChallenge.empty() || wrappedChallenge[0] != OP_RETURN) {
|
||||
// Not a wrapped challenge.
|
||||
outChallenge = wrappedChallenge;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> params;
|
||||
std::vector<uint8_t> challenge;
|
||||
|
||||
const CScript script(wrappedChallenge.begin(), wrappedChallenge.end());
|
||||
CScript::const_iterator it = script.begin(), itend = script.end();
|
||||
int i;
|
||||
for (i = 0; it != itend; i++) {
|
||||
if (i > 2) {
|
||||
throw std::runtime_error("too many operations in wrapped challenge, must be 3.");
|
||||
}
|
||||
std::vector<unsigned char> push_data;
|
||||
opcodetype opcode;
|
||||
if (!script.GetOp(it, opcode, push_data)) {
|
||||
throw std::runtime_error(strprintf("failed to parse operation %d in wrapped challenge script.", i));
|
||||
}
|
||||
if (i == 0) {
|
||||
// OP_RETURN.
|
||||
continue;
|
||||
}
|
||||
if (opcode != OP_PUSHDATA1 && opcode != OP_PUSHDATA2 && opcode != OP_PUSHDATA4) {
|
||||
throw std::runtime_error(strprintf("operation %d of wrapped challenge script must be a PUSHDATA opcode, got 0x%02x.", i, opcode));
|
||||
}
|
||||
if (i == 1) {
|
||||
params.swap(push_data);
|
||||
} else if (i == 2) {
|
||||
challenge.swap(push_data);
|
||||
}
|
||||
}
|
||||
if (i != 3) {
|
||||
throw std::runtime_error(strprintf("too few operations in wrapped challenge, must be 3, got %d.", i));
|
||||
}
|
||||
|
||||
outParams.swap(params);
|
||||
outChallenge.swap(challenge);
|
||||
}
|
||||
|
||||
void ParseSignetParams(const std::vector<uint8_t>& params, CChainParams::SigNetOptions& options) {
|
||||
if (params.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The format of params is extendable in case more fields are added in the future.
|
||||
// It is encoded as a concatenation of (field_id, value) tuples, protobuf style.
|
||||
// Currently there is only one field defined: pow_target_spacing, whose field_id
|
||||
// is 0x01 and the lendth of encoding is 8 (int64_t). So valid values of params are:
|
||||
// - empty string (checked in if block above),
|
||||
// - 0x01 followed by 8 bytes of pow_target_spacing (9 bytes in total).
|
||||
// If length is not 0 and not 9, the value can not be parsed.
|
||||
|
||||
if (params.size() != 1 + 8) {
|
||||
throw std::runtime_error(strprintf("signet params must have length %d, got %d.", 1+8, params.size()));
|
||||
}
|
||||
if (params[0] != 0x01) {
|
||||
throw std::runtime_error(strprintf("signet params[0] must be 0x01, got 0x%02x.", params[0]));
|
||||
}
|
||||
// Parse little-endian 64 bit number to uint8_t.
|
||||
const uint8_t* bytes = ¶ms[1];
|
||||
const uint64_t value = uint64_t(bytes[0]) | uint64_t(bytes[1])<<8 | uint64_t(bytes[2])<<16 | uint64_t(bytes[3])<<24 |
|
||||
uint64_t(bytes[4])<<32 | uint64_t(bytes[5])<<40 | uint64_t(bytes[6])<<48 | uint64_t(bytes[7])<<56;
|
||||
auto pow_target_spacing = int64_t(value);
|
||||
if (pow_target_spacing <= 0) {
|
||||
throw std::runtime_error("signet param pow_target_spacing <= 0.");
|
||||
}
|
||||
|
||||
options.pow_target_spacing = pow_target_spacing;
|
||||
}
|
||||
|
||||
void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options)
|
||||
{
|
||||
if (args.IsArgSet("-signetseednode")) {
|
||||
|
@ -37,7 +113,11 @@ void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& option
|
|||
if (!val) {
|
||||
throw std::runtime_error(strprintf("-signetchallenge must be hex, not '%s'.", signet_challenge[0]));
|
||||
}
|
||||
options.challenge.emplace(*val);
|
||||
std::vector<unsigned char> params;
|
||||
std::vector<unsigned char> challenge;
|
||||
ParseWrappedSignetChallenge(*val, params, challenge);
|
||||
ParseSignetParams(params, options);
|
||||
options.challenge.emplace(challenge);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,4 +28,26 @@ const CChainParams &Params();
|
|||
*/
|
||||
void SelectParams(const ChainType chain);
|
||||
|
||||
/**
|
||||
* Extracts signet params and signet challenge from wrapped signet challenge.
|
||||
* Format of wrapped signet challenge is:
|
||||
* If the challenge is in the form "OP_RETURN PUSHDATA<params> PUSHDATA<actual challenge>",
|
||||
* If the input challenge does not start with OP_RETURN,
|
||||
* sets outParams="" and outChallenge=input.
|
||||
* If the input challenge starts with OP_RETURN, but does not satisfy the format,
|
||||
* throws an exception.
|
||||
*/
|
||||
void ParseWrappedSignetChallenge(const std::vector<uint8_t>& wrappedChallenge, std::vector<uint8_t>& outParams, std::vector<uint8_t>& outChallenge);
|
||||
|
||||
/**
|
||||
* Parses signet options.
|
||||
* The format currently supports only setting pow_target_spacing, but
|
||||
* can be extended in the future.
|
||||
* Possible values:
|
||||
* - Empty (then do nothing)
|
||||
* - 0x01 (pow_target_spacing as int64_t little endian) => set pow_target_spacing.
|
||||
* If the format is wrong, throws an exception.
|
||||
*/
|
||||
void ParseSignetParams(const std::vector<uint8_t>& params, CChainParams::SigNetOptions& options);
|
||||
|
||||
#endif // BITCOIN_CHAINPARAMS_H
|
||||
|
|
|
@ -21,7 +21,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
|
|||
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);
|
||||
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); in case -signetchallenge is in the form of 'OP_RETURN PUSHDATA<params> PUSHDATA<actual challenge>', then <actual challenge> is used as a challenge and <params> is used to set parameters of signet; currently the only supported parameter is target spacing, the format of <params> to set it is 01<8 bytes value of target spacing, seconds, little endian>", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-signetseednode", "Specify a seed node for the signet network, in the hostname[:port] format, e.g. sig.net:1234 (may be used multiple times to specify multiple seed nodes; defaults to the global default signet test network seed node(s))", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::CHAINPARAMS);
|
||||
}
|
||||
|
||||
|
|
|
@ -461,7 +461,7 @@ public:
|
|||
consensus.CSVHeight = 1;
|
||||
consensus.SegwitHeight = 1;
|
||||
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
|
||||
consensus.nPowTargetSpacing = 10 * 60;
|
||||
consensus.nPowTargetSpacing = options.pow_target_spacing;
|
||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||
consensus.enforce_BIP94 = false;
|
||||
consensus.fPowNoRetargeting = false;
|
||||
|
|
|
@ -137,6 +137,7 @@ public:
|
|||
struct SigNetOptions {
|
||||
std::optional<std::vector<uint8_t>> challenge{};
|
||||
std::optional<std::vector<std::string>> seeds{};
|
||||
int64_t pow_target_spacing{10 * 60};
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,6 +47,7 @@ add_executable(test_bitcoin
|
|||
blockmanager_tests.cpp
|
||||
bloom_tests.cpp
|
||||
bswap_tests.cpp
|
||||
chainparams_tests.cpp
|
||||
checkqueue_tests.cpp
|
||||
cluster_linearize_tests.cpp
|
||||
coins_tests.cpp
|
||||
|
|
170
src/test/chainparams_tests.cpp
Normal file
170
src/test/chainparams_tests.cpp
Normal file
|
@ -0,0 +1,170 @@
|
|||
// Copyright (c) 2011-2024 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chainparams.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <util/strencodings.h>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(chainparams_tests)
|
||||
|
||||
struct ParseWrappedSignetChallenge_TestCase
|
||||
{
|
||||
std::string wrappedChallengeHex;
|
||||
std::string wantParamsHex;
|
||||
std::string wantChallengeHex;
|
||||
std::string wantError;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(parse_wrapped_signet_challenge)
|
||||
{
|
||||
static const ParseWrappedSignetChallenge_TestCase cases[] = {
|
||||
{
|
||||
"512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae",
|
||||
"",
|
||||
"512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"6a4c09011e000000000000004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae",
|
||||
"011e00000000000000",
|
||||
"512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"6a4c004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae",
|
||||
"",
|
||||
"512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae",
|
||||
"",
|
||||
},
|
||||
{
|
||||
"6a4c004c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae4c00",
|
||||
"",
|
||||
"",
|
||||
"too many operations in wrapped challenge, must be 3.",
|
||||
},
|
||||
{
|
||||
"6a4c09011e00000000000000",
|
||||
"",
|
||||
"",
|
||||
"too few operations in wrapped challenge, must be 3, got 2.",
|
||||
},
|
||||
{
|
||||
"6a4c01",
|
||||
"",
|
||||
"",
|
||||
"failed to parse operation 1 in wrapped challenge script.",
|
||||
},
|
||||
{
|
||||
"6a4c004c25512102f7561d208dd9ae99bf497273",
|
||||
"",
|
||||
"",
|
||||
"failed to parse operation 2 in wrapped challenge script.",
|
||||
},
|
||||
{
|
||||
"6a6a4c25512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae4c00",
|
||||
"",
|
||||
"",
|
||||
"operation 1 of wrapped challenge script must be a PUSHDATA opcode, got 0x6a.",
|
||||
},
|
||||
{
|
||||
"6a4c09011e0000000000000051",
|
||||
"",
|
||||
"",
|
||||
"operation 2 of wrapped challenge script must be a PUSHDATA opcode, got 0x51.",
|
||||
},
|
||||
};
|
||||
|
||||
for (unsigned int i=0; i<std::size(cases); i++)
|
||||
{
|
||||
const auto wrappedChallenge = ParseHex(cases[i].wrappedChallengeHex);
|
||||
const auto wantParamsHex = cases[i].wantParamsHex;
|
||||
const auto wantChallengeHex = cases[i].wantChallengeHex;
|
||||
const auto wantError = cases[i].wantError;
|
||||
|
||||
std::vector<uint8_t> gotParams;
|
||||
std::vector<uint8_t> gotChallenge;
|
||||
std::string gotError;
|
||||
try {
|
||||
ParseWrappedSignetChallenge(wrappedChallenge, gotParams, gotChallenge);
|
||||
} catch (const std::exception& e) {
|
||||
gotError = e.what();
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(HexStr(gotParams), wantParamsHex);
|
||||
BOOST_CHECK_EQUAL(HexStr(gotChallenge), wantChallengeHex);
|
||||
BOOST_CHECK_EQUAL(gotError, wantError);
|
||||
}
|
||||
}
|
||||
|
||||
struct ParseSignetParams_TestCase
|
||||
{
|
||||
std::string paramsHex;
|
||||
int64_t wantPowTargetSpacing;
|
||||
std::string wantError;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(parse_signet_params)
|
||||
{
|
||||
static const ParseSignetParams_TestCase cases[] = {
|
||||
{
|
||||
"",
|
||||
600,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"011e00000000000000",
|
||||
30,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"01e803000000000000",
|
||||
1000,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"015802000000000000",
|
||||
600,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"012502",
|
||||
600,
|
||||
"signet params must have length 9, got 3.",
|
||||
},
|
||||
{
|
||||
"022502000000000000",
|
||||
600,
|
||||
"signet params[0] must be 0x01, got 0x02.",
|
||||
},
|
||||
{
|
||||
"01ffffffffffffffff",
|
||||
600,
|
||||
"signet param pow_target_spacing <= 0.",
|
||||
},
|
||||
};
|
||||
|
||||
for (unsigned int i=0; i<std::size(cases); i++)
|
||||
{
|
||||
const auto params = ParseHex(cases[i].paramsHex);
|
||||
const auto wantPowTargetSpacing = cases[i].wantPowTargetSpacing;
|
||||
const auto wantError = cases[i].wantError;
|
||||
|
||||
CChainParams::SigNetOptions gotOptions;
|
||||
std::string gotError;
|
||||
try {
|
||||
ParseSignetParams(params, gotOptions);
|
||||
} catch (const std::exception& e) {
|
||||
gotError = e.what();
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(gotOptions.pow_target_spacing, wantPowTargetSpacing);
|
||||
BOOST_CHECK_EQUAL(gotError, wantError);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -75,6 +75,15 @@ BOOST_AUTO_TEST_CASE(signet_parse_tests)
|
|||
BOOST_CHECK(signet_params->GetConsensus().signet_challenge == std::vector<uint8_t>{OP_TRUE});
|
||||
CScript challenge{OP_TRUE};
|
||||
|
||||
{
|
||||
// Wrapped challenge case.
|
||||
ArgsManager signet_argsman_custom_spacing;
|
||||
signet_argsman_custom_spacing.ForceSetArg("-signetchallenge", "6a4c09011e000000000000004c0151"); // set challenge to OP_TRUE and spacing to 30 seconds
|
||||
const auto signet_params_custom_spacing = CreateChainParams(signet_argsman_custom_spacing, ChainType::SIGNET);
|
||||
BOOST_CHECK(signet_params_custom_spacing->GetConsensus().signet_challenge == std::vector<uint8_t>{OP_TRUE});
|
||||
BOOST_CHECK(signet_params_custom_spacing->GetConsensus().nPowTargetSpacing == 30);
|
||||
}
|
||||
|
||||
// empty block is invalid
|
||||
BOOST_CHECK(!SignetTxs::Create(block, challenge));
|
||||
BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
|
||||
|
|
|
@ -25,7 +25,7 @@ signet_blocks = [
|
|||
]
|
||||
|
||||
class SignetParams:
|
||||
def __init__(self, challenge=None):
|
||||
def __init__(self, challenge=None, internal_challenge=None):
|
||||
if challenge is None:
|
||||
self.challenge = SIGNET_DEFAULT_CHALLENGE
|
||||
self.shared_args = []
|
||||
|
@ -33,22 +33,28 @@ class SignetParams:
|
|||
self.challenge = challenge
|
||||
self.shared_args = [f"-signetchallenge={challenge}"]
|
||||
|
||||
if internal_challenge is None:
|
||||
internal_challenge = self.challenge
|
||||
self.internal_challenge = internal_challenge
|
||||
|
||||
class SignetBasicTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.chain = "signet"
|
||||
self.num_nodes = 6
|
||||
self.num_nodes = 8
|
||||
self.setup_clean_chain = True
|
||||
self.signets = [
|
||||
SignetParams(challenge='51'), # OP_TRUE
|
||||
SignetParams(), # default challenge
|
||||
# default challenge as a 2-of-2, which means it should fail
|
||||
SignetParams(challenge='522103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae')
|
||||
SignetParams(challenge='522103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae'),
|
||||
SignetParams(challenge='6a4c09011e000000000000004c0151', internal_challenge='51'), # OP_TRUE, target_spacing=30
|
||||
]
|
||||
|
||||
self.extra_args = [
|
||||
self.signets[0].shared_args, self.signets[0].shared_args,
|
||||
self.signets[1].shared_args, self.signets[1].shared_args,
|
||||
self.signets[2].shared_args, self.signets[2].shared_args,
|
||||
self.signets[3].shared_args, self.signets[3].shared_args,
|
||||
]
|
||||
|
||||
def setup_network(self):
|
||||
|
@ -58,6 +64,7 @@ class SignetBasicTest(BitcoinTestFramework):
|
|||
self.connect_nodes(0, 1)
|
||||
self.connect_nodes(2, 3)
|
||||
self.connect_nodes(4, 5)
|
||||
self.connect_nodes(6, 7)
|
||||
|
||||
def run_test(self):
|
||||
self.log.info("basic tests using OP_TRUE challenge")
|
||||
|
@ -66,10 +73,11 @@ class SignetBasicTest(BitcoinTestFramework):
|
|||
def check_getblockchaininfo(node_idx, signet_idx):
|
||||
blockchain_info = self.nodes[node_idx].getblockchaininfo()
|
||||
assert_equal(blockchain_info['chain'], 'signet')
|
||||
assert_equal(blockchain_info['signet_challenge'], self.signets[signet_idx].challenge)
|
||||
assert_equal(blockchain_info['signet_challenge'], self.signets[signet_idx].internal_challenge)
|
||||
check_getblockchaininfo(node_idx=1, signet_idx=0)
|
||||
check_getblockchaininfo(node_idx=2, signet_idx=1)
|
||||
check_getblockchaininfo(node_idx=5, signet_idx=2)
|
||||
check_getblockchaininfo(node_idx=6, signet_idx=3)
|
||||
|
||||
self.log.info('getmininginfo')
|
||||
def check_getmininginfo(node_idx, signet_idx):
|
||||
|
@ -80,20 +88,26 @@ class SignetBasicTest(BitcoinTestFramework):
|
|||
assert 'currentblockweight' not in mining_info
|
||||
assert_equal(mining_info['networkhashps'], Decimal('0'))
|
||||
assert_equal(mining_info['pooledtx'], 0)
|
||||
assert_equal(mining_info['signet_challenge'], self.signets[signet_idx].challenge)
|
||||
assert_equal(mining_info['signet_challenge'], self.signets[signet_idx].internal_challenge)
|
||||
check_getmininginfo(node_idx=0, signet_idx=0)
|
||||
check_getmininginfo(node_idx=3, signet_idx=1)
|
||||
check_getmininginfo(node_idx=4, signet_idx=2)
|
||||
check_getmininginfo(node_idx=7, signet_idx=3)
|
||||
|
||||
self.generate(self.nodes[0], 1, sync_fun=self.no_op)
|
||||
|
||||
self.log.info("pregenerated signet blocks check")
|
||||
|
||||
height = 0
|
||||
for block in signet_blocks:
|
||||
assert_equal(self.nodes[2].submitblock(block), None)
|
||||
height += 1
|
||||
assert_equal(self.nodes[2].getblockcount(), height)
|
||||
# Verify that nodes accept blocks mined using the default signet challenge.
|
||||
# This test includes one default signet node (2) and another node (6)
|
||||
# configured with an extended signet challenge that uses the actual script
|
||||
# OP_TRUE (accepts all blocks).
|
||||
for node_idx in [2, 6]:
|
||||
height = 0
|
||||
for block in signet_blocks:
|
||||
assert_equal(self.nodes[node_idx].submitblock(block), None)
|
||||
height += 1
|
||||
assert_equal(self.nodes[node_idx].getblockcount(), height)
|
||||
|
||||
self.log.info("pregenerated signet blocks check (incompatible solution)")
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue