def post_unpack_merkleblock(d, f):
    """
    A post-processing "post_unpack" to merkleblock messages.

    It validates the merkle proofs (throwing an exception if there's
    an error), and returns the list of transaction hashes in "tx_hashes".

    The transactions are supposed to be sent immediately after the merkleblock message.
    """
    level_widths = []
    count = d["total_transactions"]
    while count > 1:
        level_widths.append(count)
        count += 1
        count //= 2
    level_widths.append(1)
    level_widths.reverse()

    tx_acc = []
    flags = d["flags"]
    hashes = list(reversed(d["hashes"]))
    left_hash, flag_index = _recurse(level_widths, 0, 0, hashes, flags, 0, tx_acc)

    if len(hashes) > 0:
        raise ValueError("extra hashes: %s" % hashes)

    idx, r = divmod(flag_index-1, 8)
    if idx != len(flags) - 1:
        raise ValueError("not enough flags consumed")

    if flags[idx] > (1 << (r+1))-1:
        raise ValueError("unconsumed 1 flag bits set")

    if left_hash != d["header"].merkle_root:
        raise ValueError(
            "merkle root %s does not match calculated hash %s" % (
                b2h_rev(d["header"].merkle_root), b2h_rev(left_hash)))

    d["tx_hashes"] = tx_acc
    return d
A post-processing "post_unpack" to merkleblock messages.

    It validates the merkle proofs (throwing an exception if there's
    an error), and returns the list of transaction hashes in "tx_hashes".

    The transactions are supposed to be sent immediately after the merkleblock message.