Merge #11121: TestNode tidyups
[bitcoinplatinum.git] / test / functional / replace-by-fee.py
blob1d6494fe413101f203fa49de376bfd2ffc36bd00
1 #!/usr/bin/env python3
2 # Copyright (c) 2014-2016 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.
5 """Test the RBF code."""
7 from test_framework.test_framework import BitcoinTestFramework
8 from test_framework.util import *
9 from test_framework.script import *
10 from test_framework.mininode import *
12 MAX_REPLACEMENT_LIMIT = 100
14 def txToHex(tx):
15 return bytes_to_hex_str(tx.serialize())
17 def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
18 """Create a txout with a given amount and scriptPubKey
20 Mines coins as needed.
22 confirmed - txouts created will be confirmed in the blockchain;
23 unconfirmed otherwise.
24 """
25 fee = 1*COIN
26 while node.getbalance() < satoshi_round((amount + fee)/COIN):
27 node.generate(100)
29 new_addr = node.getnewaddress()
30 txid = node.sendtoaddress(new_addr, satoshi_round((amount+fee)/COIN))
31 tx1 = node.getrawtransaction(txid, 1)
32 txid = int(txid, 16)
33 i = None
35 for i, txout in enumerate(tx1['vout']):
36 if txout['scriptPubKey']['addresses'] == [new_addr]:
37 break
38 assert i is not None
40 tx2 = CTransaction()
41 tx2.vin = [CTxIn(COutPoint(txid, i))]
42 tx2.vout = [CTxOut(amount, scriptPubKey)]
43 tx2.rehash()
45 signed_tx = node.signrawtransaction(txToHex(tx2))
47 txid = node.sendrawtransaction(signed_tx['hex'], True)
49 # If requested, ensure txouts are confirmed.
50 if confirmed:
51 mempool_size = len(node.getrawmempool())
52 while mempool_size > 0:
53 node.generate(1)
54 new_size = len(node.getrawmempool())
55 # Error out if we have something stuck in the mempool, as this
56 # would likely be a bug.
57 assert(new_size < mempool_size)
58 mempool_size = new_size
60 return COutPoint(int(txid, 16), 0)
62 class ReplaceByFeeTest(BitcoinTestFramework):
64 def set_test_params(self):
65 self.num_nodes = 1
66 self.extra_args= [["-maxorphantx=1000",
67 "-whitelist=127.0.0.1",
68 "-limitancestorcount=50",
69 "-limitancestorsize=101",
70 "-limitdescendantcount=200",
71 "-limitdescendantsize=101"]]
73 def run_test(self):
74 make_utxo(self.nodes[0], 1*COIN)
76 self.log.info("Running test simple doublespend...")
77 self.test_simple_doublespend()
79 self.log.info("Running test doublespend chain...")
80 self.test_doublespend_chain()
82 self.log.info("Running test doublespend tree...")
83 self.test_doublespend_tree()
85 self.log.info("Running test replacement feeperkb...")
86 self.test_replacement_feeperkb()
88 self.log.info("Running test spends of conflicting outputs...")
89 self.test_spends_of_conflicting_outputs()
91 self.log.info("Running test new unconfirmed inputs...")
92 self.test_new_unconfirmed_inputs()
94 self.log.info("Running test too many replacements...")
95 self.test_too_many_replacements()
97 self.log.info("Running test opt-in...")
98 self.test_opt_in()
100 self.log.info("Running test RPC...")
101 self.test_rpc()
103 self.log.info("Running test prioritised transactions...")
104 self.test_prioritised_transactions()
106 self.log.info("Passed")
108 def test_simple_doublespend(self):
109 """Simple doublespend"""
110 tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
112 tx1a = CTransaction()
113 tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
114 tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))]
115 tx1a_hex = txToHex(tx1a)
116 tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
118 # Should fail because we haven't changed the fee
119 tx1b = CTransaction()
120 tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
121 tx1b.vout = [CTxOut(1*COIN, CScript([b'b']))]
122 tx1b_hex = txToHex(tx1b)
124 # This will raise an exception due to insufficient fee
125 assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, True)
127 # Extra 0.1 BTC fee
128 tx1b = CTransaction()
129 tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
130 tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
131 tx1b_hex = txToHex(tx1b)
132 tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
134 mempool = self.nodes[0].getrawmempool()
136 assert (tx1a_txid not in mempool)
137 assert (tx1b_txid in mempool)
139 assert_equal(tx1b_hex, self.nodes[0].getrawtransaction(tx1b_txid))
141 def test_doublespend_chain(self):
142 """Doublespend of a long chain"""
144 initial_nValue = 50*COIN
145 tx0_outpoint = make_utxo(self.nodes[0], initial_nValue)
147 prevout = tx0_outpoint
148 remaining_value = initial_nValue
149 chain_txids = []
150 while remaining_value > 10*COIN:
151 remaining_value -= 1*COIN
152 tx = CTransaction()
153 tx.vin = [CTxIn(prevout, nSequence=0)]
154 tx.vout = [CTxOut(remaining_value, CScript([1]))]
155 tx_hex = txToHex(tx)
156 txid = self.nodes[0].sendrawtransaction(tx_hex, True)
157 chain_txids.append(txid)
158 prevout = COutPoint(int(txid, 16), 0)
160 # Whether the double-spend is allowed is evaluated by including all
161 # child fees - 40 BTC - so this attempt is rejected.
162 dbl_tx = CTransaction()
163 dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
164 dbl_tx.vout = [CTxOut(initial_nValue - 30*COIN, CScript([1]))]
165 dbl_tx_hex = txToHex(dbl_tx)
167 # This will raise an exception due to insufficient fee
168 assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, dbl_tx_hex, True)
170 # Accepted with sufficient fee
171 dbl_tx = CTransaction()
172 dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
173 dbl_tx.vout = [CTxOut(1*COIN, CScript([1]))]
174 dbl_tx_hex = txToHex(dbl_tx)
175 self.nodes[0].sendrawtransaction(dbl_tx_hex, True)
177 mempool = self.nodes[0].getrawmempool()
178 for doublespent_txid in chain_txids:
179 assert(doublespent_txid not in mempool)
181 def test_doublespend_tree(self):
182 """Doublespend of a big tree of transactions"""
184 initial_nValue = 50*COIN
185 tx0_outpoint = make_utxo(self.nodes[0], initial_nValue)
187 def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.0001*COIN, _total_txs=None):
188 if _total_txs is None:
189 _total_txs = [0]
190 if _total_txs[0] >= max_txs:
191 return
193 txout_value = (initial_value - fee) // tree_width
194 if txout_value < fee:
195 return
197 vout = [CTxOut(txout_value, CScript([i+1]))
198 for i in range(tree_width)]
199 tx = CTransaction()
200 tx.vin = [CTxIn(prevout, nSequence=0)]
201 tx.vout = vout
202 tx_hex = txToHex(tx)
204 assert(len(tx.serialize()) < 100000)
205 txid = self.nodes[0].sendrawtransaction(tx_hex, True)
206 yield tx
207 _total_txs[0] += 1
209 txid = int(txid, 16)
211 for i, txout in enumerate(tx.vout):
212 for x in branch(COutPoint(txid, i), txout_value,
213 max_txs,
214 tree_width=tree_width, fee=fee,
215 _total_txs=_total_txs):
216 yield x
218 fee = int(0.0001*COIN)
219 n = MAX_REPLACEMENT_LIMIT
220 tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
221 assert_equal(len(tree_txs), n)
223 # Attempt double-spend, will fail because too little fee paid
224 dbl_tx = CTransaction()
225 dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
226 dbl_tx.vout = [CTxOut(initial_nValue - fee*n, CScript([1]))]
227 dbl_tx_hex = txToHex(dbl_tx)
228 # This will raise an exception due to insufficient fee
229 assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, dbl_tx_hex, True)
231 # 1 BTC fee is enough
232 dbl_tx = CTransaction()
233 dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
234 dbl_tx.vout = [CTxOut(initial_nValue - fee*n - 1*COIN, CScript([1]))]
235 dbl_tx_hex = txToHex(dbl_tx)
236 self.nodes[0].sendrawtransaction(dbl_tx_hex, True)
238 mempool = self.nodes[0].getrawmempool()
240 for tx in tree_txs:
241 tx.rehash()
242 assert (tx.hash not in mempool)
244 # Try again, but with more total transactions than the "max txs
245 # double-spent at once" anti-DoS limit.
246 for n in (MAX_REPLACEMENT_LIMIT+1, MAX_REPLACEMENT_LIMIT*2):
247 fee = int(0.0001*COIN)
248 tx0_outpoint = make_utxo(self.nodes[0], initial_nValue)
249 tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
250 assert_equal(len(tree_txs), n)
252 dbl_tx = CTransaction()
253 dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
254 dbl_tx.vout = [CTxOut(initial_nValue - 2*fee*n, CScript([1]))]
255 dbl_tx_hex = txToHex(dbl_tx)
256 # This will raise an exception
257 assert_raises_jsonrpc(-26, "too many potential replacements", self.nodes[0].sendrawtransaction, dbl_tx_hex, True)
259 for tx in tree_txs:
260 tx.rehash()
261 self.nodes[0].getrawtransaction(tx.hash)
263 def test_replacement_feeperkb(self):
264 """Replacement requires fee-per-KB to be higher"""
265 tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
267 tx1a = CTransaction()
268 tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
269 tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))]
270 tx1a_hex = txToHex(tx1a)
271 self.nodes[0].sendrawtransaction(tx1a_hex, True)
273 # Higher fee, but the fee per KB is much lower, so the replacement is
274 # rejected.
275 tx1b = CTransaction()
276 tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
277 tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000]))]
278 tx1b_hex = txToHex(tx1b)
280 # This will raise an exception due to insufficient fee
281 assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, True)
283 def test_spends_of_conflicting_outputs(self):
284 """Replacements that spend conflicting tx outputs are rejected"""
285 utxo1 = make_utxo(self.nodes[0], int(1.2*COIN))
286 utxo2 = make_utxo(self.nodes[0], 3*COIN)
288 tx1a = CTransaction()
289 tx1a.vin = [CTxIn(utxo1, nSequence=0)]
290 tx1a.vout = [CTxOut(int(1.1*COIN), CScript([b'a']))]
291 tx1a_hex = txToHex(tx1a)
292 tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
294 tx1a_txid = int(tx1a_txid, 16)
296 # Direct spend an output of the transaction we're replacing.
297 tx2 = CTransaction()
298 tx2.vin = [CTxIn(utxo1, nSequence=0), CTxIn(utxo2, nSequence=0)]
299 tx2.vin.append(CTxIn(COutPoint(tx1a_txid, 0), nSequence=0))
300 tx2.vout = tx1a.vout
301 tx2_hex = txToHex(tx2)
303 # This will raise an exception
304 assert_raises_jsonrpc(-26, "bad-txns-spends-conflicting-tx", self.nodes[0].sendrawtransaction, tx2_hex, True)
306 # Spend tx1a's output to test the indirect case.
307 tx1b = CTransaction()
308 tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)]
309 tx1b.vout = [CTxOut(1*COIN, CScript([b'a']))]
310 tx1b_hex = txToHex(tx1b)
311 tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
312 tx1b_txid = int(tx1b_txid, 16)
314 tx2 = CTransaction()
315 tx2.vin = [CTxIn(utxo1, nSequence=0), CTxIn(utxo2, nSequence=0),
316 CTxIn(COutPoint(tx1b_txid, 0))]
317 tx2.vout = tx1a.vout
318 tx2_hex = txToHex(tx2)
320 # This will raise an exception
321 assert_raises_jsonrpc(-26, "bad-txns-spends-conflicting-tx", self.nodes[0].sendrawtransaction, tx2_hex, True)
323 def test_new_unconfirmed_inputs(self):
324 """Replacements that add new unconfirmed inputs are rejected"""
325 confirmed_utxo = make_utxo(self.nodes[0], int(1.1*COIN))
326 unconfirmed_utxo = make_utxo(self.nodes[0], int(0.1*COIN), False)
328 tx1 = CTransaction()
329 tx1.vin = [CTxIn(confirmed_utxo)]
330 tx1.vout = [CTxOut(1*COIN, CScript([b'a']))]
331 tx1_hex = txToHex(tx1)
332 self.nodes[0].sendrawtransaction(tx1_hex, True)
334 tx2 = CTransaction()
335 tx2.vin = [CTxIn(confirmed_utxo), CTxIn(unconfirmed_utxo)]
336 tx2.vout = tx1.vout
337 tx2_hex = txToHex(tx2)
339 # This will raise an exception
340 assert_raises_jsonrpc(-26, "replacement-adds-unconfirmed", self.nodes[0].sendrawtransaction, tx2_hex, True)
342 def test_too_many_replacements(self):
343 """Replacements that evict too many transactions are rejected"""
344 # Try directly replacing more than MAX_REPLACEMENT_LIMIT
345 # transactions
347 # Start by creating a single transaction with many outputs
348 initial_nValue = 10*COIN
349 utxo = make_utxo(self.nodes[0], initial_nValue)
350 fee = int(0.0001*COIN)
351 split_value = int((initial_nValue-fee)/(MAX_REPLACEMENT_LIMIT+1))
353 outputs = []
354 for i in range(MAX_REPLACEMENT_LIMIT+1):
355 outputs.append(CTxOut(split_value, CScript([1])))
357 splitting_tx = CTransaction()
358 splitting_tx.vin = [CTxIn(utxo, nSequence=0)]
359 splitting_tx.vout = outputs
360 splitting_tx_hex = txToHex(splitting_tx)
362 txid = self.nodes[0].sendrawtransaction(splitting_tx_hex, True)
363 txid = int(txid, 16)
365 # Now spend each of those outputs individually
366 for i in range(MAX_REPLACEMENT_LIMIT+1):
367 tx_i = CTransaction()
368 tx_i.vin = [CTxIn(COutPoint(txid, i), nSequence=0)]
369 tx_i.vout = [CTxOut(split_value-fee, CScript([b'a']))]
370 tx_i_hex = txToHex(tx_i)
371 self.nodes[0].sendrawtransaction(tx_i_hex, True)
373 # Now create doublespend of the whole lot; should fail.
374 # Need a big enough fee to cover all spending transactions and have
375 # a higher fee rate
376 double_spend_value = (split_value-100*fee)*(MAX_REPLACEMENT_LIMIT+1)
377 inputs = []
378 for i in range(MAX_REPLACEMENT_LIMIT+1):
379 inputs.append(CTxIn(COutPoint(txid, i), nSequence=0))
380 double_tx = CTransaction()
381 double_tx.vin = inputs
382 double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))]
383 double_tx_hex = txToHex(double_tx)
385 # This will raise an exception
386 assert_raises_jsonrpc(-26, "too many potential replacements", self.nodes[0].sendrawtransaction, double_tx_hex, True)
388 # If we remove an input, it should pass
389 double_tx = CTransaction()
390 double_tx.vin = inputs[0:-1]
391 double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))]
392 double_tx_hex = txToHex(double_tx)
393 self.nodes[0].sendrawtransaction(double_tx_hex, True)
395 def test_opt_in(self):
396 """Replacing should only work if orig tx opted in"""
397 tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
399 # Create a non-opting in transaction
400 tx1a = CTransaction()
401 tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0xffffffff)]
402 tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))]
403 tx1a_hex = txToHex(tx1a)
404 tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
406 # Shouldn't be able to double-spend
407 tx1b = CTransaction()
408 tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
409 tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
410 tx1b_hex = txToHex(tx1b)
412 # This will raise an exception
413 assert_raises_jsonrpc(-26, "txn-mempool-conflict", self.nodes[0].sendrawtransaction, tx1b_hex, True)
415 tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
417 # Create a different non-opting in transaction
418 tx2a = CTransaction()
419 tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0xfffffffe)]
420 tx2a.vout = [CTxOut(1*COIN, CScript([b'a']))]
421 tx2a_hex = txToHex(tx2a)
422 tx2a_txid = self.nodes[0].sendrawtransaction(tx2a_hex, True)
424 # Still shouldn't be able to double-spend
425 tx2b = CTransaction()
426 tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
427 tx2b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
428 tx2b_hex = txToHex(tx2b)
430 # This will raise an exception
431 assert_raises_jsonrpc(-26, "txn-mempool-conflict", self.nodes[0].sendrawtransaction, tx2b_hex, True)
433 # Now create a new transaction that spends from tx1a and tx2a
434 # opt-in on one of the inputs
435 # Transaction should be replaceable on either input
437 tx1a_txid = int(tx1a_txid, 16)
438 tx2a_txid = int(tx2a_txid, 16)
440 tx3a = CTransaction()
441 tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff),
442 CTxIn(COutPoint(tx2a_txid, 0), nSequence=0xfffffffd)]
443 tx3a.vout = [CTxOut(int(0.9*COIN), CScript([b'c'])), CTxOut(int(0.9*COIN), CScript([b'd']))]
444 tx3a_hex = txToHex(tx3a)
446 self.nodes[0].sendrawtransaction(tx3a_hex, True)
448 tx3b = CTransaction()
449 tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)]
450 tx3b.vout = [CTxOut(int(0.5*COIN), CScript([b'e']))]
451 tx3b_hex = txToHex(tx3b)
453 tx3c = CTransaction()
454 tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), nSequence=0)]
455 tx3c.vout = [CTxOut(int(0.5*COIN), CScript([b'f']))]
456 tx3c_hex = txToHex(tx3c)
458 self.nodes[0].sendrawtransaction(tx3b_hex, True)
459 # If tx3b was accepted, tx3c won't look like a replacement,
460 # but make sure it is accepted anyway
461 self.nodes[0].sendrawtransaction(tx3c_hex, True)
463 def test_prioritised_transactions(self):
464 # Ensure that fee deltas used via prioritisetransaction are
465 # correctly used by replacement logic
467 # 1. Check that feeperkb uses modified fees
468 tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
470 tx1a = CTransaction()
471 tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
472 tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))]
473 tx1a_hex = txToHex(tx1a)
474 tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
476 # Higher fee, but the actual fee per KB is much lower.
477 tx1b = CTransaction()
478 tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
479 tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*740000]))]
480 tx1b_hex = txToHex(tx1b)
482 # Verify tx1b cannot replace tx1a.
483 assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, True)
485 # Use prioritisetransaction to set tx1a's fee to 0.
486 self.nodes[0].prioritisetransaction(txid=tx1a_txid, fee_delta=int(-0.1*COIN))
488 # Now tx1b should be able to replace tx1a
489 tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
491 assert(tx1b_txid in self.nodes[0].getrawmempool())
493 # 2. Check that absolute fee checks use modified fee.
494 tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
496 tx2a = CTransaction()
497 tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)]
498 tx2a.vout = [CTxOut(1*COIN, CScript([b'a']))]
499 tx2a_hex = txToHex(tx2a)
500 self.nodes[0].sendrawtransaction(tx2a_hex, True)
502 # Lower fee, but we'll prioritise it
503 tx2b = CTransaction()
504 tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
505 tx2b.vout = [CTxOut(int(1.01*COIN), CScript([b'a']))]
506 tx2b.rehash()
507 tx2b_hex = txToHex(tx2b)
509 # Verify tx2b cannot replace tx2a.
510 assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx2b_hex, True)
512 # Now prioritise tx2b to have a higher modified fee
513 self.nodes[0].prioritisetransaction(txid=tx2b.hash, fee_delta=int(0.1*COIN))
515 # tx2b should now be accepted
516 tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)
518 assert(tx2b_txid in self.nodes[0].getrawmempool())
520 def test_rpc(self):
521 us0 = self.nodes[0].listunspent()[0]
522 ins = [us0]
523 outs = {self.nodes[0].getnewaddress() : Decimal(1.0000000)}
524 rawtx0 = self.nodes[0].createrawtransaction(ins, outs, 0, True)
525 rawtx1 = self.nodes[0].createrawtransaction(ins, outs, 0, False)
526 json0 = self.nodes[0].decoderawtransaction(rawtx0)
527 json1 = self.nodes[0].decoderawtransaction(rawtx1)
528 assert_equal(json0["vin"][0]["sequence"], 4294967293)
529 assert_equal(json1["vin"][0]["sequence"], 4294967295)
531 rawtx2 = self.nodes[0].createrawtransaction([], outs)
532 frawtx2a = self.nodes[0].fundrawtransaction(rawtx2, {"replaceable": True})
533 frawtx2b = self.nodes[0].fundrawtransaction(rawtx2, {"replaceable": False})
535 json0 = self.nodes[0].decoderawtransaction(frawtx2a['hex'])
536 json1 = self.nodes[0].decoderawtransaction(frawtx2b['hex'])
537 assert_equal(json0["vin"][0]["sequence"], 4294967293)
538 assert_equal(json1["vin"][0]["sequence"], 4294967294)
540 if __name__ == '__main__':
541 ReplaceByFeeTest().main()