Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/dashpay/dash into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
PastaPastaPasta committed Aug 17, 2024
2 parents 9352ce3 + df07c38 commit 318716e
Show file tree
Hide file tree
Showing 17 changed files with 100 additions and 48 deletions.
8 changes: 8 additions & 0 deletions doc/release-notes-6189.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Tests
-----

- For the `regtest` network the activation heights of several softforks were
changed. (dash#6189)
* BIP 34 (blockheight in coinbase) from 500 to 2
* BIP 66 (DERSIG) from 1251 to 102
* BIP 65 (CLTV) from 1351 to 111
6 changes: 3 additions & 3 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,10 +794,10 @@ class CRegTestParams : public CChainParams {
consensus.nGovernanceMinQuorum = 1;
consensus.nGovernanceFilterElements = 100;
consensus.nMasternodeMinimumConfirmations = 1;
consensus.BIP34Height = 500; // BIP34 activated on regtest (Used in functional tests)
consensus.BIP34Height = 2; // BIP34 activated on regtest (Block at height 1 not enforced for testing purposes)
consensus.BIP34Hash = uint256();
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in functional tests)
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in functional tests)
consensus.BIP65Height = 111; // BIP65 activated on regtest (Block at height 110 and earlier not enforced for testing purposes)
consensus.BIP66Height = 102; // BIP66 activated on regtest (Block at height 101 and earlier not enforced for testing purposes)
consensus.BIP147Height = 432; // BIP147 activated on regtest (Used in functional tests)
consensus.CSVHeight = 432; // CSV activated on regtest (Used in rpc activation tests)
consensus.DIP0001Height = 2000;
Expand Down
15 changes: 9 additions & 6 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@

namespace Consensus {

enum BuriedDeployment : int16_t
{
/**
* A buried deployment is one where the height of the activation has been hardcoded into
* the client implementation long after the consensus change has activated. See BIP 90.
*/
enum BuriedDeployment : int16_t {
// buried deployments get negative values to avoid overlap with DeploymentPos
DEPLOYMENT_HEIGHTINCB = std::numeric_limits<int16_t>::min(),
DEPLOYMENT_DERSIG,
DEPLOYMENT_CLTV,
Expand All @@ -29,17 +33,16 @@ enum BuriedDeployment : int16_t
DEPLOYMENT_BRR,
DEPLOYMENT_V19,
};
constexpr bool ValidDeployment(BuriedDeployment dep) { return DEPLOYMENT_HEIGHTINCB <= dep && dep <= DEPLOYMENT_V19; }
constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_V19; }

enum DeploymentPos : uint16_t
{
enum DeploymentPos : uint16_t {
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_V20, // Deployment of EHF, LLMQ Randomness Beacon
DEPLOYMENT_MN_RR, // Deployment of Masternode Reward Location Reallocation
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
MAX_VERSION_BITS_DEPLOYMENTS
};
constexpr bool ValidDeployment(DeploymentPos dep) { return DEPLOYMENT_TESTDUMMY <= dep && dep <= DEPLOYMENT_MN_RR; }
constexpr bool ValidDeployment(DeploymentPos dep) { return dep < MAX_VERSION_BITS_DEPLOYMENTS; }

/**
* Struct for each individual consensus rule change using BIP9.
Expand Down
17 changes: 17 additions & 0 deletions src/deploymentstatus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <consensus/params.h>
#include <versionbits.h>

#include <type_traits>

VersionBitsCache g_versionbitscache;

/* Basic sanity checking for BuriedDeployment/DeploymentPos enums and
Expand All @@ -15,3 +17,18 @@ VersionBitsCache g_versionbitscache;
static_assert(ValidDeployment(Consensus::DEPLOYMENT_TESTDUMMY), "sanity check of DeploymentPos failed (TESTDUMMY not valid)");
static_assert(!ValidDeployment(Consensus::MAX_VERSION_BITS_DEPLOYMENTS), "sanity check of DeploymentPos failed (MAX value considered valid)");
static_assert(!ValidDeployment(static_cast<Consensus::BuriedDeployment>(Consensus::DEPLOYMENT_TESTDUMMY)), "sanity check of BuriedDeployment failed (overlaps with DeploymentPos)");

/* ValidDeployment only checks upper bounds for ensuring validity.
* This checks that the lowest possible value or the type is also a
* (specific) valid deployment so that lower bounds don't need to be checked.
*/

template<typename T, T x>
static constexpr bool is_minimum()
{
using U = typename std::underlying_type<T>::type;
return x == std::numeric_limits<U>::min();
}

static_assert(is_minimum<Consensus::BuriedDeployment, Consensus::DEPLOYMENT_HEIGHTINCB>(), "heightincb is not minimum value for BuriedDeployment");
static_assert(is_minimum<Consensus::DeploymentPos, Consensus::DEPLOYMENT_TESTDUMMY>(), "testdummy is not minimum value for DeploymentPos");
2 changes: 1 addition & 1 deletion src/deploymentstatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::Buried
inline bool DeploymentEnabled(const Consensus::Params& params, Consensus::DeploymentPos dep)
{
assert(Consensus::ValidDeployment(dep));
return params.vDeployments[dep].nTimeout != 0;
return params.vDeployments[dep].nStartTime != Consensus::BIP9Deployment::NEVER_ACTIVE;
}

/** this function is convenient helper for DIP0003 because 'active' and 'enforced' are different statuses for DIP0003 */
Expand Down
4 changes: 2 additions & 2 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ BlockAssembler::Options::Options()
}

BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, const CTxMemPool& mempool, const CChainParams& params, const Options& options) :
m_blockman(Assert(node.chainman)->m_blockman),
m_blockman(chainstate.m_blockman),
m_cpoolman(*Assert(node.cpoolman)),
m_chain_helper(*Assert(node.chain_helper)),
m_chain_helper(chainstate.ChainHelper()),
m_chainstate(chainstate),
m_dmnman(*Assert(node.dmnman)),
m_evoDb(*Assert(node.evodb)),
Expand Down
9 changes: 3 additions & 6 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1620,10 +1620,7 @@ static RPCHelpMan verifychain()
static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const Consensus::Params& params, Consensus::BuriedDeployment dep)
{
// For buried deployments.
// A buried deployment is one where the height of the activation has been hardcoded into
// the client implementation long after the consensus change has activated. See BIP 90.
// Buried deployments with activation height value of
// std::numeric_limits<int>::max() are disabled and thus hidden.

if (!DeploymentEnabled(params, dep)) return;

UniValue rv(UniValue::VOBJ);
Expand All @@ -1638,8 +1635,8 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue&
static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const std::unordered_map<uint8_t, int>& signals, UniValue& softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
{
// For BIP9 deployments.
// Deployments that are never active are hidden.
if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;

if (!DeploymentEnabled(consensusParams, id)) return;

UniValue bip9(UniValue::VOBJ);
const ThresholdState thresholdState = g_versionbitscache.State(active_chain_tip, consensusParams, id);
Expand Down
6 changes: 3 additions & 3 deletions src/test/util/setup_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,10 @@ CBlock TestChainSetup::CreateBlock(
auto cbTx = GetTxPayload<CCbTx>(*block.vtx[0]);
BOOST_ASSERT(cbTx.has_value());
BlockValidationState state;
if (!CalcCbTxMerkleRootMNList(block, m_node.chainman->ActiveChain().Tip(), cbTx->merkleRootMNList, *m_node.dmnman, state, m_node.chainman->ActiveChainstate().CoinsTip())) {
if (!CalcCbTxMerkleRootMNList(block, chainstate.m_chain.Tip(), cbTx->merkleRootMNList, *m_node.dmnman, state, chainstate.CoinsTip())) {
BOOST_ASSERT(false);
}
if (!CalcCbTxMerkleRootQuorums(block, m_node.chainman->ActiveChain().Tip(), *m_node.llmq_ctx->quorum_block_processor, cbTx->merkleRootQuorums, state)) {
if (!CalcCbTxMerkleRootQuorums(block, chainstate.m_chain.Tip(), *m_node.llmq_ctx->quorum_block_processor, cbTx->merkleRootQuorums, state)) {
BOOST_ASSERT(false);
}
CMutableTransaction tmpTx{*block.vtx[0]};
Expand All @@ -443,7 +443,7 @@ CBlock TestChainSetup::CreateBlock(
{
LOCK(cs_main);
unsigned int extraNonce = 0;
IncrementExtraNonce(&block, m_node.chainman->ActiveChain().Tip(), extraNonce);
IncrementExtraNonce(&block, chainstate.m_chain.Tip(), extraNonce);
}

while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
Expand Down
14 changes: 7 additions & 7 deletions src/test/validation_block_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
txCoinbase.vout[1].scriptPubKey = P2SH_OP_TRUE;
txCoinbase.vout[1].nValue = txCoinbase.vout[0].nValue;
txCoinbase.vout[0].nValue = 0;
// Always pad with OP_0 at the end to avoid bad-cb-length error
txCoinbase.vin[0].scriptSig = CScript{} << WITH_LOCK(::cs_main, return m_node.chainman->m_blockman.LookupBlockIndex(prev_hash)->nHeight + 1) << OP_0;
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));

return pblock;
Expand All @@ -92,6 +94,11 @@ std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock>
++(pblock->nNonce);
}

// submit block header, so that miner can get the block height from the
// global state and the node has the topology of the chain
BlockValidationState ignored;
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders({pblock->GetBlockHeader()}, ignored, Params()));

return pblock;
}

Expand Down Expand Up @@ -146,13 +153,6 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
}

bool ignored;
BlockValidationState state;
std::vector<CBlockHeader> headers;
std::transform(blocks.begin(), blocks.end(), std::back_inserter(headers), [](std::shared_ptr<const CBlock> b) { return b->GetBlockHeader(); });

// Process all the headers so we understand the toplogy of the chain
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders(headers, state, Params()));

// Connect the genesis block and drain any outstanding events
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
SyncWithValidationInterfaceQueue();
Expand Down
5 changes: 4 additions & 1 deletion test/functional/feature_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,9 @@ def run_test(self):
# b30 has a max-sized coinbase scriptSig.
self.move_tip(23)
b30 = self.next_block(30)
b30.vtx[0].vin[0].scriptSig = b'\x00' * 100
b30.vtx[0].vin[0].scriptSig = bytes(b30.vtx[0].vin[0].scriptSig) # Convert CScript to raw bytes
b30.vtx[0].vin[0].scriptSig += b'\x00' * (100 - len(b30.vtx[0].vin[0].scriptSig)) # Fill with 0s
assert_equal(len(b30.vtx[0].vin[0].scriptSig), 100)
b30.vtx[0].rehash()
b30 = self.update_block(30, [])
self.send_blocks([b30], True)
Expand Down Expand Up @@ -839,6 +841,7 @@ def run_test(self):
b61.vtx[0].rehash()
b61 = self.update_block(61, [])
assert_equal(duplicate_tx.serialize(), b61.vtx[0].serialize())
# BIP30 is always checked on regtest, regardless of the BIP34 activation height
self.send_blocks([b61], success=False, reject_reason='bad-txns-BIP30', reconnect=True)

# Test BIP30 (allow duplicate if spent)
Expand Down
13 changes: 6 additions & 7 deletions test/functional/feature_cltv.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test BIP65 (CHECKLOCKTIMEVERIFY).
Test that the CHECKLOCKTIMEVERIFY soft-fork activates at (regtest) block height
1351.
Test that the CHECKLOCKTIMEVERIFY soft-fork activates.
"""

from test_framework.blocktools import (
CLTV_HEIGHT,
create_block,
create_coinbase,
)
Expand All @@ -34,8 +34,6 @@
MiniWalletMode,
)

CLTV_HEIGHT = 1351


# Helper function to modify a transaction by
# 1) prepending a given script to the scriptSig of vin 0 and
Expand Down Expand Up @@ -66,9 +64,9 @@ def cltv_invalidate(tx, failure_reason):
# +-------------------------------------------------+------------+--------------+
[[OP_CHECKLOCKTIMEVERIFY], None, None],
[[OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP], None, None],
[[CScriptNum(1000), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, 1296688602], # timestamp of genesis block
[[CScriptNum(1000), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, 500],
[[CScriptNum(500), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0xffffffff, 500],
[[CScriptNum(100), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, 1296688602], # timestamp of genesis block
[[CScriptNum(100), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, 50],
[[CScriptNum(50), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0xffffffff, 50],
][failure_reason]

cltv_modify_tx(tx, prepend_scriptsig=scheme[0], nsequence=scheme[1], nlocktime=scheme[2])
Expand Down Expand Up @@ -111,6 +109,7 @@ def run_test(self):
self.log.info("Mining %d blocks", CLTV_HEIGHT - 2)
wallet.generate(10)
self.nodes[0].generate(CLTV_HEIGHT - 2 - 10)
assert_equal(self.nodes[0].getblockcount(), CLTV_HEIGHT - 2)

self.log.info("Test that invalid-according-to-CLTV transactions can still appear in a block")

Expand Down
12 changes: 8 additions & 4 deletions test/functional/feature_csv_activation.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from itertools import product

from test_framework.blocktools import (
CSV_ACTIVATION_HEIGHT,
create_block,
create_coinbase,
TIME_GENESIS_BLOCK,
Expand All @@ -63,12 +64,12 @@
TESTING_TX_COUNT = 83 # Number of testing transactions: 1 BIP113 tx, 16 BIP68 txs, 66 BIP112 txs (see comments above)
COINBASE_BLOCK_COUNT = TESTING_TX_COUNT # Number of coinbase blocks we need to generate as inputs for our txs
BASE_RELATIVE_LOCKTIME = 10
CSV_ACTIVATION_HEIGHT = 432
SEQ_DISABLE_FLAG = 1 << 31
SEQ_RANDOM_HIGH_BIT = 1 << 25
SEQ_TYPE_FLAG = 1 << 22
SEQ_RANDOM_LOW_BIT = 1 << 18


def relative_locktime(sdf, srhb, stf, srlb):
"""Returns a locktime with certain bits set."""

Expand All @@ -83,6 +84,7 @@ def relative_locktime(sdf, srhb, stf, srlb):
locktime |= SEQ_RANDOM_LOW_BIT
return locktime


def all_rlt_txs(txs):
return [tx['tx'] for tx in txs]

Expand All @@ -93,6 +95,7 @@ def set_test_params(self):
self.setup_clean_chain = True
# Must set '-dip3params=2000:2000' to create pre-dip3 blocks only
self.extra_args = [[
'-peertimeout=999999', # bump because mocktime might cause a disconnect otherwise
'[email protected]',
'-dip3params=2000:2000',
'-par=1', # Use only one script thread to get the exact reject reason for testing
Expand Down Expand Up @@ -148,13 +151,13 @@ def create_bip112txs(self, bip112inputs, varyOP_CSV, txversion, locktime_delta=0
for i, (sdf, srhb, stf, srlb) in enumerate(product(*[[True, False]] * 4)):
locktime = relative_locktime(sdf, srhb, stf, srlb)
tx = self.create_self_transfer_from_utxo(bip112inputs[i])
if (varyOP_CSV): # if varying OP_CSV, nSequence is fixed
if varyOP_CSV: # if varying OP_CSV, nSequence is fixed
tx.vin[0].nSequence = BASE_RELATIVE_LOCKTIME + locktime_delta
else: # vary nSequence instead, OP_CSV is fixed
tx.vin[0].nSequence = locktime + locktime_delta
tx.nVersion = txversion
self.miniwallet.sign_tx(tx)
if (varyOP_CSV):
if varyOP_CSV:
tx.vin[0].scriptSig = CScript([locktime, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig)))
else:
tx.vin[0].scriptSig = CScript([BASE_RELATIVE_LOCKTIME, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig)))
Expand Down Expand Up @@ -201,7 +204,7 @@ def run_test(self):
self.tip = int(self.nodes[0].getbestblockhash(), 16)

# Activation height is hardcoded
test_blocks = self.generate_blocks(CSV_ACTIVATION_HEIGHT-5 - COINBASE_BLOCK_COUNT)
test_blocks = self.generate_blocks(CSV_ACTIVATION_HEIGHT - 5 - COINBASE_BLOCK_COUNT)
#test_blocks = self.generate_blocks(345)
self.send_blocks(test_blocks)
assert not softfork_active(self.nodes[0], 'csv')
Expand Down Expand Up @@ -487,5 +490,6 @@ def run_test(self):
self.send_blocks([self.create_test_block(time_txs)])
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())


if __name__ == '__main__':
BIP68_112_113Test().main()
7 changes: 4 additions & 3 deletions test/functional/feature_dersig.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test BIP66 (DER SIG).
Test that the DERSIG soft-fork activates at (regtest) height 1251.
Test the DERSIG soft-fork activation on regtest.
"""

from test_framework.blocktools import (
DERSIG_HEIGHT,
create_block,
create_coinbase,
)
Expand All @@ -24,8 +25,6 @@
MiniWalletMode,
)

DERSIG_HEIGHT = 1251


# A canonical signature consists of:
# <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
Expand Down Expand Up @@ -88,8 +87,10 @@ def run_test(self):
block.rehash()
block.solve()

assert_equal(self.nodes[0].getblockcount(), DERSIG_HEIGHT - 2)
self.test_dersig_info(is_active=False) # Not active as of current tip and next block does not need to obey rules
peer.send_and_ping(msg_block(block))
assert_equal(self.nodes[0].getblockcount(), DERSIG_HEIGHT - 1)
self.test_dersig_info(is_active=True) # Not active as of current tip, but next block must obey rules
assert_equal(self.nodes[0].getbestblockhash(), block.hash)

Expand Down
8 changes: 5 additions & 3 deletions test/functional/rpc_blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

from test_framework.address import ADDRESS_BCRT1_P2SH_OP_TRUE
from test_framework.blocktools import (
CLTV_HEIGHT,
DERSIG_HEIGHT,
create_block,
create_coinbase,
TIME_GENESIS_BLOCK,
Expand Down Expand Up @@ -142,9 +144,9 @@ def _test_getblockchaininfo(self):
assert_equal(res['prune_target_size'], 576716800)
assert_greater_than(res['size_on_disk'], 0)
assert_equal(res['softforks'], {
'bip34': {'type': 'buried', 'active': False, 'height': 500},
'bip66': {'type': 'buried', 'active': False, 'height': 1251},
'bip65': {'type': 'buried', 'active': False, 'height': 1351},
'bip34': {'type': 'buried', 'active': True, 'height': 2},
'bip66': {'type': 'buried', 'active': True, 'height': DERSIG_HEIGHT},
'bip65': {'type': 'buried', 'active': True, 'height': CLTV_HEIGHT},
'bip147': { 'type': 'buried', 'active': False, 'height': 432},
'csv': {'type': 'buried', 'active': False, 'height': 432},
'dip0001': { 'type': 'buried', 'active': False, 'height': 2000},
Expand Down
9 changes: 8 additions & 1 deletion test/functional/test_framework/blocktools.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,21 @@
# Coinbase transaction outputs can only be spent after this number of new blocks (network rule)
COINBASE_MATURITY = 100

# Soft-fork activation heights
DERSIG_HEIGHT = 102 # BIP 66
CLTV_HEIGHT = 111 # BIP 65
CSV_ACTIVATION_HEIGHT = 432

NORMAL_GBT_REQUEST_PARAMS = {"rules": []} # type: ignore[var-annotated]

VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4

def create_block(hashprev=None, coinbase=None, ntime=None, *, version=None, tmpl=None, txlist=None, dip4_activated=False, v20_activated=False):
"""Create a block (with regtest difficulty)."""
block = CBlock()
if tmpl is None:
tmpl = {}
block.nVersion = version or tmpl.get('version') or 1
block.nVersion = version or tmpl.get('version') or VERSIONBITS_LAST_OLD_BLOCK_VERSION
block.nTime = ntime or tmpl.get('curtime') or int(time.time() + 600)
block.hashPrevBlock = hashprev or int(tmpl['previousblockhash'], 0x10)
if tmpl and not tmpl.get('bits') is None:
Expand Down
Loading

0 comments on commit 318716e

Please sign in to comment.