diff options
author | Andrew Chow <github@achow101.com> | 2023-10-05 12:56:48 -0400 |
---|---|---|
committer | Andrew Chow <github@achow101.com> | 2023-10-09 14:07:37 -0400 |
commit | f895f97014ac5fac46d27725c1ea7decf7ff76d4 (patch) | |
tree | 9c5b33153d63b7ec71c629ac0a87d356650e3f13 | |
parent | 37b9b734770e855b9beff3b5085125f1420dd072 (diff) |
test: Scripts with hybrid pubkeys are migrated to watchonly
Descriptors disallows hybrid pubkeys. Anything with hybrid pubkeys
should becomes a raw() descriptor that shows up in the watchonly wallet.
-rwxr-xr-x | test/functional/wallet_migration.py | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py index bcd71197bf..286dcb5fda 100755 --- a/test/functional/wallet_migration.py +++ b/test/functional/wallet_migration.py @@ -6,8 +6,13 @@ import random import shutil -from test_framework.address import script_to_p2sh +from test_framework.address import ( + script_to_p2sh, + key_to_p2pkh, + key_to_p2wpkh, +) from test_framework.descriptors import descsum_create +from test_framework.key import ECPubKey from test_framework.test_framework import BitcoinTestFramework from test_framework.messages import COIN, CTransaction, CTxOut from test_framework.script_util import key_to_p2pkh_script, script_to_p2sh_script, script_to_p2wsh_script @@ -770,6 +775,58 @@ class WalletMigrationTest(BitcoinTestFramework): wallet.unloadwallet() + def test_hybrid_pubkey(self): + self.log.info("Test migration when wallet contains a hybrid pubkey") + + wallet = self.create_legacy_wallet("hybrid_keys") + + # Get the hybrid pubkey for one of the keys in the wallet + normal_pubkey = wallet.getaddressinfo(wallet.getnewaddress())["pubkey"] + first_byte = bytes.fromhex(normal_pubkey)[0] + 4 # Get the hybrid pubkey first byte + parsed_pubkey = ECPubKey() + parsed_pubkey.set(bytes.fromhex(normal_pubkey)) + parsed_pubkey.compressed = False + hybrid_pubkey_bytes = bytearray(parsed_pubkey.get_bytes()) + hybrid_pubkey_bytes[0] = first_byte # Make it hybrid + hybrid_pubkey = hybrid_pubkey_bytes.hex() + + # Import the hybrid pubkey + wallet.importpubkey(hybrid_pubkey) + p2pkh_addr = key_to_p2pkh(hybrid_pubkey) + p2pkh_addr_info = wallet.getaddressinfo(p2pkh_addr) + assert_equal(p2pkh_addr_info["iswatchonly"], True) + assert_equal(p2pkh_addr_info["ismine"], False) # Things involving hybrid pubkeys are not spendable + + # Also import the p2wpkh for the pubkey to make sure we don't migrate it + p2wpkh_addr = key_to_p2wpkh(hybrid_pubkey) + wallet.importaddress(p2wpkh_addr) + + migrate_info = wallet.migratewallet() + + # Both addresses should only appear in the watchonly wallet + p2pkh_addr_info = wallet.getaddressinfo(p2pkh_addr) + assert_equal(p2pkh_addr_info["iswatchonly"], False) + assert_equal(p2pkh_addr_info["ismine"], False) + p2wpkh_addr_info = wallet.getaddressinfo(p2wpkh_addr) + assert_equal(p2wpkh_addr_info["iswatchonly"], False) + assert_equal(p2wpkh_addr_info["ismine"], False) + + watchonly_wallet = self.nodes[0].get_wallet_rpc(migrate_info["watchonly_name"]) + watchonly_p2pkh_addr_info = watchonly_wallet.getaddressinfo(p2pkh_addr) + assert_equal(watchonly_p2pkh_addr_info["iswatchonly"], False) + assert_equal(watchonly_p2pkh_addr_info["ismine"], True) + watchonly_p2wpkh_addr_info = watchonly_wallet.getaddressinfo(p2wpkh_addr) + assert_equal(watchonly_p2wpkh_addr_info["iswatchonly"], False) + assert_equal(watchonly_p2wpkh_addr_info["ismine"], True) + + # There should only be raw or addr descriptors + for desc in watchonly_wallet.listdescriptors()["descriptors"]: + if desc["desc"].startswith("raw(") or desc["desc"].startswith("addr("): + continue + assert False, "Hybrid pubkey watchonly wallet has more than just raw() and addr()" + + wallet.unloadwallet() + def run_test(self): self.generate(self.nodes[0], 101) @@ -787,6 +844,7 @@ class WalletMigrationTest(BitcoinTestFramework): self.test_addressbook() self.test_migrate_raw_p2sh() self.test_conflict_txs() + self.test_hybrid_pubkey() if __name__ == '__main__': WalletMigrationTest().main() |