public List<LogWithMetadata> matchingLogs(
      final Hash blockHash, final LogsQuery query, final Supplier<Boolean> isQueryAlive) {
    try {
      final Optional<BlockHeader> blockHeader = getBlockHeader(blockHash, isQueryAlive);
      if (blockHeader.isEmpty()) {
        return Collections.emptyList();
      }
      // receipts and transactions should exist if the header exists, so throwing is ok.
      final List<TransactionReceipt> receipts = getReceipts(blockHash, isQueryAlive);
      final List<Transaction> transactions = getTransactions(blockHash, isQueryAlive);
      final long number = blockHeader.get().getNumber();
      final boolean removed = getRemoved(blockHash, isQueryAlive);

      final AtomicInteger logIndexOffset = new AtomicInteger();
      return IntStream.range(0, receipts.size())
          .mapToObj(
              i -> {
                try {
                  BackendQuery.stopIfExpired(isQueryAlive);
                  final List<LogWithMetadata> result =
                      LogWithMetadata.generate(
                          logIndexOffset.intValue(),
                          receipts.get(i),
                          number,
                          blockHash,
                          transactions.get(i).getHash(),
                          i,
                          removed);
                  logIndexOffset.addAndGet(receipts.get(i).getLogs().size());
                  return result;
                } catch (final Exception e) {
                  throw new RuntimeException(e);
                }
              })
          .flatMap(Collection::stream)
          .filter(query::matches)
          .collect(Collectors.toList());
    } catch (final Exception e) {
      throw new RuntimeException(e);
    }
  }
Retrieve logs from the range of blocks with optional filtering based on logger address and log
topics.

@param fromBlockNumber The block number defining the first block in the search range
    (inclusive).
@param toBlockNumber The block number defining the last block in the search range (inclusive).
@param query Constraints on required topics by topic index. For a given index if the set of
    topics is non-empty, the topic at this index must match one of the values in the set.
@param isQueryAlive Whether the backend query should stay alive.
@return The set of logs matching the given constraints.
ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/query/BlockchainQueries.java