From a0d7985212c364303dc6be39c25f47d58acf2713 Mon Sep 17 00:00:00 2001 From: Vivek Arte <46618816+vivek-arte@users.noreply.github.com> Date: Fri, 16 Jan 2026 17:53:44 +0530 Subject: [PATCH 1/5] transparent sighashInfo refactor to reduce the dependence on version_id inside TransactionBase --- zcash_test_vectors/transaction.py | 14 +++++++------- zcash_test_vectors/transaction_v6.py | 7 +++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/zcash_test_vectors/transaction.py b/zcash_test_vectors/transaction.py index 0c8f0f21..42bf49d0 100644 --- a/zcash_test_vectors/transaction.py +++ b/zcash_test_vectors/transaction.py @@ -508,7 +508,7 @@ def is_coinbase(self): def to_bytes(self, version_bytes, version_group_id, consensus_branch_id): ret = b'' ret += self.header_bytes(version_bytes, version_group_id, consensus_branch_id) - ret += self.transparent_bytes(version_bytes) + ret += self.transparent_bytes() ret += self.sapling_bytes(version_bytes) return ret @@ -523,7 +523,7 @@ def header_bytes(self, version_bytes, version_group_id, consensus_branch_id): return ret - def transparent_bytes(self, version_bytes): + def transparent_bytes(self): ret = b'' # Transparent Transaction Fields ret += write_compact_size(len(self.vin)) @@ -532,13 +532,13 @@ def transparent_bytes(self, version_bytes): ret += write_compact_size(len(self.vout)) for x in self.vout: ret += bytes(x) - if version_bytes == NU7_TX_VERSION_BYTES: - for sighash_info in self.vSighashInfo: - ret += write_compact_size(len(sighash_info)) - ret += bytes(sighash_info) - + ret += self.transparent_sighash_info_bytes() return ret + def transparent_sighash_info_bytes(self): + # There are no such bytes for V5 transactions. + return b'' + def sapling_bytes(self, version_bytes): ret = b'' # Sapling Transaction Fields diff --git a/zcash_test_vectors/transaction_v6.py b/zcash_test_vectors/transaction_v6.py index 1598dce6..79ae4625 100644 --- a/zcash_test_vectors/transaction_v6.py +++ b/zcash_test_vectors/transaction_v6.py @@ -198,6 +198,13 @@ def header_bytes(self, version_bytes, version_group_id, consensus_branch_id): ret += struct.pack(' Date: Fri, 16 Jan 2026 18:45:40 +0530 Subject: [PATCH 2/5] Sapling sighashInfo refactor to reduce the dependence on version_id inside TransactionBase --- zcash_test_vectors/transaction.py | 21 ++++++++++----------- zcash_test_vectors/transaction_v6.py | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/zcash_test_vectors/transaction.py b/zcash_test_vectors/transaction.py index 42bf49d0..ae18933a 100644 --- a/zcash_test_vectors/transaction.py +++ b/zcash_test_vectors/transaction.py @@ -5,7 +5,6 @@ Scalar as PallasScalar, ) from .orchard.sinsemilla import group_hash as pallas_group_hash -from .orchard_zsa.digests import NU7_TX_VERSION_BYTES from .sapling.generators import find_group_hash, SPENDING_KEY_BASE from .sapling.jubjub import ( Fq, @@ -509,7 +508,7 @@ def to_bytes(self, version_bytes, version_group_id, consensus_branch_id): ret = b'' ret += self.header_bytes(version_bytes, version_group_id, consensus_branch_id) ret += self.transparent_bytes() - ret += self.sapling_bytes(version_bytes) + ret += self.sapling_bytes() return ret def header_bytes(self, version_bytes, version_group_id, consensus_branch_id): @@ -539,7 +538,7 @@ def transparent_sighash_info_bytes(self): # There are no such bytes for V5 transactions. return b'' - def sapling_bytes(self, version_bytes): + def sapling_bytes(self): ret = b'' # Sapling Transaction Fields has_sapling = len(self.vSpendsSapling) + len(self.vOutputsSapling) > 0 @@ -558,20 +557,20 @@ def sapling_bytes(self, version_bytes): for desc in self.vSpendsSapling: # vSpendProofsSapling ret += bytes(desc.proof) for desc in self.vSpendsSapling: # vSpendAuthSigsSapling - if version_bytes == NU7_TX_VERSION_BYTES: - ret += write_compact_size(len(desc.spendAuthSigInfo)) - ret += bytes(desc.spendAuthSigInfo) - ret += bytes(desc.spendAuthSig) + ret += self.sapling_spend_auth_sig_bytes(desc) for desc in self.vOutputsSapling: # vOutputProofsSapling ret += bytes(desc.proof) if has_sapling: - if version_bytes == NU7_TX_VERSION_BYTES: - ret += write_compact_size(len(self.bindingSigSaplingInfo)) - ret += bytes(self.bindingSigSaplingInfo) - ret += bytes(self.bindingSigSapling) + ret += self.sapling_binding_sig_bytes() return ret + def sapling_spend_auth_sig_bytes(self, desc): + return bytes(desc.spendAuthSig) + + def sapling_binding_sig_bytes(self): + return bytes(self.bindingSigSapling) + class TransactionV5(TransactionBase): def __init__(self, rand, consensus_branch_id): have_orchard = rand.bool() diff --git a/zcash_test_vectors/transaction_v6.py b/zcash_test_vectors/transaction_v6.py index 79ae4625..2624e9e0 100644 --- a/zcash_test_vectors/transaction_v6.py +++ b/zcash_test_vectors/transaction_v6.py @@ -205,6 +205,20 @@ def transparent_sighash_info_bytes(self): ret += bytes(sighash_info) return ret + def sapling_spend_auth_sig_bytes(self, desc): + ret = b'' + ret += write_compact_size(len(desc.spendAuthSigInfo)) + ret += bytes(desc.spendAuthSigInfo) + ret += bytes(desc.spendAuthSig) + return ret + + def sapling_binding_sig_bytes(self): + ret = b'' + ret += write_compact_size(len(self.bindingSigSaplingInfo)) + ret += bytes(self.bindingSigSaplingInfo) + ret += bytes(self.bindingSigSapling) + return ret + def issuance_field_bytes(self): ret = b'' ret += write_compact_size(len(self.issuer)) From bd1cb4eaece5836d19adf28fd323ca27ad374279 Mon Sep 17 00:00:00 2001 From: Vivek Arte <46618816+vivek-arte@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:57:32 +0530 Subject: [PATCH 3/5] adding failure to TransactionBase definition of functions that need to be defined in V5 and V6 classes --- zcash_test_vectors/transaction.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/zcash_test_vectors/transaction.py b/zcash_test_vectors/transaction.py index ae18933a..161c113a 100644 --- a/zcash_test_vectors/transaction.py +++ b/zcash_test_vectors/transaction.py @@ -534,9 +534,9 @@ def transparent_bytes(self): ret += self.transparent_sighash_info_bytes() return ret + # This must be defined in every child class. def transparent_sighash_info_bytes(self): - # There are no such bytes for V5 transactions. - return b'' + raise NotImplementedError("The transparent_sighash_info_bytes method must be implemented.") def sapling_bytes(self): ret = b'' @@ -565,11 +565,13 @@ def sapling_bytes(self): return ret + # This must be defined in every child class. def sapling_spend_auth_sig_bytes(self, desc): - return bytes(desc.spendAuthSig) + raise NotImplementedError("The sapling_spend_auth_sig_bytes method must be implemented.") + # This must be defined in every child class. def sapling_binding_sig_bytes(self): - return bytes(self.bindingSigSapling) + raise NotImplementedError("The sapling_binding_sig_bytes method must be implemented.") class TransactionV5(TransactionBase): def __init__(self, rand, consensus_branch_id): @@ -596,6 +598,16 @@ def __init__(self, rand, consensus_branch_id): def version_bytes(): return NU5_TX_VERSION_BYTES + def transparent_sighash_info_bytes(self): + # There are no such bytes for V5 transactions. + return b'' + + def sapling_spend_auth_sig_bytes(self, desc): + return bytes(desc.spendAuthSig) + + def sapling_binding_sig_bytes(self): + return bytes(self.bindingSigSapling) + def __bytes__(self): ret = b'' From 70401d5c2866455e4c45d0c5576b5645912f24b0 Mon Sep 17 00:00:00 2001 From: Vivek Arte <46618816+vivek-arte@users.noreply.github.com> Date: Mon, 19 Jan 2026 21:21:47 +0530 Subject: [PATCH 4/5] review fixes --- zcash_test_vectors/transaction.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/zcash_test_vectors/transaction.py b/zcash_test_vectors/transaction.py index 161c113a..7ce6fcb4 100644 --- a/zcash_test_vectors/transaction.py +++ b/zcash_test_vectors/transaction.py @@ -534,7 +534,6 @@ def transparent_bytes(self): ret += self.transparent_sighash_info_bytes() return ret - # This must be defined in every child class. def transparent_sighash_info_bytes(self): raise NotImplementedError("The transparent_sighash_info_bytes method must be implemented.") @@ -565,11 +564,9 @@ def sapling_bytes(self): return ret - # This must be defined in every child class. def sapling_spend_auth_sig_bytes(self, desc): raise NotImplementedError("The sapling_spend_auth_sig_bytes method must be implemented.") - # This must be defined in every child class. def sapling_binding_sig_bytes(self): raise NotImplementedError("The sapling_binding_sig_bytes method must be implemented.") From 6c3ce10589864df6df9a06a3357f6ac17a25c657 Mon Sep 17 00:00:00 2001 From: Vivek Arte <46618816+vivek-arte@users.noreply.github.com> Date: Mon, 19 Jan 2026 21:28:56 +0530 Subject: [PATCH 5/5] further review fixes --- zcash_test_vectors/transaction.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zcash_test_vectors/transaction.py b/zcash_test_vectors/transaction.py index 7ce6fcb4..b0e641d0 100644 --- a/zcash_test_vectors/transaction.py +++ b/zcash_test_vectors/transaction.py @@ -535,7 +535,7 @@ def transparent_bytes(self): return ret def transparent_sighash_info_bytes(self): - raise NotImplementedError("The transparent_sighash_info_bytes method must be implemented.") + raise NotImplementedError("The transparent_sighash_info_bytes method must be implemented in the child class.") def sapling_bytes(self): ret = b'' @@ -565,10 +565,10 @@ def sapling_bytes(self): return ret def sapling_spend_auth_sig_bytes(self, desc): - raise NotImplementedError("The sapling_spend_auth_sig_bytes method must be implemented.") + raise NotImplementedError("The sapling_spend_auth_sig_bytes method must be implemented in the child class.") def sapling_binding_sig_bytes(self): - raise NotImplementedError("The sapling_binding_sig_bytes method must be implemented.") + raise NotImplementedError("The sapling_binding_sig_bytes method must be implemented in the child class.") class TransactionV5(TransactionBase): def __init__(self, rand, consensus_branch_id):