Add rpc test for prioritisetransaction
[bitcoinplatinum.git] / qa / rpc-tests / prioritise_transaction.py
blobf376ceee5ecb637ccaf91f489b69160bfc1461ba
1 #!/usr/bin/env python2
2 # Copyright (c) 2015 The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 # Test PrioritiseTransaction code
10 from test_framework.test_framework import BitcoinTestFramework
11 from test_framework.util import *
13 COIN = 100000000
15 class PrioritiseTransactionTest(BitcoinTestFramework):
17 def __init__(self):
18 # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create
19 # So we have big transactions (and therefore can't fit very many into each block)
20 # create one script_pubkey
21 script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
22 for i in xrange (512):
23 script_pubkey = script_pubkey + "01"
24 # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
25 self.txouts = "81"
26 for k in xrange(128):
27 # add txout value
28 self.txouts = self.txouts + "0000000000000000"
29 # add length of script_pubkey
30 self.txouts = self.txouts + "fd0402"
31 # add script_pubkey
32 self.txouts = self.txouts + script_pubkey
34 def setup_chain(self):
35 print("Initializing test directory "+self.options.tmpdir)
36 initialize_chain_clean(self.options.tmpdir, 1)
38 def setup_network(self):
39 self.nodes = []
40 self.is_network_split = False
42 self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-printpriority=1"]))
43 self.relayfee = self.nodes[0].getnetworkinfo()['relayfee']
45 def create_confirmed_utxos(self, count):
46 self.nodes[0].generate(int(0.5*count)+101)
47 utxos = self.nodes[0].listunspent()
48 iterations = count - len(utxos)
49 addr1 = self.nodes[0].getnewaddress()
50 addr2 = self.nodes[0].getnewaddress()
51 if iterations <= 0:
52 return utxos
53 for i in xrange(iterations):
54 t = utxos.pop()
55 fee = self.relayfee
56 inputs = []
57 inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
58 outputs = {}
59 send_value = t['amount'] - fee
60 outputs[addr1] = satoshi_round(send_value/2)
61 outputs[addr2] = satoshi_round(send_value/2)
62 raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
63 signed_tx = self.nodes[0].signrawtransaction(raw_tx)["hex"]
64 txid = self.nodes[0].sendrawtransaction(signed_tx)
66 while (self.nodes[0].getmempoolinfo()['size'] > 0):
67 self.nodes[0].generate(1)
69 utxos = self.nodes[0].listunspent()
70 assert(len(utxos) >= count)
71 return utxos
73 def create_lots_of_big_transactions(self, utxos, fee):
74 addr = self.nodes[0].getnewaddress()
75 txids = []
76 for i in xrange(len(utxos)):
77 t = utxos.pop()
78 inputs = []
79 inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
80 outputs = {}
81 send_value = t['amount'] - fee
82 outputs[addr] = satoshi_round(send_value)
83 rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
84 newtx = rawtx[0:92]
85 newtx = newtx + self.txouts
86 newtx = newtx + rawtx[94:]
87 signresult = self.nodes[0].signrawtransaction(newtx, None, None, "NONE")
88 txid = self.nodes[0].sendrawtransaction(signresult["hex"], True)
89 txids.append(txid)
90 return txids
92 def run_test(self):
93 utxos = self.create_confirmed_utxos(90)
94 base_fee = self.relayfee*100 # our transactions are smaller than 100kb
95 txids = []
97 # Create 3 batches of transactions at 3 different fee rate levels
98 for i in xrange(3):
99 txids.append([])
100 txids[i] = self.create_lots_of_big_transactions(utxos[30*i:30*i+30], (i+1)*base_fee)
102 # add a fee delta to something in the cheapest bucket and make sure it gets mined
103 # also check that a different entry in the cheapest bucket is NOT mined (lower
104 # the priority to ensure its not mined due to priority)
105 self.nodes[0].prioritisetransaction(txids[0][0], 0, int(3*base_fee*COIN))
106 self.nodes[0].prioritisetransaction(txids[0][1], -1e15, 0)
108 self.nodes[0].generate(1)
110 mempool = self.nodes[0].getrawmempool()
111 print "Assert that prioritised transasction was mined"
112 assert(txids[0][0] not in mempool)
113 assert(txids[0][1] in mempool)
115 high_fee_tx = None
116 for x in txids[2]:
117 if x not in mempool:
118 high_fee_tx = x
120 # Something high-fee should have been mined!
121 assert(high_fee_tx != None)
123 # Add a prioritisation before a tx is in the mempool (de-prioritising a
124 # high-fee transaction).
125 self.nodes[0].prioritisetransaction(high_fee_tx, -1e15, -int(2*base_fee*COIN))
127 # Add everything back to mempool
128 self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
130 # Check to make sure our high fee rate tx is back in the mempool
131 mempool = self.nodes[0].getrawmempool()
132 assert(high_fee_tx in mempool)
134 # Now verify the high feerate transaction isn't mined.
135 self.nodes[0].generate(5)
137 # High fee transaction should not have been mined, but other high fee rate
138 # transactions should have been.
139 mempool = self.nodes[0].getrawmempool()
140 print "Assert that de-prioritised transaction is still in mempool"
141 assert(high_fee_tx in mempool)
142 for x in txids[2]:
143 if (x != high_fee_tx):
144 assert(x not in mempool)
146 if __name__ == '__main__':
147 PrioritiseTransactionTest().main()