From 7746cc8e6072b703e49e14216374489ff204198f Mon Sep 17 00:00:00 2001 From: SomberNight Date: Fri, 10 Mar 2023 14:23:17 +0000 Subject: [PATCH] bip32: (trivial) rename method strpath_to_intpath, for symmetry Required a much higher mental load to parse the name "convert_bip32_path_to_list_of_uint32" than to parse "convert_bip32_strpath_to_intpath". And we already have the ~inverse: "convert_bip32_intpath_to_strpath". --- electrum/bip32.py | 18 +++++++++--------- electrum/bip39_recovery.py | 2 +- electrum/descriptor.py | 6 +++--- electrum/keystore.py | 12 ++++++------ electrum/plugins/bitbox02/bitbox02.py | 8 ++++---- electrum/plugins/jade/jade.py | 8 ++++---- electrum/plugins/keepkey/clientbase.py | 4 ++-- electrum/plugins/ledger/ledger.py | 2 +- electrum/plugins/safe_t/clientbase.py | 4 ++-- electrum/plugins/trezor/clientbase.py | 2 +- electrum/plugins/trezor/trezor.py | 2 +- electrum/tests/test_bitcoin.py | 12 ++++++------ electrum/wallet.py | 4 ++-- 13 files changed, 42 insertions(+), 42 deletions(-) diff --git a/electrum/bip32.py b/electrum/bip32.py index 225427f78..f3ea60f95 100644 --- a/electrum/bip32.py +++ b/electrum/bip32.py @@ -236,7 +236,7 @@ class BIP32Node(NamedTuple): if path is None: raise Exception("derivation path must not be None") if isinstance(path, str): - path = convert_bip32_path_to_list_of_uint32(path) + path = convert_bip32_strpath_to_intpath(path) if not self.is_private(): raise Exception("cannot do bip32 private derivation; private key missing") if not path: @@ -262,7 +262,7 @@ class BIP32Node(NamedTuple): if path is None: raise Exception("derivation path must not be None") if isinstance(path, str): - path = convert_bip32_path_to_list_of_uint32(path) + path = convert_bip32_strpath_to_intpath(path) if not path: return self.convert_to_public() depth = self.depth @@ -313,8 +313,8 @@ def xpub_from_xprv(xprv): return BIP32Node.from_xkey(xprv).to_xpub() -def convert_bip32_path_to_list_of_uint32(n: str) -> List[int]: - """Convert bip32 path to list of uint32 integers with prime flags +def convert_bip32_strpath_to_intpath(n: str) -> List[int]: + """Convert bip32 path str to list of uint32 integers with prime flags m/0/-1/1' -> [0, 0x80000001, 0x80000001] based on code in trezorlib @@ -373,7 +373,7 @@ def is_bip32_derivation(s: str) -> bool: try: if not (s == 'm' or s.startswith('m/')): return False - convert_bip32_path_to_list_of_uint32(s) + convert_bip32_strpath_to_intpath(s) except: return False else: @@ -385,14 +385,14 @@ def normalize_bip32_derivation(s: Optional[str]) -> Optional[str]: return None if not is_bip32_derivation(s): raise ValueError(f"invalid bip32 derivation: {s}") - ints = convert_bip32_path_to_list_of_uint32(s) + ints = convert_bip32_strpath_to_intpath(s) return convert_bip32_intpath_to_strpath(ints) def is_all_public_derivation(path: Union[str, Iterable[int]]) -> bool: """Returns whether all levels in path use non-hardened derivation.""" if isinstance(path, str): - path = convert_bip32_path_to_list_of_uint32(path) + path = convert_bip32_strpath_to_intpath(path) for child_index in path: if child_index < 0: raise ValueError('the bip32 index needs to be non-negative') @@ -425,7 +425,7 @@ def is_xkey_consistent_with_key_origin_info(xkey: str, *, bip32node = BIP32Node.from_xkey(xkey) int_path = None if derivation_prefix is not None: - int_path = convert_bip32_path_to_list_of_uint32(derivation_prefix) + int_path = convert_bip32_strpath_to_intpath(derivation_prefix) if int_path is not None and len(int_path) != bip32node.depth: return False if bip32node.depth == 0: @@ -503,7 +503,7 @@ class KeyOriginInfo: fingerprint = binascii.unhexlify(s[0:8]) path: Sequence[int] = [] if len(entries) > 1: - path = convert_bip32_path_to_list_of_uint32(s[9:]) + path = convert_bip32_strpath_to_intpath(s[9:]) return cls(fingerprint, path) def get_derivation_path(self) -> str: diff --git a/electrum/bip39_recovery.py b/electrum/bip39_recovery.py index e6c7c1fa4..bf9fa5375 100644 --- a/electrum/bip39_recovery.py +++ b/electrum/bip39_recovery.py @@ -8,7 +8,7 @@ import itertools from . import bitcoin from .constants import BIP39_WALLET_FORMATS from .bip32 import BIP32_PRIME, BIP32Node -from .bip32 import convert_bip32_path_to_list_of_uint32 as bip32_str_to_ints +from .bip32 import convert_bip32_strpath_to_intpath as bip32_str_to_ints from .bip32 import convert_bip32_intpath_to_strpath as bip32_ints_to_str from .util import OldTaskGroup diff --git a/electrum/descriptor.py b/electrum/descriptor.py index 4ad9fd71a..3bce2da20 100644 --- a/electrum/descriptor.py +++ b/electrum/descriptor.py @@ -16,7 +16,7 @@ import enum -from .bip32 import convert_bip32_path_to_list_of_uint32, BIP32Node, KeyOriginInfo, BIP32_PRIME +from .bip32 import convert_bip32_strpath_to_intpath, BIP32Node, KeyOriginInfo, BIP32_PRIME from . import bitcoin from .bitcoin import construct_script, opcodes, construct_witness from . import constants @@ -250,7 +250,7 @@ class PubkeyProvider(object): if self.is_range(): assert path_str[-1] == "*" path_str = path_str[:-1] + str(pos) - path = convert_bip32_path_to_list_of_uint32(path_str) + path = convert_bip32_strpath_to_intpath(path_str) child_key = self.extkey.subkey_at_public_derivation(path) return child_key.eckey.get_public_key_bytes(compressed=compressed) else: @@ -286,7 +286,7 @@ class PubkeyProvider(object): der_suffix = self.deriv_path assert (wc_count := der_suffix.count("*")) <= 1, wc_count der_suffix = der_suffix.replace("*", str(pos)) - return convert_bip32_path_to_list_of_uint32(der_suffix) + return convert_bip32_strpath_to_intpath(der_suffix) def __lt__(self, other: 'PubkeyProvider') -> bool: return self.pubkey < other.pubkey diff --git a/electrum/keystore.py b/electrum/keystore.py index 9ccf2ab30..c1c5638a6 100644 --- a/electrum/keystore.py +++ b/electrum/keystore.py @@ -34,7 +34,7 @@ from abc import ABC, abstractmethod from . import bitcoin, ecc, constants, bip32 from .bitcoin import deserialize_privkey, serialize_privkey, BaseDecodeError from .transaction import Transaction, PartialTransaction, PartialTxInput, PartialTxOutput, TxInput -from .bip32 import (convert_bip32_path_to_list_of_uint32, BIP32_PRIME, +from .bip32 import (convert_bip32_strpath_to_intpath, BIP32_PRIME, is_xpub, is_xprv, BIP32Node, normalize_bip32_derivation, convert_bip32_intpath_to_strpath, is_xkey_consistent_with_key_origin_info, KeyOriginInfo) @@ -454,7 +454,7 @@ class MasterPublicKeyMixin(ABC): # 1. try fp against our root ks_root_fingerprint_hex = self.get_root_fingerprint() ks_der_prefix_str = self.get_derivation_prefix() - ks_der_prefix = convert_bip32_path_to_list_of_uint32(ks_der_prefix_str) if ks_der_prefix_str else None + ks_der_prefix = convert_bip32_strpath_to_intpath(ks_der_prefix_str) if ks_der_prefix_str else None if (ks_root_fingerprint_hex is not None and ks_der_prefix is not None and fp_found.hex() == ks_root_fingerprint_hex): if path_found[:len(ks_der_prefix)] == ks_der_prefix: @@ -524,11 +524,11 @@ class Xpub(MasterPublicKeyMixin): if not only_der_suffix and fingerprint_hex is not None and der_prefix_str is not None: # use root fp, and true full path fingerprint_bytes = bfh(fingerprint_hex) - der_prefix_ints = convert_bip32_path_to_list_of_uint32(der_prefix_str) + der_prefix_ints = convert_bip32_strpath_to_intpath(der_prefix_str) else: # use intermediate fp, and claim der suffix is the full path fingerprint_bytes = self.get_bip32_node_for_xpub().calc_fingerprint_of_this_node() - der_prefix_ints = convert_bip32_path_to_list_of_uint32('m') + der_prefix_ints = convert_bip32_strpath_to_intpath('m') der_full = der_prefix_ints + list(der_suffix) return fingerprint_bytes, der_full @@ -832,7 +832,7 @@ class Old_KeyStore(MasterPublicKeyMixin, Deterministic_KeyStore): fingerprint_hex = self.get_root_fingerprint() der_prefix_str = self.get_derivation_prefix() fingerprint_bytes = bfh(fingerprint_hex) - der_prefix_ints = convert_bip32_path_to_list_of_uint32(der_prefix_str) + der_prefix_ints = convert_bip32_strpath_to_intpath(der_prefix_str) der_full = der_prefix_ints + list(der_suffix) return fingerprint_bytes, der_full @@ -1030,7 +1030,7 @@ PURPOSE48_SCRIPT_TYPES_INV = inv_dict(PURPOSE48_SCRIPT_TYPES) def xtype_from_derivation(derivation: str) -> str: """Returns the script type to be used for this derivation.""" - bip32_indices = convert_bip32_path_to_list_of_uint32(derivation) + bip32_indices = convert_bip32_strpath_to_intpath(derivation) if len(bip32_indices) >= 1: if bip32_indices[0] == 84 + BIP32_PRIME: return 'p2wpkh' diff --git a/electrum/plugins/bitbox02/bitbox02.py b/electrum/plugins/bitbox02/bitbox02.py index 4b328dc6b..ccba7c126 100644 --- a/electrum/plugins/bitbox02/bitbox02.py +++ b/electrum/plugins/bitbox02/bitbox02.py @@ -201,7 +201,7 @@ class BitBox02Client(HardwareClientBase): @runs_in_hwd_thread def get_password_for_storage_encryption(self) -> str: derivation = get_derivation_used_for_hw_device_encryption() - derivation_list = bip32.convert_bip32_path_to_list_of_uint32(derivation) + derivation_list = bip32.convert_bip32_strpath_to_intpath(derivation) xpub = self.bitbox02_device.electrum_encryption_key(derivation_list) node = bip32.BIP32Node.from_xkey(xpub, net = constants.BitcoinMainnet()).subkey_at_public_derivation(()) return node.eckey.get_public_key_bytes(compressed=True).hex() @@ -218,7 +218,7 @@ class BitBox02Client(HardwareClientBase): self.fail_if_not_initialized() - xpub_keypath = bip32.convert_bip32_path_to_list_of_uint32(bip32_path) + xpub_keypath = bip32.convert_bip32_strpath_to_intpath(bip32_path) coin_network = self.coin_network_from_electrum_network() if xtype == "p2wpkh": @@ -341,7 +341,7 @@ class BitBox02Client(HardwareClientBase): "Need to setup communication first before attempting any BitBox02 calls" ) - address_keypath = bip32.convert_bip32_path_to_list_of_uint32(bip32_path) + address_keypath = bip32.convert_bip32_strpath_to_intpath(bip32_path) coin_network = self.coin_network_from_electrum_network() if address_type == "p2wpkh": @@ -548,7 +548,7 @@ class BitBox02Client(HardwareClientBase): script_config=bitbox02.btc.BTCScriptConfig( simple_type=simple_type, ), - keypath=bip32.convert_bip32_path_to_list_of_uint32(keypath), + keypath=bip32.convert_bip32_strpath_to_intpath(keypath), ), message, ) diff --git a/electrum/plugins/jade/jade.py b/electrum/plugins/jade/jade.py index 135713d6d..2a68e0ad4 100644 --- a/electrum/plugins/jade/jade.py +++ b/electrum/plugins/jade/jade.py @@ -55,7 +55,7 @@ def _register_multisig_wallet(wallet, keystore, address): for kstore in wallet.get_keystores(): fingerprint = kstore.get_root_fingerprint() bip32_path_prefix = kstore.get_derivation_prefix() - derivation_path = bip32.convert_bip32_path_to_list_of_uint32(bip32_path_prefix) + derivation_path = bip32.convert_bip32_strpath_to_intpath(bip32_path_prefix) # Jade only understands standard xtypes, so convert here node = bip32.BIP32Node.from_xkey(kstore.xpub) @@ -169,7 +169,7 @@ class Jade_Client(HardwareClientBase): self.authenticate() # Jade only provides traditional xpubs ... - path = bip32.convert_bip32_path_to_list_of_uint32(bip32_path) + path = bip32.convert_bip32_strpath_to_intpath(bip32_path) xpub = self.jade.get_xpub(self._network(), path) # ... so convert to relevant xtype locally @@ -180,7 +180,7 @@ class Jade_Client(HardwareClientBase): def sign_message(self, bip32_path_prefix, sequence, message): self.authenticate() - path = bip32.convert_bip32_path_to_list_of_uint32(bip32_path_prefix) + path = bip32.convert_bip32_strpath_to_intpath(bip32_path_prefix) path.extend(sequence) if isinstance(message, bytes) or isinstance(message, bytearray): @@ -214,7 +214,7 @@ class Jade_Client(HardwareClientBase): @runs_in_hwd_thread def show_address(self, bip32_path_prefix, sequence, txin_type): self.authenticate() - path = bip32.convert_bip32_path_to_list_of_uint32(bip32_path_prefix) + path = bip32.convert_bip32_strpath_to_intpath(bip32_path_prefix) path.extend(sequence) script_variant = self._convertAddrType(txin_type, multisig=False) address = self.jade.get_receive_address(self._network(), path, variant=script_variant) diff --git a/electrum/plugins/keepkey/clientbase.py b/electrum/plugins/keepkey/clientbase.py index 5fa2339d7..4c0257860 100644 --- a/electrum/plugins/keepkey/clientbase.py +++ b/electrum/plugins/keepkey/clientbase.py @@ -6,7 +6,7 @@ from electrum import ecc from electrum.i18n import _ from electrum.util import UserCancelled from electrum.keystore import bip39_normalize_passphrase -from electrum.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32 +from electrum.bip32 import BIP32Node, convert_bip32_strpath_to_intpath from electrum.logging import Logger from electrum.plugin import runs_in_hwd_thread from electrum.plugins.hw_wallet.plugin import HardwareClientBase, HardwareHandlerBase @@ -154,7 +154,7 @@ class KeepKeyClientBase(HardwareClientBase, GuiMixin, Logger): @staticmethod def expand_path(n): - return convert_bip32_path_to_list_of_uint32(n) + return convert_bip32_strpath_to_intpath(n) @runs_in_hwd_thread def cancel(self): diff --git a/electrum/plugins/ledger/ledger.py b/electrum/plugins/ledger/ledger.py index 5b1d213db..9ccf950f4 100644 --- a/electrum/plugins/ledger/ledger.py +++ b/electrum/plugins/ledger/ledger.py @@ -431,7 +431,7 @@ class Ledger_Client_Legacy(Ledger_Client): if xtype in ['p2wpkh-p2sh', 'p2wsh-p2sh'] and not self.supports_segwit(): raise UserFacingException(MSG_NEEDS_FW_UPDATE_SEGWIT) bip32_path = bip32.normalize_bip32_derivation(bip32_path) - bip32_intpath = bip32.convert_bip32_path_to_list_of_uint32(bip32_path) + bip32_intpath = bip32.convert_bip32_strpath_to_intpath(bip32_path) bip32_path = bip32_path[2:] # cut off "m/" if len(bip32_intpath) >= 1: prevPath = bip32.convert_bip32_intpath_to_strpath(bip32_intpath[:-1])[2:] diff --git a/electrum/plugins/safe_t/clientbase.py b/electrum/plugins/safe_t/clientbase.py index 4878a7e63..9ff5361d3 100644 --- a/electrum/plugins/safe_t/clientbase.py +++ b/electrum/plugins/safe_t/clientbase.py @@ -6,7 +6,7 @@ from electrum import ecc from electrum.i18n import _ from electrum.util import UserCancelled from electrum.keystore import bip39_normalize_passphrase -from electrum.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32 +from electrum.bip32 import BIP32Node, convert_bip32_strpath_to_intpath from electrum.logging import Logger from electrum.plugin import runs_in_hwd_thread from electrum.plugins.hw_wallet.plugin import HardwareClientBase, HardwareHandlerBase @@ -156,7 +156,7 @@ class SafeTClientBase(HardwareClientBase, GuiMixin, Logger): @staticmethod def expand_path(n): - return convert_bip32_path_to_list_of_uint32(n) + return convert_bip32_strpath_to_intpath(n) @runs_in_hwd_thread def cancel(self): diff --git a/electrum/plugins/trezor/clientbase.py b/electrum/plugins/trezor/clientbase.py index d3297bcfb..30ee4fdd0 100644 --- a/electrum/plugins/trezor/clientbase.py +++ b/electrum/plugins/trezor/clientbase.py @@ -5,7 +5,7 @@ from electrum import ecc from electrum.i18n import _ from electrum.util import UserCancelled, UserFacingException from electrum.keystore import bip39_normalize_passphrase -from electrum.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32 as parse_path +from electrum.bip32 import BIP32Node, convert_bip32_strpath_to_intpath as parse_path from electrum.logging import Logger from electrum.plugin import runs_in_hwd_thread from electrum.plugins.hw_wallet.plugin import OutdatedHwFirmwareException, HardwareClientBase diff --git a/electrum/plugins/trezor/trezor.py b/electrum/plugins/trezor/trezor.py index 390a812fa..6170ea2d3 100644 --- a/electrum/plugins/trezor/trezor.py +++ b/electrum/plugins/trezor/trezor.py @@ -3,7 +3,7 @@ import sys from typing import NamedTuple, Any, Optional, Dict, Union, List, Tuple, TYPE_CHECKING, Sequence from electrum.util import bfh, versiontuple, UserCancelled, UserFacingException -from electrum.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32 as parse_path +from electrum.bip32 import BIP32Node from electrum import descriptor from electrum import constants from electrum.i18n import _ diff --git a/electrum/tests/test_bitcoin.py b/electrum/tests/test_bitcoin.py index c3026a0d2..5699902c4 100644 --- a/electrum/tests/test_bitcoin.py +++ b/electrum/tests/test_bitcoin.py @@ -15,7 +15,7 @@ from electrum import segwit_addr from electrum.segwit_addr import DecodedBech32 from electrum.bip32 import (BIP32Node, convert_bip32_intpath_to_strpath, xpub_from_xprv, xpub_type, is_xprv, is_bip32_derivation, - is_xpub, convert_bip32_path_to_list_of_uint32, + is_xpub, convert_bip32_strpath_to_intpath, normalize_bip32_derivation, is_all_public_derivation) from electrum.crypto import sha256d, SUPPORTED_PW_HASH_VERSIONS from electrum import ecc, crypto, constants @@ -760,7 +760,7 @@ class Test_xprv_xpub(ElectrumTestCase): def _do_test_bip32(self, seed: str, sequence: str): node = BIP32Node.from_rootseed(bfh(seed), xtype='standard') xprv, xpub = node.to_xprv(), node.to_xpub() - int_path = convert_bip32_path_to_list_of_uint32(sequence) + int_path = convert_bip32_strpath_to_intpath(sequence) for n in int_path: if n & bip32.BIP32_PRIME == 0: xpub2 = BIP32Node.from_xkey(xpub).subkey_at_public_derivation([n]).to_xpub() @@ -852,10 +852,10 @@ class Test_xprv_xpub(ElectrumTestCase): self.assertFalse(is_bip32_derivation("m/q8462")) self.assertFalse(is_bip32_derivation("m/-8h")) - def test_convert_bip32_path_to_list_of_uint32(self): - self.assertEqual([0, 0x80000001, 0x80000001], convert_bip32_path_to_list_of_uint32("m/0/-1/1'")) - self.assertEqual([], convert_bip32_path_to_list_of_uint32("m/")) - self.assertEqual([2147483692, 2147488889, 221], convert_bip32_path_to_list_of_uint32("m/44'/5241h/221")) + def test_convert_bip32_strpath_to_intpath(self): + self.assertEqual([0, 0x80000001, 0x80000001], convert_bip32_strpath_to_intpath("m/0/-1/1'")) + self.assertEqual([], convert_bip32_strpath_to_intpath("m/")) + self.assertEqual([2147483692, 2147488889, 221], convert_bip32_strpath_to_intpath("m/44'/5241h/221")) def test_convert_bip32_intpath_to_strpath(self): self.assertEqual("m/0/1h/1h", convert_bip32_intpath_to_strpath([0, 0x80000001, 0x80000001])) diff --git a/electrum/wallet.py b/electrum/wallet.py index ac5aac422..17f083f21 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -50,7 +50,7 @@ import asyncio from aiorpcx import timeout_after, TaskTimeout, ignore_after, run_in_thread from .i18n import _ -from .bip32 import BIP32Node, convert_bip32_intpath_to_strpath, convert_bip32_path_to_list_of_uint32 +from .bip32 import BIP32Node, convert_bip32_intpath_to_strpath, convert_bip32_strpath_to_intpath from .crypto import sha256 from . import util from .util import (NotEnoughFunds, UserCancelled, profiler, OldTaskGroup, ignore_exceptions, @@ -3298,7 +3298,7 @@ class Deterministic_Wallet(Abstract_Wallet): def export_private_key_for_path(self, path: Union[Sequence[int], str], password: Optional[str]) -> str: if isinstance(path, str): - path = convert_bip32_path_to_list_of_uint32(path) + path = convert_bip32_strpath_to_intpath(path) pk, compressed = self.keystore.get_private_key(path, password) txin_type = self.get_txin_type() # assumes no mixed-scripts in wallet return bitcoin.serialize_privkey(pk, compressed, txin_type)