consensus: add a CSFS deployment for regtest only

This commit is contained in:
James O'Beirne 2025-03-19 16:16:58 -04:00
parent 1247b8b670
commit 7be5c60a57
8 changed files with 45 additions and 4 deletions

View file

@ -33,6 +33,7 @@ enum DeploymentPos : uint16_t {
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_TAPROOT, // Deployment of Schnorr/Taproot (BIPs 340-342)
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in deploymentinfo.cpp
DEPLOYMENT_CSFS, // Deployment of CHECKSIGFROMSTACK (BIP 348) (regtest only)
MAX_VERSION_BITS_DEPLOYMENTS
};
constexpr bool ValidDeployment(DeploymentPos dep) { return dep < MAX_VERSION_BITS_DEPLOYMENTS; }

View file

@ -17,6 +17,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B
/*.name =*/ "taproot",
/*.gbt_force =*/ true,
},
{
/*.name =*/ "csfs",
/*.gbt_force =*/ true,
},
};
std::string DeploymentName(Consensus::BuriedDeployment dep)

View file

@ -529,6 +529,11 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
consensus.vDeployments[Consensus::DEPLOYMENT_CSFS].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_CSFS].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_CSFS].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_CSFS].min_activation_height = 0; // No activation delay
consensus.nMinimumChainWork = uint256{};
consensus.defaultAssumeValid = uint256{};

View file

@ -1408,6 +1408,10 @@ UniValue DeploymentInfo(const CBlockIndex* blockindex, const ChainstateManager&
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_SEGWIT);
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TESTDUMMY);
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_TAPROOT);
if (chainman.GetParams().GetChainType() == ChainType::REGTEST) {
SoftForkDescPushBack(blockindex, softforks, chainman, Consensus::DEPLOYMENT_CSFS);
}
return softforks;
}
} // anon namespace

View file

@ -435,6 +435,12 @@ BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
// the same bit might overlap, even when non-overlapping start-end
// times are picked.
const uint32_t dep_mask{vbcache.Mask(chainParams->GetConsensus(), dep)};
if (chain_type != ChainType::REGTEST && dep == Consensus::DEPLOYMENT_CSFS) {
// CSFS only exists as a deployment on regtest, so skip over it for other
// chains.
continue;
}
BOOST_CHECK(!(chain_all_vbits & dep_mask));
chain_all_vbits |= dep_mask;
check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);

View file

@ -1231,7 +1231,13 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws)
const CTransaction& tx = *ws.m_ptx;
TxValidationState& state = ws.m_state;
constexpr unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
// CHECKSIGFROMSTACK (BIP348) is always active on regtest, but no other chain.
if (args.m_chainparams.GetChainType() == ChainType::REGTEST) {
scriptVerifyFlags |= SCRIPT_VERIFY_CHECKSIGFROMSTACK;
scriptVerifyFlags &= ~SCRIPT_VERIFY_DISCOURAGE_CHECKSIGFROMSTACK;
}
// Check input scripts and signatures.
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
@ -2410,6 +2416,11 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Ch
flags = it->second;
}
// Enforce CHECKSIGFROMSTACK (BIP348)
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_CSFS)) {
flags |= SCRIPT_VERIFY_CHECKSIGFROMSTACK;
}
// Enforce the DERSIG (BIP66) rule
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_DERSIG)) {
flags |= SCRIPT_VERIFY_DERSIG;

View file

@ -1177,9 +1177,6 @@ def spenders_taproot_active():
opcode = CScriptOp(opval)
if is_op_success(opcode):
continue
if opcode in OP_SUCCESS_OVERRIDES:
# TODO: remove this once CHECKSIGFROMSTACK gets a regtest deployment.
continue
scripts = [
("normal", CScript([OP_RETURN, opcode] + [OP_NOP] * 75)),
("op_success", CScript([OP_RETURN, CScriptOp(0x50)]))

View file

@ -251,6 +251,19 @@ class BlockchainTest(BitcoinTestFramework):
},
'height': 0,
'active': True
},
'csfs': {
'type': 'bip9',
'bip9': {
'start_time': -1,
'timeout': 9223372036854775807,
'min_activation_height': 0,
'status': 'active',
'status_next': 'active',
'since': 0,
},
'height': 0,
'active': True
}
}
})