Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: start v19 from block 1 - fire up test chains by first block - 8/n #6511

Merged
merged 7 commits into from
Jan 11, 2025
4 changes: 3 additions & 1 deletion src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ class CRegTestParams : public CChainParams {
consensus.DIP0020Height = 1; // Always active unless overridden
consensus.DIP0024Height = 1; // Always have dip0024 quorums unless overridden
consensus.DIP0024QuorumsHeight = 1; // Always have dip0024 quorums unless overridden
consensus.V19Height = 900;
consensus.V19Height = 1; // Always active unless overriden
consensus.V20Height = 900;
consensus.MN_RRHeight = 900;
consensus.MinBIP9WarningHeight = 0;
Expand Down Expand Up @@ -1031,6 +1031,8 @@ static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& conse
consensus.DIP0008Height = int{height};
} else if (name == "dip0024") {
consensus.DIP0024QuorumsHeight = int{height};
} else if (name == "v19") {
consensus.V19Height = int{height};
} else if (name == "v20") {
consensus.V20Height = int{height};
} else if (name == "mn_rr") {
Expand Down
2 changes: 1 addition & 1 deletion src/chainparamsbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
argsman.AddArg("-budgetparams=<masternode>:<budget>:<superblock>", "Override masternode, budget and superblock start heights (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-devnet=<name>", "Use devnet chain with provided name", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-dip3params=<activation>:<enforcement>", "Override DIP3 activation and enforcement heights (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (bip147, bip34, dersig, cltv, csv, brr, dip0001, dip0008, dip0024, v20, mn_rr). (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (bip147, bip34, dersig, cltv, csv, brr, dip0001, dip0008, dip0024, v19, v20, mn_rr). (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-highsubsidyblocks=<n>", "The number of blocks with a higher than normal subsidy to mine at the start of a chain. Block after that height will have fixed subsidy base. (default: 0, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-highsubsidyfactor=<n>", "The factor to multiply the normal block subsidy by while in the highsubsidyblocks window of a chain (default: 1, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-llmqchainlocks=<quorum name>", "Override the default LLMQ type used for ChainLocks. Allows using ChainLocks with smaller LLMQs. (default: llmq_devnet, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
Expand Down
35 changes: 14 additions & 21 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ CDeterministicMNCPtr CDeterministicMNList::GetMNPayee(gsl::not_null<const CBlock
return nullptr;
}

// The flag is-v19-activate is used for optimization; we don't need to go over all masternodes every pre-v19 block
const bool isv19Active{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
const bool isMNRewardReallocation{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR)};
// EvoNodes are rewarded 4 blocks in a row until MNRewardReallocation (Platform release)
Expand Down Expand Up @@ -737,7 +738,6 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no

newList.DecreaseScores();

const bool isV19Active{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
const bool isMNRewardReallocation{DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR)};

// we skip the coinbase
Expand All @@ -756,10 +756,6 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
}
auto& proTx = *opt_proTx;

if (proTx.nType == MnType::Evo && !isV19Active) {
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-payload");
}

auto dmn = std::make_shared<CDeterministicMN>(newList.GetTotalRegisteredCount(), proTx.nType);
dmn->proTxHash = tx.GetHash();

Expand Down Expand Up @@ -819,10 +815,6 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-payload");
}

if (opt_proTx->nType == MnType::Evo && !DeploymentActiveAfter(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_V19)) {
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-payload");
}

if (newList.HasUniqueProperty(opt_proTx->addr) && newList.GetUniquePropertyMN(opt_proTx->addr)->proTxHash != opt_proTx->proTxHash) {
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-dup-addr");
}
Expand Down Expand Up @@ -1236,12 +1228,6 @@ bool CDeterministicMNManager::MigrateDBIfNeeded()
return true;
}

if (DeploymentActiveAt(*m_chainstate.m_chain.Tip(), consensusParams, Consensus::DEPLOYMENT_V19)) {
// too late
LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__);
return false;
}

// Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade
// process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed,
// then we must assume that the upgrade process was already running before but was interrupted.
Expand All @@ -1264,6 +1250,13 @@ bool CDeterministicMNManager::MigrateDBIfNeeded()
return true;
}

if (DeploymentActiveAt(*m_chainstate.m_chain.Tip(), consensusParams, Consensus::DEPLOYMENT_V19)) {
// too late
LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__);
return false;
}


CDBBatch batch(m_evoDb.GetRawDB());

for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, m_chainstate.m_chain.Height() + 1)) {
Expand Down Expand Up @@ -1351,12 +1344,6 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2()
return true;
}

if (DeploymentActiveAt(*m_chainstate.m_chain.Tip(), consensusParams, Consensus::DEPLOYMENT_V19)) {
// too late
LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__);
return false;
}

// Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade
// process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed,
// then we must assume that the upgrade process was already running before but was interrupted.
Expand All @@ -1379,6 +1366,12 @@ bool CDeterministicMNManager::MigrateDBIfNeeded2()
return true;
}

if (DeploymentActiveAt(*m_chainstate.m_chain.Tip(), consensusParams, Consensus::DEPLOYMENT_V19)) {
// too late
LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__);
return false;
}
knst marked this conversation as resolved.
Show resolved Hide resolved

CDBBatch batch(m_evoDb.GetRawDB());

for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, m_chainstate.m_chain.Height() + 1)) {
Expand Down
12 changes: 2 additions & 10 deletions src/rpc/evo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,11 +643,6 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
EnsureWalletIsUnlocked(*pwallet);
}

const bool isV19active{DeploymentActiveAfter(WITH_LOCK(cs_main, return chainman.ActiveChain().Tip();), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
if (isEvoRequested && !isV19active) {
throw JSONRPCError(RPC_INVALID_REQUEST, "EvoNodes aren't allowed yet");
}

size_t paramIdx = 0;

CMutableTransaction tx;
Expand Down Expand Up @@ -965,11 +960,6 @@ static UniValue protx_update_service_common_wrapper(const JSONRPCRequest& reques

EnsureWalletIsUnlocked(*wallet);

const bool isV19active{DeploymentActiveAfter(WITH_LOCK(cs_main, return chainman.ActiveChain().Tip();), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)};
if (isEvoRequested && !isV19active) {
throw JSONRPCError(RPC_INVALID_REQUEST, "EvoNodes aren't allowed yet");
}

CProUpServTx ptx;
ptx.nType = mnType;
ptx.proTxHash = ParseHashV(request.params[0], "proTxHash");
Expand Down Expand Up @@ -1055,6 +1045,8 @@ static UniValue protx_update_service_common_wrapper(const JSONRPCRequest& reques

FundSpecialTx(*wallet, tx, ptx, feeSource);

const bool isV19active = DeploymentActiveAfter(WITH_LOCK(cs_main, return chainman.ActiveChain().Tip();),
Params().GetConsensus(), Consensus::DEPLOYMENT_V19);
SignSpecialTxPayloadByHash(tx, ptx, keyOperator, !isV19active);
SetTxPayload(tx, ptx);

Expand Down
2 changes: 1 addition & 1 deletion src/test/evo_deterministicmns_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ struct TestChainV19Setup : public TestChainV19BeforeActivationSetup {

// 5 blocks earlier
TestChainV19BeforeActivationSetup::TestChainV19BeforeActivationSetup() :
TestChainSetup(894)
TestChainSetup(494, {"-testactivationheight=v19@500"})
{
bool v19_active{DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), Params().GetConsensus(),
Consensus::DEPLOYMENT_V19)};
Expand Down
4 changes: 2 additions & 2 deletions src/test/util/setup_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,9 @@ TestChainSetup::TestChainSetup(int num_blocks, const std::vector<const char*>& e
/* TestChainDIP3BeforeActivationSetup */
{ 430, uint256S("0x0bcefaa33fec56cd84d05d0e76cd6a78badcc20f627d91903646de6a07930a14") },
/* TestChainBRRBeforeActivationSetup */
{ 497, uint256S("0x3c71d807d28b9b813434eb0679ec3d5bcf424c20088cf578f3757521c3e3eded") },
{ 497, uint256S("0x0857a9b5db51835b1c828f019f4c664b5fe6c28ac44a6d868436930f832d31e5") },
/* TestChainV19BeforeActivationSetup */
{ 894, uint256S("0x3f031e5cceade15bdfa559ddecb2ccb2b8d17083bdfd871a9d23b17d04b15292") },
{ 494, uint256S("0x44ee5c8a5e5cbd4437d63c54ddc1d40329be811b25c492fa901e11cdf408f905") },
}
};

Expand Down
7 changes: 5 additions & 2 deletions test/functional/feature_dip3_v19.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ def getmnlistdiff(self, base_block_hash, block_hash):
class DIP3V19Test(DashTestFramework):
def set_test_params(self):
self.extra_args = [[
'-testactivationheight=v20@1200', # required otherwise mine_quorum("llmq_test [100]") fails
'-testactivationheight=v19@200',
]] * 6
self.set_dash_test_params(6, 5, evo_count=2, extra_args=self.extra_args)


def run_test(self):
# Connect all nodes to node1 so that we always have the whole network connected
# Otherwise only masternode connections will be established between nodes, which won't propagate TXs/blocks
Expand All @@ -66,7 +67,9 @@ def run_test(self):
mn_list_before = self.nodes[0].masternodelist()
pubkeyoperator_list_before = set([mn_list_before[e]["pubkeyoperator"] for e in mn_list_before])

self.activate_v19(expected_activation_height=900)
self.mine_quorum(llmq_type_name='llmq_test', llmq_type=100)

self.activate_by_name('v19', expected_activation_height=200)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))

mn_list_after = self.nodes[0].masternodelist()
Expand Down
14 changes: 7 additions & 7 deletions test/functional/feature_dip4_coinbasemerkleroots.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,28 +115,28 @@ def run_test(self):

# Verify that the first quorum appears in MNLISTDIFF
expectedDeleted = []
expectedNew = [QuorumId(100, int(first_quorum, 16)), QuorumId(104, int(first_quorum, 16)), QuorumId(106, int(first_quorum, 16))]
expectedNew = [QuorumId(100, int(first_quorum, 16)), QuorumId(104, int(first_quorum, 16))]
quorumList = self.test_getmnlistdiff_quorums(null_hash, self.nodes[0].getbestblockhash(), {}, expectedDeleted, expectedNew)
baseBlockHash = self.nodes[0].getbestblockhash()

second_quorum = self.mine_quorum()

# Verify that the second quorum appears in MNLISTDIFF
expectedDeleted = []
expectedNew = [QuorumId(100, int(second_quorum, 16)), QuorumId(104, int(second_quorum, 16)), QuorumId(106, int(second_quorum, 16))]
expectedNew = [QuorumId(100, int(second_quorum, 16)), QuorumId(104, int(second_quorum, 16))]
quorums_before_third = self.test_getmnlistdiff_quorums(baseBlockHash, self.nodes[0].getbestblockhash(), quorumList, expectedDeleted, expectedNew)
block_before_third = self.nodes[0].getbestblockhash()

third_quorum = self.mine_quorum()

# Verify that the first quorum is deleted and the third quorum is added in MNLISTDIFF (the first got inactive)
expectedDeleted = [QuorumId(100, int(first_quorum, 16)), QuorumId(104, int(first_quorum, 16)), QuorumId(106, int(first_quorum, 16))]
expectedNew = [QuorumId(100, int(third_quorum, 16)), QuorumId(104, int(third_quorum, 16)), QuorumId(106, int(third_quorum, 16))]
expectedDeleted = [QuorumId(100, int(first_quorum, 16)), QuorumId(104, int(first_quorum, 16))]
expectedNew = [QuorumId(100, int(third_quorum, 16)), QuorumId(104, int(third_quorum, 16))]
self.test_getmnlistdiff_quorums(block_before_third, self.nodes[0].getbestblockhash(), quorums_before_third, expectedDeleted, expectedNew)

# Verify that the diff between genesis and best block is the current active set (second and third quorum)
expectedDeleted = []
expectedNew = [QuorumId(100, int(second_quorum, 16)), QuorumId(104, int(second_quorum, 16)), QuorumId(106, int(second_quorum, 16)), QuorumId(100, int(third_quorum, 16)), QuorumId(104, int(third_quorum, 16)), QuorumId(106, int(third_quorum, 16))]
expectedNew = [QuorumId(100, int(second_quorum, 16)), QuorumId(104, int(second_quorum, 16)), QuorumId(100, int(third_quorum, 16)), QuorumId(104, int(third_quorum, 16))]
self.test_getmnlistdiff_quorums(null_hash, self.nodes[0].getbestblockhash(), {}, expectedDeleted, expectedNew)

# Now verify that diffs are correct around the block that mined the third quorum.
Expand All @@ -153,8 +153,8 @@ def run_test(self):
self.test_getmnlistdiff_quorums(block_before_third, prev_block2, quorums_before_third, expectedDeleted, expectedNew)
self.test_getmnlistdiff_quorums(block_before_third, prev_block, quorums_before_third, expectedDeleted, expectedNew)
# The block in which the quorum was mined and the 2 after that should all give the same diff
expectedDeleted = [QuorumId(100, int(first_quorum, 16)), QuorumId(104, int(first_quorum, 16)), QuorumId(106, int(first_quorum, 16))]
expectedNew = [QuorumId(100, int(third_quorum, 16)), QuorumId(104, int(third_quorum, 16)), QuorumId(106, int(third_quorum, 16))]
expectedDeleted = [QuorumId(100, int(first_quorum, 16)), QuorumId(104, int(first_quorum, 16))]
expectedNew = [QuorumId(100, int(third_quorum, 16)), QuorumId(104, int(third_quorum, 16))]
quorums_with_third = self.test_getmnlistdiff_quorums(block_before_third, mined_in_block, quorums_before_third, expectedDeleted, expectedNew)
self.test_getmnlistdiff_quorums(block_before_third, next_block, quorums_before_third, expectedDeleted, expectedNew)
self.test_getmnlistdiff_quorums(block_before_third, next_block2, quorums_before_third, expectedDeleted, expectedNew)
Expand Down
6 changes: 3 additions & 3 deletions test/functional/feature_governance.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ def run_test(self):
self.log.info("Check 1st superblock before v20")
self.bump_mocktime(3)
self.generate(self.nodes[0], 3, sync_fun=self.sync_blocks())
assert_equal(self.nodes[0].getblockcount(), 130)
assert_equal(self.nodes[0].getblockcount(), 137)
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], False)
self.check_superblockbudget(False)

self.log.info("Check 2nd superblock before v20")
self.bump_mocktime(10)
self.generate(self.nodes[0], 10, sync_fun=self.sync_blocks())
self.bump_mocktime(3)
self.generate(self.nodes[0], 3, sync_fun=self.sync_blocks())
assert_equal(self.nodes[0].getblockcount(), 140)
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], False)
self.check_superblockbudget(False)
Expand Down
2 changes: 0 additions & 2 deletions test/functional/feature_governance_cl.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ def run_test(self):

self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.wait_for_sporks_same()
self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.mine_cycle_quorum()

self.sync_blocks()
Expand Down
2 changes: 0 additions & 2 deletions test/functional/feature_llmq_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ def run_test(self):
self.nodes[0].sporkupdate("SPORK_23_QUORUM_POSE", 4070908800)
self.wait_for_sporks_same()

self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.mine_cycle_quorum()

# Since we IS quorums are mined only using dip24 (rotation) we need to enable rotation, and continue tests on llmq_test_dip0024 for connections.
Expand Down
Loading
Loading