~ubuntu-branches/debian/stretch/bitcoin/stretch

« back to all changes in this revision

Viewing changes to qa/rpc-tests/replace-by-fee.py

  • Committer: Package Import Robot
  • Author(s): Anthony Towns
  • Date: 2016-10-21 17:13:13 UTC
  • mfrom: (1.3.2)
  • Revision ID: package-import@ubuntu.com-20161021171313-7eu2ltpbk0xag3q1
Tags: 0.13.0-0.1
* Non-maintainer upload.
* New upstream release.
* Allow compilation with gcc/g++ 6. (Closes: Bug#835963)
* Additional fixes for openssl 1.1 compatibility. (See Bug#828248)
* Check if -latomic is needed (it is on mips*).
* Remove reproducible build patch, since leveldb build system is
  no longer used in 0.13. (See Bug#791834)
* Update description since the blockchain is much more than "several GB"
  now. (Closes: Bug#835809)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python2
2
 
# Copyright (c) 2014-2015 The Bitcoin Core developers
 
1
#!/usr/bin/env python3
 
2
# Copyright (c) 2014-2016 The Bitcoin Core developers
3
3
# Distributed under the MIT software license, see the accompanying
4
4
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
5
 
11
11
from test_framework.util import *
12
12
from test_framework.script import *
13
13
from test_framework.mininode import *
14
 
import binascii
15
14
 
16
 
COIN = 100000000
17
15
MAX_REPLACEMENT_LIMIT = 100
18
16
 
19
 
def satoshi_round(amount):
20
 
    return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
21
 
 
22
17
def txToHex(tx):
23
 
    return binascii.hexlify(tx.serialize()).decode('utf-8')
 
18
    return bytes_to_hex_str(tx.serialize())
24
19
 
25
20
def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
26
21
    """Create a txout with a given amount and scriptPubKey
54
49
    tx2.vout = [CTxOut(amount, scriptPubKey)]
55
50
    tx2.rehash()
56
51
 
57
 
    binascii.hexlify(tx2.serialize()).decode('utf-8')
58
 
 
59
 
    signed_tx = node.signrawtransaction(binascii.hexlify(tx2.serialize()).decode('utf-8'))
 
52
    signed_tx = node.signrawtransaction(txToHex(tx2))
60
53
 
61
54
    txid = node.sendrawtransaction(signed_tx['hex'], True)
62
55
 
75
68
 
76
69
class ReplaceByFeeTest(BitcoinTestFramework):
77
70
 
 
71
    def __init__(self):
 
72
        super().__init__()
 
73
        self.num_nodes = 1
 
74
        self.setup_clean_chain = False
 
75
 
78
76
    def setup_network(self):
79
77
        self.nodes = []
80
78
        self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug",
89
87
    def run_test(self):
90
88
        make_utxo(self.nodes[0], 1*COIN)
91
89
 
92
 
        print "Running test simple doublespend..."
 
90
        print("Running test simple doublespend...")
93
91
        self.test_simple_doublespend()
94
92
 
95
 
        print "Running test doublespend chain..."
 
93
        print("Running test doublespend chain...")
96
94
        self.test_doublespend_chain()
97
95
 
98
 
        print "Running test doublespend tree..."
 
96
        print("Running test doublespend tree...")
99
97
        self.test_doublespend_tree()
100
98
 
101
 
        print "Running test replacement feeperkb..."
 
99
        print("Running test replacement feeperkb...")
102
100
        self.test_replacement_feeperkb()
103
101
 
104
 
        print "Running test spends of conflicting outputs..."
 
102
        print("Running test spends of conflicting outputs...")
105
103
        self.test_spends_of_conflicting_outputs()
106
104
 
107
 
        print "Running test new unconfirmed inputs..."
 
105
        print("Running test new unconfirmed inputs...")
108
106
        self.test_new_unconfirmed_inputs()
109
107
 
110
 
        print "Running test too many replacements..."
 
108
        print("Running test too many replacements...")
111
109
        self.test_too_many_replacements()
112
110
 
113
 
        print "Running test opt-in..."
 
111
        print("Running test opt-in...")
114
112
        self.test_opt_in()
115
113
 
116
 
        print "Running test prioritised transactions..."
 
114
        print("Running test prioritised transactions...")
117
115
        self.test_prioritised_transactions()
118
116
 
119
 
        print "Passed\n"
 
117
        print("Passed\n")
120
118
 
121
119
    def test_simple_doublespend(self):
122
120
        """Simple doublespend"""
123
 
        tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
 
121
        tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
124
122
 
125
123
        tx1a = CTransaction()
126
124
        tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
144
142
        # Extra 0.1 BTC fee
145
143
        tx1b = CTransaction()
146
144
        tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
147
 
        tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
 
145
        tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
148
146
        tx1b_hex = txToHex(tx1b)
149
147
        tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
150
148
 
236
234
                                  _total_txs=_total_txs):
237
235
                    yield x
238
236
 
239
 
        fee = 0.0001*COIN
 
237
        fee = int(0.0001*COIN)
240
238
        n = MAX_REPLACEMENT_LIMIT
241
239
        tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
242
240
        assert_equal(len(tree_txs), n)
269
267
        # Try again, but with more total transactions than the "max txs
270
268
        # double-spent at once" anti-DoS limit.
271
269
        for n in (MAX_REPLACEMENT_LIMIT+1, MAX_REPLACEMENT_LIMIT*2):
272
 
            fee = 0.0001*COIN
 
270
            fee = int(0.0001*COIN)
273
271
            tx0_outpoint = make_utxo(self.nodes[0], initial_nValue)
274
272
            tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
275
273
            assert_equal(len(tree_txs), n)
292
290
 
293
291
    def test_replacement_feeperkb(self):
294
292
        """Replacement requires fee-per-KB to be higher"""
295
 
        tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
 
293
        tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
296
294
 
297
295
        tx1a = CTransaction()
298
296
        tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
304
302
        # rejected.
305
303
        tx1b = CTransaction()
306
304
        tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
307
 
        tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*999000]))]
 
305
        tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000]))]
308
306
        tx1b_hex = txToHex(tx1b)
309
307
 
310
308
        try:
316
314
 
317
315
    def test_spends_of_conflicting_outputs(self):
318
316
        """Replacements that spend conflicting tx outputs are rejected"""
319
 
        utxo1 = make_utxo(self.nodes[0], 1.2*COIN)
320
 
        utxo2 = make_utxo(self.nodes[0], 3.0*COIN)
 
317
        utxo1 = make_utxo(self.nodes[0], int(1.2*COIN))
 
318
        utxo2 = make_utxo(self.nodes[0], 3*COIN)
321
319
 
322
320
        tx1a = CTransaction()
323
321
        tx1a.vin = [CTxIn(utxo1, nSequence=0)]
324
 
        tx1a.vout = [CTxOut(1.1*COIN, CScript([b'a']))]
 
322
        tx1a.vout = [CTxOut(int(1.1*COIN), CScript([b'a']))]
325
323
        tx1a_hex = txToHex(tx1a)
326
324
        tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
327
325
 
344
342
        # Spend tx1a's output to test the indirect case.
345
343
        tx1b = CTransaction()
346
344
        tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)]
347
 
        tx1b.vout = [CTxOut(1.0*COIN, CScript([b'a']))]
 
345
        tx1b.vout = [CTxOut(1*COIN, CScript([b'a']))]
348
346
        tx1b_hex = txToHex(tx1b)
349
347
        tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
350
348
        tx1b_txid = int(tx1b_txid, 16)
364
362
 
365
363
    def test_new_unconfirmed_inputs(self):
366
364
        """Replacements that add new unconfirmed inputs are rejected"""
367
 
        confirmed_utxo = make_utxo(self.nodes[0], 1.1*COIN)
368
 
        unconfirmed_utxo = make_utxo(self.nodes[0], 0.1*COIN, False)
 
365
        confirmed_utxo = make_utxo(self.nodes[0], int(1.1*COIN))
 
366
        unconfirmed_utxo = make_utxo(self.nodes[0], int(0.1*COIN), False)
369
367
 
370
368
        tx1 = CTransaction()
371
369
        tx1.vin = [CTxIn(confirmed_utxo)]
372
 
        tx1.vout = [CTxOut(1.0*COIN, CScript([b'a']))]
 
370
        tx1.vout = [CTxOut(1*COIN, CScript([b'a']))]
373
371
        tx1_hex = txToHex(tx1)
374
372
        tx1_txid = self.nodes[0].sendrawtransaction(tx1_hex, True)
375
373
 
393
391
        # Start by creating a single transaction with many outputs
394
392
        initial_nValue = 10*COIN
395
393
        utxo = make_utxo(self.nodes[0], initial_nValue)
396
 
        fee = 0.0001*COIN
 
394
        fee = int(0.0001*COIN)
397
395
        split_value = int((initial_nValue-fee)/(MAX_REPLACEMENT_LIMIT+1))
398
396
        actual_fee = initial_nValue - split_value*(MAX_REPLACEMENT_LIMIT+1)
399
397
 
446
444
 
447
445
    def test_opt_in(self):
448
446
        """ Replacing should only work if orig tx opted in """
449
 
        tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
 
447
        tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
450
448
 
451
449
        # Create a non-opting in transaction
452
450
        tx1a = CTransaction()
458
456
        # Shouldn't be able to double-spend
459
457
        tx1b = CTransaction()
460
458
        tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
461
 
        tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
 
459
        tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
462
460
        tx1b_hex = txToHex(tx1b)
463
461
 
464
462
        try:
466
464
        except JSONRPCException as exp:
467
465
            assert_equal(exp.error['code'], -26)
468
466
        else:
469
 
            print tx1b_txid
 
467
            print(tx1b_txid)
470
468
            assert(False)
471
469
 
472
 
        tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
 
470
        tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
473
471
 
474
472
        # Create a different non-opting in transaction
475
473
        tx2a = CTransaction()
481
479
        # Still shouldn't be able to double-spend
482
480
        tx2b = CTransaction()
483
481
        tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
484
 
        tx2b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
 
482
        tx2b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
485
483
        tx2b_hex = txToHex(tx2b)
486
484
 
487
485
        try:
501
499
        tx3a = CTransaction()
502
500
        tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff),
503
501
                    CTxIn(COutPoint(tx2a_txid, 0), nSequence=0xfffffffd)]
504
 
        tx3a.vout = [CTxOut(0.9*COIN, CScript([b'c'])), CTxOut(0.9*COIN, CScript([b'd']))]
 
502
        tx3a.vout = [CTxOut(int(0.9*COIN), CScript([b'c'])), CTxOut(int(0.9*COIN), CScript([b'd']))]
505
503
        tx3a_hex = txToHex(tx3a)
506
504
 
507
505
        self.nodes[0].sendrawtransaction(tx3a_hex, True)
508
506
 
509
507
        tx3b = CTransaction()
510
508
        tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)]
511
 
        tx3b.vout = [CTxOut(0.5*COIN, CScript([b'e']))]
 
509
        tx3b.vout = [CTxOut(int(0.5*COIN), CScript([b'e']))]
512
510
        tx3b_hex = txToHex(tx3b)
513
511
 
514
512
        tx3c = CTransaction()
515
513
        tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), nSequence=0)]
516
 
        tx3c.vout = [CTxOut(0.5*COIN, CScript([b'f']))]
 
514
        tx3c.vout = [CTxOut(int(0.5*COIN), CScript([b'f']))]
517
515
        tx3c_hex = txToHex(tx3c)
518
516
 
519
517
        self.nodes[0].sendrawtransaction(tx3b_hex, True)
526
524
        # correctly used by replacement logic
527
525
 
528
526
        # 1. Check that feeperkb uses modified fees
529
 
        tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
 
527
        tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
530
528
 
531
529
        tx1a = CTransaction()
532
530
        tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
537
535
        # Higher fee, but the actual fee per KB is much lower.
538
536
        tx1b = CTransaction()
539
537
        tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
540
 
        tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*740000]))]
 
538
        tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*740000]))]
541
539
        tx1b_hex = txToHex(tx1b)
542
540
 
543
541
        # Verify tx1b cannot replace tx1a.
557
555
        assert(tx1b_txid in self.nodes[0].getrawmempool())
558
556
 
559
557
        # 2. Check that absolute fee checks use modified fee.
560
 
        tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
 
558
        tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
561
559
 
562
560
        tx2a = CTransaction()
563
561
        tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)]
568
566
        # Lower fee, but we'll prioritise it
569
567
        tx2b = CTransaction()
570
568
        tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
571
 
        tx2b.vout = [CTxOut(1.01*COIN, CScript([b'a']))]
 
569
        tx2b.vout = [CTxOut(int(1.01*COIN), CScript([b'a']))]
572
570
        tx2b.rehash()
573
571
        tx2b_hex = txToHex(tx2b)
574
572