tests: update main test suite with descriptor parsing changes
What changed, and why it matters
This commit only updates the project's test file (test_jade.py). It adjusts test cases and adds new tests for how Bitcoin/Liquid wallet descriptors are parsed and validated, including new rules around SLIP-77 blinding keys on Liquid. There is no change to production firmware or wallet code in this commit, so it does not introduce or fix a runtime security vulnerability by itself.
No security action required for this commit. Treat as ordinary test maintenance. If reviewing the broader feature, verify that the corresponding production-code changes correctly enforce the new descriptor/SLIP-77 rules.
Security signals we found
Test-only change with no production code modifications
New test coverage for descriptor parsing network rules
SLIP-77 blinding-key requirement enforced for Liquid descriptors
Confidential descriptors rejected for non-Liquid networks
Evidence from the diff
The diff is confined to test_jade.py. It renumbers existing negative test cases, introduces a LIQUID_DESCRIPTORS feature flag, and adds test_descriptor_slip77_network_rules() to assert that: (1) Liquid descriptors must include a SLIP-77 blinding key, (2) non-Liquid descriptors must not be confidential, and (3) when LIQUID_DESCRIPTORS is disabled, Liquid descriptors are rejected up-front. The actual enforcement logic is not present in this commit; only the test expectations are updated.
Changed components
test_jade.pyInspect captured patch +73 / −18
diff --git a/test_jade.py b/test_jade.py
index bdad78b..61f21dd 100644
--- a/test_jade.py
+++ b/test_jade.py
@@ -19,6 +19,8 @@ from pinserver.pindb import PINDb
import wallycore as wally
from jadepy.jade import JadeAPI, JadeError
+LIQUID_DESCRIPTORS = True
+
# Enable jade logging
jadehandler = logging.StreamHandler()
@@ -1306,12 +1308,9 @@ HmWPvgD3hiTnD5KZuMkxSUsgGraZ9vavB5JSA3F9s5E4cXuCte5rvBs5N4DjfxYssQk1L82Bq4FE"
'datavalues': {'@0': DESCR_SIGNER, '@1': DESCR_SIGNER}}),
'Failed to parse descriptor'),
(('baddescr17', 'register_descriptor',
- {'network': 'liquid', 'descriptor_name': 'isgood', 'descriptor': DESCRIPTOR,
- 'datavalues': {'@0': DESCR_SIGNER}}), 'not supported on liquid'),
- (('baddescr18', 'register_descriptor',
{'network': 'testnet', 'descriptor_name': 'too_few', 'descriptor': 'test',
'datavalues': {}}), 'Failed to extract valid parameter values'),
- (('baddescr19', 'register_descriptor',
+ (('baddescr18', 'register_descriptor',
{'network': 'testnet', 'descriptor_name': 'too_many', 'descriptor': 'test',
'datavalues': {"%15d" % i: "x" * 159 for i in range(16)}}),
'Failed to extract valid parameter values'),
@@ -1366,9 +1365,6 @@ HmWPvgD3hiTnD5KZuMkxSUsgGraZ9vavB5JSA3F9s5E4cXuCte5rvBs5N4DjfxYssQk1L82Bq4FE"
{'branch': 0, 'pointer': 1, 'descriptor_name': 'does not exist',
'network': 'testnet'}), 'Cannot find named descriptor wallet'),
(('badrecvaddr17', 'get_receive_address',
- {'branch': 0, 'pointer': 1, 'descriptor_name': 'looksvalid',
- 'network': 'liquid'}), 'not supported on liquid'),
- (('badrecvaddr18', 'get_receive_address',
{'path': [1, 2, 3], 'variant': 'pkh(k)', 'confidential': True,
'network': 'mainnet'}), 'Confidential addresses only apply to liquid'),
@@ -1729,6 +1725,16 @@ HmWPvgD3hiTnD5KZuMkxSUsgGraZ9vavB5JSA3F9s5E4cXuCte5rvBs5N4DjfxYssQk1L82Bq4FE"
{'network': 'testnet', 'txn': GOODTX, 'num_inputs': 1,
'change': [None, None]}), 'Unexpected number of output entries')]
+ if not LIQUID_DESCRIPTORS:
+ bad_params.extend([
+ (('baddescr19', 'register_descriptor',
+ {'network': 'liquid', 'descriptor_name': 'isgood', 'descriptor': DESCRIPTOR,
+ 'datavalues': {'@0': DESCR_SIGNER}}), 'not supported on liquid'),
+ (('badrecvaddr18', 'get_receive_address',
+ {'branch': 0, 'pointer': 1, 'descriptor_name': 'looksvalid',
+ 'network': 'liquid'}), 'not supported on liquid'),
+ ])
+
# Test all the simple cases
for badmsg, errormsg in bad_params:
if (args.libjade or args.spts) and badmsg[1] in ['ota', 'ota_delta']:
@@ -2078,33 +2084,36 @@ dab03ecc4ae0b5e77c4fc0e5cf6c95a0100000000000f4240000000000000')
{'network': 'localtest-liquid', 'txn': GOODTX,
'num_inputs': 1, 'trusted_commitments': [{}, {}],
'change': [{}, {}]}), 'Failed to extract valid receive path'),
- (('badsignliq19', 'sign_liquid_tx', # descriptor wallet
- {'network': 'localtest-liquid', 'txn': GOODTX,
- 'num_inputs': 1, 'trusted_commitments': [{}, {}],
- 'change': [{'descriptor_name': 'looksvalid', 'is_change': True,
- 'branch': 1, 'pointer': 13}, {}]}), 'not supported on liquid'),
-
- (('badsignliq20', 'sign_liquid_tx',
+ (('badsignliq19', 'sign_liquid_tx',
{'network': 'localtest-liquid', 'txn': GOODTX,
'num_inputs': 1, 'trusted_commitments': GOOD_COMMITMENTS,
'change': None, 'asset_info': [BAD_ASSET1]}), 'Invalid asset info passed'),
- (('badsignliq21', 'sign_liquid_tx',
+ (('badsignliq20', 'sign_liquid_tx',
{'network': 'localtest-liquid', 'txn': GOODTX,
'num_inputs': 1, 'trusted_commitments': GOOD_COMMITMENTS,
'change': None, 'asset_info': [BAD_ASSET2]}), 'Invalid asset info passed'),
- (('badsignliq22', 'sign_liquid_tx',
+ (('badsignliq21', 'sign_liquid_tx',
{'network': 'localtest-liquid', 'txn': GOODTX,
'num_inputs': 1, 'trusted_commitments': GOOD_COMMITMENTS,
'change': None, 'asset_info': [BAD_ASSET3]}), 'Invalid asset info passed'),
- (('badsignliq23', 'sign_liquid_tx',
+ (('badsignliq22', 'sign_liquid_tx',
{'network': 'localtest-liquid', 'txn': GOODTX,
'num_inputs': 1, 'trusted_commitments': GOOD_COMMITMENTS,
'change': None, 'asset_info': [BAD_ASSET4]}), 'Invalid asset info passed'),
- (('badsignliq24', 'sign_liquid_tx',
+ (('badsignliq23', 'sign_liquid_tx',
{'network': 'localtest-liquid', 'txn': GOODTX,
'num_inputs': 1, 'trusted_commitments': GOOD_COMMITMENTS,
'change': None, 'asset_info': [BAD_ASSET5]}), 'Invalid asset info passed')]
+ if not LIQUID_DESCRIPTORS:
+ bad_params.append(
+ (('badsignliq24', 'sign_liquid_tx',
+ {'network': 'localtest-liquid', 'txn': GOODTX,
+ 'num_inputs': 1, 'trusted_commitments': [{}, {}],
+ 'change': [{'descriptor_name': 'looksvalid', 'is_change': True,
+ 'branch': 1, 'pointer': 13}, {}]}), 'not supported on liquid')
+ )
+
bad_liq_inputs = [(('badliqin1', 'tx_input'), 'Expecting parameters map'),
(('badliqin2', 'tx_input',
{'is_witness': True, 'path': [0]}), 'extract script'),
@@ -3494,6 +3503,7 @@ def test_miniscript_descriptor_registration(jadeapi, pattern):
for descriptor_data in _get_test_cases(pattern):
# Register the descriptor
inputdata = descriptor_data['input']
+
rslt = jadeapi.register_descriptor(inputdata['network'],
inputdata['descriptor_name'],
inputdata['descriptor'],
@@ -3547,6 +3557,50 @@ def test_miniscript_descriptor_registration(jadeapi, pattern):
assert rslt == addr_test['expected_address']
+def test_descriptor_slip77_network_rules(jadeapi):
+ descriptor_no_slip77 = 'wsh(pkh(@0/<0;1>/*))'
+ descriptor_with_slip77 = 'ct(slip77(@B),wpkh(@0/<0;1>/*))'
+ signer = "[e3ebcc79/48'/1'/0'/2']tpubDDvj9CrVJ9kWXSL2kjtA8v53rZvTmL3HmWPvgD3hiTnD5KZuMkxSUsgGra\
+Z9vavB5JSA3F9s5E4cXuCte5rvBs5N4DjfxYssQk1L82Bq4FE"
+ blinding_key = TEST_MNEMONIC_MASTER_BLINDING_KEY
+
+ if LIQUID_DESCRIPTORS:
+ # Liquid descriptor with SLIP-77 should pass
+ assert jadeapi.register_descriptor(
+ 'localtest-liquid', 'liqs77ok', descriptor_with_slip77,
+ {'@B': blinding_key, '@0': signer}) is True
+
+ # Liquid descriptor without SLIP-77 should fail.
+ _test_bad_params(
+ jadeapi.jade,
+ ('liq_s77_miss', 'register_descriptor',
+ {'network': 'localtest-liquid', 'descriptor_name': 'liqnos77',
+ 'descriptor': descriptor_no_slip77, 'datavalues': {'@0': signer}}),
+ 'must use slip77 blinding for liquid network')
+ else:
+ # Liquid descriptors disabled: reject liquid descriptors up-front
+ _test_bad_params(
+ jadeapi.jade,
+ ('liq_s77_off', 'register_descriptor',
+ {'network': 'localtest-liquid', 'descriptor_name': 'liqoff77',
+ 'descriptor': descriptor_with_slip77,
+ 'datavalues': {'@B': blinding_key, '@0': signer}}),
+ 'not supported on liquid')
+
+ # Non-liquid descriptor with SLIP-77 should fail
+ _test_bad_params(
+ jadeapi.jade,
+ ('btc_s77_bad', 'register_descriptor',
+ {'network': 'testnet', 'descriptor_name': 'btcs77bad',
+ 'descriptor': descriptor_with_slip77,
+ 'datavalues': {'@B': blinding_key, '@0': signer}}),
+ 'Descriptor must not be confidential for bitcoin network')
+
+ # Non-liquid descriptor without SLIP-77 should pass.
+ assert jadeapi.register_descriptor(
+ 'testnet', 'btcnos77', descriptor_no_slip77, {'@0': signer}) is True
+
+
def test_12word_mnemonic(jadeapi):
# Short sanity-test of 12-word mnemonic
rslt = jadeapi.set_mnemonic(TEST_MNEMONIC_12)
@@ -3869,6 +3923,7 @@ def run_api_tests(jadeapi, isble, qemu, authuser=False):
# Test descriptor wallets
test_miniscript_descriptor_registration(jadeapi, DESCRIPTOR_REG_TESTS)
+ test_descriptor_slip77_network_rules(jadeapi)
if not args.json_filter:
# Get (receive) green-addresses, get-xpub, and sign-message
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.