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-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 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 | ||||
Show All 21 Lines | class AbandonConflictTest(BitcoinTestFramework): | ||||
def skip_test_if_missing_module(self): | def skip_test_if_missing_module(self): | ||||
self.skip_if_no_wallet() | self.skip_if_no_wallet() | ||||
def run_test(self): | def run_test(self): | ||||
def total_fees(*txids): | def total_fees(*txids): | ||||
total = 0 | total = 0 | ||||
for txid in txids: | for txid in txids: | ||||
total += self.nodes[0].calculate_fee_from_txid(txid) | total -= self.nodes[0].gettransaction(txid)['fee'] | ||||
Fabien: Please add a comment to explain that the returned fee is negative. | |||||
return satoshi_round(total) | return satoshi_round(total) | ||||
self.nodes[1].generate(100) | self.nodes[1].generate(100) | ||||
sync_blocks(self.nodes) | sync_blocks(self.nodes) | ||||
balance = self.nodes[0].getbalance() | balance = self.nodes[0].getbalance() | ||||
txA = self.nodes[0].sendtoaddress( | txA = self.nodes[0].sendtoaddress( | ||||
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( | ||||
Show All 16 Lines | def run_test(self): | ||||
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 | # Disconnect nodes so node0's transactions don't get into node1's | ||||
# mempool | # mempool | ||||
disconnect_nodes(self.nodes[0], self.nodes[1]) | disconnect_nodes(self.nodes[0], self.nodes[1]) | ||||
# Identify the 10btc outputs | # Identify the 10btc outputs | ||||
nA = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction( | nA = next(tx_out["vout"] for tx_out in self.nodes[0].gettransaction( | ||||
txA, 1)["vout"]) if vout["value"] == Decimal("10")) | txA)["details"] if tx_out["amount"] == Decimal("10")) | ||||
nB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction( | nB = next(tx_out["vout"] for tx_out in self.nodes[0].gettransaction( | ||||
txB, 1)["vout"]) if vout["value"] == Decimal("10")) | txB)["details"] if tx_out["amount"] == Decimal("10")) | ||||
nC = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction( | nC = next(tx_out["vout"] for tx_out in self.nodes[0].gettransaction( | ||||
txC, 1)["vout"]) if vout["value"] == Decimal("10")) | txC)["details"] if tx_out["amount"] == Decimal("10")) | ||||
inputs = [] | inputs = [] | ||||
# spend 10btc outputs from txA and txB | # spend 10btc outputs from txA and txB | ||||
inputs.append({"txid": txA, "vout": nA}) | inputs.append({"txid": txA, "vout": nA}) | ||||
inputs.append({"txid": txB, "vout": nB}) | inputs.append({"txid": txB, "vout": nB}) | ||||
outputs = {} | outputs = {} | ||||
outputs[self.nodes[0].getnewaddress()] = Decimal("14.99998") | outputs[self.nodes[0].getnewaddress()] = Decimal("14.99998") | ||||
outputs[self.nodes[1].getnewaddress()] = Decimal("5") | outputs[self.nodes[1].getnewaddress()] = Decimal("5") | ||||
signed = self.nodes[0].signrawtransactionwithwallet( | signed = self.nodes[0].signrawtransactionwithwallet( | ||||
self.nodes[0].createrawtransaction(inputs, outputs)) | self.nodes[0].createrawtransaction(inputs, outputs)) | ||||
txAB1 = self.nodes[0].sendrawtransaction(signed["hex"]) | txAB1 = self.nodes[0].sendrawtransaction(signed["hex"]) | ||||
# Identify the 14.99998btc output | # Identify the 14.99998btc output | ||||
nAB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction( | nAB = next(tx_out["vout"] for tx_out in self.nodes[0].gettransaction( | ||||
txAB1, 1)["vout"]) if vout["value"] == Decimal("14.99998")) | txAB1)["details"] if tx_out["amount"] == Decimal("14.99998")) | ||||
# Create a child tx spending AB1 and C | # Create a child tx spending AB1 and C | ||||
inputs = [] | inputs = [] | ||||
# Amount 14.99998 BCH | # Amount 14.99998 BCH | ||||
inputs.append({"txid": txAB1, "vout": nAB}) | inputs.append({"txid": txAB1, "vout": nAB}) | ||||
# Amount 10 BCH | # Amount 10 BCH | ||||
inputs.append({"txid": txC, "vout": nC}) | inputs.append({"txid": txC, "vout": nC}) | ||||
outputs = {} | outputs = {} | ||||
▲ Show 20 Lines • Show All 120 Lines • Show Last 20 Lines |
Please add a comment to explain that the returned fee is negative.