Skip to content

Commit 6bed516

Browse files
darosiorinstagibbs
andcommitted
script: introduce verify flags for OP_TEMPLATE
Script validation of OP_TEMPLATE is enabled past its activation height, which means it is currently never enabled on mainnet/testnet and always is on regtest. Tapscript spends making use of OP_TEMPLATE do not get relayed nor included in blocks until the soft fork is active. Note how the standardness script verify flags are set such as even post activation, an OP_TEMPLATEHASH related error would not be reported as a consensus error (and lead to peer disconnection). This can be changed in a future release, once the soft fork activation isn't recent anymore. Co-Authored-by: Greg Sanders <[email protected]>
1 parent 260bb47 commit 6bed516

File tree

6 files changed

+27
-4
lines changed

6 files changed

+27
-4
lines changed

src/policy/policy.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERI
123123
SCRIPT_VERIFY_CONST_SCRIPTCODE |
124124
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION |
125125
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS |
126-
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE};
126+
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE |
127+
SCRIPT_VERIFY_DISCOURAGE_TEMPLATEHASH |
128+
SCRIPT_VERIFY_TEMPLATEHASH};
127129

128130
/** For convenience, standard but not mandatory verify flags. */
129131
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS{STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS};

src/script/interpreter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ enum : uint32_t {
143143
// Making unknown public key versions (in BIP 342 scripts) non-standard
144144
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE = (1U << 20),
145145

146+
// OP_TEMPLATEHASH validation (BIP xx)
147+
SCRIPT_VERIFY_TEMPLATEHASH = (1U << 21),
148+
149+
// Make OP_TEMPLATEHASH spend non-standard before activation.
150+
SCRIPT_VERIFY_DISCOURAGE_TEMPLATEHASH = (1U << 22),
151+
146152
// Constants to point to the highest flag in use. Add new flags above this line.
147153
//
148154
SCRIPT_VERIFY_END_MARKER

src/test/fuzz/script_assets_test_minimizer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,14 @@ const std::map<std::string, unsigned int> FLAG_NAMES = {
9898
{std::string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY},
9999
{std::string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS},
100100
{std::string("TAPROOT"), (unsigned int)SCRIPT_VERIFY_TAPROOT},
101+
{std::string("TEMPLATE"), (unsigned int)SCRIPT_VERIFY_TEMPLATEHASH},
101102
};
102103

103104
std::vector<unsigned int> AllFlags()
104105
{
105106
std::vector<unsigned int> ret;
106107

107-
for (unsigned int i = 0; i < 128; ++i) {
108+
for (unsigned int i = 0; i < 256; ++i) {
108109
unsigned int flag = 0;
109110
if (i & 1) flag |= SCRIPT_VERIFY_P2SH;
110111
if (i & 2) flag |= SCRIPT_VERIFY_DERSIG;
@@ -113,6 +114,7 @@ std::vector<unsigned int> AllFlags()
113114
if (i & 16) flag |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
114115
if (i & 32) flag |= SCRIPT_VERIFY_WITNESS;
115116
if (i & 64) flag |= SCRIPT_VERIFY_TAPROOT;
117+
if (i & 128) flag |= SCRIPT_VERIFY_TEMPLATEHASH;
116118

117119
// SCRIPT_VERIFY_WITNESS requires SCRIPT_VERIFY_P2SH
118120
if (flag & SCRIPT_VERIFY_WITNESS && !(flag & SCRIPT_VERIFY_P2SH)) continue;

src/test/script_tests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@ static std::vector<unsigned int> AllConsensusFlags()
15531553
{
15541554
std::vector<unsigned int> ret;
15551555

1556-
for (unsigned int i = 0; i < 128; ++i) {
1556+
for (unsigned int i = 0; i < 256; ++i) {
15571557
unsigned int flag = 0;
15581558
if (i & 1) flag |= SCRIPT_VERIFY_P2SH;
15591559
if (i & 2) flag |= SCRIPT_VERIFY_DERSIG;
@@ -1562,6 +1562,7 @@ static std::vector<unsigned int> AllConsensusFlags()
15621562
if (i & 16) flag |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
15631563
if (i & 32) flag |= SCRIPT_VERIFY_WITNESS;
15641564
if (i & 64) flag |= SCRIPT_VERIFY_TAPROOT;
1565+
if (i & 128) flag |= SCRIPT_VERIFY_TEMPLATEHASH;
15651566

15661567
// SCRIPT_VERIFY_WITNESS requires SCRIPT_VERIFY_P2SH
15671568
if (flag & SCRIPT_VERIFY_WITNESS && !(flag & SCRIPT_VERIFY_P2SH)) continue;

src/test/transaction_tests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ static std::map<std::string, unsigned int> mapFlagNames = {
7070
{std::string("DISCOURAGE_UPGRADABLE_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE},
7171
{std::string("DISCOURAGE_OP_SUCCESS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS},
7272
{std::string("DISCOURAGE_UPGRADABLE_TAPROOT_VERSION"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION},
73+
{std::string("TEMPLATEHASH"), (unsigned int)SCRIPT_VERIFY_TEMPLATEHASH},
74+
{std::string("DISCOURAGE_TEMPLATEHASH"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_TEMPLATEHASH},
7375
};
7476

7577
unsigned int ParseScriptFlags(std::string strFlags)

src/validation.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,12 @@ bool MemPoolAccept::PolicyScriptChecks(const ATMPArgs& args, Workspace& ws)
12331233
const CTransaction& tx = *ws.m_ptx;
12341234
TxValidationState& state = ws.m_state;
12351235

1236-
constexpr unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
1236+
unsigned int scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS;
1237+
1238+
// Past activation, don't discourage OP_TEMPLATEHASH spends.
1239+
if (DeploymentActiveAt(*m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman, Consensus::DEPLOYMENT_TEMPLATEHASH)) {
1240+
scriptVerifyFlags &= ~SCRIPT_VERIFY_DISCOURAGE_TEMPLATEHASH;
1241+
}
12371242

12381243
// Check input scripts and signatures.
12391244
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
@@ -2406,6 +2411,11 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const Ch
24062411
flags |= SCRIPT_VERIFY_NULLDUMMY;
24072412
}
24082413

2414+
// Enforce OP_TEMPLATEHASH (BIPxx)
2415+
if (DeploymentActiveAt(block_index, chainman, Consensus::DEPLOYMENT_TEMPLATEHASH)) {
2416+
flags |= SCRIPT_VERIFY_TEMPLATEHASH;
2417+
}
2418+
24092419
return flags;
24102420
}
24112421

0 commit comments

Comments
 (0)