Skip to content

Commit e4715e6

Browse files
jl2012elichai
authored andcommitted
Taproot policy change
1 parent b7b3779 commit e4715e6

File tree

4 files changed

+61
-36
lines changed

4 files changed

+61
-36
lines changed

src/policy/policy.cpp

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,27 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
219219
if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram))
220220
return false;
221221

222-
// Check P2WSH standard limits
223-
if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
224-
if (tx.vin[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)
225-
return false;
226-
size_t sizeWitnessStack = tx.vin[i].scriptWitness.stack.size() - 1;
227-
if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS)
228-
return false;
229-
for (unsigned int j = 0; j < sizeWitnessStack; j++) {
230-
if (tx.vin[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)
231-
return false;
222+
auto stack = tx.vin[i].scriptWitness.stack;
223+
if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) {
224+
return false; // annex is non-standard
225+
}
226+
227+
bool p2wsh = (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE);
228+
bool taproot = (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE && (witnessprogram[0] & 0xfe) == 0);
229+
230+
// Preprocessing for TAPROOT
231+
if (taproot) {
232+
if (stack.size() <= 1) return true;
233+
stack.pop_back();
234+
}
235+
236+
// Check P2WSH and TAPROOT standard limits
237+
if (p2wsh || taproot) {
238+
if (stack.back().size() > MAX_STANDARD_WITNESS_SCRIPT_SIZE) return false;
239+
stack.pop_back();
240+
if (stack.size() > MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS) return false;
241+
for (const auto& item : stack) {
242+
if (item.size() > MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE) return false;
232243
}
233244
}
234245
}

src/policy/policy.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE = 1000;
3636
static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20;
3737
/** Default for -permitbaremultisig */
3838
static const bool DEFAULT_PERMIT_BAREMULTISIG = true;
39-
/** The maximum number of witness stack items in a standard P2WSH script */
40-
static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS = 100;
41-
/** The maximum size of each witness stack item in a standard P2WSH script */
42-
static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEM_SIZE = 80;
43-
/** The maximum size of a standard witnessScript */
44-
static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
39+
/** The maximum number of witness input stack items in a standard witness script */
40+
static const unsigned int MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS = 210;
41+
/** The maximum size of each witness stack item in a standard witness script */
42+
static const unsigned int MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE = 80;
43+
/** The maximum size of a standard witness script */
44+
static const unsigned int MAX_STANDARD_WITNESS_SCRIPT_SIZE = 7100;
4545
/** Min feerate for defining dust. Historically this has been based on the
4646
* minRelayTxFee, however changing the dust limit changes which transactions are
4747
* standard and should be done with care and ideally rarely. It makes sense to
@@ -68,7 +68,12 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VE
6868
SCRIPT_VERIFY_WITNESS |
6969
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM |
7070
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE |
71-
SCRIPT_VERIFY_CONST_SCRIPTCODE;
71+
SCRIPT_VERIFY_CONST_SCRIPTCODE |
72+
SCRIPT_VERIFY_TAPROOT |
73+
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION |
74+
SCRIPT_VERIFY_DISCOURAGE_UNKNOWN_ANNEX |
75+
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS |
76+
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE;
7277

7378
/** For convenience, standard but not mandatory verify flags. */
7479
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;

src/script/interpreter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ struct ScriptExecutionData
187187
/** Signature hash sizes */
188188
static constexpr size_t WITNESS_V0_SCRIPTHASH_SIZE = 32;
189189
static constexpr size_t WITNESS_V0_KEYHASH_SIZE = 20;
190+
static constexpr size_t WITNESS_V1_TAPROOT_SIZE = 33;
190191

191192
template <class T>
192193
uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache = nullptr);

test/functional/p2p_segwit.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@
8989
MAX_SIGOP_COST = 80000
9090

9191
SEGWIT_HEIGHT = 120
92+
MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS = 210
93+
MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE = 80
94+
MAX_STANDARD_WITNESS_SCRIPT_SIZE = 7100
95+
# Extra restrictions make tests easier
96+
assert MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS < 403 and (MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS % 2) == 0
97+
assert MAX_STANDARD_WITNESS_SCRIPT_SIZE % 50 == 0
9298

9399
class UTXO():
94100
"""Used to keep track of anyone-can-spend outputs that we can use in the tests."""
@@ -1797,10 +1803,12 @@ def test_non_standard_witness(self):
17971803

17981804
# Create scripts for tests
17991805
scripts = []
1800-
scripts.append(CScript([OP_DROP] * 100))
1801-
scripts.append(CScript([OP_DROP] * 99))
1802-
scripts.append(CScript([pad * 59] * 59 + [OP_DROP] * 60))
1803-
scripts.append(CScript([pad * 59] * 59 + [OP_DROP] * 61))
1806+
scripts.append(CScript([OP_2DROP] * (MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS // 2)))
1807+
scripts.append(CScript([OP_2DROP] * (MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS // 2 - 1) + [OP_DROP]))
1808+
scripts.append(CScript([pad * 48] * (MAX_STANDARD_WITNESS_SCRIPT_SIZE // 50) + [OP_DROP] * (MAX_STANDARD_WITNESS_SCRIPT_SIZE // 50)))
1809+
scripts.append(CScript([pad * 48] * (MAX_STANDARD_WITNESS_SCRIPT_SIZE // 50) + [OP_DROP] * (MAX_STANDARD_WITNESS_SCRIPT_SIZE // 50 + 1)))
1810+
assert len(scripts[2]) == MAX_STANDARD_WITNESS_SCRIPT_SIZE
1811+
assert len(scripts[3]) == MAX_STANDARD_WITNESS_SCRIPT_SIZE + 1
18041812

18051813
p2wsh_scripts = []
18061814

@@ -1840,45 +1848,45 @@ def test_non_standard_witness(self):
18401848
p2sh_txs.append(p2sh_tx)
18411849

18421850
# Testing native P2WSH
1843-
# Witness stack size, excluding witnessScript, over 100 is non-standard
1844-
p2wsh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]]
1851+
# Witness stack size, excluding witnessScript, over MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS is non-standard
1852+
p2wsh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * (MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS + 1) + [scripts[0]]
18451853
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[0], True, False, 'bad-witness-nonstandard')
18461854
# Non-standard nodes should accept
18471855
test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[0], True, True)
18481856

1849-
# Stack element size over 80 bytes is non-standard
1850-
p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]]
1857+
# Stack element size over MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE bytes is non-standard
1858+
p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * (MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE + 1)] * MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS + [scripts[1]]
18511859
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, False, 'bad-witness-nonstandard')
18521860
# Non-standard nodes should accept
18531861
test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[1], True, True)
1854-
# Standard nodes should accept if element size is not over 80 bytes
1855-
p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]]
1862+
# Standard nodes should accept if element size is not over MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE
1863+
p2wsh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE] * MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS + [scripts[1]]
18561864
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[1], True, True)
18571865

1858-
# witnessScript size at 3600 bytes is standard
1859-
p2wsh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]]
1866+
# witnessScript size at 7100 bytes is standard
1867+
p2wsh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, scripts[2]]
18601868
test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[2], True, True)
18611869
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[2], True, True)
18621870

1863-
# witnessScript size at 3601 bytes is non-standard
1864-
p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]]
1871+
# witnessScript size at 7101 bytes is non-standard
1872+
p2wsh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[3]]
18651873
test_transaction_acceptance(self.nodes[1], self.std_node, p2wsh_txs[3], True, False, 'bad-witness-nonstandard')
18661874
# Non-standard nodes should accept
18671875
test_transaction_acceptance(self.nodes[0], self.test_node, p2wsh_txs[3], True, True)
18681876

18691877
# Repeating the same tests with P2SH-P2WSH
1870-
p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * 101 + [scripts[0]]
1878+
p2sh_txs[0].wit.vtxinwit[0].scriptWitness.stack = [pad] * (MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS + 1) + [scripts[0]]
18711879
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[0], True, False, 'bad-witness-nonstandard')
18721880
test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[0], True, True)
1873-
p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 81] * 100 + [scripts[1]]
1881+
p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * (MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE + 1)] * MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS + [scripts[1]]
18741882
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, False, 'bad-witness-nonstandard')
18751883
test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[1], True, True)
1876-
p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * 80] * 100 + [scripts[1]]
1884+
p2sh_txs[1].wit.vtxinwit[0].scriptWitness.stack = [pad * MAX_STANDARD_WITNESS_INPUT_STACK_ITEM_SIZE] * MAX_STANDARD_WITNESS_INPUT_STACK_ITEMS + [scripts[1]]
18771885
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[1], True, True)
1878-
p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[2]]
1886+
p2sh_txs[2].wit.vtxinwit[0].scriptWitness.stack = [pad, scripts[2]]
18791887
test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[2], True, True)
18801888
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[2], True, True)
1881-
p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, pad, scripts[3]]
1889+
p2sh_txs[3].wit.vtxinwit[0].scriptWitness.stack = [pad, pad, scripts[3]]
18821890
test_transaction_acceptance(self.nodes[1], self.std_node, p2sh_txs[3], True, False, 'bad-witness-nonstandard')
18831891
test_transaction_acceptance(self.nodes[0], self.test_node, p2sh_txs[3], True, True)
18841892

0 commit comments

Comments
 (0)