Implement BIP8 for taproot
This commit is contained in:
parent
beb0f22f26
commit
3865f76a97
@ -85,13 +85,11 @@ public:
|
||||
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 = 1619222400; // April 24th, 2021
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1628640000; // August 11th, 2021
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 709632; // Approximately November 12th, 2021
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartHeight = 2128896;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeoutHeight = 2322432;
|
||||
|
||||
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000004e2a7117519981b028e");
|
||||
consensus.defaultAssumeValid = uint256S("0x90c346e4bd95b964cd09cd27f27f15dfed5b1a601b752371e45735cf55015af3"); // 1962809
|
||||
@ -200,13 +198,11 @@ public:
|
||||
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 = 1619222400; // April 24th, 2021
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1628640000; // August 11th, 2021
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
|
||||
|
||||
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000004260a1758f04aa");
|
||||
consensus.defaultAssumeValid = uint256S("0x4a280c0e150e3b74ebe19618e6394548c8a39d5549fd9941b9c431c73822fbd5"); // 1737876
|
||||
@ -293,12 +289,10 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
|
||||
|
||||
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{};
|
||||
@ -352,11 +346,12 @@ public:
|
||||
/**
|
||||
* Allows modifying the Version Bits regtest parameters.
|
||||
*/
|
||||
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int min_activation_height)
|
||||
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nStartHeight, int64_t nTimeoutHeight)
|
||||
{
|
||||
consensus.vDeployments[d].nStartTime = nStartTime;
|
||||
consensus.vDeployments[d].nTimeout = nTimeout;
|
||||
consensus.vDeployments[d].min_activation_height = min_activation_height;
|
||||
consensus.vDeployments[d].nStartHeight = nStartHeight;
|
||||
consensus.vDeployments[d].nTimeoutHeight = nTimeoutHeight;
|
||||
}
|
||||
void UpdateActivationParametersFromArgs(const ArgsManager& args);
|
||||
};
|
||||
@ -379,26 +374,28 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
|
||||
for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
|
||||
std::vector<std::string> vDeploymentParams;
|
||||
boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
|
||||
if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) {
|
||||
throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]");
|
||||
if (vDeploymentParams.size() < 3 || 5 < vDeploymentParams.size()) {
|
||||
throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:heightstart:heightend]");
|
||||
}
|
||||
int64_t nStartTime, nTimeout;
|
||||
int min_activation_height = 0;
|
||||
int64_t nStartTime, nTimeout, nStartHeight, nTimeoutHeight;
|
||||
if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
|
||||
throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
|
||||
}
|
||||
if (!ParseInt64(vDeploymentParams[2], &nTimeout)) {
|
||||
throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
|
||||
}
|
||||
if (vDeploymentParams.size() >= 4 && !ParseInt32(vDeploymentParams[3], &min_activation_height)) {
|
||||
throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3]));
|
||||
if (vDeploymentParams.size() > 3 && !ParseInt64(vDeploymentParams[3], &nStartHeight)) {
|
||||
throw std::runtime_error(strprintf("Invalid nStartHeight (%s)", vDeploymentParams[3]));
|
||||
}
|
||||
if (vDeploymentParams.size() > 4 && !ParseInt64(vDeploymentParams[4], &nTimeoutHeight)) {
|
||||
throw std::runtime_error(strprintf("Invalid nTimeoutHeight (%s)", vDeploymentParams[4]));
|
||||
}
|
||||
bool found = false;
|
||||
for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
|
||||
if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
|
||||
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, min_activation_height);
|
||||
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, nStartHeight, nTimeoutHeight);
|
||||
found = true;
|
||||
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d\n", vDeploymentParams[0], nStartTime, nTimeout, min_activation_height);
|
||||
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, start_height=%d, timeout_height=%d\n", vDeploymentParams[0], nStartTime, nTimeout, nStartHeight, nTimeoutHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
|
||||
"This is intended for regression testing tools and app development. Equivalent to -chain=regtest.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-segwitheight=<n>", "Set the activation height of segwit. -1 to disable. (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("-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("-vbparams=deployment:start:end[:start_height:end_height]", "Use given start/end times and start/end block heights 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_STRING, 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_STRING, OptionsCategory::CHAINPARAMS);
|
||||
|
||||
@ -26,14 +26,13 @@ struct BIP9Deployment {
|
||||
/** Bit position to select the particular bit in nVersion. */
|
||||
int bit;
|
||||
/** Start MedianTime for version bits miner confirmation. Can be a date in the past */
|
||||
int64_t nStartTime;
|
||||
int64_t nStartTime = 0;
|
||||
/** Timeout/expiry MedianTime for the deployment attempt. */
|
||||
int64_t nTimeout;
|
||||
/** If lock in occurs, delay activation until at least this block
|
||||
* height. Note that activation will only occur on a retarget
|
||||
* boundary.
|
||||
*/
|
||||
int min_activation_height{0};
|
||||
int64_t nTimeout = 0;
|
||||
/** Start block height for version bits miner confirmation. Should be a retarget block, can be in the past */
|
||||
int64_t nStartHeight = 0;
|
||||
/** Timeout/expiry block height for the deployment attempt. Should be a retarget block. */
|
||||
int64_t nTimeoutHeight = 0;
|
||||
|
||||
/** Constant for nTimeout very far in the future. */
|
||||
static constexpr int64_t NO_TIMEOUT = std::numeric_limits<int64_t>::max();
|
||||
|
||||
@ -1211,7 +1211,7 @@ static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name,
|
||||
softforks.pushKV(name, rv);
|
||||
}
|
||||
|
||||
static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
static void VBSoftForkDescPushBack(UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
{
|
||||
// For BIP9 deployments.
|
||||
// Deployments that are never active are hidden.
|
||||
@ -1230,8 +1230,15 @@ static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &nam
|
||||
{
|
||||
bip9.pushKV("bit", consensusParams.vDeployments[id].bit);
|
||||
}
|
||||
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
|
||||
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
|
||||
bool fHeightBased = consensusParams.vDeployments[id].nStartTime == 0 && consensusParams.vDeployments[id].nTimeout == 0;
|
||||
if (fHeightBased) {
|
||||
bip9.pushKV("start_height", consensusParams.vDeployments[id].nStartHeight);
|
||||
bip9.pushKV("timeout_height", consensusParams.vDeployments[id].nTimeoutHeight);
|
||||
} else {
|
||||
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
|
||||
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
|
||||
}
|
||||
|
||||
int64_t since_height = VersionBitsTipStateSinceHeight(consensusParams, id);
|
||||
bip9.pushKV("since", since_height);
|
||||
if (ThresholdState::STARTED == thresholdState)
|
||||
@ -1245,11 +1252,10 @@ static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &nam
|
||||
statsUV.pushKV("possible", statsStruct.possible);
|
||||
bip9.pushKV("statistics", statsUV);
|
||||
}
|
||||
bip9.pushKV("min_activation_height", consensusParams.vDeployments[id].min_activation_height);
|
||||
|
||||
UniValue rv(UniValue::VOBJ);
|
||||
rv.pushKV("type", "bip9");
|
||||
rv.pushKV("bip9", bip9);
|
||||
rv.pushKV("type", fHeightBased ? "bip8" : "bip9");
|
||||
rv.pushKV(fHeightBased ? "bip8" : "bip9", bip9);
|
||||
if (ThresholdState::ACTIVE == thresholdState) {
|
||||
rv.pushKV("height", since_height);
|
||||
}
|
||||
@ -1292,7 +1298,8 @@ RPCHelpMan getblockchaininfo()
|
||||
{RPCResult::Type::NUM_TIME, "start_time", "the minimum median time past of a block at which the bit gains its meaning"},
|
||||
{RPCResult::Type::NUM_TIME, "timeout", "the median time past of a block at which the deployment is considered failed if not yet locked in"},
|
||||
{RPCResult::Type::NUM, "since", "height of the first block to which the status applies"},
|
||||
{RPCResult::Type::NUM, "min_activation_height", "minimum height of blocks for which the rules may be enforced"},
|
||||
{RPCResult::Type::NUM, "start_height", "minimum block height at which the bit gains its meaning"},
|
||||
{RPCResult::Type::NUM, "timeout_height", "block height at which the deployment is considered failed if not yet locked in"},
|
||||
{RPCResult::Type::OBJ, "statistics", "numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)",
|
||||
{
|
||||
{RPCResult::Type::NUM, "period", "the length in blocks of the BIP9 signalling period"},
|
||||
@ -1353,8 +1360,8 @@ RPCHelpMan getblockchaininfo()
|
||||
BuriedForkDescPushBack(softforks, "bip65", consensusParams.BIP65Height);
|
||||
BuriedForkDescPushBack(softforks, "csv", consensusParams.CSVHeight);
|
||||
BuriedForkDescPushBack(softforks, "segwit", consensusParams.SegwitHeight);
|
||||
BIP9SoftForkDescPushBack(softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
|
||||
BIP9SoftForkDescPushBack(softforks, "taproot", consensusParams, Consensus::DEPLOYMENT_TAPROOT);
|
||||
VBSoftForkDescPushBack(softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
|
||||
VBSoftForkDescPushBack(softforks, "taproot", consensusParams, Consensus::DEPLOYMENT_TAPROOT);
|
||||
obj.pushKV("softforks", softforks);
|
||||
|
||||
obj.pushKV("warnings", GetWarnings(false).original);
|
||||
|
||||
@ -32,24 +32,26 @@ class TestConditionChecker : public AbstractThresholdConditionChecker
|
||||
{
|
||||
private:
|
||||
mutable ThresholdConditionCache cache;
|
||||
bool height_based = false;
|
||||
int64_t height_start = 0;
|
||||
int64_t height_timeout = 0;
|
||||
|
||||
public:
|
||||
int64_t BeginTime(const Consensus::Params& params) const override { return TestTime(10000); }
|
||||
int64_t EndTime(const Consensus::Params& params) const override { return TestTime(20000); }
|
||||
int64_t BeginTime(const Consensus::Params& params) const override { return this->height_based ? 0 : TestTime(10000); }
|
||||
int64_t EndTime(const Consensus::Params& params) const override { return this->height_based ? 0 : TestTime(20000); }
|
||||
int64_t BeginHeight(const Consensus::Params& params) const override { return this->height_start; }
|
||||
int64_t EndHeight(const Consensus::Params& params) const override { return this->height_timeout; }
|
||||
int Period(const Consensus::Params& params) const override { return 1000; }
|
||||
int Threshold(const Consensus::Params& params) const override { return 900; }
|
||||
bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return (pindex->nVersion & 0x100); }
|
||||
void SetHeightBased(int64_t flag) { this->height_based = flag; }
|
||||
void SetHeightStart(int64_t n) { this->height_start = n; }
|
||||
void SetHeightTimeout(int64_t n) { this->height_timeout = n; }
|
||||
|
||||
ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, paramsDummy, cache); }
|
||||
int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, paramsDummy, cache); }
|
||||
};
|
||||
|
||||
class TestDelayedActivationConditionChecker : public TestConditionChecker
|
||||
{
|
||||
public:
|
||||
int MinActivationHeight(const Consensus::Params& params) const override { return 15000; }
|
||||
};
|
||||
|
||||
class TestAlwaysActiveConditionChecker : public TestConditionChecker
|
||||
{
|
||||
public:
|
||||
@ -73,8 +75,6 @@ class VersionBitsTester
|
||||
// The first one performs all checks, the second only 50%, the third only 25%, etc...
|
||||
// This is to test whether lack of cached information leads to the same results.
|
||||
TestConditionChecker checker[CHECKERS];
|
||||
// Another 6 that assume delayed activation
|
||||
TestDelayedActivationConditionChecker checker_delayed[CHECKERS];
|
||||
// Another 6 that assume always active activation
|
||||
TestAlwaysActiveConditionChecker checker_always[CHECKERS];
|
||||
// Another 6 that assume never active activation
|
||||
@ -86,6 +86,16 @@ class VersionBitsTester
|
||||
public:
|
||||
VersionBitsTester() : num(1000) {}
|
||||
|
||||
VersionBitsTester& SetCheckerHeightBasedTest(bool flag, int64_t height_start, int64_t height_timeout)
|
||||
{
|
||||
for (unsigned int i = 0; i < CHECKERS; i++) {
|
||||
checker[i].SetHeightBased(flag);
|
||||
checker[i].SetHeightStart(height_start);
|
||||
checker[i].SetHeightTimeout(height_timeout);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
VersionBitsTester& Reset() {
|
||||
// Have each group of tests be counted by the 1000s part, starting at 1000
|
||||
num = num - (num % 1000) + 1000;
|
||||
@ -95,7 +105,6 @@ public:
|
||||
}
|
||||
for (unsigned int i = 0; i < CHECKERS; i++) {
|
||||
checker[i] = TestConditionChecker();
|
||||
checker_delayed[i] = TestDelayedActivationConditionChecker();
|
||||
checker_always[i] = TestAlwaysActiveConditionChecker();
|
||||
checker_never[i] = TestNeverActiveConditionChecker();
|
||||
}
|
||||
@ -131,7 +140,6 @@ public:
|
||||
for (int i = 0; i < CHECKERS; i++) {
|
||||
if (InsecureRandBits(i) == 0) {
|
||||
BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(tip) == height, strprintf("Test %i for StateSinceHeight", num));
|
||||
BOOST_CHECK_MESSAGE(checker_delayed[i].GetStateSinceHeightFor(tip) == height_delayed, strprintf("Test %i for StateSinceHeight (delayed)", num));
|
||||
BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (always active)", num));
|
||||
BOOST_CHECK_MESSAGE(checker_never[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (never active)", num));
|
||||
}
|
||||
@ -157,14 +165,12 @@ public:
|
||||
for (int i = 0; i < CHECKERS; i++) {
|
||||
if (InsecureRandBits(i) == 0) {
|
||||
ThresholdState got = checker[i].GetStateFor(pindex);
|
||||
ThresholdState got_delayed = checker_delayed[i].GetStateFor(pindex);
|
||||
ThresholdState got_always = checker_always[i].GetStateFor(pindex);
|
||||
ThresholdState got_never = checker_never[i].GetStateFor(pindex);
|
||||
// nHeight of the next block. If vpblock is empty, the next (ie first)
|
||||
// block should be the genesis block with nHeight == 0.
|
||||
int height = pindex == nullptr ? 0 : pindex->nHeight + 1;
|
||||
BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got)));
|
||||
BOOST_CHECK_MESSAGE(got_delayed == exp_delayed, strprintf("Test %i for %s height %d (got %s; delayed case)", num, StateName(exp_delayed), height, StateName(got_delayed)));
|
||||
BOOST_CHECK_MESSAGE(got_always == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE height %d (got %s; always active case)", num, height, StateName(got_always)));
|
||||
BOOST_CHECK_MESSAGE(got_never == ThresholdState::FAILED, strprintf("Test %i for FAILED height %d (got %s; never active case)", num, height, StateName(got_never)));
|
||||
}
|
||||
@ -179,9 +185,6 @@ public:
|
||||
VersionBitsTester& TestActive() { return TestState(ThresholdState::ACTIVE); }
|
||||
VersionBitsTester& TestFailed() { return TestState(ThresholdState::FAILED); }
|
||||
|
||||
// non-delayed should be active; delayed should still be locked in
|
||||
VersionBitsTester& TestActiveDelayed() { return TestState(ThresholdState::ACTIVE, ThresholdState::LOCKED_IN); }
|
||||
|
||||
CBlockIndex* Tip() { return vpblock.empty() ? nullptr : vpblock.back(); }
|
||||
};
|
||||
|
||||
@ -189,7 +192,7 @@ BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(versionbits_test)
|
||||
{
|
||||
for (int i = 0; i < 64; i++) {
|
||||
for (int i = 0; i < 1; i++) {
|
||||
// DEFINED -> STARTED after timeout reached -> FAILED
|
||||
VersionBitsTester().TestDefined().TestStateSinceHeight(0)
|
||||
.Mine(1, TestTime(1), 0x100).TestDefined().TestStateSinceHeight(0)
|
||||
@ -222,8 +225,6 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
|
||||
.Mine(2999, TestTime(30000), 0x100).TestStarted().TestStateSinceHeight(2000) // 999 new blocks
|
||||
.Mine(3000, TestTime(30000), 0x100).TestLockedIn().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
|
||||
.Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
|
||||
.Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
|
||||
.Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
|
||||
.Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
|
||||
|
||||
// DEFINED -> STARTED -> LOCKEDIN before timeout -> ACTIVE
|
||||
@ -236,8 +237,6 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
|
||||
.Mine(2999, TestTime(19999), 0x200).TestStarted().TestStateSinceHeight(2000) // 49 old blocks
|
||||
.Mine(3000, TestTime(29999), 0x200).TestLockedIn().TestStateSinceHeight(3000) // 1 old block (so 900 out of the past 1000)
|
||||
.Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
|
||||
.Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000) // delayed will not become active until height=15000
|
||||
.Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
|
||||
.Mine(15000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
|
||||
.Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
|
||||
|
||||
@ -253,6 +252,28 @@ BOOST_AUTO_TEST_CASE(versionbits_test)
|
||||
.Mine(6000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(6000)
|
||||
.Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000)
|
||||
.Mine(24000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000) // stay in FAILED no matter how much we signal
|
||||
|
||||
// DEFINED -> STARTED -> LOCKEDIN -> ACTIVE (mandatory lockin)
|
||||
.Reset().SetCheckerHeightBasedTest(true, 2000, 4000).TestDefined().TestStateSinceHeight(0)
|
||||
.Mine(999, TestTime(999), 0).TestDefined().TestStateSinceHeight(0)
|
||||
.Mine(1000, TestTime(1000), 0).TestDefined().TestStateSinceHeight(0)
|
||||
.Mine(2000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(2000)
|
||||
.Mine(4000, TestTime(10001), 0).TestLockedIn().TestStateSinceHeight(4000)
|
||||
.Mine(5000, TestTime(10002), 0).TestActive().TestStateSinceHeight(5000)
|
||||
.Mine(7000, TestTime(20000), 0x100).TestActive().TestStateSinceHeight(5000)
|
||||
|
||||
// DEFINED -> STARTED -> LOCKEDIN -> ACTIVE (mandatory lockin but activation by signalling)
|
||||
.Reset().SetCheckerHeightBasedTest(true, 3000, 10000).TestDefined().TestStateSinceHeight(0)
|
||||
.Mine(1, TestTime(1), 0x200).TestDefined().TestStateSinceHeight(0)
|
||||
.Mine(1000, TestTime(9999) - 1, 0x200).TestDefined().TestStateSinceHeight(0)
|
||||
.Mine(2000, TestTime(10000), 0x101).TestDefined().TestStateSinceHeight(0)
|
||||
.Mine(3000, TestTime(10010), 0x200).TestStarted().TestStateSinceHeight(3000)
|
||||
.Mine(3050, TestTime(10020), 0x200).TestStarted().TestStateSinceHeight(3000) // 50 old blocks
|
||||
.Mine(3950, TestTime(11999), 0x100).TestStarted().TestStateSinceHeight(3000) // 900 new blocks
|
||||
.Mine(3999, TestTime(12000), 0x200).TestStarted().TestStateSinceHeight(3000) // 49 old blocks
|
||||
.Mine(4000, TestTime(12500), 0x200).TestLockedIn().TestStateSinceHeight(4000) // 1 old block
|
||||
.Mine(4999, TestTime(13000), 0).TestLockedIn().TestStateSinceHeight(4000)
|
||||
.Mine(5000, TestTime(13001), 0).TestActive().TestStateSinceHeight(5000)
|
||||
;
|
||||
}
|
||||
}
|
||||
@ -267,11 +288,12 @@ BOOST_AUTO_TEST_CASE(versionbits_sanity)
|
||||
// Make sure that no deployment tries to set an invalid bit.
|
||||
BOOST_CHECK_EQUAL(bitmask & ~(uint32_t)VERSIONBITS_TOP_MASK, bitmask);
|
||||
|
||||
// Check min_activation_height is on a retarget boundary
|
||||
BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].min_activation_height % mainnetParams.nMinerConfirmationWindow, 0U);
|
||||
// Check min_activation_height is 0 for ALWAYS_ACTIVE and never active deployments
|
||||
// Check start height is on a retarget boundary
|
||||
BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].nStartHeight % mainnetParams.nMinerConfirmationWindow, 0U);
|
||||
// Check start_height is 0 for ALWAYS_ACTIVE and never active deployments
|
||||
if (mainnetParams.vDeployments[i].nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE || mainnetParams.vDeployments[i].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) {
|
||||
BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].min_activation_height, 0);
|
||||
BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].nStartHeight, 0);
|
||||
BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].nStartHeight, 0);
|
||||
}
|
||||
|
||||
// Verify that the deployment windows of different deployment using the
|
||||
@ -299,7 +321,8 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||
int64_t bit = params.vDeployments[dep].bit;
|
||||
int64_t nStartTime = params.vDeployments[dep].nStartTime;
|
||||
int64_t nTimeout = params.vDeployments[dep].nTimeout;
|
||||
int min_activation_height = params.vDeployments[dep].min_activation_height;
|
||||
int64_t nStartHeight = params.vDeployments[dep].nStartHeight;
|
||||
int64_t nTimeoutHeight = params.vDeployments[dep].nTimeoutHeight;
|
||||
|
||||
// should not be any signalling for first block
|
||||
BOOST_CHECK_EQUAL(ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
|
||||
@ -308,13 +331,14 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||
if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE) return;
|
||||
if (nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
|
||||
|
||||
BOOST_REQUIRE(nStartTime < nTimeout);
|
||||
BOOST_REQUIRE(nStartTime >= 0);
|
||||
BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
|
||||
BOOST_REQUIRE(0 <= bit && bit < 32);
|
||||
BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
|
||||
BOOST_REQUIRE(min_activation_height >= 0);
|
||||
BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
|
||||
BOOST_CHECK(nStartTime < nTimeout);
|
||||
BOOST_CHECK(nStartTime >= 0);
|
||||
BOOST_CHECK(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
|
||||
BOOST_CHECK(0 <= bit && bit < 32);
|
||||
BOOST_CHECK(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
|
||||
BOOST_CHECK(nStartHeight >= 0);
|
||||
BOOST_CHECK_EQUAL(nStartHeight % params.nMinerConfirmationWindow, 0U);
|
||||
BOOST_CHECK(nTimeoutHeight <= std::numeric_limits<uint32_t>::max());
|
||||
|
||||
// In the first chain, test that the bit is set by CBV until it has failed.
|
||||
// In the second chain, test the bit is set by CBV while STARTED and
|
||||
@ -425,14 +449,6 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
|
||||
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||
|
||||
if (lastBlock->nHeight + 1 < min_activation_height) {
|
||||
// check signalling continues while min_activation_height is not reached
|
||||
lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
|
||||
// then reach min_activation_height, which was already REQUIRE'd to start a new period
|
||||
lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
|
||||
}
|
||||
|
||||
// Check that we don't signal after activation
|
||||
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
|
||||
}
|
||||
@ -441,7 +457,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_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET, CBaseChainParams::REGTEST}) {
|
||||
for (const auto& chain_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::REGTEST}) {
|
||||
const auto chainParams = CreateChainParams(*m_node.args, chain_name);
|
||||
for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
|
||||
check_computeblockversion(chainParams->GetConsensus(), static_cast<Consensus::DeploymentPos>(i));
|
||||
|
||||
@ -1855,6 +1855,8 @@ public:
|
||||
|
||||
int64_t BeginTime(const Consensus::Params& params) const override { return 0; }
|
||||
int64_t EndTime(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); }
|
||||
int64_t BeginHeight(const Consensus::Params& params) const override { return 0; }
|
||||
int64_t EndHeight(const Consensus::Params& params) const override { return std::numeric_limits<int64_t>::max(); }
|
||||
int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
|
||||
int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
|
||||
|
||||
|
||||
@ -9,9 +9,11 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
|
||||
{
|
||||
int nPeriod = Period(params);
|
||||
int nThreshold = Threshold(params);
|
||||
int min_activation_height = MinActivationHeight(params);
|
||||
int64_t nTimeStart = BeginTime(params);
|
||||
int64_t nTimeTimeout = EndTime(params);
|
||||
int64_t nHeightStart = BeginHeight(params);
|
||||
int64_t nHeightTimeout = EndHeight(params);
|
||||
bool fHeightBased = (nTimeStart == 0 && nTimeTimeout == 0) ? true : false;
|
||||
|
||||
// Check if this deployment is always active.
|
||||
if (nTimeStart == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
|
||||
@ -36,7 +38,8 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
|
||||
cache[pindexPrev] = ThresholdState::DEFINED;
|
||||
break;
|
||||
}
|
||||
if (pindexPrev->GetMedianTimePast() < nTimeStart) {
|
||||
if ((fHeightBased && (pindexPrev->nHeight + 1) < nHeightStart) ||
|
||||
(!fHeightBased && pindexPrev->GetMedianTimePast() < nTimeStart)) {
|
||||
// Optimization: don't recompute down further, as we know every earlier block will be before the start time
|
||||
cache[pindexPrev] = ThresholdState::DEFINED;
|
||||
break;
|
||||
@ -56,8 +59,9 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
|
||||
vToCompute.pop_back();
|
||||
|
||||
switch (state) {
|
||||
case ThresholdState::DEFINED: {
|
||||
if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
|
||||
case ThresholdState::DEFINED: {
|
||||
if ((fHeightBased && (pindexPrev->nHeight + 1) >= nHeightStart) ||
|
||||
(!fHeightBased && pindexPrev->GetMedianTimePast() >= nTimeStart)) {
|
||||
stateNext = ThresholdState::STARTED;
|
||||
}
|
||||
break;
|
||||
@ -74,16 +78,14 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex*
|
||||
}
|
||||
if (count >= nThreshold) {
|
||||
stateNext = ThresholdState::LOCKED_IN;
|
||||
} else if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
|
||||
stateNext = ThresholdState::FAILED;
|
||||
} else if((fHeightBased && (pindexPrev->nHeight + 1) >= nHeightTimeout) ||
|
||||
(!fHeightBased && pindexPrev->GetMedianTimePast() >= nTimeTimeout)) {
|
||||
stateNext = (fHeightBased == true) ? ThresholdState::LOCKED_IN : ThresholdState::FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ThresholdState::LOCKED_IN: {
|
||||
// Progresses into ACTIVE provided activation height will have been reached.
|
||||
if (pindexPrev->nHeight + 1 >= min_activation_height) {
|
||||
stateNext = ThresholdState::ACTIVE;
|
||||
}
|
||||
stateNext = ThresholdState::ACTIVE;
|
||||
break;
|
||||
}
|
||||
case ThresholdState::FAILED:
|
||||
@ -174,7 +176,8 @@ private:
|
||||
protected:
|
||||
int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
|
||||
int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
|
||||
int MinActivationHeight(const Consensus::Params& params) const override { return params.vDeployments[id].min_activation_height; }
|
||||
int64_t BeginHeight(const Consensus::Params& params) const override { return params.vDeployments[id].nStartHeight; }
|
||||
int64_t EndHeight(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeoutHeight; }
|
||||
int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
|
||||
int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
|
||||
|
||||
|
||||
@ -56,7 +56,9 @@ class AbstractThresholdConditionChecker {
|
||||
protected:
|
||||
virtual bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const =0;
|
||||
virtual int64_t BeginTime(const Consensus::Params& params) const =0;
|
||||
virtual int64_t EndTime(const Consensus::Params& params) const =0;
|
||||
virtual int64_t EndTime(const Consensus::Params& params) const = 0;
|
||||
virtual int64_t BeginHeight(const Consensus::Params& params) const = 0;
|
||||
virtual int64_t EndHeight(const Consensus::Params& params) const = 0;
|
||||
virtual int MinActivationHeight(const Consensus::Params& params) const { return 0; }
|
||||
virtual int Period(const Consensus::Params& params) const =0;
|
||||
virtual int Threshold(const Consensus::Params& params) const =0;
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.test_framework import BitcoinTestFramework, SkipTest
|
||||
from test_framework.util import assert_equal
|
||||
|
||||
signet_blocks = [
|
||||
@ -40,6 +40,9 @@ class SignetBasicTest(BitcoinTestFramework):
|
||||
]
|
||||
|
||||
def run_test(self):
|
||||
if True:
|
||||
raise SkipTest("Signet not supported")
|
||||
|
||||
self.log.info("basic tests using OP_TRUE challenge")
|
||||
|
||||
self.log.info('getmininginfo')
|
||||
|
||||
@ -145,7 +145,6 @@ class BlockchainTest(BitcoinTestFramework):
|
||||
'count': 57,
|
||||
'possible': True,
|
||||
},
|
||||
'min_activation_height': 0,
|
||||
},
|
||||
'active': False
|
||||
},
|
||||
@ -156,7 +155,6 @@ class BlockchainTest(BitcoinTestFramework):
|
||||
'start_time': -1,
|
||||
'timeout': 9223372036854775807,
|
||||
'since': 0,
|
||||
'min_activation_height': 0,
|
||||
},
|
||||
'height': 0,
|
||||
'active': True
|
||||
|
||||
@ -230,7 +230,7 @@ BASE_SCRIPTS = [
|
||||
'rpc_bind.py --ipv6',
|
||||
'rpc_bind.py --nonloopback',
|
||||
'mining_basic.py',
|
||||
#'feature_signet.py',
|
||||
'feature_signet.py',
|
||||
'wallet_bumpfee.py',
|
||||
'wallet_bumpfee.py --descriptors',
|
||||
'wallet_implicitsegwit.py --legacy-wallet',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user