From 02592f4c5e6d9416165deef96398ac7760f457d1 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 10 Jan 2017 16:45:30 +0100 Subject: [Wallet] split the keypool in an internal and external part --- test/functional/fundrawtransaction.py | 3 +++ test/functional/keypool.py | 37 ++++++++++++++++++++++++----------- test/functional/wallet-dump.py | 6 +++--- test/functional/wallet-hd.py | 19 ++++++++++++++++++ 4 files changed, 51 insertions(+), 14 deletions(-) (limited to 'test') diff --git a/test/functional/fundrawtransaction.py b/test/functional/fundrawtransaction.py index 1dc00f2ba1..a28ff94655 100755 --- a/test/functional/fundrawtransaction.py +++ b/test/functional/fundrawtransaction.py @@ -467,6 +467,8 @@ class RawTransactionsTest(BitcoinTestFramework): # drain the keypool self.nodes[1].getnewaddress() + self.nodes[1].getrawchangeaddress() + self.nodes[1].getrawchangeaddress() inputs = [] outputs = {self.nodes[0].getnewaddress():1.1} rawTx = self.nodes[1].createrawtransaction(inputs, outputs) @@ -476,6 +478,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) diff --git a/test/functional/keypool.py b/test/functional/keypool.py index cee58563f0..26585fc4ad 100755 --- a/test/functional/keypool.py +++ b/test/functional/keypool.py @@ -27,28 +27,38 @@ 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-, +20% internal-keys, 2 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'], 2) + assert_equal(wi['keypoolsize'], 6) - # drain the keys + # drain the internal keys + 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 +67,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'], 20) + 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..7eaa8090b5 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*1.2) # 90 keys plus 20% 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*1.2 + 50) # old reserve keys are marked as change now + assert_equal(found_addr_rsv, 90*1.2) if __name__ == '__main__': WalletDumpTest().main () diff --git a/test/functional/wallet-hd.py b/test/functional/wallet-hd.py index c40662dc3d..b17f788433 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(keypath[0:7] == "m/0'/1'") if __name__ == '__main__': WalletHDTest().main () -- cgit v1.2.3 From 79df9df3482d71391dee1dd59054aed8f7bbfa6b Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 17 Jan 2017 08:55:30 +0100 Subject: Switch to 100% for the HD internal keypool size --- test/functional/fundrawtransaction.py | 1 - test/functional/keypool.py | 10 +++++++--- test/functional/wallet-dump.py | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/functional/fundrawtransaction.py b/test/functional/fundrawtransaction.py index a28ff94655..6bb7d7f334 100755 --- a/test/functional/fundrawtransaction.py +++ b/test/functional/fundrawtransaction.py @@ -468,7 +468,6 @@ class RawTransactionsTest(BitcoinTestFramework): # drain the keypool self.nodes[1].getnewaddress() self.nodes[1].getrawchangeaddress() - self.nodes[1].getrawchangeaddress() inputs = [] outputs = {self.nodes[0].getnewaddress():1.1} rawTx = self.nodes[1].createrawtransaction(inputs, outputs) diff --git a/test/functional/keypool.py b/test/functional/keypool.py index 26585fc4ad..cb9ab688d1 100755 --- a/test/functional/keypool.py +++ b/test/functional/keypool.py @@ -29,17 +29,21 @@ class KeyPoolTest(BitcoinTestFramework): assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid']) assert_raises_jsonrpc(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress) - # put six (plus 2) new keys in the keypool (100% external-, +20% internal-keys, 2 in min) + # 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(6) nodes[0].walletlock() wi = nodes[0].getwalletinfo() - assert_equal(wi['keypoolsize_hd_internal'], 2) + assert_equal(wi['keypoolsize_hd_internal'], 6) assert_equal(wi['keypoolsize'], 6) # drain the internal keys nodes[0].getrawchangeaddress() nodes[0].getrawchangeaddress() + nodes[0].getrawchangeaddress() + nodes[0].getrawchangeaddress() + nodes[0].getrawchangeaddress() + nodes[0].getrawchangeaddress() addr = set() # the next one should fail assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].getrawchangeaddress) @@ -72,7 +76,7 @@ class KeyPoolTest(BitcoinTestFramework): nodes[0].walletpassphrase('test', 100) nodes[0].keypoolrefill(100) wi = nodes[0].getwalletinfo() - assert_equal(wi['keypoolsize_hd_internal'], 20) + assert_equal(wi['keypoolsize_hd_internal'], 100) assert_equal(wi['keypoolsize'], 100) def __init__(self): diff --git a/test/functional/wallet-dump.py b/test/functional/wallet-dump.py index 7eaa8090b5..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.2) # 90 keys plus 20% internal keys + 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.2 + 50) # old reserve keys are marked as change now - assert_equal(found_addr_rsv, 90*1.2) + 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 () -- cgit v1.2.3 From 1090502c3e90f3f24fdc6c1e74f62d7669697b31 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 26 Jan 2017 20:52:57 +0100 Subject: Fix superfluous cast and code style nits in RPC wallet-hd.py test --- test/functional/wallet-hd.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/functional/wallet-hd.py b/test/functional/wallet-hd.py index b17f788433..64a6c92782 100755 --- a/test/functional/wallet-hd.py +++ b/test/functional/wallet-hd.py @@ -42,7 +42,7 @@ class WalletHDTest(BitcoinTestFramework): masterkeyid = self.nodes[1].getwalletinfo()['hdmasterkeyid'] assert_equal(len(masterkeyid), 40) - #create an internal key + # 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 @@ -70,7 +70,7 @@ class WalletHDTest(BitcoinTestFramework): self.nodes[0].sendtoaddress(non_hd_add, 1) self.nodes[0].generate(1) - #create an internal key (again) + # 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 @@ -100,7 +100,7 @@ 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 + # 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 = "" @@ -108,7 +108,7 @@ class WalletHDTest(BitcoinTestFramework): if out['value'] != 1: keypath = self.nodes[1].validateaddress(out['scriptPubKey']['addresses'][0])['hdkeypath'] - assert(keypath[0:7] == "m/0'/1'") + assert_equal(keypath[0:7], "m/0'/1'") if __name__ == '__main__': WalletHDTest().main () -- cgit v1.2.3 From 1b3b5c6f8fa6aff93935319888bf0cfd242359dd Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 1 Feb 2017 09:12:13 +0100 Subject: Slightly modify fundrawtransaction.py test (change getnewaddress() into getrawchangeaddress()) --- test/functional/fundrawtransaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/functional/fundrawtransaction.py b/test/functional/fundrawtransaction.py index 6bb7d7f334..69f2c29f51 100755 --- a/test/functional/fundrawtransaction.py +++ b/test/functional/fundrawtransaction.py @@ -646,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) -- cgit v1.2.3