mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-04 21:04:58 +02:00
Merge bitcoin/bitcoin#19651: wallet: importdescriptors update existing
3efaf83c75wallet: deactivate descriptor (S3RK)6737d9655btest: wallet importdescriptors update existing (S3RK)586f1d53d6wallet: maintain SPK consistency on internal flag change (S3RK)f1b7db1474wallet: don't mute exceptions in importdescriptors (S3RK)bf68ebc1cdwallet: allow to import same descriptor twice (S3RK) Pull request description: Rationale: allow updating existing descriptors with `importdescriptors` command. Currently if you run same `importdescriptors` command twice with a descriptor containing private key you will get very confusing error — `Missing required fields`. What happens is that Wallet tries to write imported private key to the disk, but it exists already so we get `DB_KEYEXIST (-30995)` from BerkelyDB. Please note, that we set `DB_NOOVERWRITE` (I guess not to lose some keys accidentally). The exception is caught in `catch (...)` in rpcdump.cpp with a generic error. With this PR if a descriptor is already present than we will update its activeness, internalness, label, range and next_index. For the range only expansion is allowed (range start can only decrease, range end increase). ACKs for top commit: achow101: re-ACK3efaf83c75meshcollider: Code review ACK3efaf83c75jonatack: Light ACK3efaf83c75per `git range-diffa000cb05d96704 3efaf83` and as a sanity check, re-debug-built on debian with gcc 10.2.1 and clang 11, ran wallet_importdescriptors.py Tree-SHA512: 122c4b621d64ec8a3b625f3aed9f01a2b5cbaf2029ad0325b5ff38d67fff5cd35324335fabe2dd5169548b01b267c81be6ae0f5c834342f3d5f6eeed515c4843
This commit is contained in:
@@ -79,7 +79,6 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
# RPC importdescriptors -----------------------------------------------
|
||||
|
||||
# # Test import fails if no descriptor present
|
||||
key = get_generate_key()
|
||||
self.log.info("Import should fail if a descriptor is not provided")
|
||||
self.test_importdesc({"timestamp": "now"},
|
||||
success=False,
|
||||
@@ -89,10 +88,10 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
# # Test importing of a P2PKH descriptor
|
||||
key = get_generate_key()
|
||||
self.log.info("Should import a p2pkh descriptor")
|
||||
self.test_importdesc({"desc": descsum_create("pkh(" + key.pubkey + ")"),
|
||||
"timestamp": "now",
|
||||
"label": "Descriptor import test"},
|
||||
success=True)
|
||||
import_request = {"desc": descsum_create("pkh(" + key.pubkey + ")"),
|
||||
"timestamp": "now",
|
||||
"label": "Descriptor import test"}
|
||||
self.test_importdesc(import_request, success=True)
|
||||
test_address(w1,
|
||||
key.p2pkh_addr,
|
||||
solvable=True,
|
||||
@@ -100,11 +99,15 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
labels=["Descriptor import test"])
|
||||
assert_equal(w1.getwalletinfo()['keypoolsize'], 0)
|
||||
|
||||
self.log.info("Test can import same descriptor with public key twice")
|
||||
self.test_importdesc(import_request, success=True)
|
||||
|
||||
self.log.info("Test can update descriptor label")
|
||||
self.test_importdesc({**import_request, "label": "Updated label"}, success=True)
|
||||
test_address(w1, key.p2pkh_addr, solvable=True, ismine=True, labels=["Updated label"])
|
||||
|
||||
self.log.info("Internal addresses cannot have labels")
|
||||
self.test_importdesc({"desc": descsum_create("pkh(" + key.pubkey + ")"),
|
||||
"timestamp": "now",
|
||||
"internal": True,
|
||||
"label": "Descriptor import test"},
|
||||
self.test_importdesc({**import_request, "internal": True},
|
||||
success=False,
|
||||
error_code=-8,
|
||||
error_message="Internal addresses should not have a label")
|
||||
@@ -252,6 +255,39 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
self.test_importdesc({"desc": descsum_create(desc), "timestamp": "now", "range": [0, 1000001]},
|
||||
success=False, error_code=-8, error_message='Range is too large')
|
||||
|
||||
self.log.info("Verify we can only extend descriptor's range")
|
||||
range_request = {"desc": descsum_create(desc), "timestamp": "now", "range": [5, 10], 'active': True}
|
||||
self.test_importdesc(range_request, wallet=wpriv, success=True)
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 6)
|
||||
self.test_importdesc({**range_request, "range": [0, 10]}, wallet=wpriv, success=True)
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 11)
|
||||
self.test_importdesc({**range_request, "range": [0, 20]}, wallet=wpriv, success=True)
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
|
||||
# Can keep range the same
|
||||
self.test_importdesc({**range_request, "range": [0, 20]}, wallet=wpriv, success=True)
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
|
||||
|
||||
self.test_importdesc({**range_request, "range": [5, 10]}, wallet=wpriv, success=False,
|
||||
error_code=-8, error_message='new range must include current range = [0,20]')
|
||||
self.test_importdesc({**range_request, "range": [0, 10]}, wallet=wpriv, success=False,
|
||||
error_code=-8, error_message='new range must include current range = [0,20]')
|
||||
self.test_importdesc({**range_request, "range": [5, 20]}, wallet=wpriv, success=False,
|
||||
error_code=-8, error_message='new range must include current range = [0,20]')
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
|
||||
|
||||
self.log.info("Check we can change descriptor internal flag")
|
||||
self.test_importdesc({**range_request, "range": [0, 20], "internal": True}, wallet=wpriv, success=True)
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 0)
|
||||
assert_raises_rpc_error(-4, 'This wallet has no available keys', wpriv.getnewaddress, '', 'p2sh-segwit')
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize_hd_internal'], 21)
|
||||
wpriv.getrawchangeaddress('p2sh-segwit')
|
||||
|
||||
self.test_importdesc({**range_request, "range": [0, 20], "internal": False}, wallet=wpriv, success=True)
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize'], 21)
|
||||
wpriv.getnewaddress('', 'p2sh-segwit')
|
||||
assert_equal(wpriv.getwalletinfo()['keypoolsize_hd_internal'], 0)
|
||||
assert_raises_rpc_error(-4, 'This wallet has no available keys', wpriv.getrawchangeaddress, 'p2sh-segwit')
|
||||
|
||||
# Make sure ranged imports import keys in order
|
||||
w1 = self.nodes[1].get_wallet_rpc('w1')
|
||||
self.log.info('Key ranges should be imported in order')
|
||||
@@ -303,9 +339,21 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
w1.keypoolrefill()
|
||||
assert_equal(w1.getwalletinfo()['keypoolsize'], 5 * 3)
|
||||
|
||||
self.log.info("Check we can change next_index")
|
||||
# go back and forth with next_index
|
||||
for i in [4, 0, 2, 1, 3]:
|
||||
self.test_importdesc({'desc': descsum_create('wpkh([80002067/0h/0h]' + xpub + '/*)'),
|
||||
'active': True,
|
||||
'range': [0, 9],
|
||||
'next_index': i,
|
||||
'timestamp': 'now'
|
||||
},
|
||||
success=True)
|
||||
assert_equal(w1.getnewaddress('', 'bech32'), addresses[i])
|
||||
|
||||
# Check active=False default
|
||||
self.log.info('Check imported descriptors are not active by default')
|
||||
self.test_importdesc({'desc': descsum_create('pkh([12345678/0h/0h]' + xpub + '/*)'),
|
||||
self.test_importdesc({'desc': descsum_create('pkh([12345678/1h]' + xpub + '/*)'),
|
||||
'range' : [0, 2],
|
||||
'timestamp': 'now',
|
||||
'internal': True
|
||||
@@ -313,6 +361,32 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
success=True)
|
||||
assert_raises_rpc_error(-4, 'This wallet has no available keys', w1.getrawchangeaddress, 'legacy')
|
||||
|
||||
self.log.info('Check can activate inactive descriptor')
|
||||
self.test_importdesc({'desc': descsum_create('pkh([12345678]' + xpub + '/*)'),
|
||||
'range': [0, 5],
|
||||
'active': True,
|
||||
'timestamp': 'now',
|
||||
'internal': True
|
||||
},
|
||||
success=True)
|
||||
address = w1.getrawchangeaddress('legacy')
|
||||
assert_equal(address, "mpA2Wh9dvZT7yfELq1UnrUmAoc5qCkMetg")
|
||||
|
||||
self.log.info('Check can deactivate active descriptor')
|
||||
self.test_importdesc({'desc': descsum_create('pkh([12345678]' + xpub + '/*)'),
|
||||
'range': [0, 5],
|
||||
'active': False,
|
||||
'timestamp': 'now',
|
||||
'internal': True
|
||||
},
|
||||
success=True)
|
||||
assert_raises_rpc_error(-4, 'This wallet has no available keys', w1.getrawchangeaddress, 'legacy')
|
||||
|
||||
self.log.info('Verify activation state is persistent')
|
||||
w1.unloadwallet()
|
||||
self.nodes[1].loadwallet('w1')
|
||||
assert_raises_rpc_error(-4, 'This wallet has no available keys', w1.getrawchangeaddress, 'legacy')
|
||||
|
||||
# # Test importing a descriptor containing a WIF private key
|
||||
wif_priv = "cTe1f5rdT8A8DFgVWTjyPwACsDPJM9ff4QngFxUixCSvvbg1x6sh"
|
||||
address = "2MuhcG52uHPknxDgmGPsV18jSHFBnnRgjPg"
|
||||
@@ -322,6 +396,10 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
"timestamp": "now"},
|
||||
success=True,
|
||||
wallet=wpriv)
|
||||
|
||||
self.log.info('Test can import same descriptor with private key twice')
|
||||
self.test_importdesc({"desc": descsum_create(desc), "timestamp": "now"}, success=True, wallet=wpriv)
|
||||
|
||||
test_address(wpriv,
|
||||
address,
|
||||
solvable=True,
|
||||
@@ -339,14 +417,25 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
wmulti_priv = self.nodes[1].get_wallet_rpc("wmulti_priv")
|
||||
assert_equal(wmulti_priv.getwalletinfo()['keypoolsize'], 0)
|
||||
|
||||
self.test_importdesc({"desc":"wsh(multi(2,tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52/84h/0h/0h/*,tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq/84h/0h/0h/*,tprv8ZgxMBicQKsPeonDt8Ka2mrQmHa61hQ5FQCsvWBTpSNzBFgM58cV2EuXNAHF14VawVpznnme3SuTbA62sGriwWyKifJmXntfNeK7zeqMCj1/84h/0h/0h/*))#m2sr93jn",
|
||||
xprv1 = 'tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52'
|
||||
acc_xpub1 = 'tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8' # /84'/0'/0'
|
||||
chg_xpub1 = 'tpubDCXqdwWZcszwqYJSnZp8eARkxGJfHAk23KDxbztV4BbschfaTfYLTcSkSJ3TN64dRqwa1rnFUScsYormKkGqNbbPwkorQimVevXjxzUV9Gf' # /84'/1'/0'
|
||||
xprv2 = 'tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq'
|
||||
acc_xprv2 = 'tprv8gVCsmRAxVSxyUpsL13Y7ZEWBFPWbgS5E2MmFVNGuANrknvmmn2vWnmHvU8AwEFYzR2ji6EeZLSCLVacsYkvor3Pcb5JY5FGcevqTwYvdYx'
|
||||
acc_xpub2 = 'tpubDDBF2BTR6s8drwrfDei8WxtckGuSm1cyoKxYY1QaKSBFbHBYQArWhHPA6eJrzZej6nfHGLSURYSLHr7GuYch8aY5n61tGqgn8b4cXrMuoPH'
|
||||
chg_xpub2 = 'tpubDCYfZY2ceyHzYzMMVPt9MNeiqtQ2T7Uyp9QSFwYXh8Vi9iJFYXcuphJaGXfF3jUQJi5Y3GMNXvM11gaL4txzZgNGK22BFAwMXynnzv4z2Jh'
|
||||
xprv3 = 'tprv8ZgxMBicQKsPeonDt8Ka2mrQmHa61hQ5FQCsvWBTpSNzBFgM58cV2EuXNAHF14VawVpznnme3SuTbA62sGriwWyKifJmXntfNeK7zeqMCj1'
|
||||
acc_xpub3 = 'tpubDCsWoW1kuQB9kG5MXewHqkbjPtqPueRnXju7uM2NK7y3JYb2ajAZ9EiuZXNNuE4661RAfriBWhL8UsnAPpk8zrKKnZw1Ug7X4oHgMdZiU4E'
|
||||
chg_xpub3 = 'tpubDC6UGqnsQStngYuGD4MKsMy7eD1Yg9NTJfPdvjdG2JE5oZ7EsSL3WHg4Gsw2pR5K39ZwJ46M1wZayhedVdQtMGaUhq5S23PH6fnENK3V1sb'
|
||||
|
||||
self.test_importdesc({"desc":"wsh(multi(2," + xprv1 + "/84h/0h/0h/*," + xprv2 + "/84h/0h/0h/*," + xprv3 + "/84h/0h/0h/*))#m2sr93jn",
|
||||
"active": True,
|
||||
"range": 1000,
|
||||
"next_index": 0,
|
||||
"timestamp": "now"},
|
||||
success=True,
|
||||
wallet=wmulti_priv)
|
||||
self.test_importdesc({"desc":"wsh(multi(2,tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52/84h/1h/0h/*,tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq/84h/1h/0h/*,tprv8ZgxMBicQKsPeonDt8Ka2mrQmHa61hQ5FQCsvWBTpSNzBFgM58cV2EuXNAHF14VawVpznnme3SuTbA62sGriwWyKifJmXntfNeK7zeqMCj1/84h/1h/0h/*))#q3sztvx5",
|
||||
self.test_importdesc({"desc":"wsh(multi(2," + xprv1 + "/84h/1h/0h/*," + xprv2 + "/84h/1h/0h/*," + xprv3 + "/84h/1h/0h/*))#q3sztvx5",
|
||||
"active": True,
|
||||
"internal" : True,
|
||||
"range": 1000,
|
||||
@@ -374,14 +463,14 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
wmulti_pub = self.nodes[1].get_wallet_rpc("wmulti_pub")
|
||||
assert_equal(wmulti_pub.getwalletinfo()['keypoolsize'], 0)
|
||||
|
||||
self.test_importdesc({"desc":"wsh(multi(2,[7b2d0242/84h/0h/0h]tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8/*,[59b09cd6/84h/0h/0h]tpubDDBF2BTR6s8drwrfDei8WxtckGuSm1cyoKxYY1QaKSBFbHBYQArWhHPA6eJrzZej6nfHGLSURYSLHr7GuYch8aY5n61tGqgn8b4cXrMuoPH/*,[e81a0532/84h/0h/0h]tpubDCsWoW1kuQB9kG5MXewHqkbjPtqPueRnXju7uM2NK7y3JYb2ajAZ9EiuZXNNuE4661RAfriBWhL8UsnAPpk8zrKKnZw1Ug7X4oHgMdZiU4E/*))#tsry0s5e",
|
||||
self.test_importdesc({"desc":"wsh(multi(2,[7b2d0242/84h/0h/0h]" + acc_xpub1 + "/*,[59b09cd6/84h/0h/0h]" + acc_xpub2 + "/*,[e81a0532/84h/0h/0h]" + acc_xpub3 +"/*))#tsry0s5e",
|
||||
"active": True,
|
||||
"range": 1000,
|
||||
"next_index": 0,
|
||||
"timestamp": "now"},
|
||||
success=True,
|
||||
wallet=wmulti_pub)
|
||||
self.test_importdesc({"desc":"wsh(multi(2,[7b2d0242/84h/1h/0h]tpubDCXqdwWZcszwqYJSnZp8eARkxGJfHAk23KDxbztV4BbschfaTfYLTcSkSJ3TN64dRqwa1rnFUScsYormKkGqNbbPwkorQimVevXjxzUV9Gf/*,[59b09cd6/84h/1h/0h]tpubDCYfZY2ceyHzYzMMVPt9MNeiqtQ2T7Uyp9QSFwYXh8Vi9iJFYXcuphJaGXfF3jUQJi5Y3GMNXvM11gaL4txzZgNGK22BFAwMXynnzv4z2Jh/*,[e81a0532/84h/1h/0h]tpubDC6UGqnsQStngYuGD4MKsMy7eD1Yg9NTJfPdvjdG2JE5oZ7EsSL3WHg4Gsw2pR5K39ZwJ46M1wZayhedVdQtMGaUhq5S23PH6fnENK3V1sb/*))#c08a2rzv",
|
||||
self.test_importdesc({"desc":"wsh(multi(2,[7b2d0242/84h/1h/0h]" + chg_xpub1 + "/*,[59b09cd6/84h/1h/0h]" + chg_xpub2 + "/*,[e81a0532/84h/1h/0h]" + chg_xpub3 + "/*))#c08a2rzv",
|
||||
"active": True,
|
||||
"internal" : True,
|
||||
"range": 1000,
|
||||
@@ -396,8 +485,15 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
change_addr = wmulti_pub.getrawchangeaddress('bech32')
|
||||
assert_equal(change_addr, 'bcrt1qt9uhe3a9hnq7vajl7a094z4s3crm9ttf8zw3f5v9gr2nyd7e3lnsy44n8e')
|
||||
assert_equal(wmulti_pub.getwalletinfo()['keypoolsize'], 999)
|
||||
|
||||
# generate some utxos for next tests
|
||||
txid = w0.sendtoaddress(addr, 10)
|
||||
vout = find_vout_for_address(self.nodes[0], txid, addr)
|
||||
|
||||
addr2 = wmulti_pub.getnewaddress('', 'bech32')
|
||||
txid2 = w0.sendtoaddress(addr2, 10)
|
||||
vout2 = find_vout_for_address(self.nodes[0], txid2, addr2)
|
||||
|
||||
self.nodes[0].generate(6)
|
||||
self.sync_all()
|
||||
assert_equal(wmulti_pub.getbalance(), wmulti_priv.getbalance())
|
||||
@@ -411,14 +507,14 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
wmulti_priv1 = self.nodes[1].get_wallet_rpc("wmulti_priv1")
|
||||
res = wmulti_priv1.importdescriptors([
|
||||
{
|
||||
"desc": descsum_create("wsh(multi(2,tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52/84h/0h/0h/*,[59b09cd6/84h/0h/0h]tpubDDBF2BTR6s8drwrfDei8WxtckGuSm1cyoKxYY1QaKSBFbHBYQArWhHPA6eJrzZej6nfHGLSURYSLHr7GuYch8aY5n61tGqgn8b4cXrMuoPH/*,[e81a0532/84h/0h/0h]tpubDCsWoW1kuQB9kG5MXewHqkbjPtqPueRnXju7uM2NK7y3JYb2ajAZ9EiuZXNNuE4661RAfriBWhL8UsnAPpk8zrKKnZw1Ug7X4oHgMdZiU4E/*))"),
|
||||
"desc": descsum_create("wsh(multi(2," + xprv1 + "/84h/0h/0h/*,[59b09cd6/84h/0h/0h]" + acc_xpub2 + "/*,[e81a0532/84h/0h/0h]" + acc_xpub3 + "/*))"),
|
||||
"active": True,
|
||||
"range": 1000,
|
||||
"next_index": 0,
|
||||
"timestamp": "now"
|
||||
},
|
||||
{
|
||||
"desc": descsum_create("wsh(multi(2,tprv8ZgxMBicQKsPevADjDCWsa6DfhkVXicu8NQUzfibwX2MexVwW4tCec5mXdCW8kJwkzBRRmAay1KZya4WsehVvjTGVW6JLqiqd8DdZ4xSg52/84h/1h/0h/*,[59b09cd6/84h/1h/0h]tpubDCYfZY2ceyHzYzMMVPt9MNeiqtQ2T7Uyp9QSFwYXh8Vi9iJFYXcuphJaGXfF3jUQJi5Y3GMNXvM11gaL4txzZgNGK22BFAwMXynnzv4z2Jh/*,[e81a0532/84h/1h/0h]tpubDC6UGqnsQStngYuGD4MKsMy7eD1Yg9NTJfPdvjdG2JE5oZ7EsSL3WHg4Gsw2pR5K39ZwJ46M1wZayhedVdQtMGaUhq5S23PH6fnENK3V1sb/*))"),
|
||||
"desc": descsum_create("wsh(multi(2," + xprv1 + "/84h/1h/0h/*,[59b09cd6/84h/1h/0h]" + chg_xpub2 + "/*,[e81a0532/84h/1h/0h]" + chg_xpub3 + "/*))"),
|
||||
"active": True,
|
||||
"internal" : True,
|
||||
"range": 1000,
|
||||
@@ -434,14 +530,14 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
wmulti_priv2 = self.nodes[1].get_wallet_rpc('wmulti_priv2')
|
||||
res = wmulti_priv2.importdescriptors([
|
||||
{
|
||||
"desc": descsum_create("wsh(multi(2,[7b2d0242/84h/0h/0h]tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8/*,tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq/84h/0h/0h/*,[e81a0532/84h/0h/0h]tpubDCsWoW1kuQB9kG5MXewHqkbjPtqPueRnXju7uM2NK7y3JYb2ajAZ9EiuZXNNuE4661RAfriBWhL8UsnAPpk8zrKKnZw1Ug7X4oHgMdZiU4E/*))"),
|
||||
"desc": descsum_create("wsh(multi(2,[7b2d0242/84h/0h/0h]" + acc_xpub1 + "/*," + xprv2 + "/84h/0h/0h/*,[e81a0532/84h/0h/0h]" + acc_xpub3 + "/*))"),
|
||||
"active": True,
|
||||
"range": 1000,
|
||||
"next_index": 0,
|
||||
"timestamp": "now"
|
||||
},
|
||||
{
|
||||
"desc": descsum_create("wsh(multi(2,[7b2d0242/84h/1h/0h]tpubDCXqdwWZcszwqYJSnZp8eARkxGJfHAk23KDxbztV4BbschfaTfYLTcSkSJ3TN64dRqwa1rnFUScsYormKkGqNbbPwkorQimVevXjxzUV9Gf/*,tprv8ZgxMBicQKsPdSNWUhDiwTScDr6JfkZuLshTRwzvZGnMSnGikV6jxpmdDkC3YRc4T3GD6Nvg9uv6hQg73RVv1EiTXDZwxVbsLugVHU8B1aq/84h/1h/0h/*,[e81a0532/84h/1h/0h]tpubDC6UGqnsQStngYuGD4MKsMy7eD1Yg9NTJfPdvjdG2JE5oZ7EsSL3WHg4Gsw2pR5K39ZwJ46M1wZayhedVdQtMGaUhq5S23PH6fnENK3V1sb/*))"),
|
||||
"desc": descsum_create("wsh(multi(2,[7b2d0242/84h/1h/0h]" + chg_xpub1 + "/*," + xprv2 + "/84h/1h/0h/*,[e81a0532/84h/1h/0h]" + chg_xpub3 + "/*))"),
|
||||
"active": True,
|
||||
"internal" : True,
|
||||
"range": 1000,
|
||||
@@ -531,6 +627,33 @@ class ImportDescriptorsTest(BitcoinTestFramework):
|
||||
)
|
||||
|
||||
|
||||
self.log.info("Amending multisig with new private keys")
|
||||
self.nodes[1].createwallet(wallet_name="wmulti_priv3", descriptors=True)
|
||||
wmulti_priv3 = self.nodes[1].get_wallet_rpc("wmulti_priv3")
|
||||
res = wmulti_priv3.importdescriptors([
|
||||
{
|
||||
"desc": descsum_create("wsh(multi(2," + xprv1 + "/84h/0h/0h/*,[59b09cd6/84h/0h/0h]" + acc_xpub2 + "/*,[e81a0532/84h/0h/0h]" + acc_xpub3 + "/*))"),
|
||||
"active": True,
|
||||
"range": 1000,
|
||||
"next_index": 0,
|
||||
"timestamp": "now"
|
||||
}])
|
||||
assert_equal(res[0]['success'], True)
|
||||
res = wmulti_priv3.importdescriptors([
|
||||
{
|
||||
"desc": descsum_create("wsh(multi(2," + xprv1 + "/84h/0h/0h/*,[59b09cd6/84h/0h/0h]" + acc_xprv2 + "/*,[e81a0532/84h/0h/0h]" + acc_xpub3 + "/*))"),
|
||||
"active": True,
|
||||
"range": 1000,
|
||||
"next_index": 0,
|
||||
"timestamp": "now"
|
||||
}])
|
||||
assert_equal(res[0]['success'], True)
|
||||
|
||||
rawtx = self.nodes[1].createrawtransaction([{'txid': txid2, 'vout': vout2}], {w0.getnewaddress(): 9.999})
|
||||
tx = wmulti_priv3.signrawtransactionwithwallet(rawtx)
|
||||
assert_equal(tx['complete'], True)
|
||||
self.nodes[1].sendrawtransaction(tx['hex'])
|
||||
|
||||
self.log.info("Combo descriptors cannot be active")
|
||||
self.test_importdesc({"desc": descsum_create("combo(tpubDCJtdt5dgJpdhW4MtaVYDhG4T4tF6jcLR1PxL43q9pq1mxvXgMS9Mzw1HnXG15vxUGQJMMSqCQHMTy3F1eW5VkgVroWzchsPD5BUojrcWs8/*)"),
|
||||
"active": True,
|
||||
|
||||
Reference in New Issue
Block a user