verifier: further sanity checks for SPV verification.
Thanks to @JeremyRand
This commit is contained in:
@@ -142,13 +142,20 @@ class SPV(NetworkJobOnDefaultServer):
|
||||
try:
|
||||
h = hash_decode(tx_hash)
|
||||
merkle_branch_bytes = [hash_decode(item) for item in merkle_branch]
|
||||
int(leaf_pos_in_tree) # raise if invalid
|
||||
leaf_pos_in_tree = int(leaf_pos_in_tree) # raise if invalid
|
||||
except Exception as e:
|
||||
raise MerkleVerificationFailure(e)
|
||||
|
||||
for i, item in enumerate(merkle_branch_bytes):
|
||||
h = sha256d(item + h) if ((leaf_pos_in_tree >> i) & 1) else sha256d(h + item)
|
||||
if leaf_pos_in_tree < 0:
|
||||
raise MerkleVerificationFailure('leaf_pos_in_tree must be non-negative')
|
||||
index = leaf_pos_in_tree
|
||||
for item in merkle_branch_bytes:
|
||||
if len(item) != 32:
|
||||
raise MerkleVerificationFailure('all merkle branch items have to 32 bytes long')
|
||||
h = sha256d(item + h) if (index & 1) else sha256d(h + item)
|
||||
index >>= 1
|
||||
cls._raise_if_valid_tx(bh2u(h))
|
||||
if index != 0:
|
||||
raise MerkleVerificationFailure(f'leaf_pos_in_tree too large for branch')
|
||||
return hash_encode(h)
|
||||
|
||||
@classmethod
|
||||
@@ -192,6 +199,8 @@ def verify_tx_is_in_block(tx_hash: str, merkle_branch: Sequence[str],
|
||||
if not block_header:
|
||||
raise MissingBlockHeader("merkle verification failed for {} (missing header {})"
|
||||
.format(tx_hash, block_height))
|
||||
if len(merkle_branch) > 30:
|
||||
raise MerkleVerificationFailure(f"merkle branch too long: {len(merkle_branch)}")
|
||||
calc_merkle_root = SPV.hash_merkle_root(merkle_branch, tx_hash, leaf_pos_in_tree)
|
||||
if block_header.get('merkle_root') != calc_merkle_root:
|
||||
raise MerkleRootMismatch("merkle verification failed for {} ({} != {})".format(
|
||||
|
||||
Reference in New Issue
Block a user