From 5791d55e2f49d1cf07e0345f7ed18ab46878a303 Mon Sep 17 00:00:00 2001 From: kdmukai <934746+kdmukai@users.noreply.github.com> Date: Fri, 14 Aug 2026 17:56:44 -0500 Subject: [PATCH] Require the cache argument on the internal helpers Defaulting it to None means a call site that forgets it silently derives without a cache. No caller omitted it; now none can. _derive_with_cache keeps its optional cache, since that branch is the plain embit derive() the equivalence test compares against. --- src/seedsigner/models/psbt_parser.py | 14 +++++++------- tests/test_psbt_parser.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/seedsigner/models/psbt_parser.py b/src/seedsigner/models/psbt_parser.py index a219eaed..a67fb2a6 100644 --- a/src/seedsigner/models/psbt_parser.py +++ b/src/seedsigner/models/psbt_parser.py @@ -303,7 +303,7 @@ class PSBTParser(): @staticmethod - def _get_policy(scope, scriptpubkey, xpubs, child_key_derivation_cache=None): + def _get_policy(scope, scriptpubkey, xpubs, child_key_derivation_cache: dict | None): """Parse scope and get policy""" # we don't know the policy yet, let's parse it script_type = scriptpubkey.script_type() @@ -371,7 +371,7 @@ class PSBTParser(): @staticmethod - def _derive_with_cache(parent_key: bip32.HDKey, derivation_path: List[int], cache: dict | None = None) -> bip32.HDKey: + def _derive_with_cache(parent_key: bip32.HDKey, derivation_path: List[int], child_key_derivation_cache: dict | None = None) -> bip32.HDKey: """ Derives the key that sits at the given derivation path below parent_key, reusing any levels along the way that have already been derived during this parse. @@ -397,7 +397,7 @@ class PSBTParser(): The cache stops accepting new levels at MAX_CACHED_DERIVATIONS. """ - if cache is None: + if child_key_derivation_cache is None: return parent_key.derive(derivation_path) derived_key = parent_key @@ -407,14 +407,14 @@ class PSBTParser(): for index in derivation_path: derivation_path_so_far += (index,) cache_key = (id(parent_key), derivation_path_so_far) - cached_entry = cache.get(cache_key) + cached_entry = child_key_derivation_cache.get(cache_key) if cached_entry is None: # First time deriving this level. Do the work to derive this level's child # and store it in the cache. already_derived = derived_key.child(index) - if len(cache) < PSBTParser.MAX_CACHED_DERIVATIONS: + if len(child_key_derivation_cache) < PSBTParser.MAX_CACHED_DERIVATIONS: # Parent must also be stored to keep its id() from being reused - cache[cache_key] = (parent_key, already_derived) + child_key_derivation_cache[cache_key] = (parent_key, already_derived) else: cached_parent, already_derived = cached_entry derived_key = already_derived @@ -422,7 +422,7 @@ class PSBTParser(): @staticmethod - def _get_cosigners(pubkeys, derivations, xpubs, child_key_derivation_cache=None): + def _get_cosigners(pubkeys, derivations, xpubs, child_key_derivation_cache: dict | None): """Returns xpubs used to derive pubkeys using global xpub field from psbt""" cosigners = [] for i, pubkey in enumerate(pubkeys): diff --git a/tests/test_psbt_parser.py b/tests/test_psbt_parser.py index 81a8f2c0..27c7ef57 100644 --- a/tests/test_psbt_parser.py +++ b/tests/test_psbt_parser.py @@ -654,7 +654,7 @@ class TestPSBTParserOptimizations: inp = psbt.inputs[0] pubkeys = list(inp.bip32_derivations.keys()) - uncached = PSBTParser._get_cosigners(pubkeys, inp.bip32_derivations, psbt.xpubs) + uncached = PSBTParser._get_cosigners(pubkeys, inp.bip32_derivations, psbt.xpubs, None) child_key_derivation_cache = {} cached = PSBTParser._get_cosigners(