diff --git a/configure.ac b/configure.ac index 6f7496ef1..611656de6 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.69]) define(_CLIENT_VERSION_MAJOR, 6) define(_CLIENT_VERSION_MINOR, 0) -define(_CLIENT_VERSION_BUILD, 42) +define(_CLIENT_VERSION_BUILD, 43) define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true ) define(_COPYRIGHT_YEAR, 2026) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 513a4f852..337abe338 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -108,8 +108,6 @@ class CMainParams : public CChainParams { // Two days consensus.nASERTHalfLife = 2 * 24 * 60 * 60; - // ASERT activation time: 2026-04-20 10:09:00 UTC, at FACT's birthday - consensus.asertActivationTime = 1776679740; consensus.nBitsMin = 32; consensus.nBitsMax = 1022; @@ -119,7 +117,7 @@ class CMainParams : public CChainParams { 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 = 1; // No activation delay + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay consensus.nMinimumChainWork = uint256S("0x10a8"); consensus.defaultAssumeValid = genesis.GetHash(); @@ -145,6 +143,12 @@ class CMainParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_INTERIM_DAA].nThreshold = Consensus::INTERIM_DAA_THRESHOLD; consensus.vDeployments[Consensus::DEPLOYMENT_INTERIM_DAA].max_active_blocks = Consensus::INTERIM_DAA_MAX_ACTIVE; + // ASERT DAA deployment (uses global defaults for period/threshold) + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].bit = 24; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].nStartTime = 1772323200LL; // 2026-03-01 + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].nTimeout = 1803859200LL; // 2027-03-01 + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].min_activation_height = 0; + /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -242,8 +246,6 @@ class CTestNetParams : public CChainParams { // One hour consensus.nASERTHalfLife = 60 * 60; - // ASERT always active on testnet - consensus.asertActivationTime = 0; consensus.nBitsMin = 32; consensus.nBitsMax = 1022; @@ -275,6 +277,12 @@ class CTestNetParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_INTERIM_DAA].nThreshold = Consensus::INTERIM_DAA_THRESHOLD; consensus.vDeployments[Consensus::DEPLOYMENT_INTERIM_DAA].max_active_blocks = Consensus::INTERIM_DAA_MAX_ACTIVE; + // ASERT DAA deployment + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].bit = 24; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].min_activation_height = 0; + //Number of rounds for gHash to generate random Ws around which to search for semiprimes. consensus.hashRounds = 1; @@ -404,8 +412,6 @@ class SigNetParams : public CChainParams { // Two days consensus.nASERTHalfLife = 2 * 24 * 60 * 60; - // ASERT always active on signet - consensus.asertActivationTime = 0; consensus.nBitsMin = 32; consensus.nBitsMax = 1022; @@ -448,6 +454,12 @@ class SigNetParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_INTERIM_DAA].nThreshold = Consensus::INTERIM_DAA_THRESHOLD; consensus.vDeployments[Consensus::DEPLOYMENT_INTERIM_DAA].max_active_blocks = Consensus::INTERIM_DAA_MAX_ACTIVE; + // ASERT DAA deployment + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].bit = 24; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].min_activation_height = 0; + vFixedSeeds.clear(); base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); @@ -497,8 +509,6 @@ class CRegTestParams : public CChainParams { // One hour (match testnet for fast testing) consensus.nASERTHalfLife = 60 * 60; - // ASERT always active on regtest - consensus.asertActivationTime = 0; consensus.nBitsMin = 32; consensus.nBitsMax = 1022; @@ -542,6 +552,12 @@ class CRegTestParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_INTERIM_DAA].nThreshold = Consensus::INTERIM_DAA_THRESHOLD; consensus.vDeployments[Consensus::DEPLOYMENT_INTERIM_DAA].max_active_blocks = Consensus::INTERIM_DAA_MAX_ACTIVE; + // ASERT DAA deployment + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].bit = 24; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; + consensus.vDeployments[Consensus::DEPLOYMENT_ASERT].min_activation_height = 0; + UpdateActivationParametersFromArgs(args); vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. diff --git a/src/consensus/params.h b/src/consensus/params.h index 414b9ff0d..b37c5d39c 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -31,6 +31,7 @@ constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_ enum DeploymentPos : uint16_t { DEPLOYMENT_TESTDUMMY, DEPLOYMENT_INTERIM_DAA, + DEPLOYMENT_ASERT, // NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp MAX_VERSION_BITS_DEPLOYMENTS }; @@ -120,7 +121,6 @@ struct Params { bool fPowNoRetargeting; int64_t nPowTargetSpacing; int64_t nASERTHalfLife; - int64_t asertActivationTime; int32_t nBitsMin; // FACTOR ASERT: minimum allowed nBits (easiest difficulty) int32_t nBitsMax; // FACTOR ASERT: maximum allowed nBits (hardest difficulty) int64_t nPowTargetTimespan; diff --git a/src/deploymentinfo.cpp b/src/deploymentinfo.cpp index 7dbb6c9c5..38dfeade3 100644 --- a/src/deploymentinfo.cpp +++ b/src/deploymentinfo.cpp @@ -15,6 +15,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B /*.name =*/ "interim_daa", /*.gbt_force =*/ true, }, + { + /*.name =*/ "asert", + /*.gbt_force =*/ true, + }, }; std::string DeploymentName(Consensus::BuriedDeployment dep) diff --git a/src/pow.cpp b/src/pow.cpp index 561b4ff92..8efc3db84 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -46,63 +46,54 @@ bool IsASERTEnabled(const Consensus::Params ¶ms, return false; } - return pindexPrev->GetBlockTime() >= params.asertActivationTime; + return DeploymentActiveAfter(pindexPrev, params, Consensus::DEPLOYMENT_ASERT); } /** * Returns a pointer to the anchor block used for ASERT. * - * The anchor is the first block whose timestamp >= asertActivationTime. - * Its difficulty was still set by the old DAA, so it serves as the - * reference point from which ASERT computes all subsequent difficulties. + * The anchor is the last block whose difficulty was set by the old DAA, + * serving as the reference point from which ASERT computes all subsequent + * difficulties. + * + * For ALWAYS_ACTIVE deployments (testnet/signet), the anchor is block 1. + * For real BIP9 activation, the anchor is the last block of the LOCKED_IN + * period (one before the first block of the ACTIVE period). * * This function is meant to be removed some time after the upgrade, once * the anchor block is deeply buried, and behind a hard-coded checkpoint. * - * Preconditions: - pindex must not be nullptr - * - pindex must satisfy: IsASERTEnabled(params, pindex) == true - * Postcondition: Returns a pointer to the first (lowest) block for which - * IsASERTEnabled is true, and for which IsASERTEnabled(pprev) - * is false (or for which pprev is nullptr). The return value may - * be pindex itself. + * Precondition: pindex must not be nullptr. + * Postcondition: Returns a pointer to the anchor block, which is an + * ancestor of (or equal to) pindex. */ static const CBlockIndex *GetASERTAnchorBlock(const CBlockIndex *const pindex, const Consensus::Params ¶ms) { assert(pindex); - // - We check if we have a cached result, and if we do and it is really the - // ancestor of pindex, then we return it. - // - // - If we do not or if the cached result is not the ancestor of pindex, - // then we proceed with the more expensive walk back to find the ASERT - // anchor block. - // - // CBlockIndex::GetAncestor() is reasonably efficient; it uses CBlockIndex::pskip - // Note that if pindex == cachedAnchor, GetAncestor() here will return cachedAnchor, - // which is what we want. + // Fast path: if we have a cached anchor that is an ancestor of pindex, + // return it immediately (no versionbits query needed). + // Note that if pindex == cachedAnchor, GetAncestor() returns cachedAnchor. const CBlockIndex *lastCached = cachedAnchor.load(); if (lastCached && pindex->GetAncestor(lastCached->nHeight) == lastCached) return lastCached; - // Slow path: walk back until we find the first ancestor for which IsASERTEnabled() == true. - const CBlockIndex *anchor = pindex; - - while (anchor->pprev) { - // first, skip backwards testing IsASERTEnabled - // The below code leverages CBlockIndex::pskip to walk back efficiently. - if (IsASERTEnabled(params, anchor->pskip)) { - // skip backward - anchor = anchor->pskip; - continue; // continue skipping - } - // cannot skip here, walk back by 1 - if (!IsASERTEnabled(params, anchor->pprev)) { - // found it -- highest block where ASERT is not enabled is anchor->pprev, and - // anchor points to the first block for which IsASERTEnabled() == true - break; - } - anchor = anchor->pprev; - } + // StateSinceHeight returns: + // 0 for ALWAYS_ACTIVE (no chain walk) + // H for real BIP9 (first block of the ACTIVE period) + // + // The anchor is the last block computed by the old DAA: + // block 1 for ALWAYS_ACTIVE (genesis has no ASERT history) + // block H-1 for real BIP9 (last block of LOCKED_IN period) + int activeSince = g_versionbitscache.StateSinceHeight( + pindex, params, Consensus::DEPLOYMENT_ASERT); + int anchorHeight = (activeSince <= 1) ? 1 : activeSince - 1; + + // GetAncestor(h) returns the block at height h (the block itself when + // h == pindex->nHeight), so when computing difficulty for the first + // ACTIVE block — where pindex is the anchor — this returns pindex. + const CBlockIndex *anchor = pindex->GetAncestor(anchorHeight); + assert(anchor != nullptr); // Overwrite the cache with the anchor we found. More likely than not, the next // time we are asked to validate a header it will be part of same / similar chain, not @@ -223,14 +214,7 @@ static uint16_t GetNextFACTORASERTWorkRequired( } // Anchor selection - const CBlockIndex *pindexAnchor; - if (params.asertActivationTime == 0) { - // Testnet / regtest / signet: anchor is always block 1 - pindexAnchor = pindexPrev->GetAncestor(1); - } else { - // Mainnet: first block where block time >= activation time - pindexAnchor = GetASERTAnchorBlock(pindexPrev, params); - } + const CBlockIndex *pindexAnchor = GetASERTAnchorBlock(pindexPrev, params); assert(pindexAnchor != nullptr); // Normalize anchor nBits to even (floor) and clamp into [nBitsMin, nBitsMax]. diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index c5f97d326..c55a27f94 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -5,8 +5,10 @@ #include #include +#include #include #include +#include #include @@ -167,60 +169,77 @@ BOOST_AUTO_TEST_SUITE_END() // ============================================================================ -// Anchor discovery tests — exercises GetASERTAnchorBlock via mainnet params. +// Anchor discovery tests — exercises GetASERTAnchorBlock via regtest params +// with real BIP9 activation (not ALWAYS_ACTIVE). +// +// Regtest BIP9 timeline for DEPLOYMENT_ASERT (period=32, threshold=24, bit=24): +// Period 0 (heights 0-31): DEFINED +// Period 1 (heights 32-63): STARTED — all blocks signal +// Period 2 (heights 64-95): LOCKED_IN +// Period 3 (heights 96+ ): ACTIVE +// +// Anchor = block 95 (last block of LOCKED_IN, i.e. activeSince − 1). // ============================================================================ -// Like BuildMockChain but populates pskip (required by GetASERTAnchorBlock). -static std::vector BuildMockChainWithSkip(int64_t genesis_time, - uint16_t genesis_nBits, - int count, - int64_t spacing) { +// Build a mock chain where ASERT activates via BIP9 at the standard regtest +// boundary. Blocks 32-63 signal with version bit 24; all others do not. +// Populates pskip (required by GetAncestor / BIP9 state walks). +static std::vector BuildBIP9ActivatedChain(int64_t genesis_time, + uint16_t genesis_nBits, + int count, + int64_t spacing) { + assert(count > 96); // must reach ACTIVE state + const int32_t SIGNAL_VERSION = VERSIONBITS_TOP_BITS | (1 << 24); + std::vector chain(count); for (int i = 0; i < count; i++) { chain[i].nHeight = i; chain[i].nTime = genesis_time + i * spacing; chain[i].nBits = genesis_nBits; chain[i].pprev = (i > 0) ? &chain[i - 1] : nullptr; + chain[i].nVersion = (i >= 32 && i <= 63) ? SIGNAL_VERSION : 1; chain[i].BuildSkip(); } + + // Sanity: signaling window must land in the STARTED period. + // If this fires, someone changed regtest nStartTime for DEPLOYMENT_ASERT + // and the hardcoded signaling range [32,63] no longer aligns with BIP9. + const Consensus::Params& params = Params().GetConsensus(); + g_versionbitscache.Clear(); + ThresholdState state = g_versionbitscache.State(&chain[31], params, Consensus::DEPLOYMENT_ASERT); + assert(state == ThresholdState::STARTED); + return chain; } -struct MainnetTestingSetup : public BasicTestingSetup { - MainnetTestingSetup() : BasicTestingSetup(CBaseChainParams::MAIN) {} +static const int ANCHOR_HEIGHT = 95; + +struct RegtestTestingSetup : public BasicTestingSetup { + RegtestTestingSetup() : BasicTestingSetup(CBaseChainParams::REGTEST) {} }; -BOOST_FIXTURE_TEST_SUITE(pow_anchor_tests, MainnetTestingSetup) +BOOST_FIXTURE_TEST_SUITE(pow_anchor_tests, RegtestTestingSetup) -// Chain crosses activation boundary at block 5. Each block gets a unique -// nBits so we can identify exactly which block was chosen as anchor. +// Verify that GetASERTAnchorBlock finds block 95 (last block of the +// LOCKED_IN period) as the anchor after real BIP9 activation. BOOST_AUTO_TEST_CASE(anchor_discovery_at_boundary) { const Consensus::Params& params = Params().GetConsensus(); CBlockHeader header; ResetASERTAnchorBlockCache(); - // Place activation boundary at block 5 - const int64_t genesis_time = params.asertActivationTime - 5 * params.nPowTargetSpacing; - auto chain = BuildMockChainWithSkip(genesis_time, 32, 20, params.nPowTargetSpacing); - - // Give every block a unique even nBits in [32, 70] - for (int i = 0; i < 20; i++) { - chain[i].nBits = static_cast(32 + 2 * i); - } - // Block 5 (the anchor) has nBits = 32 + 10 = 42 + auto chain = BuildBIP9ActivatedChain(1650443545, 32, 120, params.nPowTargetSpacing); - // Query from block 6 (first block after anchor): anchor is block 5, - // heightDiff=1, timeDiff=1*spacing → steady state → returns anchor nBits - uint16_t nBits = GetNextWorkRequired(&chain[6], &header, params); - BOOST_CHECK_EQUAL(nBits, 42); + // Give the anchor a unique nBits so we can identify it in the output. + chain[ANCHOR_HEIGHT].nBits = 222; - // Query from block 10: same anchor - nBits = GetNextWorkRequired(&chain[10], &header, params); - BOOST_CHECK_EQUAL(nBits, 42); + // Block 96 is first ACTIVE block. Query for block 97 (pindexPrev=96): + // heightDiff=1, timeDiff=1*spacing → steady state → returns anchor nBits. + uint16_t nBits = GetNextWorkRequired(&chain[96], &header, params); + BOOST_CHECK_EQUAL(nBits, 222); - // Query from block 15: anchor must still be block 5 - nBits = GetNextWorkRequired(&chain[15], &header, params); - BOOST_CHECK_EQUAL(nBits, 42); + // Further along the chain — anchor must still be block 95. + nBits = GetNextWorkRequired(&chain[110], &header, params); + BOOST_CHECK_EQUAL(nBits, 222); } // Two independent chains with different anchor nBits. The atomic cache @@ -230,27 +249,27 @@ BOOST_AUTO_TEST_CASE(anchor_cache_reorg) { CBlockHeader header; ResetASERTAnchorBlockCache(); - const int64_t genesis_time = params.asertActivationTime - 5 * params.nPowTargetSpacing; - - // Chain A: anchor (block 5) has nBits=100 - auto chainA = BuildMockChainWithSkip(genesis_time, 32, 20, params.nPowTargetSpacing); - chainA[5].nBits = 100; + auto chainA = BuildBIP9ActivatedChain(1650443545, 32, 120, params.nPowTargetSpacing); + chainA[ANCHOR_HEIGHT].nBits = 100; - // Chain B: anchor (block 5) has nBits=200 - auto chainB = BuildMockChainWithSkip(genesis_time, 32, 20, params.nPowTargetSpacing); - chainB[5].nBits = 200; + auto chainB = BuildBIP9ActivatedChain(1650443545, 32, 120, params.nPowTargetSpacing); + chainB[ANCHOR_HEIGHT].nBits = 200; - // Query chain A — populates cache with &chainA[5] - uint16_t nBitsA = GetNextWorkRequired(&chainA[10], &header, params); + // Query chain A — populates anchor cache with &chainA[95] + uint16_t nBitsA = GetNextWorkRequired(&chainA[100], &header, params); BOOST_CHECK_EQUAL(nBitsA, 100); - // Query chain B — cache must invalidate (different pointer) - uint16_t nBitsB = GetNextWorkRequired(&chainB[10], &header, params); + // Query chain B — g_versionbitscache is NOT cleared. The two chains have + // disjoint CBlockIndex* addresses, so chainB queries naturally miss on + // chainA's cached entries and recompute from scratch (same as a real reorg + // where post-fork blocks are distinct allocations). The anchor pointer + // cache (cachedAnchor) still points to chainA[95], forcing the pointer- + // identity check to detect the chain switch and re-discover the anchor. + uint16_t nBitsB = GetNextWorkRequired(&chainB[100], &header, params); BOOST_CHECK_EQUAL(nBitsB, 200); - // Query chain A again — cache was overwritten by chain B's anchor, - // must invalidate again and re-find chain A's anchor - uint16_t nBitsA2 = GetNextWorkRequired(&chainA[15], &header, params); + // Query chain A again — same situation in reverse + uint16_t nBitsA2 = GetNextWorkRequired(&chainA[110], &header, params); BOOST_CHECK_EQUAL(nBitsA2, 100); } @@ -260,12 +279,11 @@ BOOST_AUTO_TEST_CASE(anchor_fast_blocks) { CBlockHeader header; ResetASERTAnchorBlockCache(); - const int64_t genesis_time = params.asertActivationTime - 5 * params.nPowTargetSpacing; - auto chain = BuildMockChainWithSkip(genesis_time, 32, 200, params.nPowTargetSpacing); + auto chain = BuildBIP9ActivatedChain(1650443545, 32, 200, params.nPowTargetSpacing); - // 1-second spacing post-activation to generate a large positive exponent - for (int i = 6; i < 200; i++) { - chain[i].nTime = chain[5].nTime + (i - 5); + // 1-second spacing post-activation + for (int i = ANCHOR_HEIGHT + 1; i < 200; i++) { + chain[i].nTime = chain[ANCHOR_HEIGHT].nTime + (i - ANCHOR_HEIGHT); } uint16_t nBits = GetNextWorkRequired(&chain[199], &header, params); @@ -278,18 +296,17 @@ BOOST_AUTO_TEST_CASE(anchor_slow_blocks) { CBlockHeader header; ResetASERTAnchorBlockCache(); - const int64_t genesis_time = params.asertActivationTime - 5 * params.nPowTargetSpacing; - auto chain = BuildMockChainWithSkip(genesis_time, 32, 20, params.nPowTargetSpacing); + auto chain = BuildBIP9ActivatedChain(1650443545, 32, 120, params.nPowTargetSpacing); // Anchor at nBits=100 so there's room to decrease - chain[5].nBits = 100; + chain[ANCHOR_HEIGHT].nBits = 100; // Double the spacing for post-activation blocks - for (int i = 6; i < 20; i++) { - chain[i].nTime = chain[5].nTime + (i - 5) * (params.nPowTargetSpacing * 2); + for (int i = ANCHOR_HEIGHT + 1; i < 120; i++) { + chain[i].nTime = chain[ANCHOR_HEIGHT].nTime + (i - ANCHOR_HEIGHT) * (params.nPowTargetSpacing * 2); } - uint16_t nBits = GetNextWorkRequired(&chain[15], &header, params); + uint16_t nBits = GetNextWorkRequired(&chain[115], &header, params); BOOST_CHECK_LT(nBits, 100); } diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 690031cdc..e74eb57d3 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -267,6 +267,9 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus int64_t nTimeout = params.vDeployments[dep].nTimeout; int min_activation_height = params.vDeployments[dep].min_activation_height; + // Effective period: use per-deployment override if set, else global nMinerConfirmationWindow + int nPeriod = params.vDeployments[dep].nPeriod > 0 ? params.vDeployments[dep].nPeriod : params.nMinerConfirmationWindow; + // should not be any signalling for first block BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS); @@ -285,8 +288,8 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus // Make sure that no deployment tries to set an invalid bit. BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0); BOOST_REQUIRE(min_activation_height >= 0); - // Check min_activation_height is on a retarget boundary - BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U); + // Check min_activation_height is on a period boundary + BOOST_REQUIRE_EQUAL(min_activation_height % nPeriod, 0U); const uint32_t bitmask{g_versionbitscache.Mask(params, dep)}; BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit); @@ -306,9 +309,9 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus // since CBlockIndex::nTime is uint32_t we can't represent any // earlier time, so will transition from DEFINED to STARTED at the // end of the first period by mining blocks at nTime == 0 - lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + lastBlock = firstChain.Mine(nPeriod - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); - lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + lastBlock = firstChain.Mine(nPeriod, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); // then we'll keep mining at nStartTime... } else { @@ -316,25 +319,25 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus --nTime; // Start generating blocks before nStartTime - lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + lastBlock = firstChain.Mine(nPeriod, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet. - for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) { - lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + for (uint32_t i = 1; i < nPeriod - 4; i++) { + lastBlock = firstChain.Mine(nPeriod + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); } // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so // CBV should still not yet set the bit. nTime = nStartTime; - for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) { - lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + for (uint32_t i = nPeriod - 4; i <= nPeriod; i++) { + lastBlock = firstChain.Mine(nPeriod + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK_EQUAL(g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); } // Next we will advance to the next period and transition to STARTED, } - lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + lastBlock = firstChain.Mine(nPeriod * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); // so ComputeBlockVersion should now set the bit, BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); // and should also be using the VERSIONBITS_TOP_BITS. @@ -342,8 +345,8 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus // Check that ComputeBlockVersion will set the bit until nTimeout nTime += 600; - uint32_t blocksToMine = params.nMinerConfirmationWindow * 2; // test blocks for up to 2 time periods - uint32_t nHeight = params.nMinerConfirmationWindow * 3; + uint32_t blocksToMine = nPeriod * 2; // test blocks for up to 2 time periods + uint32_t nHeight = nPeriod * 3; // These blocks are all before nTimeout is reached. while (nTime < nTimeout && blocksToMine > 0) { lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); @@ -360,7 +363,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus nTime = nTimeout; // finish the last period before we start timing out - while (nHeight % params.nMinerConfirmationWindow != 0) { + while (nHeight % nPeriod != 0) { lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); nHeight += 1; @@ -368,7 +371,7 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus // FAILED is only triggered at the end of a period, so CBV should be setting // the bit until the period transition. - for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) { + for (uint32_t i = 0; i < nPeriod - 1; i++) { lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); nHeight += 1; @@ -385,20 +388,20 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus // Mine one period worth of blocks, and check that the bit will be on for the // next period. - lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); + lastBlock = secondChain.Mine(nPeriod, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); BOOST_CHECK((g_versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); // Mine another period worth of blocks, signaling the new bit. - lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<nHeight + 1 < min_activation_height) { // check signalling continues while min_activation_height is not reached