55"""Test the wallet keypool and interaction with wallet encryption/locking."""
66
77import time
8+ from decimal import Decimal
89
910from test_framework .test_framework import BitcoinTestFramework
1011from test_framework .util import assert_equal , assert_raises_rpc_error
@@ -53,12 +54,12 @@ def run_test(self):
5354 assert_raises_rpc_error (- 12 , "Keypool ran out" , nodes [0 ].getrawchangeaddress )
5455
5556 # drain the external keys
56- addr .add (nodes [0 ].getnewaddress ())
57- addr .add (nodes [0 ].getnewaddress ())
58- addr .add (nodes [0 ].getnewaddress ())
59- addr .add (nodes [0 ].getnewaddress ())
60- addr .add (nodes [0 ].getnewaddress ())
61- addr .add (nodes [0 ].getnewaddress ())
57+ addr .add (nodes [0 ].getnewaddress (address_type = "bech32" ))
58+ addr .add (nodes [0 ].getnewaddress (address_type = "bech32" ))
59+ addr .add (nodes [0 ].getnewaddress (address_type = "bech32" ))
60+ addr .add (nodes [0 ].getnewaddress (address_type = "bech32" ))
61+ addr .add (nodes [0 ].getnewaddress (address_type = "bech32" ))
62+ addr .add (nodes [0 ].getnewaddress (address_type = "bech32" ))
6263 assert len (addr ) == 6
6364 # the next one should fail
6465 assert_raises_rpc_error (- 12 , "Error: Keypool ran out, please call keypoolrefill first" , nodes [0 ].getnewaddress )
@@ -82,5 +83,52 @@ def run_test(self):
8283 assert_equal (wi ['keypoolsize_hd_internal' ], 100 )
8384 assert_equal (wi ['keypoolsize' ], 100 )
8485
86+ # create a blank wallet
87+ nodes [0 ].createwallet (wallet_name = 'w2' , blank = True )
88+ w2 = nodes [0 ].get_wallet_rpc ('w2' )
89+
90+ # refer to initial wallet as w1
91+ w1 = nodes [0 ].get_wallet_rpc ('' )
92+
93+ # import private key and fund it
94+ address = addr .pop ()
95+ privkey = w1 .dumpprivkey (address )
96+ res = w2 .importmulti ([{'scriptPubKey' : {'address' : address }, 'keys' : [privkey ], 'timestamp' : 'now' }])
97+ assert_equal (res [0 ]['success' ], True )
98+ w1 .walletpassphrase ('test' , 100 )
99+
100+ res = w1 .sendtoaddress (address = address , amount = 0.00010000 )
101+ nodes [0 ].generate (1 )
102+ destination = addr .pop ()
103+
104+ # Using a fee rate (10 sat / byte) well above the minimum relay rate
105+ # creating a 5,000 sat transaction with change should not be possible
106+ assert_raises_rpc_error (- 4 , "Transaction needs a change address, but we can't generate it. Please call keypoolrefill first." , w2 .walletcreatefundedpsbt , inputs = [], outputs = [{addr .pop (): 0.00005000 }], options = {"subtractFeeFromOutputs" : [0 ], "feeRate" : 0.00010 })
107+
108+ # creating a 10,000 sat transaction without change, with a manual input, should still be possible
109+ res = w2 .walletcreatefundedpsbt (inputs = w2 .listunspent (), outputs = [{destination : 0.00010000 }], options = {"subtractFeeFromOutputs" : [0 ], "feeRate" : 0.00010 })
110+ assert_equal ("psbt" in res , True )
111+
112+ # creating a 10,000 sat transaction without change should still be possible
113+ res = w2 .walletcreatefundedpsbt (inputs = [], outputs = [{destination : 0.00010000 }], options = {"subtractFeeFromOutputs" : [0 ], "feeRate" : 0.00010 })
114+ assert_equal ("psbt" in res , True )
115+ # should work without subtractFeeFromOutputs if the exact fee is subtracted from the amount
116+ res = w2 .walletcreatefundedpsbt (inputs = [], outputs = [{destination : 0.00008900 }], options = {"feeRate" : 0.00010 })
117+ assert_equal ("psbt" in res , True )
118+
119+ # dust change should be removed
120+ res = w2 .walletcreatefundedpsbt (inputs = [], outputs = [{destination : 0.00008800 }], options = {"feeRate" : 0.00010 })
121+ assert_equal ("psbt" in res , True )
122+
123+ # create a transaction without change at the maximum fee rate, such that the output is still spendable:
124+ res = w2 .walletcreatefundedpsbt (inputs = [], outputs = [{destination : 0.00010000 }], options = {"subtractFeeFromOutputs" : [0 ], "feeRate" : 0.0008824 })
125+ assert_equal ("psbt" in res , True )
126+ assert_equal (res ["fee" ], Decimal ("0.00009706" ))
127+
128+ # creating a 10,000 sat transaction with a manual change address should be possible
129+ res = w2 .walletcreatefundedpsbt (inputs = [], outputs = [{destination : 0.00010000 }], options = {"subtractFeeFromOutputs" : [0 ], "feeRate" : 0.00010 , "changeAddress" : addr .pop ()})
130+ assert_equal ("psbt" in res , True )
131+
132+
85133if __name__ == '__main__' :
86134 KeyPoolTest ().main ()
0 commit comments