MessageData constructGetTrieNodesResponse(final MessageData message) {
    if (!isStarted.get()) {
      return EMPTY_TRIE_NODES_MESSAGE;
    }
    StopWatch stopWatch = StopWatch.createStarted();

    final GetTrieNodesMessage getTrieNodesMessage = GetTrieNodesMessage.readFrom(message);
    final GetTrieNodesMessage.TrieNodesPaths triePaths = getTrieNodesMessage.paths(true);
    final int maxResponseBytes = Math.min(triePaths.responseBytes().intValue(), MAX_RESPONSE_SIZE);
    LOGGER
        .atTrace()
        .setMessage("Received get trie nodes message of size {}")
        .addArgument(() -> triePaths.paths().size())
        .log();

    try {
      return worldStateStorageProvider
          .apply(triePaths.worldStateRootHash())
          .map(
              storage -> {
                LOGGER.trace("obtained worldstate in {}", stopWatch);
                ArrayList<Bytes> trieNodes = new ArrayList<>();
                var triePathList =
                    triePaths.paths().size() < MAX_TRIE_LOOKUPS_PER_REQUEST
                        ? triePaths.paths()
                        : triePaths.paths().subList(0, MAX_TRIE_LOOKUPS_PER_REQUEST);
                for (var triePath : triePathList) {
                  // first element in paths is account
                  if (triePath.size() == 1) {
                    // if there is only one path, presume it should be compact encoded account path
                    final Bytes location = CompactEncoding.decode(triePath.get(0));
                    var optStorage = storage.getTrieNodeUnsafe(location);
                    if (optStorage.isEmpty() && location.isEmpty()) {
                      optStorage = Optional.of(MerkleTrie.EMPTY_TRIE_NODE);
                    }
                    var trieNode = optStorage.orElse(Bytes.EMPTY);
                    if (!trieNodes.isEmpty()
                        && (sumListBytes(trieNodes) + trieNode.size() > maxResponseBytes
                            || stopWatch.getTime(TimeUnit.MILLISECONDS)
                                > ResponseSizePredicate.MAX_MILLIS_PER_REQUEST)) {
                      break;
                    }
                    trieNodes.add(trieNode);
                  } else {
                    // There must be at least one element in the path otherwise it is invalid
                    if (triePath.isEmpty()) {
                      LOGGER.debug("returned empty trie nodes message due to invalid path");
                      return EMPTY_TRIE_NODES_MESSAGE;
                    }

                    // otherwise the first element should be account hash, and subsequent paths
                    // are compact encoded account storage paths

                    final Bytes32 accountPrefix = Bytes32.leftPad(triePath.getFirst());
                    var optAccount = storage.getAccount(Hash.wrap(accountPrefix));
                    if (optAccount.isEmpty()) {
                      continue;
                    }

                    List<Bytes> storagePaths = triePath.subList(1, triePath.size());
                    for (var path : storagePaths) {
                      final Bytes location = CompactEncoding.decode(path);
                      var optStorage =
                          storage.getTrieNodeUnsafe(Bytes.concatenate(accountPrefix, location));
                      if (optStorage.isEmpty() && location.isEmpty()) {
                        optStorage = Optional.of(MerkleTrie.EMPTY_TRIE_NODE);
                      }
                      var trieNode = optStorage.orElse(Bytes.EMPTY);
                      if (!trieNodes.isEmpty()
                          && sumListBytes(trieNodes) + trieNode.size() > maxResponseBytes) {
                        break;
                      }
                      trieNodes.add(trieNode);
                    }
                  }
                }
                var resp = TrieNodesMessage.create(trieNodes);
                LOGGER.debug(
                    "returned in {} trie nodes message with {} entries, resp size {} of max {}",
                    stopWatch,
                    trieNodes.size(),
                    resp.getCode(),
                    maxResponseBytes);
                return resp;
              })
          .orElseGet(
              () -> {
                LOGGER.debug("returned empty trie nodes message due to missing worldstate");
                return EMPTY_TRIE_NODES_MESSAGE;
              });
    } catch (Exception ex) {
      LOGGER.error("Unexpected exception serving trienodes request", ex);
      return EMPTY_TRIE_NODES_MESSAGE;
    }
  }
Create a snap server without registering a listener for worldstate initial sync events or
priming worldstates by root hash. Used by unit tests.
ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java