mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-26 22:08:58 +01:00
[wallet] allow transaction without change if keypool is empty
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
"""Test the wallet keypool and interaction with wallet encryption/locking."""
|
||||
|
||||
import time
|
||||
from decimal import Decimal
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal, assert_raises_rpc_error
|
||||
@@ -53,12 +54,12 @@ class KeyPoolTest(BitcoinTestFramework):
|
||||
assert_raises_rpc_error(-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())
|
||||
addr.add(nodes[0].getnewaddress(address_type="bech32"))
|
||||
addr.add(nodes[0].getnewaddress(address_type="bech32"))
|
||||
addr.add(nodes[0].getnewaddress(address_type="bech32"))
|
||||
addr.add(nodes[0].getnewaddress(address_type="bech32"))
|
||||
addr.add(nodes[0].getnewaddress(address_type="bech32"))
|
||||
addr.add(nodes[0].getnewaddress(address_type="bech32"))
|
||||
assert len(addr) == 6
|
||||
# the next one should fail
|
||||
assert_raises_rpc_error(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress)
|
||||
@@ -82,5 +83,52 @@ class KeyPoolTest(BitcoinTestFramework):
|
||||
assert_equal(wi['keypoolsize_hd_internal'], 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.00008900}], options={"feeRate": 0.00010})
|
||||
assert_equal("psbt" in res, True)
|
||||
|
||||
# dust change should be removed
|
||||
res = w2.walletcreatefundedpsbt(inputs=[], outputs=[{destination: 0.00008800}], 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.0008824})
|
||||
assert_equal("psbt" in res, True)
|
||||
assert_equal(res["fee"], Decimal("0.00009706"))
|
||||
|
||||
# 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__':
|
||||
KeyPoolTest().main()
|
||||
|
||||
Reference in New Issue
Block a user