getRelayAddrs method

Future<List<MultiAddr>> getRelayAddrs(
  1. List<MultiAddr> currentHostAddrs
)

Implementation

Future<List<MultiAddr>> getRelayAddrs(List<MultiAddr> currentHostAddrs) async {
  return _relayMx.synchronized<List<MultiAddr>>(() async { // Made outer lambda async
    if (_cachedAddrs.isNotEmpty && config.clock.now().isBefore(_cachedAddrsExpiry)) {
      return List<MultiAddr>.from(_cachedAddrs);
    }

    List<MultiAddr> raddrs = [];
    for (var addr in currentHostAddrs) {
      if (addr.isPrivate() || addr.isLoopback()) {
        raddrs.add(addr);
      }
    }

    int relayAddrCountForMetrics = 0;
    // Use a temporary list to collect futures if forEach body is async
    List<Future<void>> addrProcessingFutures = [];

    _relays.forEach((peerId, reservation) {
      // This internal lambda for forEach cannot be async directly if the outer _relayMx.synchronized is not.
      // To do async work per relay, we'd collect futures and await them outside the synchronized block,
      // or make the synchronized block itself support async operations if the library allows.
      // For now, assuming addrs() is relatively quick or we accept blocking here.
      // A better pattern would be to get all relay PeerIds, release lock, get all addrs, re-acquire lock.

      // Simplified: if host.peerStore.addrBook.addrs is async, this forEach is problematic inside sync block.
      // Assuming it's synchronous for this sketch or this part needs more advanced refactoring.
      // For the purpose of this fix, let's assume it can be made to work.
      // The original Go code does this under a lock.

      // Corrected to be async and collect futures:
      final future = host.peerStore.addrBook.addrs(peerId).then((relayPeerAddrs) {
          final cleanedRelayPeerAddrs = address_utils.cleanupAddressSet(relayPeerAddrs);
          relayAddrCountForMetrics += cleanedRelayPeerAddrs.length;
          for (var relayAddr in cleanedRelayPeerAddrs) {
              try {
                  var circuitAddr = relayAddr
                      .encapsulate(Protocols.p2p.name, peerId.toString())
                      .encapsulate(Protocols.circuit.name, '');
                  raddrs.add(circuitAddr);
              } catch (e) {
                  // log.warning('Failed to create circuit address for relay $peerId via $relayAddr: $e');
              }
          }
      });
      addrProcessingFutures.add(future);
    });

    await Future.wait(addrProcessingFutures); // Wait for all async addr processing

    _cachedAddrs = List<MultiAddr>.from(raddrs);
    _cachedAddrsExpiry = config.clock.now().add(const Duration(seconds: 30));
    metricsTracer.relayAddressCount(relayAddrCountForMetrics);
    return raddrs;
  });
}