diff --git a/src/test/bls_tests.cpp b/src/test/bls_tests.cpp index 4ebfeb931586..40f244e3e818 100644 --- a/src/test/bls_tests.cpp +++ b/src/test/bls_tests.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -636,23 +635,6 @@ BOOST_AUTO_TEST_CASE(test_get_hash_consistency) BOOST_CHECK(hash1 == hash2); } -namespace { -struct TestChainV19Setup : public TestChainSetup { - TestChainV19Setup() : - TestChainSetup(494, CBaseChainParams::REGTEST, - {"-testactivationheight=v19@500", "-testactivationheight=v20@500", "-testactivationheight=mn_rr@500"}) - { - const CScript coinbase_pk = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); - // Mine up to the block just before V19 activation - for (int i = 0; i < 5; ++i) { - CreateAndProcessBlock({}, coinbase_pk); - } - assert(DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), Consensus::DEPLOYMENT_V19) && - !DeploymentActiveAt(*m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), Consensus::DEPLOYMENT_V19)); - } -}; -} // namespace - BOOST_AUTO_TEST_CASE(v19_boundary_validation_failure_restores_bls_scheme) { TestChainV19Setup setup; diff --git a/src/test/evo_deterministicmns_tests.cpp b/src/test/evo_deterministicmns_tests.cpp index 4241faa7fa8f..b3bc63a27a97 100644 --- a/src/test/evo_deterministicmns_tests.cpp +++ b/src/test/evo_deterministicmns_tests.cpp @@ -15,8 +15,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -712,6 +712,7 @@ void FuncMNPaymentMultiplicityV24Boundary(TestChainSetup& setup) // Start in the pre-v24 window: v19 active (basic BLS scheme) so we can register a v2 MN, but // v24 -- and thus strict multiplicity matching -- not yet active. BOOST_REQUIRE(DeploymentActiveAfter(tip_index(), consensus, Consensus::DEPLOYMENT_V19)); + BOOST_REQUIRE(!DeploymentActiveAfter(tip_index(), consensus, Consensus::DEPLOYMENT_MN_RR)); BOOST_REQUIRE(!DeploymentActiveAfter(tip_index(), chainman, Consensus::DEPLOYMENT_V24)); BOOST_REQUIRE(!bls::bls_legacy_scheme.load()); @@ -876,6 +877,7 @@ void FuncMNPaymentMultiplicityV24Boundary(TestChainSetup& setup) sync_dmn_tip(); } BOOST_REQUIRE(DeploymentActiveAfter(tip_index(), chainman, Consensus::DEPLOYMENT_V24)); + BOOST_REQUIRE(!DeploymentActiveAfter(tip_index(), consensus, Consensus::DEPLOYMENT_MN_RR)); // ---- Post-v24: strict multiplicity matching REJECTS the same merge (two expected outputs, one // distinct actual). Rejection is observed as the tip not advancing. @@ -1506,9 +1508,15 @@ static void SmlCache(TestChainSetup& setup) BOOST_AUTO_TEST_SUITE(evo_dip3_activation_tests) +// FuncDIP3Protx registers six masternodes in successive blocks. Height 109 is the lowest boundary +// that keeps two mature coinbases available for every 1000 DASH collateral; height 108 runs out on +// the sixth registration. +constexpr int DIP3_ACTIVATION_HEIGHT{109}; + struct TestChainDIP3BeforeActivationSetup : public TestChainSetup { TestChainDIP3BeforeActivationSetup() : - TestChainSetup(430) + TestChainSetup(DIP3_ACTIVATION_HEIGHT - 2, CBaseChainParams::REGTEST, {"-dip3params=109:500"}, + /*coins_db_in_memory=*/true, /*block_tree_db_in_memory=*/true) { } }; @@ -1521,39 +1529,12 @@ struct TestChainDIP3Setup : public TestChainDIP3BeforeActivationSetup { } }; -struct TestChainV19BeforeActivationSetup : public TestChainSetup { - TestChainV19BeforeActivationSetup(); -}; - -struct TestChainV19Setup : public TestChainV19BeforeActivationSetup { - TestChainV19Setup() - { - const CScript coinbase_pk = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); - // Activate V19 - for (int i = 0; i < 5; ++i) { - CreateAndProcessBlock({}, coinbase_pk); - } - bool v19_just_activated{WITH_LOCK(::cs_main, return DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), Consensus::DEPLOYMENT_V19) && - !DeploymentActiveAt(*m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), Consensus::DEPLOYMENT_V19))}; - assert(v19_just_activated); - } -}; - -// 5 blocks earlier -TestChainV19BeforeActivationSetup::TestChainV19BeforeActivationSetup() : - TestChainSetup(494, CBaseChainParams::REGTEST, {"-testactivationheight=v19@500", "-testactivationheight=v20@500", "-testactivationheight=mn_rr@500"}) -{ - bool v19_active{WITH_LOCK(::cs_main, return DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), - Consensus::DEPLOYMENT_V19))}; - assert(!v19_active); -} - struct TestChainV24SignalBeforeV19Setup : public TestChainSetup { TestChainV24SignalBeforeV19Setup() : TestChainSetup(494, CBaseChainParams::REGTEST, {"-testactivationheight=v19@500", "-testactivationheight=v20@500", - "-testactivationheight=mn_rr@500", - "-vbparams=v24:0:9999999999:0:500:400:300:5:0"}) + "-testactivationheight=mn_rr@511", "-vbparams=v24:0:9999999999:510:1:1:1:5:0"}, + /*coins_db_in_memory=*/true, /*block_tree_db_in_memory=*/true) { assert(WITH_LOCK(::cs_main, return !DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), Consensus::DEPLOYMENT_V19))); @@ -1562,21 +1543,17 @@ struct TestChainV24SignalBeforeV19Setup : public TestChainSetup { } }; -// v19/v20/mn_rr active at height 500, with v24 signalled but still PENDING (not yet locked in). -// The 500-block window means v24 locks in well after v19, so this fixture stops in the window -// where basic-BLS (v2) registrations are valid but strict multiplicity matching is off, letting -// a single test cross the v24 activation boundary. -struct TestChainV24PendingSetup : public TestChainSetup { - TestChainV24PendingSetup() : - TestChainSetup(494, CBaseChainParams::REGTEST, - {"-testactivationheight=v19@500", "-testactivationheight=v20@500", - "-testactivationheight=mn_rr@500", - "-vbparams=v24:0:9999999999:0:500:400:300:5:0"}) +// Advance the shared v24 chain just far enough that v19/v20 are active while v24 remains held in +// LOCKED_IN by its minimum activation height. Delaying mn_rr until the block after v24 keeps the +// subsidy-only masternode reward even on both sides of the boundary, so the duplicate-payment +// helper does not need to mine to the next subsidy epoch. +struct TestChainV24PendingSetup : public TestChainV24SignalBeforeV19Setup { + TestChainV24PendingSetup() { const CScript coinbase_pk = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); auto& chainman = *Assert(m_node.chainman); auto& dmnman = *Assert(m_node.dmnman); - // Mine just enough to activate v19/v20/mn_rr (height 500) while keeping v24 pending. + // Mine just enough to activate v19/v20 (height 500) while keeping v24 and mn_rr pending. for (int i = 0; i < 20 && WITH_LOCK(::cs_main, return !DeploymentActiveAfter(chainman.ActiveChain().Tip(), chainman.GetConsensus(), Consensus::DEPLOYMENT_V19)); ++i) { CreateAndProcessBlock({}, coinbase_pk); dmnman.UpdatedBlockTip(WITH_LOCK(::cs_main, return chainman.ActiveChain().Tip())); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 957c494dfcc1..57a4efe0e819 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -480,12 +480,16 @@ TestChainSetup::TestChainSetup( { 98, uint256S("0x150e127929d578d8129b77a6cb7e2e343a1379aa3feaaa9cce59e0a645756a81") }, /*TestChain100Setup=*/ { 100, uint256S("0x6ffb83129c19ebdf1ae3771be6a67fe34b35f4c956326b9ba152fac1649f65ae") }, + /*TestChainV19BeforeActivationSetup=*/ + { 103, uint256S("0x13adad9565d0ca558f5675c50e3828f4354d26b64de044ebc88686056f30faab") }, + /*TestChainDIP3BeforeActivationSetup=*/ + { 107, uint256S("0x40233e79ab24bc7c3e5686ac2b63915e15e1b1deecc3d0919f7ec32a9433fdfb") }, /*TestChainDIP3BeforeActivationSetup=*/ { 430, uint256S("0x0bcefaa33fec56cd84d05d0e76cd6a78badcc20f627d91903646de6a07930a14") }, + /*TestChainV24SignalBeforeV19Setup=*/ + { 494, uint256S("0x083fa179797ea7e5893198ff1b6eab632526c2eeb6f0ca6c42fcac9cb9bad366") }, /*TestChainBRRBeforeActivationSetup=*/ { 497, uint256S("0x0857a9b5db51835b1c828f019f4c664b5fe6c28ac44a6d868436930f832d31e5") }, - /*TestChainV19BeforeActivationSetup=*/ - { 494, uint256S("0x44ee5c8a5e5cbd4437d63c54ddc1d40329be811b25c492fa901e11cdf408f905") }, } }; @@ -498,6 +502,36 @@ TestChainSetup::TestChainSetup( } } +namespace { +// This is the lowest activation height that leaves enough mature pre-mined coinbases for all +// consumers of the shared fixture. The DIP3 prerequisite is active before the v19 boundary work. +constexpr int V19_ACTIVATION_HEIGHT{109}; +} // namespace + +TestChainV19BeforeActivationSetup::TestChainV19BeforeActivationSetup() : + TestChainSetup{V19_ACTIVATION_HEIGHT - 6, + CBaseChainParams::REGTEST, + {"-dip3params=100:500", "-testactivationheight=v19@109", "-testactivationheight=v20@109", + "-testactivationheight=mn_rr@109"}, + /*coins_db_in_memory=*/true, + /*block_tree_db_in_memory=*/true} +{ + assert(WITH_LOCK(::cs_main, return !DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), + Consensus::DEPLOYMENT_V19))); +} + +TestChainV19Setup::TestChainV19Setup() +{ + const CScript coinbase_pk = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); + for (int i = 0; i < 5; ++i) { + CreateAndProcessBlock({}, coinbase_pk); + } + assert(WITH_LOCK(::cs_main, return DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), + Consensus::DEPLOYMENT_V19) && + !DeploymentActiveAt(*m_node.chainman->ActiveChain().Tip(), m_node.chainman->GetConsensus(), + Consensus::DEPLOYMENT_V19))); +} + void TestChainSetup::mineBlocks(int num_blocks) { CScript scriptPubKey = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index 8001b84248df..63f2a9d52a16 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -217,6 +217,16 @@ struct TestChainSetup : public TestingSetup CKey coinbaseKey; // private/public key needed to spend coinbase transactions }; +/** Test chain stopped five blocks before v19 activation at height 109. */ +struct TestChainV19BeforeActivationSetup : public TestChainSetup { + TestChainV19BeforeActivationSetup(); +}; + +/** Test chain whose next block activates v19 at height 109. */ +struct TestChainV19Setup : public TestChainV19BeforeActivationSetup { + TestChainV19Setup(); +}; + /** * Testing fixture that pre-creates a 100-block REGTEST-mode block chain */