Ejemplo n.º 1
0
 def generate_blocks(self,
                     number,
                     version,
                     test_blocks=[],
                     finaltx=False,
                     sync=True):
     for i in range(number):
         block = create_block(self.tip, create_coinbase(self.height),
                              self.last_block_time + 1)
         block.nVersion = version
         tx_final = CTransaction()
         if finaltx:
             tx_final.nVersion = 2  # FIXME?
             tx_final.vin.extend(self.finaltx_vin)
             tx_final.vout.append(CTxOut(0, CScript([OP_TRUE])))
             tx_final.nLockTime = block.vtx[0].nLockTime
             tx_final.lock_height = block.vtx[0].lock_height
             tx_final.rehash()
             block.vtx.append(tx_final)
             block.hashMerkleRoot = block.calc_merkle_root()
         block.rehash()
         block.solve()
         if sync:
             self.nodes[0].submitblock(ToHex(block))
             assert_equal(self.nodes[0].getbestblockhash(), block.hash)
         test_blocks.append([block, True])
         self.last_block_time += 1
         self.tip = block.sha256
         self.height += 1
         self.finaltx_vin = []
         for txout in tx_final.vout:
             self.finaltx_vin.append(
                 CTxIn(COutPoint(tx_final.sha256, 0), CScript([]),
                       0xffffffff))
     return test_blocks
Ejemplo n.º 2
0
    def run_test(self):
        bitno = 1
        activated_version = 0x20000000 | (1 << bitno)

        node = self.nodes[0]  # convenience reference to the node

        self.bootstrap_p2p()  # Add one p2p connection to the node

        assert_equal(self.get_bip9_status('finaltx')['status'], 'defined')
        assert_equal(self.get_bip9_status('finaltx')['since'], 0)

        self.log.info(
            "Generate some blocks to get the chain going and un-stick the mining RPCs"
        )
        node.generate(2)
        assert_equal(node.getblockcount(), 2)
        self.height = 3  # height of the next block to build
        self.tip = int("0x" + node.getbestblockhash(), 0)
        self.nodeaddress = node.getnewaddress()
        self.last_block_time = int(time.time())

        self.log.info("\'finaltx\' begins in DEFINED state")
        assert_equal(self.get_bip9_status('finaltx')['status'], 'defined')
        assert_equal(self.get_bip9_status('finaltx')['since'], 0)
        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' not in tmpl['rules'])
        assert ('finaltx' not in tmpl['vbavailable'])
        assert ('finaltx' not in tmpl)
        assert_equal(tmpl['vbrequired'], 0)
        assert_equal(tmpl['version'] & activated_version, 0x20000000)

        self.log.info("Test 1: Advance from DEFINED to STARTED")
        test_blocks = self.generate_blocks(141, 4)  # height = 143

        assert_equal(self.get_bip9_status('finaltx')['status'], 'started')
        assert_equal(self.get_bip9_status('finaltx')['since'], 144)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['elapsed'], 0)
        assert_equal(self.get_bip9_status('finaltx')['statistics']['count'], 0)
        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' not in tmpl['rules'])
        assert_equal(tmpl['vbavailable']['finaltx'], bitno)
        assert_equal(tmpl['vbrequired'], 0)
        assert ('finaltx' not in tmpl)
        assert_equal(tmpl['version'] & activated_version, activated_version)

        self.log.info(
            "Save one of the anyone-can-spend coinbase outputs for later.")
        assert_equal(test_blocks[-1][0].vtx[0].vout[0].nValue, 5000000000)
        assert_equal(test_blocks[-1][0].vtx[0].vout[0].scriptPubKey,
                     CScript([OP_TRUE]))
        early_coin = COutPoint(test_blocks[-1][0].vtx[0].sha256, 0)

        self.log.info(
            "Test 2: Check stats after max number of \"not signalling\" blocks such that LOCKED_IN still possible this period"
        )
        self.generate_blocks(36, 4)  # 0x00000004 (not signalling)
        self.generate_blocks(10,
                             activated_version)  # 0x20000001 (not signalling)

        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['elapsed'], 46)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['count'], 10)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['possible'], True)

        self.log.info(
            "Test 3: Check stats after one additional \"not signalling\" block -- LOCKED_IN no longer possible this period"
        )
        self.generate_blocks(1, 4)  # 0x00000004 (not signalling)

        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['elapsed'], 47)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['count'], 10)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['possible'], False)

        self.log.info(
            "Test 4: Finish period with \"ready\" blocks, but soft fork will still fail to advance to LOCKED_IN"
        )
        self.generate_blocks(
            97, activated_version)  # 0x20000001 (signalling ready)

        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['elapsed'], 0)
        assert_equal(self.get_bip9_status('finaltx')['statistics']['count'], 0)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['possible'], True)
        assert_equal(self.get_bip9_status('finaltx')['status'], 'started')

        self.log.info(
            "Test 5: Fail to achieve LOCKED_IN 100 out of 144 signal bit 1 using a variety of bits to simulate multiple parallel softforks"
        )
        self.generate_blocks(
            50, activated_version)  # 0x20000001 (signalling ready)
        self.generate_blocks(20, 4)  # 0x00000004 (not signalling)
        self.generate_blocks(
            50, activated_version)  # 0x20000101 (signalling ready)
        self.generate_blocks(24, 4)  # 0x20010000 (not signalling)

        assert_equal(self.get_bip9_status('finaltx')['status'], 'started')
        assert_equal(self.get_bip9_status('finaltx')['since'], 144)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['elapsed'], 0)
        assert_equal(self.get_bip9_status('finaltx')['statistics']['count'], 0)
        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' not in tmpl['rules'])
        assert_equal(tmpl['vbavailable']['finaltx'], bitno)
        assert_equal(tmpl['vbrequired'], 0)
        assert_equal(tmpl['version'] & activated_version, activated_version)

        self.log.info(
            "Test 6: 108 out of 144 signal bit 1 to achieve LOCKED_IN using a variety of bits to simulate multiple parallel softforks"
        )
        self.generate_blocks(
            57, activated_version)  # 0x20000001 (signalling ready)
        self.generate_blocks(26, 4)  # 0x00000004 (not signalling)
        self.generate_blocks(
            50, activated_version)  # 0x20000101 (signalling ready)
        self.generate_blocks(10, 4)  # 0x20010000 (not signalling)

        self.log.info(
            "check counting stats and \"possible\" flag before last block of this period achieves LOCKED_IN..."
        )
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['elapsed'], 143)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['count'], 107)
        assert_equal(
            self.get_bip9_status('finaltx')['statistics']['possible'], True)
        assert_equal(self.get_bip9_status('finaltx')['status'], 'started')

        self.log.info("Test 7: ...continue with Test 6")
        self.generate_blocks(
            1, activated_version)  # 0x20000001 (signalling ready)

        assert_equal(self.get_bip9_status('finaltx')['status'], 'locked_in')
        assert_equal(self.get_bip9_status('finaltx')['since'], 576)
        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' not in tmpl['rules'])

        self.log.info(
            "Test 8: 143 more version 536870913 blocks (waiting period-1)")
        self.generate_blocks(143, 4)

        assert_equal(self.get_bip9_status('finaltx')['status'], 'locked_in')
        assert_equal(self.get_bip9_status('finaltx')['since'], 576)
        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' not in tmpl['rules'])
        assert ('finaltx' in tmpl['vbavailable'])
        assert_equal(tmpl['vbrequired'], 0)
        assert_equal(tmpl['version'] & activated_version, activated_version)

        self.log.info(
            "Test 9: Generate a block without any spendable outputs, which should be allowed under normal circumstances."
        )
        test_blocks = self.generate_blocks(1, 4, sync=False)
        for txout in test_blocks[-1][0].vtx[0].vout:
            txout.scriptPubKey = CScript([OP_FALSE])
        test_blocks[-1][0].vtx[0].rehash()
        test_blocks[-1][0].hashMerkleRoot = test_blocks[-1][
            0].calc_merkle_root()
        test_blocks[-1][0].rehash()
        test_blocks[-1][0].solve()
        node.submitblock(ToHex(test_blocks[-1][0]))
        assert_equal(node.getbestblockhash(), test_blocks[-1][0].hash)
        self.tip = test_blocks[-1][0].sha256  # Hash has changed

        assert_equal(self.get_bip9_status('finaltx')['status'], 'active')
        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' in tmpl['rules'])
        assert ('finaltx' not in tmpl['vbavailable'])
        assert_equal(tmpl['vbrequired'], 0)
        assert (not (tmpl['version'] & (1 << bitno)))

        self.log.info(
            "Test 10: Attempt to do the same thing: generate a block with no spendable outputs in the coinbase. This fails because the next block needs at least one trivially spendable output to start the block-final transaction chain."
        )
        block = create_block(self.tip, create_coinbase(self.height),
                             self.last_block_time + 1)
        block.nVersion = 5
        for txout in block.vtx[0].vout:
            txout.scriptPubKey = CScript([OP_FALSE])
        block.vtx[0].rehash()
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(),
                     ser_uint256(self.tip)[::-1].hex())

        self.log.info(
            "Test 11: Generate the first block with block-final-tx rules enforced, which reuires the coinbase to have a trivially-spendable output."
        )
        self.generate_blocks(1, 4)
        assert (any(out.scriptPubKey == CScript([OP_TRUE])
                    for out in test_blocks[-1][0].vtx[0].vout))
        for n, txout in enumerate(test_blocks[-1][0].vtx[0].vout):
            non_protected_output = COutPoint(test_blocks[-1][0].vtx[0].sha256,
                                             n)
            assert_equal(txout.nValue, 312500000)

        self.log.info("Test 12: Generate 98 blocks (maturity period - 2)")
        self.generate_blocks(98, 4)

        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' not in tmpl)

        self.log.info(
            "Test 13: Generate one more block to allow non_protected_output to mature, which causes the block-final transaction to be required in the next block."
        )
        self.generate_blocks(1, 4)

        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' in tmpl)
        assert_equal(len(tmpl['finaltx']['prevout']), 1)
        assert_equal(
            tmpl['finaltx']['prevout'][0]['txid'],
            encode(ser_uint256(non_protected_output.hash)[::-1],
                   'hex_codec').decode('ascii'))
        assert_equal(tmpl['finaltx']['prevout'][0]['vout'],
                     non_protected_output.n)
        assert_equal(tmpl['finaltx']['prevout'][0]['amount'], 312470199)

        self.log.info(
            "Extra pass-through value is not included in the coinbasevalue field."
        )
        assert_equal(tmpl['coinbasevalue'],
                     5000000000 // 2**(self.height // 150))

        self.log.info(
            "The transactions field does not contain the block-final transaction."
        )
        assert_equal(len(tmpl['transactions']), 0)

        self.log.info(
            "Test 14: Attempt to create a block without the block-final transaction, which fails."
        )
        block = create_block(self.tip, create_coinbase(self.height),
                             self.last_block_time + 1)
        block.nVersion = 4
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(),
                     ser_uint256(self.tip)[::-1].hex())

        self.log.info(
            "Test 15: Add the block-final transaction, and it passes.")
        tx_final = CTransaction()
        tx_final.nVersion = 2
        tx_final.vin.append(
            CTxIn(non_protected_output, CScript([]), 0xffffffff))
        tx_final.vout.append(CTxOut(312470199, CScript([OP_TRUE])))
        tx_final.nLockTime = block.vtx[0].nLockTime
        tx_final.lock_height = block.vtx[0].lock_height
        tx_final.rehash()
        block.vtx.append(tx_final)
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(), block.hash)
        prev_final_tx = block.vtx[-1]
        self.last_block_time += 1
        self.tip = block.sha256
        self.height += 1

        tmpl = node.getblocktemplate(
            {'rules': ['segwit', 'finaltx', 'auxpow']})
        assert ('finaltx' in tmpl)
        assert_equal(len(tmpl['finaltx']['prevout']), 1)
        assert_equal(
            tmpl['finaltx']['prevout'][0]['txid'],
            encode(ser_uint256(tx_final.sha256)[::-1],
                   'hex_codec').decode('ascii'))
        assert_equal(tmpl['finaltx']['prevout'][0]['vout'], 0)
        assert_equal(tmpl['finaltx']['prevout'][0]['amount'], 312469901)

        self.log.info(
            "Test 16: Create a block-final transaction with multiple outputs, which doesn't work because the number of outputs is restricted to be no greater than the number of inputs."
        )
        block = create_block(self.tip, create_coinbase(self.height),
                             self.last_block_time + 1)
        block.nVersion = 4
        tx_final = CTransaction()
        tx_final.nVersion = 2
        tx_final.vin.append(
            CTxIn(COutPoint(prev_final_tx.sha256, 0), CScript([]), 0xffffffff))
        tx_final.vout.append(CTxOut(156234951, CScript([OP_TRUE])))
        tx_final.vout.append(CTxOut(156234950, CScript([OP_TRUE])))
        tx_final.nLockTime = block.vtx[0].nLockTime
        tx_final.lock_height = block.vtx[0].lock_height
        tx_final.rehash()
        block.vtx.append(tx_final)
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(),
                     ser_uint256(self.tip)[::-1].hex())

        self.log.info(
            "Test 17: Try increasing the number of inputs by using an old one doesn't work, because the block-final transaction must source its user inputs from the same block."
        )
        utxo = node.gettxout(
            encode(ser_uint256(early_coin.hash)[::-1],
                   'hex_codec').decode('ascii'), early_coin.n)
        assert ('amount' in utxo)
        utxo_amount = int(100000000 * utxo['amount'])
        block.vtx[-1].vin.append(CTxIn(early_coin, CScript([]), 0xffffffff))
        block.vtx[-1].rehash()
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(),
                     ser_uint256(self.tip)[::-1].hex())

        self.log.info(
            "Test 18: But spend it via a user transaction instead, and it can be captured and sent to the coinbase as fee."
        )

        # Insert spending transaction
        spend_tx = CTransaction()
        spend_tx.nVersion = 2
        spend_tx.vin.append(CTxIn(early_coin, CScript([]), 0xffffffff))
        spend_tx.vout.append(CTxOut(utxo_amount, CScript([OP_TRUE])))
        spend_tx.nLockTime = 0
        spend_tx.lock_height = block.vtx[0].lock_height
        spend_tx.rehash()
        block.vtx.insert(1, spend_tx)
        # Capture output of spend_tx in block-final tx (but don't update the
        # outputs--the value passes on to the coinbase as fee).
        block.vtx[-1].vin[-1].prevout = COutPoint(spend_tx.sha256, 0)
        block.vtx[-1].rehash()
        # Add the captured value to the block reward.
        block.vtx[0].vout[0].nValue += utxo_amount
        block.vtx[0].rehash()
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(), block.hash)
        prev_final_tx = block.vtx[-1]
        self.last_block_time += 1
        self.tip = block.sha256
        self.height += 1

        self.log.info(
            "Test 19: Spending only one of the prior outputs is insufficient.  ALL prior block-final outputs must be spent."
        )
        block = create_block(self.tip, create_coinbase(self.height),
                             self.last_block_time + 1)
        block.nVersion = 4
        tx_final = CTransaction()
        tx_final.nVersion = 2
        tx_final.vin.append(
            CTxIn(COutPoint(prev_final_tx.sha256, 0), CScript([]), 0xffffffff))
        tx_final.vout.append(CTxOut(156234801, CScript([OP_TRUE])))
        tx_final.nLockTime = block.vtx[0].nLockTime
        tx_final.lock_height = block.vtx[0].lock_height
        tx_final.rehash()
        block.vtx.append(tx_final)
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(),
                     ser_uint256(self.tip)[::-1].hex())

        self.log.info(
            "Test 20: But spend all the prior outputs and it goes through.")
        block.vtx[-1].vin.append(
            CTxIn(COutPoint(prev_final_tx.sha256, 1), CScript([]), 0xffffffff))
        block.vtx[-1].vout[0].nValue *= 2
        block.vtx[-1].rehash()
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(), block.hash)
        prev_final_tx = block.vtx[-1]
        self.last_block_time += 1
        self.tip = block.sha256
        self.height += 1

        self.log.info(
            "Test 21: Now that the rules have activated, transactions spending the previous block-final transaction's outputs are rejected from the mempool."
        )
        self.log.info(
            "First we do this with a non-block-final input to demonstrate the test would otherwise work."
        )
        height = node.getblockcount() - 99
        while True:
            blk = node.getblock(node.getblockhash(height))
            txid = blk['tx'][0]
            utxo = node.gettxout(txid, 0)
            if utxo is not None and utxo['scriptPubKey']['hex'] == "51":
                break
            height -= 1

        spend_tx = CTransaction()
        spend_tx.nVersion = 2
        spend_tx.vin.append(
            CTxIn(COutPoint(uint256_from_str(unhexlify(txid)[::-1]), 0),
                  CScript([]), 0xffffffff))
        spend_tx.vout.append(
            CTxOut(
                int(utxo['amount'] * 100000000) - 10000, CScript([b'a' * 100]))
        )  # Make transaction large enough to avoid tx-size-small standardness check
        spend_tx.nLockTime = 0
        spend_tx.lock_height = utxo['refheight']
        spend_tx.rehash()
        node.sendrawtransaction(ToHex(spend_tx))
        mempool = node.getrawmempool()
        assert (spend_tx.hash in mempool)

        self.log.info(
            "Now we do the same exact thing with the last block-final transaction's outputs. It should not enter the mempool."
        )
        spend_tx = CTransaction()
        spend_tx.nVersion = 2
        spend_tx.vin.append(
            CTxIn(COutPoint(prev_final_tx.sha256, 0), CScript([]), 0xffffffff))
        spend_tx.vout.append(
            CTxOut(int(utxo['amount'] * 100000000), CScript([b'a' * 100]))
        )  # Make transaction large enough to avoid tx-size-small standardness check
        spend_tx.nLockTime = 0
        spend_tx.lock_height = utxo['refheight']
        spend_tx.rehash()
        try:
            node.sendrawtransaction(ToHex(spend_tx))
        except JSONRPCException as e:
            assert ("spend-block-final-txn" in e.error['message'])
        else:
            assert (False)
        mempool = node.getrawmempool()
        assert (spend_tx.hash not in mempool)

        self.log.info(
            "Test 22: Invalidate the tip, then malleate and re-solve the same block. This is a fast way of testing test that the block-final txid is restored on a reorg."
        )
        height = node.getblockcount()
        node.invalidateblock(block.hash)
        assert_equal(node.getblockcount(), height - 1)
        block.nVersion ^= 2
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getblockcount(), height)
        assert_equal(node.getbestblockhash(), block.hash)

        self.tip = block.sha256
        self.finaltx_vin = [
            CTxIn(COutPoint(block.vtx[-1].sha256, 0), CScript([]), 0xffffffff)
        ]

        self.log.info(
            "Test 22-25: Mine two blocks with trivially-spendable coinbase outputs, then test that the one that is exactly 100 blocks old is allowed to be spent in a block-final transaction, but the older one cannot."
        )
        self.generate_blocks(1, 4, finaltx=True)
        assert_equal(test_blocks[-1][0].vtx[0].vout[0].scriptPubKey,
                     CScript([OP_TRUE]))
        txin1 = CTxIn(COutPoint(test_blocks[-1][0].vtx[0].sha256, 0),
                      CScript([]), 0xffffffff)

        self.generate_blocks(1, 4, finaltx=True)
        assert_equal(test_blocks[-1][0].vtx[0].vout[0].scriptPubKey,
                     CScript([OP_TRUE]))
        txin2 = CTxIn(COutPoint(test_blocks[-1][0].vtx[0].sha256, 0),
                      CScript([]), 0xffffffff)

        self.generate_blocks(1, 4, finaltx=True)
        assert_equal(test_blocks[-1][0].vtx[0].vout[0].scriptPubKey,
                     CScript([OP_TRUE]))
        txin3 = CTxIn(COutPoint(test_blocks[-1][0].vtx[0].sha256, 0),
                      CScript([]), 0xffffffff)

        self.generate_blocks(98, 4, finaltx=True)

        # txin1 is too old -- it should have been collected on the last block
        block = create_block(self.tip, create_coinbase(self.height),
                             self.last_block_time + 1)
        block.nVersion = 4
        tx_final = CTransaction()
        tx_final.nVersion = 2
        tx_final.vin.extend(self.finaltx_vin)
        tx_final.vin.append(txin1)
        tx_final.vout.append(CTxOut(0, CScript([OP_TRUE])))
        tx_final.nLockTime = block.vtx[0].nLockTime
        tx_final.lock_height = block.vtx[0].lock_height
        tx_final.rehash()
        block.vtx.append(tx_final)
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(),
                     ser_uint256(self.tip)[::-1].hex())

        # txin3 is too young -- it hasn't matured
        block.vtx[-1].vin.pop()
        block.vtx[-1].vin.append(txin3)
        block.vtx[-1].rehash()
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(),
                     ser_uint256(self.tip)[::-1].hex())

        # txin2 is just right
        block.vtx[-1].vin.pop()
        block.vtx[-1].vin.append(txin2)
        block.vtx[-1].rehash()
        block.hashMerkleRoot = block.calc_merkle_root()
        block.rehash()
        block.solve()
        node.submitblock(ToHex(block))
        assert_equal(node.getbestblockhash(), block.hash)

        self.last_block_time += 1
        self.tip = block.sha256
        self.height += 1
        self.finaltx_vin = [
            CTxIn(COutPoint(block.vtx[-1].sha256, 0), CScript([]), 0xffffffff)
        ]