Switch hardened derivation marker to h in descriptors

This makes it easier to handle descriptor strings manually. E.g. an RPC call that takes an array of descriptors can now use '["desc": ".../0h/..."]'.

Both markers can still be parsed. The default for new descriptors is changed to h. In normalized form h is also used. For private keys the chosen marker is preserved in a round trip.

The hdkeypath field in getaddressinfo is also impacted by this change.
This commit is contained in:
Sjors Provoost
2023-04-04 18:33:08 +02:00
parent fe1b325688
commit bd13dc2f46
20 changed files with 161 additions and 142 deletions

View File

@@ -60,43 +60,43 @@ class WalletDescriptorTest(BitcoinTestFramework):
addr = self.nodes[0].getnewaddress("", "legacy")
addr_info = self.nodes[0].getaddressinfo(addr)
assert addr_info['desc'].startswith('pkh(')
assert_equal(addr_info['hdkeypath'], 'm/44\'/1\'/0\'/0/0')
assert_equal(addr_info['hdkeypath'], 'm/44h/1h/0h/0/0')
addr = self.nodes[0].getnewaddress("", "p2sh-segwit")
addr_info = self.nodes[0].getaddressinfo(addr)
assert addr_info['desc'].startswith('sh(wpkh(')
assert_equal(addr_info['hdkeypath'], 'm/49\'/1\'/0\'/0/0')
assert_equal(addr_info['hdkeypath'], 'm/49h/1h/0h/0/0')
addr = self.nodes[0].getnewaddress("", "bech32")
addr_info = self.nodes[0].getaddressinfo(addr)
assert addr_info['desc'].startswith('wpkh(')
assert_equal(addr_info['hdkeypath'], 'm/84\'/1\'/0\'/0/0')
assert_equal(addr_info['hdkeypath'], 'm/84h/1h/0h/0/0')
addr = self.nodes[0].getnewaddress("", "bech32m")
addr_info = self.nodes[0].getaddressinfo(addr)
assert addr_info['desc'].startswith('tr(')
assert_equal(addr_info['hdkeypath'], 'm/86\'/1\'/0\'/0/0')
assert_equal(addr_info['hdkeypath'], 'm/86h/1h/0h/0/0')
# Check that getrawchangeaddress works
addr = self.nodes[0].getrawchangeaddress("legacy")
addr_info = self.nodes[0].getaddressinfo(addr)
assert addr_info['desc'].startswith('pkh(')
assert_equal(addr_info['hdkeypath'], 'm/44\'/1\'/0\'/1/0')
assert_equal(addr_info['hdkeypath'], 'm/44h/1h/0h/1/0')
addr = self.nodes[0].getrawchangeaddress("p2sh-segwit")
addr_info = self.nodes[0].getaddressinfo(addr)
assert addr_info['desc'].startswith('sh(wpkh(')
assert_equal(addr_info['hdkeypath'], 'm/49\'/1\'/0\'/1/0')
assert_equal(addr_info['hdkeypath'], 'm/49h/1h/0h/1/0')
addr = self.nodes[0].getrawchangeaddress("bech32")
addr_info = self.nodes[0].getaddressinfo(addr)
assert addr_info['desc'].startswith('wpkh(')
assert_equal(addr_info['hdkeypath'], 'm/84\'/1\'/0\'/1/0')
assert_equal(addr_info['hdkeypath'], 'm/84h/1h/0h/1/0')
addr = self.nodes[0].getrawchangeaddress("bech32m")
addr_info = self.nodes[0].getaddressinfo(addr)
assert addr_info['desc'].startswith('tr(')
assert_equal(addr_info['hdkeypath'], 'm/86\'/1\'/0\'/1/0')
assert_equal(addr_info['hdkeypath'], 'm/86h/1h/0h/1/0')
# Make a wallet to receive coins at
self.nodes[0].createwallet(wallet_name="desc2", descriptors=True)
@@ -178,14 +178,14 @@ class WalletDescriptorTest(BitcoinTestFramework):
self.nodes[0].createwallet(wallet_name='desc_import', disable_private_keys=True, descriptors=True)
imp_rpc = self.nodes[0].get_wallet_rpc('desc_import')
addr_types = [('legacy', False, 'pkh(', '44\'/1\'/0\'', -13),
('p2sh-segwit', False, 'sh(wpkh(', '49\'/1\'/0\'', -14),
('bech32', False, 'wpkh(', '84\'/1\'/0\'', -13),
('bech32m', False, 'tr(', '86\'/1\'/0\'', -13),
('legacy', True, 'pkh(', '44\'/1\'/0\'', -13),
('p2sh-segwit', True, 'sh(wpkh(', '49\'/1\'/0\'', -14),
('bech32', True, 'wpkh(', '84\'/1\'/0\'', -13),
('bech32m', True, 'tr(', '86\'/1\'/0\'', -13)]
addr_types = [('legacy', False, 'pkh(', '44h/1h/0h', -13),
('p2sh-segwit', False, 'sh(wpkh(', '49h/1h/0h', -14),
('bech32', False, 'wpkh(', '84h/1h/0h', -13),
('bech32m', False, 'tr(', '86h/1h/0h', -13),
('legacy', True, 'pkh(', '44h/1h/0h', -13),
('p2sh-segwit', True, 'sh(wpkh(', '49h/1h/0h', -14),
('bech32', True, 'wpkh(', '84h/1h/0h', -13),
('bech32m', True, 'tr(', '86h/1h/0h', -13)]
for addr_type, internal, desc_prefix, deriv_path, int_idx in addr_types:
int_str = 'internal' if internal else 'external'