#!/usr/bin/env python3 # Copyright (c) 2016-2024 The Hush developers # Copyright (c) 2014 The Bitcoin Core developers # Distributed under the GPLv3 software license, see the accompanying # file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html from test_framework.test_framework import BitcoinTestFramework from test_framework.authproxy import JSONRPCException from test_framework.util import initialize_chain_clean, start_node from binascii import a2b_hex, b2a_hex from hashlib import sha256 from struct import pack def check_array_result(object_array, to_match, expected): """ Pass in array of JSON objects, a dictionary with key/value pairs to match against, and another dictionary with expected key/value pairs. """ num_matched = 0 for item in object_array: all_match = True for key,value in to_match.items(): if item[key] != value: all_match = False if not all_match: continue for key,value in expected.items(): if item[key] != value: raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) num_matched = num_matched+1 if num_matched == 0: raise AssertionError("No objects matched %s"%(str(to_match))) def b2x(b): return b2a_hex(b).decode('ascii') # NOTE: This does not work for signed numbers (set the high bit) or zero (use b'\0') def encodeUNum(n): s = bytearray(b'\1') while n > 127: s[0] += 1 s.append(n % 256) n //= 256 s.append(n) return bytes(s) def varlenEncode(n): if n < 0xfd: return pack(' 1: n = [] if len(cur) & 1: cur.append(cur[-1]) for i in range(0, len(cur), 2): n.append(dblsha(cur[i] + cur[i+1])) cur = n return cur[0] # --------------------------------------------------------------------------- # Sapling v4 transaction layout. # # This test was written against the pre-Overwinter serialization, where a tx # began with a 4-byte nVersion immediately followed by the vin count, so the # first input's prevout hash lived at offset 4+1. DragonX transactions are # Sapling v4: 4-byte header (nVersion | fOverwintered) + 4-byte nVersionGroupId # + vin count, so the prevout hash starts 4 bytes further in. Poking the old # offset corrupts nVersionGroupId and every proposal below just comes back # "Block decode failed" instead of exercising any consensus rule. CB_PREVOUT_OFF = 4+4+1 # Likewise the tx no longer ends at nLockTime: nExpiryHeight (4), valueBalance # (8) and the empty vShieldedSpend/vShieldedOutput/vJoinSplit counts (1 each) # trail it, so nLockTime is the 4 bytes at [-19:-15]. TX_TAIL_AFTER_LOCKTIME = 4+8+1+1+1 def tx_seq_off(tx): """Offset of the first input's nSequence in a Sapling v4 tx.""" scriptlen_off = CB_PREVOUT_OFF + 32 + 4 # after prevout hash + prevout.n return scriptlen_off + 1 + tx[scriptlen_off] def tx_vout0_value_off(tx): """Offset of the first output's 8-byte value in a Sapling v4 tx.""" return tx_seq_off(tx) + 4 + 1 # after nSequence + vout count def template_to_bytes(tmpl, txlist): blkver = pack('