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 *
15 class PrioritiseTransactionTest(BitcoinTestFramework
):
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
28 self
.txouts
= self
.txouts
+ "0000000000000000"
29 # add length of script_pubkey
30 self
.txouts
= self
.txouts
+ "fd0402"
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
):
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()
53 for i
in xrange(iterations
):
57 inputs
.append({ "txid" : t
["txid"], "vout" : t
["vout"]})
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
)
73 def create_lots_of_big_transactions(self
, utxos
, fee
):
74 addr
= self
.nodes
[0].getnewaddress()
76 for i
in xrange(len(utxos
)):
79 inputs
.append({ "txid" : t
["txid"], "vout" : t
["vout"]})
81 send_value
= t
['amount'] - fee
82 outputs
[addr
] = satoshi_round(send_value
)
83 rawtx
= self
.nodes
[0].createrawtransaction(inputs
, outputs
)
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)
93 utxos
= self
.create_confirmed_utxos(90)
94 base_fee
= self
.relayfee
*100 # our transactions are smaller than 100kb
97 # Create 3 batches of transactions at 3 different fee rate levels
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
)
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
)
143 if (x
!= high_fee_tx
):
144 assert(x
not in mempool
)
146 if __name__
== '__main__':
147 PrioritiseTransactionTest().main()