Skip to content

Commit cccc1e7

Browse files
author
MarcoFalke
committed
Enforce Taproot script flags whenever WITNESS is set
1 parent fa42299 commit cccc1e7

File tree

4 files changed

+28
-27
lines changed

4 files changed

+28
-27
lines changed

src/chainparams.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <consensus/merkle.h>
1010
#include <deploymentinfo.h>
1111
#include <hash.h> // for signet block challenge hash
12+
#include <script/interpreter.h>
1213
#include <util/system.h>
1314

1415
#include <assert.h>
@@ -65,7 +66,10 @@ class CMainParams : public CChainParams {
6566
consensus.signet_blocks = false;
6667
consensus.signet_challenge.clear();
6768
consensus.nSubsidyHalvingInterval = 210000;
68-
consensus.BIP16Exception = uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22");
69+
consensus.script_flag_exceptions.emplace( // BIP16 exception
70+
uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22"), SCRIPT_VERIFY_NONE);
71+
consensus.script_flag_exceptions.emplace( // Taproot exception
72+
uint256S("0x0000000000000000000f14c35b2d841e986ab5441de8c585d5ffe55ea1e395ad"), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS);
6973
consensus.BIP34Height = 227931;
7074
consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8");
7175
consensus.BIP65Height = 388381; // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
@@ -184,7 +188,8 @@ class CTestNetParams : public CChainParams {
184188
consensus.signet_blocks = false;
185189
consensus.signet_challenge.clear();
186190
consensus.nSubsidyHalvingInterval = 210000;
187-
consensus.BIP16Exception = uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105");
191+
consensus.script_flag_exceptions.emplace( // BIP16 exception
192+
uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105"), SCRIPT_VERIFY_NONE);
188193
consensus.BIP34Height = 21111;
189194
consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8");
190195
consensus.BIP65Height = 581885; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
@@ -323,7 +328,6 @@ class SigNetParams : public CChainParams {
323328
consensus.signet_blocks = true;
324329
consensus.signet_challenge.assign(bin.begin(), bin.end());
325330
consensus.nSubsidyHalvingInterval = 210000;
326-
consensus.BIP16Exception = uint256{};
327331
consensus.BIP34Height = 1;
328332
consensus.BIP34Hash = uint256{};
329333
consensus.BIP65Height = 1;
@@ -391,7 +395,6 @@ class CRegTestParams : public CChainParams {
391395
consensus.signet_blocks = false;
392396
consensus.signet_challenge.clear();
393397
consensus.nSubsidyHalvingInterval = 150;
394-
consensus.BIP16Exception = uint256();
395398
consensus.BIP34Height = 1; // Always active unless overridden
396399
consensus.BIP34Hash = uint256();
397400
consensus.BIP65Height = 1; // Always active unless overridden

src/consensus/params.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
#define BITCOIN_CONSENSUS_PARAMS_H
88

99
#include <uint256.h>
10+
1011
#include <limits>
12+
#include <map>
1113

1214
namespace Consensus {
1315

@@ -70,8 +72,13 @@ struct BIP9Deployment {
7072
struct Params {
7173
uint256 hashGenesisBlock;
7274
int nSubsidyHalvingInterval;
73-
/* Block hash that is excepted from BIP16 enforcement */
74-
uint256 BIP16Exception;
75+
/**
76+
* Hashes of blocks that
77+
* - are known to be consensus valid, and
78+
* - buried in the chain, and
79+
* - fail if the default script verify flags are applied.
80+
*/
81+
std::map<uint256, uint32_t> script_flag_exceptions;
7582
/** Block height and hash at which BIP34 becomes active */
7683
int BIP34Height;
7784
uint256 BIP34Hash;

src/validation.cpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,18 +1581,18 @@ static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS] GUARDED_BY(cs_
15811581

15821582
static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Consensus::Params& consensusparams)
15831583
{
1584-
unsigned int flags = SCRIPT_VERIFY_NONE;
1585-
15861584
// BIP16 didn't become active until Apr 1 2012 (on mainnet, and
15871585
// retroactively applied to testnet)
15881586
// However, only one historical block violated the P2SH rules (on both
1589-
// mainnet and testnet), so for simplicity, always leave P2SH
1590-
// on except for the one violating block.
1591-
if (consensusparams.BIP16Exception.IsNull() || // no bip16 exception on this chain
1592-
*Assert(block_index.phashBlock) != consensusparams.BIP16Exception) // this block isn't the historical exception
1593-
{
1594-
// Enforce WITNESS rules whenever P2SH is in effect
1595-
flags |= SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS;
1587+
// mainnet and testnet).
1588+
// Similarly, only one historical block violated the TAPROOT rules on
1589+
// mainnet.
1590+
// For simplicity, always leave P2SH+WITNESS+TAPROOT on except for the two
1591+
// violating blocks.
1592+
uint32_t flags{SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_TAPROOT};
1593+
const auto it{consensusparams.script_flag_exceptions.find(*Assert(block_index.phashBlock))};
1594+
if (it != consensusparams.script_flag_exceptions.end()) {
1595+
flags = it->second;
15961596
}
15971597

15981598
// Enforce the DERSIG (BIP66) rule
@@ -1610,11 +1610,6 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Co
16101610
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
16111611
}
16121612

1613-
// Enforce Taproot (BIP340-BIP342)
1614-
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_TAPROOT)) {
1615-
flags |= SCRIPT_VERIFY_TAPROOT;
1616-
}
1617-
16181613
// Enforce BIP147 NULLDUMMY (activated simultaneously with segwit)
16191614
if (DeploymentActiveAt(block_index, consensusparams, Consensus::DEPLOYMENT_SEGWIT)) {
16201615
flags |= SCRIPT_VERIFY_NULLDUMMY;

test/functional/feature_taproot.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,15 +1181,11 @@ def spenders_taproot_inactive():
11811181
]
11821182
tap = taproot_construct(pub, scripts)
11831183

1184-
# Test that keypath spending is valid & non-standard, regardless of validity.
1184+
# Test that valid spending is standard.
11851185
add_spender(spenders, "inactive/keypath_valid", key=sec, tap=tap, standard=Standard.V23)
1186-
add_spender(spenders, "inactive/keypath_invalidsig", key=sec, tap=tap, standard=False, sighash=bitflipper(default_sighash))
1187-
add_spender(spenders, "inactive/keypath_empty", key=sec, tap=tap, standard=False, witness=[])
1188-
1189-
# Same for scriptpath spending (and features like annex, leaf versions, or OP_SUCCESS don't change this)
11901186
add_spender(spenders, "inactive/scriptpath_valid", key=sec, tap=tap, leaf="pk", standard=Standard.V23, inputs=[getter("sign")])
1191-
add_spender(spenders, "inactive/scriptpath_invalidsig", key=sec, tap=tap, leaf="pk", standard=False, inputs=[getter("sign")], sighash=bitflipper(default_sighash))
1192-
add_spender(spenders, "inactive/scriptpath_invalidcb", key=sec, tap=tap, leaf="pk", standard=False, inputs=[getter("sign")], controlblock=bitflipper(default_controlblock))
1187+
1188+
# Test that features like annex, leaf versions, or OP_SUCCESS are valid but non-standard
11931189
add_spender(spenders, "inactive/scriptpath_valid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")])
11941190
add_spender(spenders, "inactive/scriptpath_invalid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")], sighash=bitflipper(default_sighash))
11951191
add_spender(spenders, "inactive/scriptpath_valid_opsuccess", key=sec, tap=tap, leaf="op_success", standard=False, inputs=[getter("sign")])

0 commit comments

Comments
 (0)