Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_abandonconflict.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2014-2016 The Bitcoin Core developers | # Copyright (c) 2014-2016 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 abandontransaction RPC. | """Test the abandontransaction RPC. | ||||
The abandontransaction RPC marks a transaction and all its in-wallet | The abandontransaction RPC marks a transaction and all its in-wallet | ||||
descendants as abandoned which allows their inputs to be respent. It can be | descendants as abandoned which allows their inputs to be respent. It can be | ||||
used to replace "stuck" or evicted transactions. It only works on transactions | used to replace "stuck" or evicted transactions. It only works on transactions | ||||
which are not included in a block and are not currently in the mempool. It has | which are not included in a block and are not currently in the mempool. It has | ||||
no effect on transactions which are already conflicted or abandoned. | no effect on transactions which are already abandoned. | ||||
""" | """ | ||||
from decimal import Decimal | from decimal import Decimal | ||||
from test_framework.messages import CTransaction, FromHex | from test_framework.messages import CTransaction, FromHex | ||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.util import ( | from test_framework.util import ( | ||||
assert_equal, | assert_equal, | ||||
assert_raises_rpc_error, | |||||
connect_nodes, | connect_nodes, | ||||
disconnect_nodes, | disconnect_nodes, | ||||
satoshi_round, | satoshi_round, | ||||
sync_blocks, | sync_blocks, | ||||
sync_mempools, | sync_mempools, | ||||
) | ) | ||||
Show All 18 Lines | def run_test(self): | ||||
self.nodes[0].getnewaddress(), Decimal("10")) | self.nodes[0].getnewaddress(), Decimal("10")) | ||||
txB = self.nodes[0].sendtoaddress( | txB = self.nodes[0].sendtoaddress( | ||||
self.nodes[0].getnewaddress(), Decimal("10")) | self.nodes[0].getnewaddress(), Decimal("10")) | ||||
txC = self.nodes[0].sendtoaddress( | txC = self.nodes[0].sendtoaddress( | ||||
self.nodes[0].getnewaddress(), Decimal("10")) | self.nodes[0].getnewaddress(), Decimal("10")) | ||||
sync_mempools(self.nodes) | sync_mempools(self.nodes) | ||||
self.nodes[1].generate(1) | self.nodes[1].generate(1) | ||||
# Can not abandon non-wallet transaction | |||||
assert_raises_rpc_error(-5, 'Invalid or non-wallet transaction id', | |||||
lambda: self.nodes[0].abandontransaction(txid='ff' * 32)) | |||||
# Can not abandon confirmed transaction | |||||
assert_raises_rpc_error(-5, 'Transaction not eligible for abandonment', | |||||
lambda: self.nodes[0].abandontransaction(txid=txA)) | |||||
sync_blocks(self.nodes) | sync_blocks(self.nodes) | ||||
newbalance = self.nodes[0].getbalance() | newbalance = self.nodes[0].getbalance() | ||||
# no more than fees lost | # no more than fees lost | ||||
assert(balance - newbalance <= total_fees(txA, txB, txC)) | assert(balance - newbalance <= total_fees(txA, txB, txC)) | ||||
balance = newbalance | balance = newbalance | ||||
# Disconnect nodes so node0's transactions don't get into node1's mempool | # Disconnect nodes so node0's transactions don't get into node1's mempool | ||||
▲ Show 20 Lines • Show All 150 Lines • Show Last 20 Lines |