Skip to content

Commit c7f5ec1

Browse files
committed
descriptor: add elements wallet policy tests
1 parent 3243cec commit c7f5ec1

2 files changed

Lines changed: 112 additions & 14 deletions

File tree

src/ctest/test_descriptor.c

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,34 +50,39 @@ static struct wally_map_item g_key_map_items[] = {
5050
{ B("slip77_key"), B("b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04") }
5151
};
5252

53-
static const struct wally_map g_key_map = {
54-
g_key_map_items,
55-
NUM_ELEMS(g_key_map_items),
56-
NUM_ELEMS(g_key_map_items),
57-
NULL
58-
};
59-
6053
static struct wally_map_item g_policy_map_items[] = {
54+
{ B("@B"), B("b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04") },
6155
{ B("@0"), B("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL") },
6256
{ B("@1"), B("xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU") }
6357
};
6458

59+
static struct wally_map_item g_elip150_map_items[] = {
60+
{ B("@B"), B("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL") },
61+
{ B("@0"), B("xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU") }
62+
};
63+
6564
/* key-variable maps for policy testing.
6665
* The bip refers to these as "key information vectors".
6766
*/
68-
static const struct wally_map g_policy_maps[3] = {
67+
static struct wally_map g_vars[] = {
6968
/* Standard convenience key map for more readable test cases */
70-
g_key_map,
69+
{ g_key_map_items, NUM_ELEMS(g_key_map_items), NUM_ELEMS(g_key_map_items), NULL },
7170
/* Wallet policy key map with 1 element "@0" */
72-
{ g_policy_map_items, 1, 1, NULL },
71+
{ &g_policy_map_items[1], 1, 1, NULL },
7372
/* Wallet policy key map with 2 elements "@0", "@1" */
74-
{ g_policy_map_items, 2, 2, NULL }
73+
{ &g_policy_map_items[1], 2, 2, NULL },
74+
/* Confidential wallet policy key map with 2 elements "@B", "@0" */
75+
{ &g_policy_map_items[0], 2, 2, NULL },
76+
/* Confidential wallet policy key map with 2 elements "@B", "@0" - @B is an elip150 key */
77+
{ &g_elip150_map_items[0], 2, 2, NULL }
7578
};
7679

80+
/* Indices into g_vars */
7781
#define VARS_STD 0
7882
#define VARS_P_1 1
7983
#define VARS_P_2 2
8084
#define VARS_P_B 3
85+
#define VARS_PKB 4
8186

8287
static const uint32_t g_miniscript_index_0 = 0;
8388
static const uint32_t g_miniscript_index_16 = 0x10;
@@ -1092,6 +1097,34 @@ static const struct descriptor_test {
10921097
"a9146cc69bc5443e97b8a30918cb6297ba4efb3d6dc387",
10931098
"45w36ywr", VARS_P_2
10941099
},
1100+
#ifdef BUILD_ELEMENTS
1101+
/* Elements/Confidential wallet policies */
1102+
{
1103+
"policy - single asterisk reconciliation (elements)",
1104+
"elpkh(mainnet_xpub/*)",
1105+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL, 0,
1106+
"76a914bb57ca9e62c7084081edc68d2cbc9524a523784288ac",
1107+
"j4aaf0ll", VARS_STD
1108+
}, {
1109+
"policy - single asterisk (elements)",
1110+
"elpkh(@0/*)", // Becomes "elpkh(mainnet_xpub/*)" i.e. the test case above this
1111+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL, WALLY_MINISCRIPT_POLICY_TEMPLATE,
1112+
"76a914bb57ca9e62c7084081edc68d2cbc9524a523784288ac",
1113+
"j4aaf0ll", VARS_P_1
1114+
}, {
1115+
"ct policy - reconcile 'single asterisk (elements)'",
1116+
"ct(slip77(@B),elpkh(@0/*))", // Becomes "elpkh(mainnet_xpub/*)"
1117+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL, WALLY_MINISCRIPT_POLICY_TEMPLATE,
1118+
"76a914bb57ca9e62c7084081edc68d2cbc9524a523784288ac",
1119+
"a9kmw73l", VARS_P_B
1120+
}, {
1121+
"ct policy - elip150 pkh",
1122+
"ct(@B,elpkh(@0/**))",
1123+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL, WALLY_MINISCRIPT_POLICY_TEMPLATE,
1124+
"76a91462efbe8dc3addddf826260b6be0fac3489b606e088ac",
1125+
"q5gxyjhu", VARS_PKB
1126+
},
1127+
#endif
10951128
/*
10961129
* Misc error cases (code coverage)
10971130
*/
@@ -1676,6 +1709,43 @@ static const struct descriptor_test {
16761709
"ct(0202fc9a38e765d955e9b0bcc18fa9ae81b0c893e2dd1ef5542a9c73780a086b90,elwpkh(key_4))",
16771710
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL, 0, NULL, "", VARS_STD
16781711
}
1712+
/* Elements/Confidential wallet policy error cases */
1713+
, {
1714+
"ct policy errchk - No substitutions",
1715+
"ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elpkh(xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))",
1716+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL,
1717+
WALLY_MINISCRIPT_POLICY_TEMPLATE, NULL, "", VARS_P_1
1718+
}, {
1719+
"ct policy errchk - No blinding key substitution",
1720+
"ct(slip77(b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04),elpkh(@0/**))",
1721+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL,
1722+
WALLY_MINISCRIPT_POLICY_TEMPLATE, NULL, "", VARS_P_B
1723+
}, {
1724+
"ct policy errchk - No blinding key in vars",
1725+
"ct(slip77(@B),elpkh(@0/**))",
1726+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL,
1727+
WALLY_MINISCRIPT_POLICY_TEMPLATE, NULL, "", VARS_P_1
1728+
}, {
1729+
"ct policy errchk - blinding key with child path",
1730+
"ct(slip77(@B/**),elpkh(@0/**))",
1731+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL,
1732+
WALLY_MINISCRIPT_POLICY_TEMPLATE, NULL, "", VARS_P_B
1733+
}, {
1734+
"ct policy errchk - key without child path",
1735+
"ct(slip77(@B),elpkh(@0))",
1736+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL,
1737+
WALLY_MINISCRIPT_POLICY_TEMPLATE, NULL, "", VARS_P_B
1738+
}, {
1739+
"ct policy errchk - elip150 blinding key with child path",
1740+
"ct(@B/**,elpkh(@0/**))",
1741+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL,
1742+
WALLY_MINISCRIPT_POLICY_TEMPLATE, NULL, "", VARS_PKB
1743+
}, {
1744+
"ct policy errchk - elip150 with no blinding key substitution",
1745+
"ct(@0/**,elpkh(@1/**))",
1746+
WALLY_NETWORK_LIQUID, 0, 0, 0, NULL,
1747+
WALLY_MINISCRIPT_POLICY_TEMPLATE, NULL, "", VARS_P_2
1748+
},
16791749
#endif /* BUILD_ELEMENTS */
16801750
};
16811751

@@ -2270,7 +2340,7 @@ static bool check_descriptor_to_script(const struct descriptor_test* test)
22702340
uint32_t multi_index = 0;
22712341
uint32_t child_num = test->child_num ? *test->child_num : 0, features;
22722342
const bool is_policy = test->flags & WALLY_MINISCRIPT_POLICY_TEMPLATE;
2273-
const struct wally_map *keys = &g_policy_maps[test->policy_map_index];
2343+
const struct wally_map *keys = &g_vars[test->policy_map_index];
22742344

22752345
/* Parse the descriptor. */
22762346
expected_ret = test->script ? WALLY_OK : WALLY_EINVAL;
@@ -2416,8 +2486,8 @@ static bool check_descriptor_to_address(const struct address_test *test)
24162486
size_t i;
24172487
int ret, expected_ret = *test->addresses[0] ? WALLY_OK : WALLY_EINVAL;
24182488

2419-
ret = wally_descriptor_parse(test->descriptor, &g_key_map, test->network,
2420-
flags, &descriptor);
2489+
ret = wally_descriptor_parse(test->descriptor, &g_vars[VARS_STD],
2490+
test->network, flags, &descriptor);
24212491

24222492
if (expected_ret == WALLY_OK || ret == expected_ret) {
24232493
/* For failure cases, we may fail when generating instead of parsing,

src/test/test_descriptor.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ def test_features_and_depth(self):
338338
def test_policy(self):
339339
"""Test policy parsing"""
340340
# Substitution variables
341+
slip77 = 'b2396b3ee20509cdb64fe24180a14a72dbd671728eaa49bac69d2bdecb5f5a04'
341342
xpriv = 'xprvA2YKGLieCs6cWCiczALiH1jzk3VCCS5M1pGQfWPkamCdR9UpBgE2Gb8AKAyVjKHkz8v37avcfRjdcnP19dVAmZrvZQfvTcXXSAiFNQ6tTtU'
342343
xpub1 = 'xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL'
343344
xpub2 = 'xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU'
@@ -385,6 +386,33 @@ def make_keys(xpubs):
385386
self.assertEqual(ret, WALLY_EINVAL)
386387
wally_map_free(keys)
387388

389+
# Elements confidential policy parsing"""
390+
if not wally_is_elements_build()[1]:
391+
return # Not enabled
392+
393+
P = POLICY
394+
cases = [
395+
# slip77 with a 64 byte hex slip77 blinding key
396+
[P, 'ct(slip77(@B),elpkh(@0/*))', {'@B': slip77, '@0': xpub1}],
397+
# elip150 with a 64 byte hex private blinding key
398+
[P, 'ct(@B,elpkh(@0/*))', {'@B': slip77, '@0': xpub1}],
399+
# elip150 with an xpub blinding key
400+
[P, 'ct(@B,elpkh(@0/*))', {'@B': xpub1, '@0': xpub2}],
401+
]
402+
d = c_void_p()
403+
for flags, policy, key_items in cases:
404+
keys = wally_map_from_dict(key_items)
405+
ret = wally_descriptor_parse(policy, keys, NETWORK_LIQUID, flags, d)
406+
self.assertEqual(ret, WALLY_OK)
407+
ret, num_keys = wally_descriptor_get_num_keys(d)
408+
self.assertEqual((ret, num_keys), (WALLY_OK, 1)) # Only non-blinding
409+
ret, key_str = wally_descriptor_get_key(d, 0)
410+
self.assertEqual((ret, key_str), (WALLY_OK, key_items['@0']))
411+
ret, key_info = wally_descriptor_get_key(d, BLINDING_KEY_INDEX)
412+
self.assertEqual((ret, key_info), (WALLY_OK, key_items['@B']))
413+
wally_map_free(keys)
414+
wally_descriptor_free(d)
415+
388416
def test_key_iteration(self):
389417
"""Test iterating descriptor keys"""
390418
origin_fp = 'd34db33f'

0 commit comments

Comments
 (0)