Extract the existing chain state transactions from the existing state engine at a particular block height,
    parse them using the new state engine, and process them using the new state engine.

    Returns the consensus hash of the block on success.

def state_engine_replay_block(existing_state_engine, new_state_engine, block_height, expected_snapshots={}):
    """
    Extract the existing chain state transactions from the existing state engine at a particular block height,
    parse them using the new state engine, and process them using the new state engine.

    Returns the consensus hash of the block on success.
    """
    
    assert new_state_engine.lastblock + 1 == block_height, 'Block height mismatch: {} + 1 != {}'.format(new_state_engine.lastblock, block_height)

    db_con = StateEngine.db_open(existing_state_engine.impl, existing_state_engine.working_dir)
    chainstate_block = existing_state_engine.db_chainstate_get_block(db_con, block_height)
    db_con.close()

    log.debug("{} transactions accepted at block {} in chainstate {}; replaying in {}".format(len(chainstate_block), block_height, existing_state_engine.working_dir, new_state_engine.working_dir))

    parsed_txs = dict([(txdata['txid'], transactions.tx_parse(txdata['tx_hex'], blockchain=existing_state_engine.impl.get_blockchain())) for txdata in chainstate_block])
    txs = [
        {
            'txid': txdata['txid'],
            'txindex': txdata['txindex'],
            'nulldata': '{}{}{}'.format(existing_state_engine.impl.get_magic_bytes().encode('hex'), txdata['opcode'].encode('hex'), txdata['data_hex']),
            'ins': parsed_txs[txdata['txid']]['ins'],
            'outs': parsed_txs[txdata['txid']]['outs'],
            'senders': txdata['senders'],
            'fee': txdata['fee'],
            'hex': txdata['tx_hex'],
            'tx_merkle_path': txdata['tx_merkle_path'],
        }
        for txdata in chainstate_block]

    new_state_engine.db_set_indexing(True, new_state_engine.impl, new_state_engine.working_dir)

    ops = new_state_engine.parse_block(block_height, txs)
    consensus_hash = new_state_engine.process_block(block_height, ops, expected_snapshots=expected_snapshots)

    new_state_engine.db_set_indexing(False, new_state_engine.impl, new_state_engine.working_dir)

    return consensus_hash