<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def genesis_block_audit(genesis_block_stages, key_bundle=GENESIS_BLOCK_SIGNING_KEYS):
 """ Verify the authenticity of the stages of the genesis block, optionally with a given set of keys. Return True if valid Return False if not """

    gpg2_path = find_gpg2()
    if gpg2_path is None:
        raise Exception('You must install gpg2 to audit the genesis block, and it must be in your PATH')

    log.debug('Loading {} signing key(s)...'.format(len(key_bundle)))
    res = load_signing_keys(gpg2_path, [key_bundle[kid] for kid in key_bundle])
    if not res:
        raise Exception('Failed to install signing keys')

    log.debug('Verifying {} signing key(s)...'.format(len(key_bundle)))
    res = check_gpg2_keys(gpg2_path, key_bundle.keys())
    if not res:
        raise Exception('Failed to verify installation of signing keys')

    d = tempfile.mkdtemp(prefix='.genesis-block-audit-')

    # each entry in genesis_block_stages is a genesis block with its own history 
    for stage_id, stage in enumerate(genesis_block_stages):
        log.debug('Verify stage {}'.format(stage_id))

        try:
            jsonschema.validate(GENESIS_BLOCK_SCHEMA, stage)
        except jsonschema.ValidationError:
            shutil.rmtree(d)
            log.error('Invalid genesis block -- does not match schema')
            raise ValueError('Invalid genesis block')

        # all history rows must be signed with a trusted key
        for history_id, history_row in enumerate(stage['history']):
            with open(os.path.join(d, 'sig'), 'w') as f:
                f.write(history_row['signature'])
            with open(os.path.join(d, 'hash'), 'w') as f:
                f.write(history_row['hash'])

            p = subprocess.Popen([gpg2_path, '--verify', os.path.join(d,'sig'), os.path.join(d,'hash')], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            out, err = p.communicate()
            if p.returncode != 0:
                log.error('Failed to verify stage {} history {}'.format(stage_id, history_id))
                shutil.rmtree(d)
                return False

        gb_rows_str = json.dumps(stage['rows'], sort_keys=True, separators=(',',':')) + '\n'
        gb_rows_hash = hashlib.sha256(gb_rows_str).hexdigest()

        # must match final history row 
        if gb_rows_hash != stage['history'][-1]['hash']:
            log.error('Genesis block stage {} hash mismatch: {} != {}'.format(stage_id, gb_rows_hash, stage['history'][-1]['hash']))
            shutil.rmtree(d)
            return False

    shutil.rmtree(d)
    log.info('Genesis block is legitimate')
    return True