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
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
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