descriptor.py: do more validation in PubkeyProvider, and add tests
This commit is contained in:
@@ -186,6 +186,8 @@ class PubkeyProvider(object):
|
|||||||
if wildcard_count == 1:
|
if wildcard_count == 1:
|
||||||
if deriv_path[-1] != "*":
|
if deriv_path[-1] != "*":
|
||||||
raise ValueError("wildcard in descriptor only allowed in last position")
|
raise ValueError("wildcard in descriptor only allowed in last position")
|
||||||
|
if deriv_path[0] != "/":
|
||||||
|
raise ValueError(f"deriv_path suffix must start with a '/'. got {deriv_path!r}")
|
||||||
# Make ExtendedKey from pubkey if it isn't hex
|
# Make ExtendedKey from pubkey if it isn't hex
|
||||||
self.extkey = None
|
self.extkey = None
|
||||||
try:
|
try:
|
||||||
@@ -194,6 +196,8 @@ class PubkeyProvider(object):
|
|||||||
except Exception:
|
except Exception:
|
||||||
# Not hex, maybe xpub (but don't allow ypub/zpub)
|
# Not hex, maybe xpub (but don't allow ypub/zpub)
|
||||||
self.extkey = BIP32Node.from_xkey(pubkey, allow_custom_headers=False)
|
self.extkey = BIP32Node.from_xkey(pubkey, allow_custom_headers=False)
|
||||||
|
if deriv_path and self.extkey is None:
|
||||||
|
raise ValueError("deriv_path suffix present for simple pubkey")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse(cls, s: str) -> 'PubkeyProvider':
|
def parse(cls, s: str) -> 'PubkeyProvider':
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from electrum.descriptor import (
|
|||||||
PKHDescriptor,
|
PKHDescriptor,
|
||||||
WPKHDescriptor,
|
WPKHDescriptor,
|
||||||
WSHDescriptor,
|
WSHDescriptor,
|
||||||
|
PubkeyProvider,
|
||||||
)
|
)
|
||||||
from electrum import ecc
|
from electrum import ecc
|
||||||
from electrum.util import bfh
|
from electrum.util import bfh
|
||||||
@@ -335,3 +336,27 @@ class TestDescriptor(ElectrumTestCase):
|
|||||||
desc = parse_descriptor("wpkh([535e473f/0h]ypub6TLJVy4mZfqBJhoQBTgDR1TzM7s91WbVnMhZj31swV6xxPiwCqeGYrBn2dNHbDrP86qqxbM6FNTX3VjhRjNoXYyBAR5G3o75D3r2djmhZwM/0/*)")
|
desc = parse_descriptor("wpkh([535e473f/0h]ypub6TLJVy4mZfqBJhoQBTgDR1TzM7s91WbVnMhZj31swV6xxPiwCqeGYrBn2dNHbDrP86qqxbM6FNTX3VjhRjNoXYyBAR5G3o75D3r2djmhZwM/0/*)")
|
||||||
with self.assertRaises(ValueError): # only standard xpub/xprv allowed
|
with self.assertRaises(ValueError): # only standard xpub/xprv allowed
|
||||||
desc = parse_descriptor("wpkh([535e473f/0h]zpub6nAZodjgiMNf9zzX1pTqd6ZVX61ax8azhUDnWRumKVUr1VYATVoqAuqv3qKsb8WJXjxei4wei2p4vnMG9RnpKnen2kmgdhvZUmug2NnHNsr/0/*)")
|
desc = parse_descriptor("wpkh([535e473f/0h]zpub6nAZodjgiMNf9zzX1pTqd6ZVX61ax8azhUDnWRumKVUr1VYATVoqAuqv3qKsb8WJXjxei4wei2p4vnMG9RnpKnen2kmgdhvZUmug2NnHNsr/0/*)")
|
||||||
|
|
||||||
|
def test_pubkey_provider_deriv_path(self):
|
||||||
|
xpub = "xpub68W3CJPrQzHhTQcHM6tbCvNVB9ih4tbzsFBLwe7zZUj5uHuhxBUhvnXe1RQhbKCTiTj3D7kXni6yAD88i2xnjKHaJ5NqTtHawKnPFCDnmo4"
|
||||||
|
# valid:
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=xpub, deriv_path="/1/7")
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=xpub, deriv_path="/1/*")
|
||||||
|
# invalid:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=xpub, deriv_path="1")
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=xpub, deriv_path="1/7")
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=xpub, deriv_path="m/1/7")
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=xpub, deriv_path="*/7")
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=xpub, deriv_path="*/*")
|
||||||
|
|
||||||
|
pubkey_hex = "02a0507c8bb3d96dfd7731bafb0ae30e6ed10bbadd6a9f9f88eaf0602b9cc99adc"
|
||||||
|
# valid:
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=pubkey_hex, deriv_path=None)
|
||||||
|
# invalid:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
pp = PubkeyProvider(origin=None, pubkey=pubkey_hex, deriv_path="/1/7")
|
||||||
|
|||||||
Reference in New Issue
Block a user