getRelayAddrs method
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;
});
}