Example #1
0
    def run_test(self):
        node = self.nodes[0]
        # Mine a block to leave initial block download
        node.generate(1)

        prevblk = node.getblock(node.getbestblockhash())

        tmpl = node.getblocktemplate()
        self.log.info("getblocktemplate: Test capability advertised")

        assert 'rules' in tmpl
        assert 'vbavailable' in tmpl
        assert 'transactions' in tmpl
        assert 'coinbaseaux' in tmpl
        assert 'coinbasetxn' not in tmpl
        assert 'mutable' in tmpl
        assert isinstance(tmpl['version'], int)
        assert isinstance(tmpl['curtime'], int)
        assert isinstance(tmpl['vbrequired'], int)
        assert isinstance(tmpl['coinbasevalue'], int)
        assert_is_hex_string(tmpl['bits'])
        assert_is_hash_string(tmpl['target'])
        assert_is_hash_string(tmpl['previousblockhash'])
        assert_equal(tmpl['sizelimit'], 32000000)
        assert_equal(tmpl['sigoplimit'], 640000)
        assert_equal(tmpl['mintime'], prevblk['mediantime'] + 1)
        assert_equal(tmpl['height'], prevblk['height'] + 1)
        assert_equal(tmpl['noncerange'], "00000000ffffffff")

        coinbase_tx = create_coinbase(height=int(tmpl["height"]) + 1)
        # sequence numbers must not be max for nLockTime to have effect
        coinbase_tx.vin[0].nSequence = 2 ** 32 - 2
        coinbase_tx.rehash()

        block = CBlock()
        block.nVersion = tmpl["version"]
        block.hashPrevBlock = int(tmpl["previousblockhash"], 16)
        block.nTime = tmpl["curtime"]
        block.nBits = int(tmpl["bits"], 16)
        block.nNonce = 0
        block.vtx = [coinbase_tx]

        self.log.info("getblocktemplate: Test valid block")
        #assert_template(node, block, None)

        self.log.info("submitblock: Test block decode failure")
        assert_raises_rpc_error(-22, "Block decode failed",
                                node.submitblock, b2x(block.serialize()[:-15]))

        block.hashMerkleRoot = block.calc_merkle_root()
        node.submitblock(b2x(block.serialize()[:]))
    def create_bad_block(self, template):
        coinbase_tx = create_coinbase(height=int(template["height"]) + 1)
        coinbase_tx.vin[0].nSequence = 2**32 - 2
        coinbase_tx.rehash()
        block = CBlock()
        block.nVersion = template["version"]
        block.nTime = template["curtime"]
        block.nBits = int(template["bits"], 16)
        block.nNonce = 0
        block.vtx = [coinbase_tx]

        # Make this block incorrect.
        block.hashPrevBlock = 123
        block.hashMerkleRoot = block.calc_merkle_root()

        return block
Example #3
0
 def make_block_withP2SH_coinbase(self):
     tmpl = self.nodes[0].getblocktemplate()
     coinbase_tx = create_coinbase_P2SH(
         int(tmpl["height"]) + 1, example_script_hash)
     coinbase_tx.vin[0].nSequence = 2**32 - 2
     coinbase_tx.rehash()
     block = CBlock()
     block.nVersion = tmpl["version"]
     block.hashPrevBlock = int(tmpl["previousblockhash"], 16)
     block.nTime = tmpl["curtime"]
     block.nBits = int(tmpl["bits"], 16)
     block.nNonce = 0
     block.vtx = [coinbase_tx]
     block.hashMerkleRoot = block.calc_merkle_root()
     block.solve()
     block.rehash()
     return block
Example #4
0
def mine_large_blocks(node, n):
    # Make a large scriptPubKey for the coinbase transaction. This is OP_RETURN
    # followed by 950k of OP_NOP. This would be non-standard in a non-coinbase
    # transaction but is consensus valid.

    # Set the nTime if this is the first time this function has been called.
    # A static variable ensures that time is monotonicly increasing and is therefore
    # different for each block created => blockhash is unique.
    if "nTimes" not in mine_large_blocks.__dict__:
        mine_large_blocks.nTime = 0

    # Get the block parameters for the first block
    big_script = CScript([OP_RETURN] + [OP_NOP] * 950000)
    best_block = node.getblock(node.getbestblockhash())
    height = int(best_block["height"]) + 1
    mine_large_blocks.nTime = max(mine_large_blocks.nTime,
                                  int(best_block["time"])) + 1
    previousblockhash = int(best_block["hash"], 16)

    for _ in range(n):
        # Build the coinbase transaction (with large scriptPubKey)
        coinbase_tx = create_coinbase(height)
        coinbase_tx.vin[0].nSequence = 2**32 - 1
        coinbase_tx.vout[0].scriptPubKey = big_script
        coinbase_tx.rehash()

        # Build the block
        block = CBlock()
        block.nVersion = 0x620004
        block.hashPrevBlock = previousblockhash
        block.nTime = mine_large_blocks.nTime
        block.nBits = int('207fffff', 16)
        block.nNonce = 0
        block.vtx = [coinbase_tx]
        block.hashMerkleRoot = block.calc_merkle_root()
        block.calc_sha256()
        block.solve()

        # Submit to the node
        node.submitblock(block.serialize().hex())

        previousblockhash = block.sha256
        height += 1
        mine_large_blocks.nTime += 1
    def mine_using_template(self, nodeidx=0):
        tmpl = self.nodes[nodeidx].getblocktemplate()
        assert 'proposal' in tmpl['capabilities']
        assert 'coinbasetxn' not in tmpl
        coinbase_tx = create_coinbase(height=int(tmpl["height"]))
        block = CBlock()
        block.nVersion = int(tmpl["version"])
        block.hashPrevBlock = int(tmpl["previousblockhash"], 16)
        block.nTime = tmpl["curtime"]
        block.nBits = int(tmpl["bits"], 16)
        block.nNonce = 0

        # extended block
        block.nStakeDifficulty = int(tmpl["stakedifficulty"], 16)
        block.nVoteBits = tmpl["votebits"]
        block.nTicketPoolSize = tmpl["ticketpoolsize"]
        block.ticketLotteryState = tmpl["ticketlotterystate"]
        block.nVoters = tmpl["voters"]
        block.nFreshStake = tmpl["freshstake"]
        block.nRevocations = tmpl["revocations"]
        block.extraData = tmpl["extradata"]
        block.nStakeVersion = tmpl["stakeversion"]

        block.vtx = [coinbase_tx]
        for tx in tmpl["transactions"]:
            ctx = CTransaction()
            ctx.deserialize(BytesIO(hex_str_to_bytes(tx['data'])))
            ctx.rehash()
            block.vtx.append(ctx)
        block.hashMerkleRoot = block.calc_merkle_root()
        add_witness_commitment(block)
        block.solve()
        print("-------------")
        print("mine using template on node:", nodeidx)
        print('solved hash', block.hash)
        # print("submit for height", idx)
        submit_result = self.nodes[nodeidx].submitblock(ToHex(block))
        print(submit_result)
        assert (submit_result in [None, "inconclusive"])
        return block.hash