mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-03 20:35:17 +02:00
Merge #11667: Add scripts to dumpwallet RPC
656fde5Add script birthtime metadata to dump and import wallet (MeshCollider)1bab9b2Add script dump note to RPC help text and release notes (MeshCollider)68c1e00Add test for importwallet (MeshCollider)9e1184dAdd dumpwallet scripts test (MeshCollider)ef0c730Add scripts to importwallet RPC (MeshCollider)b702ae8Add CScripts to dumpwallet RPC (MeshCollider)cdc260aAdd GetCScripts to CBasicKeyStore (MeshCollider) Pull request description: As discussed in https://github.com/bitcoin/bitcoin/pull/11289#issuecomment-334600457, adds the CScripts from the wallet to the `dumpwallet` RPC and then allows them to be imported with the `importwallet` RPC. Includes a basic test, and modifies the helptext of the dumpwallet RPC. Notes: - Reviewers: use `?w=1` to avoid the indentation-only change in commit `Add scripts to importwallet RPC ` - currently the scripts are followed with `# addr=` comments just as the other keys are, unsure if this might confuse users into thinking all the scripts are for valid P2SH addresses though, but I don't think that should be an issue. - there are no birthtimes for scripts, so script imports don't affect rescans - `importwallet` imports the CScripts but I'm not sure how to approach specifying whether scripts are for P2SH addresses, BIP173 addresses, etc. whether that matters or not. Otherwise the RPC helptext might just need modification. Fixes #11715 Tree-SHA512: 36c55837b3a58b9d3499d4c0c2ae82153d62aa71919e751574651b63a1d2b8ecc83796db4553cc65dad9b5341c3a42ae2fcf4d62598c30af267f8e1461ba8272
This commit is contained in:
@@ -10,13 +10,14 @@ from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (assert_equal, assert_raises_rpc_error)
|
||||
|
||||
|
||||
def read_dump(file_name, addrs, hd_master_addr_old):
|
||||
def read_dump(file_name, addrs, script_addrs, hd_master_addr_old):
|
||||
"""
|
||||
Read the given dump, count the addrs that match, count change and reserve.
|
||||
Also check that the old hd_master is inactive
|
||||
"""
|
||||
with open(file_name, encoding='utf8') as inputfile:
|
||||
found_addr = 0
|
||||
found_script_addr = 0
|
||||
found_addr_chg = 0
|
||||
found_addr_rsv = 0
|
||||
hd_master_addr_ret = None
|
||||
@@ -38,6 +39,9 @@ def read_dump(file_name, addrs, hd_master_addr_old):
|
||||
# ensure we have generated a new hd master key
|
||||
assert(hd_master_addr_old != addr)
|
||||
hd_master_addr_ret = addr
|
||||
elif keytype == "script=1":
|
||||
# scripts don't have keypaths
|
||||
keypath = None
|
||||
else:
|
||||
keypath = addr_keypath.rstrip().split("hdkeypath=")[1]
|
||||
|
||||
@@ -52,7 +56,14 @@ def read_dump(file_name, addrs, hd_master_addr_old):
|
||||
elif keytype == "reserve=1":
|
||||
found_addr_rsv += 1
|
||||
break
|
||||
return found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_ret
|
||||
|
||||
# count scripts
|
||||
for script_addr in script_addrs:
|
||||
if script_addr == addr.rstrip() and keytype == "script=1":
|
||||
found_script_addr += 1
|
||||
break
|
||||
|
||||
return found_addr, found_script_addr, found_addr_chg, found_addr_rsv, hd_master_addr_ret
|
||||
|
||||
|
||||
class WalletDumpTest(BitcoinTestFramework):
|
||||
@@ -81,13 +92,19 @@ class WalletDumpTest(BitcoinTestFramework):
|
||||
# Should be a no-op:
|
||||
self.nodes[0].keypoolrefill()
|
||||
|
||||
# Test scripts dump by adding a P2SH witness and a 1-of-1 multisig address
|
||||
witness_addr = self.nodes[0].addwitnessaddress(addrs[0]["address"], True)
|
||||
multisig_addr = self.nodes[0].addmultisigaddress(1, [addrs[1]["address"]])
|
||||
script_addrs = [witness_addr, multisig_addr]
|
||||
|
||||
# dump unencrypted wallet
|
||||
result = self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.unencrypted.dump")
|
||||
assert_equal(result['filename'], os.path.abspath(tmpdir + "/node0/wallet.unencrypted.dump"))
|
||||
|
||||
found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_unenc = \
|
||||
read_dump(tmpdir + "/node0/wallet.unencrypted.dump", addrs, None)
|
||||
found_addr, found_script_addr, found_addr_chg, found_addr_rsv, hd_master_addr_unenc = \
|
||||
read_dump(tmpdir + "/node0/wallet.unencrypted.dump", addrs, script_addrs, None)
|
||||
assert_equal(found_addr, test_addr_count) # all keys must be in the dump
|
||||
assert_equal(found_script_addr, 2) # all scripts must be in the dump
|
||||
assert_equal(found_addr_chg, 50) # 50 blocks where mined
|
||||
assert_equal(found_addr_rsv, 90*2) # 90 keys plus 100% internal keys
|
||||
|
||||
@@ -99,14 +116,29 @@ class WalletDumpTest(BitcoinTestFramework):
|
||||
self.nodes[0].keypoolrefill()
|
||||
self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.encrypted.dump")
|
||||
|
||||
found_addr, found_addr_chg, found_addr_rsv, _ = \
|
||||
read_dump(tmpdir + "/node0/wallet.encrypted.dump", addrs, hd_master_addr_unenc)
|
||||
found_addr, found_script_addr, found_addr_chg, found_addr_rsv, _ = \
|
||||
read_dump(tmpdir + "/node0/wallet.encrypted.dump", addrs, script_addrs, hd_master_addr_unenc)
|
||||
assert_equal(found_addr, test_addr_count)
|
||||
assert_equal(found_script_addr, 2)
|
||||
assert_equal(found_addr_chg, 90*2 + 50) # old reserve keys are marked as change now
|
||||
assert_equal(found_addr_rsv, 90*2)
|
||||
|
||||
# Overwriting should fail
|
||||
assert_raises_rpc_error(-8, "already exists", self.nodes[0].dumpwallet, tmpdir + "/node0/wallet.unencrypted.dump")
|
||||
|
||||
# Restart node with new wallet, and test importwallet
|
||||
self.stop_node(0)
|
||||
self.start_node(0, ['-wallet=w2'])
|
||||
|
||||
# Make sure the address is not IsMine before import
|
||||
result = self.nodes[0].validateaddress(multisig_addr)
|
||||
assert(result['ismine'] == False)
|
||||
|
||||
self.nodes[0].importwallet(os.path.abspath(tmpdir + "/node0/wallet.unencrypted.dump"))
|
||||
|
||||
# Now check IsMine is true
|
||||
result = self.nodes[0].validateaddress(multisig_addr)
|
||||
assert(result['ismine'] == True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
WalletDumpTest().main ()
|
||||
|
||||
Reference in New Issue
Block a user