aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2017-03-29 12:41:43 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2017-03-29 12:51:06 +0200
commitf34cdcbd806d3e7c9d5dbac2a201755a4cc9828b (patch)
tree566d1ae4b6938a4e3070e04d93c6f4693c5f7359 /test/functional
parentf2734c2828f69d9cfd535e5eab0592a7674b2b61 (diff)
parent4115af7ac78971617c4fb80b7db336ff6bf254db (diff)
downloadbitcoin-f34cdcbd806d3e7c9d5dbac2a201755a4cc9828b.tar.xz
Merge #9294: Use internal HD chain for change outputs (hd split)
4115af7 Fix rebase issue where pwalletMain was used instead of pwallet Ser./Deser. nInternalChainCounter as last element (Jonas Schnelli) 9382f04 Do not break backward compatibility during wallet encryption (Jonas Schnelli) 1df08d1 Add assertion for CanSupportFeature(FEATURE_HD_SPLIT) (Jonas Schnelli) cd468d0 Define CWallet::DeriveNewChildKey() as private (Jonas Schnelli) ed79e4f Optimize GetOldestKeyPoolTime(), return as soon as we have both oldest keys (Jonas Schnelli) 771a304 Make sure we set the wallets min version to FEATURE_HD_SPLIT at the very first point (Jonas Schnelli) 1b3b5c6 Slightly modify fundrawtransaction.py test (change getnewaddress() into getrawchangeaddress()) (Jonas Schnelli) 003e197 Remove FEATURE_HD_SPLIT bump TODO (Jonas Schnelli) d9638e5 Overhaul the internal/external key derive switch (Jonas Schnelli) 1090502 Fix superfluous cast and code style nits in RPC wallet-hd.py test (Jonas Schnelli) 58e1483 CKeyPool avoid "catch (...)" in SerializationOp (Jonas Schnelli) e138876 Only show keypoolsize_hd_internal if HD split is enabled (Jonas Schnelli) add38d9 GetOldestKeyPoolTime: if HD & HD Chain Split is enabled, response max(oldest-internal-key, oldest-external-key) (Jonas Schnelli) dd526c2 Don't switch to HD-chain-split during wallet encryption of non HD-chain-split wallets (Jonas Schnelli) 79df9df Switch to 100% for the HD internal keypool size (Jonas Schnelli) bcafca1 Make sure we always generate one keypool key at minimum (Jonas Schnelli) d0a627a Fix issue where CDataStream->nVersion was taken a CKeyPool record version (Jonas Schnelli) 9af8f00 Make sure we hand out keypool keys if HD_SPLIT is not enabled (Jonas Schnelli) 469a47b Make sure ReserveKeyFromKeyPool only hands out internal keys if HD_SPLIT is supported (Jonas Schnelli) 05a9b49 Fix wrong keypool internal size in RPC getwalletinfo help (Jonas Schnelli) 01de822 Removed redundant IsLocked() check in NewKeyPool() (Jonas Schnelli) d59531d Immediately return setKeyPool's size if HD or HD_SPLIT is disabled or not supported (Jonas Schnelli) 02592f4 [Wallet] split the keypool in an internal and external part (Jonas Schnelli) Tree-SHA512: 80d355d5e844b48c3163b56c788ab8b5b5285db0ceeb19858a3ef517d5a702afeca21dbae526d7b8fb4101c2a745af1d92bf557c40cf516780f17992bf678c1a
Diffstat (limited to 'test/functional')
-rwxr-xr-xtest/functional/fundrawtransaction.py4
-rwxr-xr-xtest/functional/keypool.py41
-rwxr-xr-xtest/functional/wallet-dump.py6
-rwxr-xr-xtest/functional/wallet-hd.py19
4 files changed, 55 insertions, 15 deletions
diff --git a/test/functional/fundrawtransaction.py b/test/functional/fundrawtransaction.py
index 3bfc05d37b..b86ea2d877 100755
--- a/test/functional/fundrawtransaction.py
+++ b/test/functional/fundrawtransaction.py
@@ -467,6 +467,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# drain the keypool
self.nodes[1].getnewaddress()
+ self.nodes[1].getrawchangeaddress()
inputs = []
outputs = {self.nodes[0].getnewaddress():1.1}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
@@ -476,6 +477,7 @@ class RawTransactionsTest(BitcoinTestFramework):
#refill the keypool
self.nodes[1].walletpassphrase("test", 100)
+ self.nodes[1].keypoolrefill(8) #need to refill the keypool to get an internal change address
self.nodes[1].walletlock()
assert_raises_jsonrpc(-13, "walletpassphrase", self.nodes[1].sendtoaddress, self.nodes[0].getnewaddress(), 1.2)
@@ -644,7 +646,7 @@ class RawTransactionsTest(BitcoinTestFramework):
if out['value'] > 1.0:
changeaddress += out['scriptPubKey']['addresses'][0]
assert(changeaddress != "")
- nextaddr = self.nodes[3].getnewaddress()
+ nextaddr = self.nodes[3].getrawchangeaddress()
# frt should not have removed the key from the keypool
assert(changeaddress == nextaddr)
diff --git a/test/functional/keypool.py b/test/functional/keypool.py
index cee58563f0..cb9ab688d1 100755
--- a/test/functional/keypool.py
+++ b/test/functional/keypool.py
@@ -27,28 +27,42 @@ class KeyPoolTest(BitcoinTestFramework):
wallet_info = nodes[0].getwalletinfo()
assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid'])
assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid'])
-
assert_raises_jsonrpc(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress)
- # put three new keys in the keypool
+ # put six (plus 2) new keys in the keypool (100% external-, +100% internal-keys, 1 in min)
nodes[0].walletpassphrase('test', 12000)
- nodes[0].keypoolrefill(3)
+ nodes[0].keypoolrefill(6)
nodes[0].walletlock()
+ wi = nodes[0].getwalletinfo()
+ assert_equal(wi['keypoolsize_hd_internal'], 6)
+ assert_equal(wi['keypoolsize'], 6)
- # drain the keys
+ # drain the internal keys
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
+ nodes[0].getrawchangeaddress()
addr = set()
- addr.add(nodes[0].getrawchangeaddress())
- addr.add(nodes[0].getrawchangeaddress())
- addr.add(nodes[0].getrawchangeaddress())
- addr.add(nodes[0].getrawchangeaddress())
- # assert that four unique addresses were returned
- assert(len(addr) == 4)
# the next one should fail
assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].getrawchangeaddress)
+ # drain the external keys
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ addr.add(nodes[0].getnewaddress())
+ assert(len(addr) == 6)
+ # the next one should fail
+ assert_raises_jsonrpc(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress)
+
# refill keypool with three new addresses
nodes[0].walletpassphrase('test', 1)
nodes[0].keypoolrefill(3)
+
# test walletpassphrase timeout
time.sleep(1.1)
assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0)
@@ -57,9 +71,14 @@ class KeyPoolTest(BitcoinTestFramework):
nodes[0].generate(1)
nodes[0].generate(1)
nodes[0].generate(1)
- nodes[0].generate(1)
assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].generate, 1)
+ nodes[0].walletpassphrase('test', 100)
+ nodes[0].keypoolrefill(100)
+ wi = nodes[0].getwalletinfo()
+ assert_equal(wi['keypoolsize_hd_internal'], 100)
+ assert_equal(wi['keypoolsize'], 100)
+
def __init__(self):
super().__init__()
self.setup_clean_chain = False
diff --git a/test/functional/wallet-dump.py b/test/functional/wallet-dump.py
index b819b72b75..8876f935a4 100755
--- a/test/functional/wallet-dump.py
+++ b/test/functional/wallet-dump.py
@@ -88,7 +88,7 @@ class WalletDumpTest(BitcoinTestFramework):
read_dump(tmpdir + "/node0/wallet.unencrypted.dump", addrs, None)
assert_equal(found_addr, test_addr_count) # all keys must be in the dump
assert_equal(found_addr_chg, 50) # 50 blocks where mined
- assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one)
+ assert_equal(found_addr_rsv, 90*2) # 90 keys plus 100% internal keys
#encrypt wallet, restart, unlock and dump
self.nodes[0].encryptwallet('test')
@@ -102,8 +102,8 @@ class WalletDumpTest(BitcoinTestFramework):
found_addr, found_addr_chg, found_addr_rsv, hd_master_addr_enc = \
read_dump(tmpdir + "/node0/wallet.encrypted.dump", addrs, hd_master_addr_unenc)
assert_equal(found_addr, test_addr_count)
- assert_equal(found_addr_chg, 90 + 1 + 50) # old reserve keys are marked as change now
- assert_equal(found_addr_rsv, 90 + 1) # keypool size (TODO: fix off-by-one)
+ assert_equal(found_addr_chg, 90*2 + 50) # old reserve keys are marked as change now
+ assert_equal(found_addr_rsv, 90*2)
if __name__ == '__main__':
WalletDumpTest().main ()
diff --git a/test/functional/wallet-hd.py b/test/functional/wallet-hd.py
index c40662dc3d..64a6c92782 100755
--- a/test/functional/wallet-hd.py
+++ b/test/functional/wallet-hd.py
@@ -42,6 +42,11 @@ class WalletHDTest(BitcoinTestFramework):
masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid']
assert_equal(len(masterkeyid), 40)
+ # create an internal key
+ change_addr = self.nodes[1].getrawchangeaddress()
+ change_addrV= self.nodes[1].validateaddress(change_addr);
+ assert_equal(change_addrV["hdkeypath"], "m/0'/1'/0'") #first internal child key
+
# Import a non-HD private key in the HD wallet
non_hd_add = self.nodes[0].getnewaddress()
self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add))
@@ -65,6 +70,11 @@ class WalletHDTest(BitcoinTestFramework):
self.nodes[0].sendtoaddress(non_hd_add, 1)
self.nodes[0].generate(1)
+ # create an internal key (again)
+ change_addr = self.nodes[1].getrawchangeaddress()
+ change_addrV= self.nodes[1].validateaddress(change_addr);
+ assert_equal(change_addrV["hdkeypath"], "m/0'/1'/1'") #second internal child key
+
self.sync_all()
assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1)
@@ -90,6 +100,15 @@ class WalletHDTest(BitcoinTestFramework):
#connect_nodes_bi(self.nodes, 0, 1)
assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1)
+ # send a tx and make sure its using the internal chain for the changeoutput
+ txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1)
+ outs = self.nodes[1].decoderawtransaction(self.nodes[1].gettransaction(txid)['hex'])['vout'];
+ keypath = ""
+ for out in outs:
+ if out['value'] != 1:
+ keypath = self.nodes[1].validateaddress(out['scriptPubKey']['addresses'][0])['hdkeypath']
+
+ assert_equal(keypath[0:7], "m/0'/1'")
if __name__ == '__main__':
WalletHDTest().main ()