bitcoin.py: add helper func: neuter_bitcoin_address

This commit is contained in:
SomberNight
2026-04-20 13:27:21 +00:00
parent 45458c2f89
commit 68e6995a3c
3 changed files with 18 additions and 6 deletions
+13 -2
View File
@@ -439,7 +439,7 @@ def script_to_address(script: bytes, *, net=None) -> Optional[str]:
def address_to_script(addr: str, *, net=None) -> bytes:
if net is None: net = constants.net
if not is_address(addr, net=net):
raise BitcoinException(f"invalid bitcoin address: {addr}")
raise BitcoinException(f"invalid bitcoin address: {neuter_bitcoin_address(addr)}")
witver, witprog = segwit_addr.decode_segwit_address(net.SEGWIT_HRP, addr)
if witprog is not None:
if not (0 <= witver <= 16):
@@ -455,6 +455,17 @@ def address_to_script(addr: str, *, net=None) -> bytes:
return script
def neuter_bitcoin_address(addr: str) -> str:
"""Truncate a bitcoin address, for display in errors that might get sent to the crash reporter,
to reduce harm to the user's privacy.
"""
assert isinstance(addr, str), type(addr)
if len(addr) <= 7:
return addr
neutered_addr = addr[:5] + '..' + addr[-2:]
return f"{neutered_addr!r} (len={len(addr)})"
class OnchainOutputType(Enum):
"""Opaque types of scriptPubKeys.
In case of p2sh, p2wsh and similar, no knowledge of redeem script, etc.
@@ -470,7 +481,7 @@ def address_to_payload(addr: str, *, net=None) -> Tuple[OnchainOutputType, bytes
"""Return (type, pubkey hash / witness program) for an address."""
if net is None: net = constants.net
if not is_address(addr, net=net):
raise BitcoinException(f"invalid bitcoin address: {addr}")
raise BitcoinException(f"invalid bitcoin address: {neuter_bitcoin_address(addr)}")
witver, witprog = segwit_addr.decode_segwit_address(net.SEGWIT_HRP, addr)
if witprog is not None:
if witver == 0:
+3 -3
View File
@@ -33,7 +33,7 @@ from aiorpcx import run_in_thread, RPCError
from . import util
from .transaction import Transaction, PartialTransaction
from .util import make_aiohttp_session, NetworkJobOnDefaultServer, random_shuffled_copy, OldTaskGroup
from .bitcoin import address_to_scripthash, is_address
from .bitcoin import address_to_scripthash, is_address, neuter_bitcoin_address
from .logging import Logger
from .interface import GracefulDisconnect, NetworkTimeout
@@ -84,12 +84,12 @@ class SynchronizerBase(NetworkJobOnDefaultServer):
self.session.unsubscribe(self.status_queue)
def add(self, addr: str) -> None:
if not is_address(addr): raise ValueError(f"invalid bitcoin address {addr}")
if not is_address(addr): raise ValueError(f"invalid bitcoin address {neuter_bitcoin_address(addr)}")
self._adding_addrs.add(addr) # this lets is_up_to_date already know about addr
async def _add_address(self, addr: str):
try:
if not is_address(addr): raise ValueError(f"invalid bitcoin address {addr}")
if not is_address(addr): raise ValueError(f"invalid bitcoin address {neuter_bitcoin_address(addr)}")
if addr in self.requested_addrs: return
self.requested_addrs.add(addr)
await self.taskgroup.spawn(self._subscribe_to_address, addr)
+2 -1
View File
@@ -1415,9 +1415,10 @@ class WalletDBUpgrader(Logger):
if len(recv_addrs) > 0:
first_address = recv_addrs[0]
if not bitcoin.is_address(first_address):
neutered_addr = first_address[:5] + '..' + first_address[-2:]
raise WalletFileException(
f"The addresses in this wallet are not bitcoin addresses. "
f"e.g. {first_address!r}")
f"e.g. {neutered_addr} (len={len(first_address)})")
# if so, save genesis hash
self.data['genesis_blockhash'] = constants.net.GENESIS
self.data['seed_version'] = 71