feat: instant activation dip-0008 on regtest on first block

This commit is contained in:
Konstantin Akimov 2024-08-08 18:26:14 +07:00
parent cfd7ea2bc3
commit 593c6cff14
No known key found for this signature in database
GPG Key ID: 2176C4A5D01EA524
19 changed files with 36 additions and 56 deletions

View File

@ -804,7 +804,7 @@ public:
consensus.DIP0003Height = 432;
consensus.DIP0003EnforcementHeight = 500;
consensus.DIP0003EnforcementHash = uint256();
consensus.DIP0008Height = 432;
consensus.DIP0008Height = 1; // Always active unless overridden
consensus.BRRHeight = 1000; // see block_reward_reallocation_tests
consensus.DIP0020Height = 1;
consensus.DIP0024Height = 900;
@ -1054,6 +1054,8 @@ static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& conse
consensus.BIP65Height = int{height};
} else if (name == "csv") {
consensus.CSVHeight = int{height};
} else if (name == "dip0008") {
consensus.DIP0008Height = int{height};
} else if (name == "dip0020") {
consensus.DIP0020Height = int{height};
} else {

View File

@ -22,7 +22,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
argsman.AddArg("-dip3params=<activation>:<enforcement>", "Override DIP3 activation and enforcement heights (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-dip8params=<activation>", "Override DIP8 activation height (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
argsman.AddArg("-bip147height=<activation>", "Override BIP147 activation height (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, dip0020). (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, dip0008, dip0020). (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);

View File

@ -341,7 +341,7 @@ TestChainSetup::TestChainSetup(int num_blocks, const std::vector<const char*>& e
/* TestChainDIP3Setup */
{ 431, uint256S("0x49db248651517f3fc3725fbbc7087db90552d487d11e0962b0148fc4788aeb77") },
/* TestChainBRRBeforeActivationSetup */
{ 497, uint256S("0x15445246f9f9fd4fdb1021dd8278ace7246b3e3cb545e1632a277d3a02eb011f") },
{ 497, uint256S("0x626036f6adff51fbbdd0c609e827ef6a3730ce2498a3eb33edeb27092d006170") },
/* TestChainV19BeforeActivationSetup */
{ 894, uint256S("0x03cbf1871d7d915cda10aded00ced45f71a4e2acf6a3c7a77a1ff488267dd1cd") },
/* TestChainV19Setup */

View File

@ -57,8 +57,6 @@ class DIP3V19Test(DashTestFramework):
if i != 0:
self.connect_nodes(i, 0)
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.wait_for_sporks_same()

View File

@ -17,6 +17,7 @@ from test_framework.p2p import P2PInterface
from test_framework.test_framework import DashTestFramework
from test_framework.util import assert_equal
DIP0008_HEIGHT = 432
# TODO: this helper used in many tests, find a new home for it
class TestP2PConn(P2PInterface):
@ -42,8 +43,8 @@ class TestP2PConn(P2PInterface):
class LLMQCoinbaseCommitmentsTest(DashTestFramework):
def set_test_params(self):
self.set_dash_test_params(4, 3, fast_dip3_enforcement=True)
self.extra_args = [[ f'-testactivationheight=dip0008@{DIP0008_HEIGHT}', "-vbparams=testdummy:999999999999:999999999999" ]] * 4
self.set_dash_test_params(4, 3, extra_args = self.extra_args, fast_dip3_enforcement=True)
def run_test(self):
# No IS or Chainlocks in this test
self.bump_mocktime(1)
@ -240,6 +241,18 @@ class LLMQCoinbaseCommitmentsTest(DashTestFramework):
return d
def activate_dip8(self, slow_mode=False):
# NOTE: set slow_mode=True if you are activating dip8 after a huge reorg
# or nodes might fail to catch up otherwise due to a large
# (MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16 blocks) reorg error.
self.log.info("Wait for dip0008 activation")
while self.nodes[0].getblockcount() < DIP0008_HEIGHT:
self.bump_mocktime(10)
self.nodes[0].generate(10)
if slow_mode:
self.sync_blocks()
self.sync_blocks()
def test_dip8_quorum_merkle_root_activation(self, with_initial_quorum, slow_mode=False):
if with_initial_quorum:
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)

View File

@ -12,7 +12,7 @@ from test_framework.util import assert_equal, satoshi_round, set_node_times, wai
class DashGovernanceTest (DashTestFramework):
def set_test_params(self):
self.v20_start_time = 1417713500
self.v20_start_time = 1417713500 + 80
# using adjusted v20 deployment params to test an edge case where superblock maturity window is equal to deployment window size
self.set_dash_test_params(6, 5, [["-budgetparams=10:10:10", f"-vbparams=v20:{self.v20_start_time}:999999999999:0:10:8:6:5:0"]] * 6, fast_dip3_enforcement=True)
@ -118,14 +118,16 @@ class DashGovernanceTest (DashTestFramework):
self.expected_old_budget = satoshi_round("928.57142840")
self.expected_v20_budget = satoshi_round("18.57142860")
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", 4070908800)
self.nodes[0].sporkupdate("SPORK_9_SUPERBLOCKS_ENABLED", 0)
self.wait_for_sporks_same()
assert_equal(len(self.nodes[0].gobject("list-prepared")), 0)
# TODO: drop these extra 80 blocks - doesn't work without them
self.nodes[0].generate(80)
self.bump_mocktime(80)
self.nodes[0].generate(3)
self.bump_mocktime(3)
self.sync_blocks()

View File

@ -31,8 +31,6 @@ class LLMQChainLocksTest(DashTestFramework):
if i != 1:
self.connect_nodes(i, 1)
self.activate_dip8()
self.test_coinbase_best_cl(self.nodes[0], expected_cl_in_cb=False)
self.activate_v20(expected_activation_height=1200)

View File

@ -144,7 +144,6 @@ class QuorumDataRecoveryTest(DashTestFramework):
node.sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
node.sporkupdate("SPORK_21_QUORUM_ALL_CONNECTED", 0)
self.wait_for_sporks_same()
self.activate_dip8()
logger.info("Test automated DGK data recovery")
# This two nodes will remain the only ones with valid DKG data

View File

@ -17,8 +17,6 @@ class LLMQDKGErrors(DashTestFramework):
self.set_dash_test_params(4, 3, [["-whitelist=127.0.0.1"]] * 4, fast_dip3_enforcement=True)
def run_test(self):
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.wait_for_sporks_same()

View File

@ -61,8 +61,6 @@ class LLMQEvoNodesTest(DashTestFramework):
if i != 0:
self.connect_nodes(i, 0)
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", 1)
self.wait_for_sporks_same()

View File

@ -54,8 +54,6 @@ class LLMQ_IS_CL_Conflicts(DashTestFramework):
self.supports_cli = False
def run_test(self):
self.activate_dip8()
self.test_node = self.nodes[0].add_p2p_connection(TestP2PConn())
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)

View File

@ -25,8 +25,6 @@ class LLMQ_IS_RetroactiveSigning(DashTestFramework):
self.set_dash_test_params(5, 4, [["-whitelist=127.0.0.1"], [], [], [], ["-minrelaytxfee=0.001"]], fast_dip3_enforcement=True)
def run_test(self):
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
# Turn mempool IS signing off
self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", 1)

View File

@ -69,8 +69,6 @@ class LLMQQuorumRotationTest(DashTestFramework):
if i != 1:
self.connect_nodes(i, 0)
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.wait_for_sporks_same()

View File

@ -100,7 +100,6 @@ class NotificationsTest(DashTestFramework):
self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 4070908800)
self.wait_for_sporks_same()

View File

@ -86,16 +86,16 @@ class PruneTest(BitcoinTestFramework):
# Create nodes 0 and 1 to mine.
# Create node 2 to test pruning.
self.full_node_default_args = ["-dip3params=2000:2000", "-dip8params=2000", "-maxreceivebuffer=20000", "-blockmaxsize=999000", "-checkblocks=5"]
self.full_node_default_args = ["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-maxreceivebuffer=20000", "-blockmaxsize=999000", "-checkblocks=5"]
# Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later)
# Create nodes 5 to test wallet in prune mode, but do not connect
self.extra_args = [
self.full_node_default_args,
self.full_node_default_args,
["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance","-txindex=0","-maxreceivebuffer=20000","-prune=550"],
["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance","-txindex=0","-maxreceivebuffer=20000","-blockmaxsize=999000"],
["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance","-txindex=0","-maxreceivebuffer=20000","-blockmaxsize=999000"],
["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance","-txindex=0","-prune=550"],
["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance","-txindex=0","-maxreceivebuffer=20000","-prune=550"],
["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance","-txindex=0","-maxreceivebuffer=20000","-blockmaxsize=999000"],
["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance","-txindex=0","-maxreceivebuffer=20000","-blockmaxsize=999000"],
["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance","-txindex=0","-prune=550"],
]
self.rpc_timeout = 120
@ -283,13 +283,13 @@ class PruneTest(BitcoinTestFramework):
def manual_test(self, node_number, use_timestamp):
# at this point, node has 995 blocks and has not yet run in prune mode
self.start_node(node_number, extra_args=["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance", "-txindex=0"])
self.start_node(node_number, extra_args=["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance", "-txindex=0"])
node = self.nodes[node_number]
assert_equal(node.getblockcount(), 995)
assert_raises_rpc_error(-1, "Cannot prune blocks because node is not in prune mode", node.pruneblockchain, 500)
# now re-start in manual pruning mode
self.restart_node(node_number, extra_args=["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance", "-txindex=0", "-prune=1"], expected_stderr=EXPECTED_STDERR_NO_GOV)
self.restart_node(node_number, extra_args=["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance", "-txindex=0", "-prune=1"], expected_stderr=EXPECTED_STDERR_NO_GOV)
node = self.nodes[node_number]
assert_equal(node.getblockcount(), 995)
@ -358,14 +358,14 @@ class PruneTest(BitcoinTestFramework):
assert not has_block(3), "blk00003.dat is still there, should be pruned by now"
# stop node, start back up with auto-prune at 550 MiB, make sure still runs
self.restart_node(node_number, extra_args=["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance", "-txindex=0", "-prune=550"], expected_stderr=EXPECTED_STDERR_NO_GOV_PRUNE)
self.restart_node(node_number, extra_args=["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance", "-txindex=0", "-prune=550"], expected_stderr=EXPECTED_STDERR_NO_GOV_PRUNE)
self.log.info("Success")
def wallet_test(self):
# check that the pruning node's wallet is still in good shape
self.log.info("Stop and start pruning node to trigger wallet rescan")
self.restart_node(2, extra_args=["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance", "-txindex=0", "-prune=550"], expected_stderr=EXPECTED_STDERR_NO_GOV_PRUNE)
self.restart_node(2, extra_args=["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance", "-txindex=0", "-prune=550"], expected_stderr=EXPECTED_STDERR_NO_GOV_PRUNE)
self.log.info("Success")
# check that wallet loads successfully when restarting a pruned node after IBD.
@ -374,7 +374,7 @@ class PruneTest(BitcoinTestFramework):
self.connect_nodes(0, 5)
nds = [self.nodes[0], self.nodes[5]]
self.sync_blocks(nds, wait=5, timeout=300)
self.restart_node(5, extra_args=["-dip3params=2000:2000", "-dip8params=2000", "-disablegovernance", "-txindex=0", "-prune=550"], expected_stderr=EXPECTED_STDERR_NO_GOV_PRUNE) # restart to trigger rescan
self.restart_node(5, extra_args=["-dip3params=2000:2000", "-testactivationheight=dip0008@2000", "-disablegovernance", "-txindex=0", "-prune=550"], expected_stderr=EXPECTED_STDERR_NO_GOV_PRUNE) # restart to trigger rescan
self.log.info("Success")
def run_test(self):

View File

@ -127,7 +127,6 @@ class DashZMQTest (DashTestFramework):
# Setup the ZMQ subscriber context
self.zmq_context = zmq.Context()
# Initialize the network
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.wait_for_sporks_same()
self.activate_v19(expected_activation_height=900)

View File

@ -149,7 +149,7 @@ class BlockchainTest(BitcoinTestFramework):
'csv': {'type': 'buried', 'active': True, 'height': 1},
'dip0001': { 'type': 'buried', 'active': False, 'height': 2000},
'dip0003': { 'type': 'buried', 'active': False, 'height': 432},
'dip0008': { 'type': 'buried', 'active': False, 'height': 432},
'dip0008': { 'type': 'buried', 'active': True, 'height': 1},
'dip0020': { 'type': 'buried', 'active': True, 'height': 1},
'dip0024': { 'type': 'buried', 'active': False, 'height': 900},
'realloc': { 'type': 'buried', 'active': False, 'height': 1000},

View File

@ -28,7 +28,6 @@ class RPCVerifyChainLockTest(DashTestFramework):
def run_test(self):
node0 = self.nodes[0]
node1 = self.nodes[1]
self.activate_dip8()
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.wait_for_sporks_same()
self.mine_quorum()

View File

@ -1079,9 +1079,6 @@ class DashTestFramework(BitcoinTestFramework):
for i in range(0, num_nodes):
self.extra_args[i].append("-dip3params=30:50")
# make sure to activate dip8 after prepare_masternodes has finished its job already
self.set_dash_dip8_activation(200)
# LLMQ default test params (no need to pass -llmqtestparams)
self.llmq_size = 3
self.llmq_threshold = 2
@ -1092,22 +1089,6 @@ class DashTestFramework(BitcoinTestFramework):
# This is EXPIRATION_TIMEOUT + EXPIRATION_BIAS in CQuorumDataRequest
self.quorum_data_request_expiration_timeout = 360
def set_dash_dip8_activation(self, activate_after_block):
self.dip8_activation_height = activate_after_block
for i in range(0, self.num_nodes):
self.extra_args[i].append("-dip8params=%d" % (activate_after_block))
def activate_dip8(self, slow_mode=False):
# NOTE: set slow_mode=True if you are activating dip8 after a huge reorg
# or nodes might fail to catch up otherwise due to a large
# (MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16 blocks) reorg error.
self.log.info("Wait for dip0008 activation")
while self.nodes[0].getblockcount() < self.dip8_activation_height:
self.bump_mocktime(10)
self.nodes[0].generate(10)
if slow_mode:
self.sync_blocks()
self.sync_blocks()
def activate_by_name(self, name, expected_activation_height=None):
assert not softfork_active(self.nodes[0], name)