Merge pull request #2339 from Eunovo/bip352-invalid-control-block-vector

Bip352: Add consensus-validity requirement to Scanning requirements
This commit is contained in:
Murch authored and GitHub committed 2026-11-05 18:10:07 +01:00
commit a0190d01a1
2 files changed
+8

No files matched your search

+1
View File
@@ -190,6 +190,7 @@ Future silent payments versions will use the following scheme:
For silent payments v0 a transaction MUST be scanned if and only if all of the following are true:
* The transaction is consensus-valid
* The transaction contains at least one BIP341 taproot output (note: spent transactions optionally can be skipped by only considering transactions with at least one unspent taproot output)
* The transaction has at least one input from the ''[[#inputs-for-shared-secret-derivation|Inputs For Shared Secret Derivation]]'' list
* The transaction does not spend an output with SegWit version > 1<ref name="skip_txs_with_unknown_prevouts">'''Why skip transactions that spend SegWit version > 1?''' Skipping transactions that spend unknown output scripts allows us to have a clean upgrade path for silent payments by avoiding the need to scan the same transaction multiple times with different rule sets. If a new SegWit version is added in the future and silent payments v1 is released with support, we would want to avoid having to first scan the transaction with the silent payment v0 rules and then again with the silent payment v1 rules. Note: this restriction only applies to the inputs of a transaction.</ref>
+7
View File
@@ -32,6 +32,10 @@ from bitcoin_utils import (
K_max = 2323 # per-group recipient limit
NUMS_H = 0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0
TAPROOT_CONTROL_BASE_SIZE = 33
TAPROOT_CONTROL_NODE_SIZE = 32
TAPROOT_CONTROL_MAX_NODE_COUNT = 128
TAPROOT_CONTROL_MAX_SIZE = TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * TAPROOT_CONTROL_MAX_NODE_COUNT
def get_pubkey_from_input(vin: VinInfo) -> GE:
@@ -79,6 +83,9 @@ def get_pubkey_from_input(vin: VinInfo) -> GE:
# Script-path spend
control_block = witnessStack[-1]
# control block is <control byte> <32 byte internal key> and 0 or more <32 byte hash>
assert len(control_block) >= TAPROOT_CONTROL_BASE_SIZE
assert len(control_block) <= TAPROOT_CONTROL_MAX_SIZE
assert (len(control_block) - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE == 0
internal_key = control_block[1:33]
if (internal_key == NUMS_H.to_bytes(32, 'big')):
# Skip if NUMS_H