Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_abandonconflict.py
Show All 13 Lines | |||||
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, | assert_raises_rpc_error, | ||||
connect_nodes, | connect_nodes, | ||||
disconnect_nodes, | disconnect_nodes, | ||||
satoshi_round, | satoshi_round, | ||||
sync_blocks, | |||||
sync_mempools, | |||||
) | ) | ||||
class AbandonConflictTest(BitcoinTestFramework): | class AbandonConflictTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 2 | self.num_nodes = 2 | ||||
self.extra_args = [["-minrelaytxfee=0.00001"], []] | self.extra_args = [["-minrelaytxfee=0.00001"], []] | ||||
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: | ||||
# '-=' is because gettransaction(txid)['fee'] returns a negative | # '-=' is because gettransaction(txid)['fee'] returns a negative | ||||
total -= self.nodes[0].gettransaction(txid)['fee'] | total -= self.nodes[0].gettransaction(txid)['fee'] | ||||
return satoshi_round(total) | return satoshi_round(total) | ||||
self.nodes[1].generate(100) | self.nodes[1].generate(100) | ||||
sync_blocks(self.nodes) | self.sync_blocks() | ||||
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( | ||||
self.nodes[0].getnewaddress(), Decimal("10")) | self.nodes[0].getnewaddress(), Decimal("10")) | ||||
sync_mempools(self.nodes) | self.sync_mempools() | ||||
self.nodes[1].generate(1) | self.nodes[1].generate(1) | ||||
# Can not abandon non-wallet transaction | # Can not abandon non-wallet transaction | ||||
assert_raises_rpc_error(-5, 'Invalid or non-wallet transaction id', | assert_raises_rpc_error(-5, 'Invalid or non-wallet transaction id', | ||||
lambda: self.nodes[0].abandontransaction(txid='ff' * 32)) | lambda: self.nodes[0].abandontransaction(txid='ff' * 32)) | ||||
# Can not abandon confirmed transaction | # Can not abandon confirmed transaction | ||||
assert_raises_rpc_error(-5, 'Transaction not eligible for abandonment', | assert_raises_rpc_error(-5, 'Transaction not eligible for abandonment', | ||||
lambda: self.nodes[0].abandontransaction(txid=txA)) | lambda: self.nodes[0].abandontransaction(txid=txA)) | ||||
sync_blocks(self.nodes) | self.sync_blocks() | ||||
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 | # Disconnect nodes so node0's transactions don't get into node1's | ||||
# mempool | # mempool | ||||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
outputs = {} | outputs = {} | ||||
outputs[self.nodes[1].getnewaddress()] = Decimal("9.9999") | outputs[self.nodes[1].getnewaddress()] = Decimal("9.9999") | ||||
tx = self.nodes[0].createrawtransaction(inputs, outputs) | tx = self.nodes[0].createrawtransaction(inputs, outputs) | ||||
signed = self.nodes[0].signrawtransactionwithwallet(tx) | signed = self.nodes[0].signrawtransactionwithwallet(tx) | ||||
self.nodes[1].sendrawtransaction(signed["hex"]) | self.nodes[1].sendrawtransaction(signed["hex"]) | ||||
self.nodes[1].generate(1) | self.nodes[1].generate(1) | ||||
connect_nodes(self.nodes[0], self.nodes[1]) | connect_nodes(self.nodes[0], self.nodes[1]) | ||||
sync_blocks(self.nodes) | self.sync_blocks() | ||||
# Verify that B and C's 10 BCH outputs are available for spending again | # Verify that B and C's 10 BCH outputs are available for spending again | ||||
# because AB1 is now conflicted | # because AB1 is now conflicted | ||||
newbalance = self.nodes[0].getbalance() | newbalance = self.nodes[0].getbalance() | ||||
assert_equal(newbalance, balance + Decimal("20")) | assert_equal(newbalance, balance + Decimal("20")) | ||||
balance = newbalance | balance = newbalance | ||||
# There is currently a minor bug around this and so this test doesn't work. See Issue #7315 | # There is currently a minor bug around this and so this test doesn't work. See Issue #7315 | ||||
Show All 14 Lines |