Skip to content

Commit e67740b

Browse files
committed
descriptor: add tests for the number of keys in a descriptor
In particular, ensure that ct() blinding keys are not returned as regular keys.
1 parent 1c3c74b commit e67740b

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

src/test/test_descriptor.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -238,63 +238,81 @@ def test_features_and_depth(self):
238238
k1 = 'xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB'
239239
k2 = 'xprvA2YKGLieCs6cWCiczALiH1jzk3VCCS5M1pGQfWPkamCdR9UpBgE2Gb8AKAyVjKHkz8v37avcfRjdcnP19dVAmZrvZQfvTcXXSAiFNQ6tTtU'
240240
# Valid args
241+
# descriptor, flags, expected_features, expected_depth, expected keys
241242
cases = [
242243
# Bip32 xpub
243244
(f'pkh({k1})',
244-
0, MS_IS_DESCRIPTOR, 2),
245+
0, MS_IS_DESCRIPTOR, 2, 1),
245246
# Bip32 xpub with range
246247
(f'pkh({k1}/*)',
247-
0, MS_IS_RANGED|MS_IS_DESCRIPTOR, 2),
248+
0, MS_IS_RANGED|MS_IS_DESCRIPTOR, 2, 1),
248249
# BIP32 xprv
249250
(f'pkh({k2}/*)',
250-
0, MS_IS_PRIVATE|MS_IS_RANGED|MS_IS_DESCRIPTOR, 2),
251+
0, MS_IS_PRIVATE|MS_IS_RANGED|MS_IS_DESCRIPTOR, 2, 1),
251252
# WIF
252253
('pkh(L1AAHuEC7XuDM7pJ7yHLEqYK1QspMo8n1kgxyZVdgvEpVC1rkUrM)',
253-
0, MS_IS_PRIVATE|MS_IS_RAW|MS_IS_DESCRIPTOR, 2),
254+
0, MS_IS_PRIVATE|MS_IS_RAW|MS_IS_DESCRIPTOR, 2, 1),
254255
# Hex pubkey, compressed
255256
('pk(03b428da420cd337c7208ed42c5331ebb407bb59ffbe3dc27936a227c619804284)',
256-
0, MS_IS_RAW|MS_IS_DESCRIPTOR, 2),
257+
0, MS_IS_RAW|MS_IS_DESCRIPTOR, 2, 1),
257258
# Hex pubkey, uncompressed
258259
('pk(0414fc03b8df87cd7b872996810db8458d61da8448e531569c8517b469a119d267be5645686309c6e6736dbd93940707cc9143d3cf29f1b877ff340e2cb2d259cf)',
259-
0, MS_IS_UNCOMPRESSED|MS_IS_RAW|MS_IS_DESCRIPTOR, 2),
260+
0, MS_IS_UNCOMPRESSED|MS_IS_RAW|MS_IS_DESCRIPTOR, 2, 1),
260261
# Miniscript
261262
('j:and_v(vdv:after(1567547623),older(2016))',
262-
MS_ONLY, 0, 3),
263+
MS_ONLY, 0, 3, 0),
263264
# pk() is both descriptor and miniscript valid and should parse as each
264265
(f'or_d(thresh(1,pk({k1})),and_v(v:thresh(1,pk({k2}/)),older(30)))',
265-
0, MS_IS_PRIVATE, 5),
266+
0, MS_IS_PRIVATE, 5, 2),
266267
(f'or_d(thresh(1,pk({k1})),and_v(v:thresh(1,pk({k2}/)),older(30)))',
267-
MS_ONLY, MS_IS_PRIVATE, 5),
268+
MS_ONLY, MS_IS_PRIVATE, 5, 2),
268269
]
269270
if is_elements_build:
270271
slip77 = 'ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))'
271272
cases.extend([
272273
# Parsing a descriptor as elements returns elements in its features
273274
(f'tr({k1})',
274-
AS_ELEMENTS, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS, 2),
275+
AS_ELEMENTS, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS, 2, 1),
275276
# el-prefixed builtins return elements in their features
276277
(f'eltr({k1})',
277-
0, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS, 2),
278+
0, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS, 2, 1),
279+
# Note that ct() blinding keys aren't returned in the key count.
278280
# slip77 builtins return elements and slip77 in their features,
279-
# and the ct() parent wrapper is included in their depth
281+
# and the ct() parent wrapper is included in their depth.
280282
(slip77,
281-
0, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS|MS_IS_SLIP77, 3),
283+
0, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS|MS_IS_SLIP77, 3, 1),
284+
# An xpub ELIP-150 key
285+
(f'ct({k1},elpkh({k1}))',
286+
0, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS|MS_IS_ELIP150, 3, 1),
287+
# A hex public ELIP-150 key.
288+
(f'ct(0286fc9a38e765d955e9b0bcc18fa9ae81b0c893e2dd1ef5542a9c73780a086b90,elpkh({k1}))',
289+
0, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS|MS_IS_ELIP150, 3, 1),
290+
# An xpriv ELIP-150 key. Note that MS_IS_PRIVATE is not
291+
# returned because the blinding key is not included in the
292+
# key count.
293+
(f'ct({k2},elpkh({k1}))',
294+
0, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS|MS_IS_ELIP150, 3, 1),
295+
# A hex private ELIP-150 key. As above MS_IS_PRIVATE is not
296+
# returned.
297+
(f'ct(c25deb86fa11e49d651d7eae27c220ef930fbd86ea023eebfa73e54875647963,elpkh({k1}))',
298+
0, MS_IS_DESCRIPTOR|MS_IS_ELEMENTS|MS_IS_ELIP150, 3, 1),
282299
])
283300

284-
for descriptor, flags, expected, expected_depth in cases:
301+
for descriptor, flags, expected_features, expected_depth, expected_keys in cases:
285302
d = c_void_p()
286303
ret = wally_descriptor_parse(descriptor, None, NETWORK_NONE, flags, d)
287304
ret, features = wally_descriptor_get_features(d)
288-
self.assertEqual((ret, features), (WALLY_OK, expected))
305+
self.assertEqual((ret, features), (WALLY_OK, expected_features))
289306
ret, depth = wally_descriptor_get_depth(d)
290307
self.assertEqual((ret, depth), (WALLY_OK, expected_depth))
308+
ret, num_keys = wally_descriptor_get_num_keys(d)
309+
self.assertEqual((ret, num_keys), (WALLY_OK, expected_keys))
291310
wally_descriptor_free(d)
292311
# Check the maximum depth parsing limit
293312
for limit, expected in [(depth-1, WALLY_EINVAL), (depth, WALLY_OK)]:
294313
ret = wally_descriptor_parse(descriptor, None, NETWORK_NONE,
295314
flags | (limit << 16), d)
296315
self.assertEqual(ret, expected)
297-
wally_descriptor_free(d)
298316

299317
# Invalid args
300318
ret, features = wally_descriptor_get_features(None) # NULL descriptor

0 commit comments

Comments
 (0)