aboutsummaryrefslogtreecommitdiff
path: root/qa/rpc-tests/abandonconflict.py
diff options
context:
space:
mode:
authorJohn Newbery <john@johnnewbery.com>2017-03-08 15:56:30 -0500
committerJohn Newbery <john@johnnewbery.com>2017-03-20 10:40:31 -0400
commit00902c48cdc5d6a531abfd279fd8e7779cf0a0b8 (patch)
tree41891484a478a7478937fe4a12b63e6c7f31799a /qa/rpc-tests/abandonconflict.py
parentd34995a7bac6ed20ce42aa00c6252b900786e649 (diff)
downloadbitcoin-00902c48cdc5d6a531abfd279fd8e7779cf0a0b8.tar.xz
Rename qa directory to test
Diffstat (limited to 'qa/rpc-tests/abandonconflict.py')
-rwxr-xr-xqa/rpc-tests/abandonconflict.py166
1 files changed, 0 insertions, 166 deletions
diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py
deleted file mode 100755
index 887dbebd4f..0000000000
--- a/qa/rpc-tests/abandonconflict.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) 2014-2016 The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-"""Test the abandontransaction RPC.
-
- The abandontransaction RPC marks a transaction and all its in-wallet
- 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
- 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.
-"""
-
-from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import *
-import urllib.parse
-
-class AbandonConflictTest(BitcoinTestFramework):
- def __init__(self):
- super().__init__()
- self.num_nodes = 2
- self.setup_clean_chain = False
-
- def setup_network(self):
- self.nodes = []
- self.nodes.append(start_node(0, self.options.tmpdir, ["-minrelaytxfee=0.00001"]))
- self.nodes.append(start_node(1, self.options.tmpdir))
- connect_nodes(self.nodes[0], 1)
-
- def run_test(self):
- self.nodes[1].generate(100)
- sync_blocks(self.nodes)
- balance = self.nodes[0].getbalance()
- txA = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10"))
- txB = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10"))
- txC = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10"))
- sync_mempools(self.nodes)
- self.nodes[1].generate(1)
-
- sync_blocks(self.nodes)
- newbalance = self.nodes[0].getbalance()
- assert(balance - newbalance < Decimal("0.001")) #no more than fees lost
- balance = newbalance
-
- url = urllib.parse.urlparse(self.nodes[1].url)
- self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1)))
-
- # Identify the 10btc outputs
- nA = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txA, 1)["vout"]) if vout["value"] == Decimal("10"))
- nB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txB, 1)["vout"]) if vout["value"] == Decimal("10"))
- nC = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txC, 1)["vout"]) if vout["value"] == Decimal("10"))
-
- inputs =[]
- # spend 10btc outputs from txA and txB
- inputs.append({"txid":txA, "vout":nA})
- inputs.append({"txid":txB, "vout":nB})
- outputs = {}
-
- outputs[self.nodes[0].getnewaddress()] = Decimal("14.99998")
- outputs[self.nodes[1].getnewaddress()] = Decimal("5")
- signed = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs))
- txAB1 = self.nodes[0].sendrawtransaction(signed["hex"])
-
- # Identify the 14.99998btc output
- nAB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txAB1, 1)["vout"]) if vout["value"] == Decimal("14.99998"))
-
- #Create a child tx spending AB1 and C
- inputs = []
- inputs.append({"txid":txAB1, "vout":nAB})
- inputs.append({"txid":txC, "vout":nC})
- outputs = {}
- outputs[self.nodes[0].getnewaddress()] = Decimal("24.9996")
- signed2 = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs))
- txABC2 = self.nodes[0].sendrawtransaction(signed2["hex"])
-
- # In mempool txs from self should increase balance from change
- newbalance = self.nodes[0].getbalance()
- assert_equal(newbalance, balance - Decimal("30") + Decimal("24.9996"))
- balance = newbalance
-
- # Restart the node with a higher min relay fee so the parent tx is no longer in mempool
- # TODO: redo with eviction
- stop_node(self.nodes[0],0)
- self.nodes[0]=start_node(0, self.options.tmpdir, ["-minrelaytxfee=0.0001"])
-
- # Verify txs no longer in mempool
- assert_equal(len(self.nodes[0].getrawmempool()), 0)
-
- # Not in mempool txs from self should only reduce balance
- # inputs are still spent, but change not received
- newbalance = self.nodes[0].getbalance()
- assert_equal(newbalance, balance - Decimal("24.9996"))
- # Unconfirmed received funds that are not in mempool, also shouldn't show
- # up in unconfirmed balance
- unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance()
- assert_equal(unconfbalance, newbalance)
- # Also shouldn't show up in listunspent
- assert(not txABC2 in [utxo["txid"] for utxo in self.nodes[0].listunspent(0)])
- balance = newbalance
-
- # Abandon original transaction and verify inputs are available again
- # including that the child tx was also abandoned
- self.nodes[0].abandontransaction(txAB1)
- newbalance = self.nodes[0].getbalance()
- assert_equal(newbalance, balance + Decimal("30"))
- balance = newbalance
-
- # Verify that even with a low min relay fee, the tx is not reaccepted from wallet on startup once abandoned
- stop_node(self.nodes[0],0)
- self.nodes[0]=start_node(0, self.options.tmpdir, ["-minrelaytxfee=0.00001"])
- assert_equal(len(self.nodes[0].getrawmempool()), 0)
- assert_equal(self.nodes[0].getbalance(), balance)
-
- # But if its received again then it is unabandoned
- # And since now in mempool, the change is available
- # But its child tx remains abandoned
- self.nodes[0].sendrawtransaction(signed["hex"])
- newbalance = self.nodes[0].getbalance()
- assert_equal(newbalance, balance - Decimal("20") + Decimal("14.99998"))
- balance = newbalance
-
- # Send child tx again so its unabandoned
- self.nodes[0].sendrawtransaction(signed2["hex"])
- newbalance = self.nodes[0].getbalance()
- assert_equal(newbalance, balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996"))
- balance = newbalance
-
- # Remove using high relay fee again
- stop_node(self.nodes[0],0)
- self.nodes[0]=start_node(0, self.options.tmpdir, ["-minrelaytxfee=0.0001"])
- assert_equal(len(self.nodes[0].getrawmempool()), 0)
- newbalance = self.nodes[0].getbalance()
- assert_equal(newbalance, balance - Decimal("24.9996"))
- balance = newbalance
-
- # Create a double spend of AB1 by spending again from only A's 10 output
- # Mine double spend from node 1
- inputs =[]
- inputs.append({"txid":txA, "vout":nA})
- outputs = {}
- outputs[self.nodes[1].getnewaddress()] = Decimal("9.9999")
- tx = self.nodes[0].createrawtransaction(inputs, outputs)
- signed = self.nodes[0].signrawtransaction(tx)
- self.nodes[1].sendrawtransaction(signed["hex"])
- self.nodes[1].generate(1)
-
- connect_nodes(self.nodes[0], 1)
- sync_blocks(self.nodes)
-
- # Verify that B and C's 10 BTC outputs are available for spending again because AB1 is now conflicted
- newbalance = self.nodes[0].getbalance()
- assert_equal(newbalance, balance + Decimal("20"))
- balance = newbalance
-
- # There is currently a minor bug around this and so this test doesn't work. See Issue #7315
- # Invalidate the block with the double spend and B's 10 BTC output should no longer be available
- # Don't think C's should either
- self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
- newbalance = self.nodes[0].getbalance()
- #assert_equal(newbalance, balance - Decimal("10"))
- self.log.info("If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer")
- self.log.info("conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315")
- self.log.info(str(balance) + " -> " + str(newbalance) + " ?")
-
-if __name__ == '__main__':
- AbandonConflictTest().main()