Builds a list of blocks or resources derived from blocks,
        handling multiple possible filter requests:
            - filtered by a set of ids
            - filtered by head block
            - filtered by both id and head block
            - not filtered (all current resources)

        Note:
            This method will fail if `_block_store` has not been set

        Args:
            request (object): The parsed protobuf request object
            head_id (str): Either request.head_id, or the current chain head
            filter_ids (list of str): the resource ids (if any) to filter by
            resource_fetcher (function): Fetches a resource by its id
                Expected args:
                    resource_id: The id of the resource to be fetched
                Expected return:
                    object: The resource to be appended to the results
            block_xform (function): Transforms a block into a list of resources
                Expected args:
                    block: A block object from the block store
                Expected return:
                    list: To be concatenated to the end of the results

        Returns:
            list: List of blocks or data from blocks. If filtered by ids,
                they will be listed in the same order as the id filters,
                otherwise they will be ordered from newest to oldest

def _list_store_resources(self, request, head_id, filter_ids,
                              resource_fetcher, block_xform):
        """Builds a list of blocks or resources derived from blocks,
        handling multiple possible filter requests:
            - filtered by a set of ids
            - filtered by head block
            - filtered by both id and head block
            - not filtered (all current resources)

        Note:
            This method will fail if `_block_store` has not been set

        Args:
            request (object): The parsed protobuf request object
            head_id (str): Either request.head_id, or the current chain head
            filter_ids (list of str): the resource ids (if any) to filter by
            resource_fetcher (function): Fetches a resource by its id
                Expected args:
                    resource_id: The id of the resource to be fetched
                Expected return:
                    object: The resource to be appended to the results
            block_xform (function): Transforms a block into a list of resources
                Expected args:
                    block: A block object from the block store
                Expected return:
                    list: To be concatenated to the end of the results

        Returns:
            list: List of blocks or data from blocks. If filtered by ids,
                they will be listed in the same order as the id filters,
                otherwise they will be ordered from newest to oldest
        """
        resources = []

        # Simply fetch by id if filtered by id but not by head block
        if filter_ids and not request.head_id:
            for resource_id in filter_ids:
                try:
                    resources.append(resource_fetcher(resource_id))
                except (KeyError, ValueError, TypeError):
                    # Invalid ids should be omitted, not raise an exception
                    pass

        # Traverse block chain to build results for most scenarios
        else:
            current_id = head_id
            while current_id in self._block_store:
                block = self._block_store[current_id].block
                resources += block_xform(block)
                header = BlockHeader()
                header.ParseFromString(block.header)
                current_id = header.previous_block_id

        # If filtering by head AND ids, the traverse results must be winnowed
        if request.head_id and filter_ids:
            matches = {
                r.header_signature: r
                for r in resources if r.header_signature in filter_ids
            }
            resources = [matches[i] for i in filter_ids if i in matches]

        return resources