Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_keypool.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2014-2019 The Bitcoin Core developers | # Copyright (c) 2014-2019 The Bitcoin Core developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
"""Test the wallet keypool and interaction with wallet encryption/locking.""" | """Test the wallet keypool and interaction with wallet encryption/locking.""" | ||||
import time | import time | ||||
from decimal import Decimal | |||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.util import assert_equal, assert_raises_rpc_error | from test_framework.util import assert_equal, assert_raises_rpc_error | ||||
class KeyPoolTest(BitcoinTestFramework): | class KeyPoolTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
assert_raises_rpc_error(-12, "Keypool ran out", nodes[0].getnewaddress) | assert_raises_rpc_error(-12, "Keypool ran out", nodes[0].getnewaddress) | ||||
nodes[0].walletpassphrase('test', 100) | nodes[0].walletpassphrase('test', 100) | ||||
nodes[0].keypoolrefill(100) | nodes[0].keypoolrefill(100) | ||||
wi = nodes[0].getwalletinfo() | wi = nodes[0].getwalletinfo() | ||||
assert_equal(wi['keypoolsize_hd_internal'], 100) | assert_equal(wi['keypoolsize_hd_internal'], 100) | ||||
assert_equal(wi['keypoolsize'], 100) | assert_equal(wi['keypoolsize'], 100) | ||||
# create a blank wallet | |||||
nodes[0].createwallet(wallet_name='w2', blank=True) | |||||
w2 = nodes[0].get_wallet_rpc('w2') | |||||
# refer to initial wallet as w1 | |||||
w1 = nodes[0].get_wallet_rpc('') | |||||
# import private key and fund it | |||||
address = addr.pop() | |||||
privkey = w1.dumpprivkey(address) | |||||
res = w2.importmulti( | |||||
[{'scriptPubKey': {'address': address}, 'keys': [privkey], 'timestamp': 'now'}]) | |||||
assert_equal(res[0]['success'], True) | |||||
w1.walletpassphrase('test', 100) | |||||
res = w1.sendtoaddress(address=address, amount=0.00010000) | |||||
nodes[0].generate(1) | |||||
destination = addr.pop() | |||||
# Using a fee rate (10 sat / byte) well above the minimum relay rate | |||||
# creating a 5,000 sat transaction with change should not be possible | |||||
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}) | |||||
# creating a 10,000 sat transaction without change, with a manual | |||||
# input, should still be possible | |||||
res = w2.walletcreatefundedpsbt( | |||||
inputs=w2.listunspent(), | |||||
outputs=[{destination: 0.00010000}], | |||||
options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010}) | |||||
assert_equal("psbt" in res, True) | |||||
# creating a 10,000 sat transaction without change should still be | |||||
# possible | |||||
res = w2.walletcreatefundedpsbt( | |||||
inputs=[], | |||||
outputs=[{destination: 0.00010000}], | |||||
options={"subtractFeeFromOutputs": [0], "feeRate": 0.00010}) | |||||
assert_equal("psbt" in res, True) | |||||
# should work without subtractFeeFromOutputs if the exact fee is | |||||
# subtracted from the amount | |||||
res = w2.walletcreatefundedpsbt(inputs=[], | |||||
outputs=[{destination: 0.00008000}], | |||||
options={"feeRate": 0.00010}) | |||||
assert_equal("psbt" in res, True) | |||||
# dust change should be removed | |||||
res = w2.walletcreatefundedpsbt(inputs=[], | |||||
outputs=[{destination: 0.00007900}], | |||||
options={"feeRate": 0.00010}) | |||||
assert_equal("psbt" in res, True) | |||||
# create a transaction without change at the maximum fee rate, such | |||||
# that the output is still spendable: | |||||
res = w2.walletcreatefundedpsbt( | |||||
inputs=[], | |||||
outputs=[{destination: 0.00010000}], | |||||
options={"subtractFeeFromOutputs": [0], "feeRate": 0.0004949}) | |||||
assert_equal("psbt" in res, True) | |||||
assert_equal(res["fee"], Decimal("0.00009453")) | |||||
# creating a 10,000 sat transaction with a manual change address should | |||||
# be possible | |||||
res = w2.walletcreatefundedpsbt(inputs=[], | |||||
outputs=[{destination: 0.00010000}], | |||||
options={"subtractFeeFromOutputs": [0], | |||||
"feeRate": 0.00010, | |||||
"changeAddress": addr.pop()}) | |||||
assert_equal("psbt" in res, True) | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
KeyPoolTest().main() | KeyPoolTest().main() |