From 991461816210cf8afab6da57590d50370243f177 Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 15 May 2024 16:14:18 +0200 Subject: [PATCH 01/34] add wildcard addr resolver --- libp2p/services/wildcardresolverservice.nim | 211 ++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 libp2p/services/wildcardresolverservice.nim diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim new file mode 100644 index 0000000000..2dbbc3935e --- /dev/null +++ b/libp2p/services/wildcardresolverservice.nim @@ -0,0 +1,211 @@ +# Nim-LibP2P +# Copyright (c) 2024 Status Research & Development GmbH +# Licensed under either of +# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) +# * MIT license ([LICENSE-MIT](LICENSE-MIT)) +# at your option. +# This file may not be copied, modified, or distributed except according to +# those terms. + +{.push raises: [].} + +import std/[deques, sequtils] +import stew/[byteutils, results, endians2] +import chronos, chronos/transports/[osnet, ipnet], metrics +import ../[multiaddress, multicodec] +import ../switch +import ../wire +import ../utils/heartbeat +import ../crypto/crypto + +logScope: + topics = "libp2p wildcardresolverservice" + +type + # This type is used to resolve wildcard addresses of the type "0.0.0.0" for IPv4 or "::" for IPv6. + WildcardAddressResolverService* = ref object of Service + # Used to get the list of network addresses. + networkInterfaceProvider: NetworkInterfaceProvider + # An implementation of an address mapper that takes a list of listen addresses and expands each wildcard address + # to the respective list of interface addresses. As an example, if the listen address is 0.0.0.0:4001 + # and the machine has 2 interfaces with IPs 172.217.11.174 and 64.233.177.113, the address mapper will + # expand the wildcard address to 172.217.11.174:4001 and 64.233.177.113:4001. + addressMapper: AddressMapper + # Represents the task that is scheduled to run the service. + scheduleHandle: Future[void] + # The interval at which the service should run. + scheduleInterval: Opt[Duration] + + NetworkInterfaceProvider* = ref object of RootObj + +proc isLoopbackOrUp(networkInterface: NetworkInterface): bool = + if (networkInterface.ifType == IfSoftwareLoopback) or + (networkInterface.state == StatusUp): true else: false + +## This method retrieves the addresses of network interfaces based on the specified address family. +## +## The `getAddresses` method filters the available network interfaces to include only +## those that are either loopback or up. It then collects all the addresses from these +## interfaces and filters them to match the provided address family. +## +## Parameters: +## - `networkInterfaceProvider`: A provider that offers access to network interfaces. +## - `addrFamily`: The address family to filter the network addresses (e.g., `AddressFamily.IPv4` or `AddressFamily.IPv6`). +## +## Returns: +## - A sequence of `InterfaceAddress` objects that match the specified address family. +method getAddresses*( + networkInterfaceProvider: NetworkInterfaceProvider, addrFamily: AddressFamily +): seq[InterfaceAddress] {.base.} = + let + interfaces = getInterfaces().filterIt(it.isLoopbackOrUp()) + flatInterfaceAddresses = concat(interfaces.mapIt(it.addresses)) + filteredInterfaceAddresses = + flatInterfaceAddresses.filterIt(it.host.family == addrFamily) + return filteredInterfaceAddresses + +proc new*( + T: typedesc[WildcardAddressResolverService], + scheduleInterval: Opt[Duration] = Opt.none(Duration), + networkInterfaceProvider: NetworkInterfaceProvider = new(NetworkInterfaceProvider), +): T = + return T( + scheduleInterval: scheduleInterval, + networkInterfaceProvider: networkInterfaceProvider, + ) + +proc schedule( + service: WildcardAddressResolverService, switch: Switch, interval: Duration +) {.async.} = + heartbeat "Scheduling WildcardAddressResolverService run", interval: + await service.run(switch) + +proc getProtocolArgument*(ma: MultiAddress, codec: MultiCodec): MaResult[seq[byte]] = + var buffer: seq[byte] + for item in ma: + let + ritem = ?item + code = ?ritem.protoCode() + if code == codec: + let arg = ?ritem.protoAddress() + return ok(arg) + + err("Multiaddress codec has not been found") + +proc getWildcardMultiAddresses( + interfaceAddresses: seq[InterfaceAddress], + protocol: Protocol, + port: Port, + suffix: MultiAddress, +): seq[MultiAddress] = + var addresses: seq[MultiAddress] + for ifaddr in interfaceAddresses: + var address = ifaddr.host + address.port = port + MultiAddress.init(address, protocol).toOpt.withValue(maddress): + maddress.concat(suffix).toOpt.withValue(a): + addresses.add(a) + addresses + +proc getWildcardAddress( + maddress: MultiAddress, + multiCodec: MultiCodec, + anyAddr: openArray[uint8], + addrFamily: AddressFamily, + port: Port, + networkInterfaceProvider: NetworkInterfaceProvider, + peerId: MultiAddress, +): seq[MultiAddress] = + var addresses: seq[MultiAddress] + maddress.getProtocolArgument(multiCodec).toOpt.withValue(address): + if address == anyAddr: + let filteredInterfaceAddresses = networkInterfaceProvider.getAddresses(addrFamily) + addresses.add( + getWildcardMultiAddresses(filteredInterfaceAddresses, IPPROTO_TCP, port, peerId) + ) + else: + maddress.concat(peerId).toOpt.withValue(a): + addresses.add(a) + return addresses + +proc expandWildcardAddresses( + networkInterfaceProvider: NetworkInterfaceProvider, + peerId: PeerId, + listenAddrs: seq[MultiAddress], +): seq[MultiAddress] = + let peerIdMa = MultiAddress.init(multiCodec("p2p"), peerId).valueOr: + return default(seq[MultiAddress]) + + var addresses: seq[MultiAddress] + # In this loop we expand bounded addresses like `0.0.0.0` and `::` to list of interface addresses. + for listenAddr in listenAddrs: + if TCP_IP.matchPartial(listenAddr): + listenAddr.getProtocolArgument(multiCodec("tcp")).toOpt.withValue(portArg): + if len(portArg) == sizeof(uint16): + let port = Port(uint16.fromBytesBE(portArg)) + if IP4.matchPartial(listenAddr): + let wildcardAddresses = getWildcardAddress( + listenAddr, + multiCodec("ip4"), + AnyAddress.address_v4, + AddressFamily.IPv4, + port, + networkInterfaceProvider, + peerIdMa, + ) + addresses.add(wildcardAddresses) + elif IP6.matchPartial(listenAddr): + let wildcardAddresses = getWildcardAddress( + listenAddr, + multiCodec("ip6"), + AnyAddress6.address_v6, + AddressFamily.IPv6, + port, + networkInterfaceProvider, + peerIdMa, + ) + addresses.add(wildcardAddresses) + else: + listenAddr.concat(peerIdMa).withValue(ma): + addresses.add(ma) + else: + let suffixed = listenAddr.concat(peerIdMa).valueOr: + continue + addresses.add(suffixed) + addresses + +method setup*( + self: WildcardAddressResolverService, switch: Switch +): Future[bool] {.async.} = + self.addressMapper = proc( + listenAddrs: seq[MultiAddress] + ): Future[seq[MultiAddress]] {.async.} = + echo listenAddrs + return expandWildcardAddresses( + self.networkInterfaceProvider, switch.peerInfo.peerId, listenAddrs + ) + + debug "Setting up WildcardAddressResolverService" + let hasBeenSetup = await procCall Service(self).setup(switch) + if hasBeenSetup: + self.scheduleInterval.withValue(interval): + self.scheduleHandle = schedule(self, switch, interval) + switch.peerInfo.addressMappers.add(self.addressMapper) + return hasBeenSetup + +method run*(self: WildcardAddressResolverService, switch: Switch) {.async, public.} = + trace "Running WildcardAddressResolverService" + await switch.peerInfo.update() + +method stop*( + self: WildcardAddressResolverService, switch: Switch +): Future[bool] {.async, public.} = + debug "Stopping WildcardAddressResolverService" + let hasBeenStopped = await procCall Service(self).stop(switch) + if hasBeenStopped: + if not isNil(self.scheduleHandle): + self.scheduleHandle.cancel() + self.scheduleHandle = nil + switch.peerInfo.addressMappers.keepItIf(it != self.addressMapper) + await switch.peerInfo.update() + return hasBeenStopped From 7990325c4d52a0fd97d2814e2acda8913ec71794 Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 15 May 2024 16:14:23 +0200 Subject: [PATCH 02/34] add test --- tests/testwildcardresolverservice.nim | 80 +++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tests/testwildcardresolverservice.nim diff --git a/tests/testwildcardresolverservice.nim b/tests/testwildcardresolverservice.nim new file mode 100644 index 0000000000..1e5ecaff1e --- /dev/null +++ b/tests/testwildcardresolverservice.nim @@ -0,0 +1,80 @@ +{.used.} + +# Nim-Libp2p +# Copyright (c) 2024 Status Research & Development GmbH +# Licensed under either of +# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) +# * MIT license ([LICENSE-MIT](LICENSE-MIT)) +# at your option. +# This file may not be copied, modified, or distributed except according to +# those terms. + +import std/[options, sequtils] +import stew/[byteutils] +import chronos, metrics +import unittest2 +import ../libp2p/[builders, switch] +import ../libp2p/services/wildcardresolverservice +import ../libp2p/[multiaddress, multicodec] +import ./helpers + +type NetworkInterfaceProviderMock* = ref object of NetworkInterfaceProvider + +method getAddresses*( + networkInterfaceProvider: NetworkInterfaceProviderMock, addrFamily: AddressFamily +): seq[InterfaceAddress] = + try: + if addrFamily == AddressFamily.IPv4: + return + @[ + InterfaceAddress.init(initTAddress("127.0.0.1:0"), 8), + InterfaceAddress.init(initTAddress("192.168.1.22:0"), 24), + ] + else: + return + @[ + InterfaceAddress.init(initTAddress("::1:0"), 8), + InterfaceAddress.init(initTAddress("fe80::1:0"), 64), + ] + except TransportAddressError as e: + echo "Error: " & $e.msg + fail() + +proc createSwitch(svc: Service): Switch = + SwitchBuilder + .new() + .withRng(newRng()) + .withAddresses( + @[ + MultiAddress.init("/ip4/0.0.0.0/tcp/0/").tryGet(), + MultiAddress.init("/ip6/::/tcp/0/").tryGet(), + ] + ) + .withTcpTransport() + .withMplex() + .withNoise() + .withServices(@[svc]) + .build() + +suite "WildcardAddressResolverService": + teardown: + checkTrackers() + + asyncTest "WildcardAddressResolverService must resolve all wildcard addresses": + let svc: Service = WildcardAddressResolverService.new( + networkInterfaceProvider = NetworkInterfaceProviderMock.new() + ) + let switch = createSwitch(svc) + await switch.start() + await svc.run(switch) + let peerId = MultiAddress.init(multiCodec("p2p"), switch.peerInfo.peerId).get + let tcpIp4 = switch.peerInfo.addrs[0][multiCodec("tcp")].get # tcp port for ip4 + let tcpIp6 = switch.peerInfo.addrs[2][multiCodec("tcp")].get # tcp port for ip6 + check switch.peerInfo.addrs == + @[ + MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4).get.concat(peerId).get, + MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4).get.concat(peerId).get, + MultiAddress.init("/ip6/::1" & $tcpIp6).get.concat(peerId).get, + MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get.concat(peerId).get, + ] + await switch.stop() From 04f8b835a90375aa7d03e0f8d69917a570ad8e09 Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 15 May 2024 16:14:37 +0200 Subject: [PATCH 03/34] add withvalue for result --- libp2p/utility.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libp2p/utility.nim b/libp2p/utility.nim index 211ddbec41..2fa236c4ca 100644 --- a/libp2p/utility.nim +++ b/libp2p/utility.nim @@ -112,6 +112,9 @@ template withValue*[T](self: Opt[T] | Option[T], value, body: untyped): untyped let value {.inject.} = temp.get() body +template withValue*[T, E](self: Result[T, E], value, body: untyped): untyped = + self.toOpt().withValue(value, body) + macro withValue*[T](self: Opt[T] | Option[T], value, body, elseStmt: untyped): untyped = let elseBody = elseStmt[0] quote do: From d04d3a0ce5dfa42a0710c42f6451975016f90710 Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 16 May 2024 16:08:33 +0200 Subject: [PATCH 04/34] add doc comments --- libp2p/services/wildcardresolverservice.nim | 40 ++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index 2dbbc3935e..1489a7774f 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -22,19 +22,19 @@ logScope: topics = "libp2p wildcardresolverservice" type - # This type is used to resolve wildcard addresses of the type "0.0.0.0" for IPv4 or "::" for IPv6. WildcardAddressResolverService* = ref object of Service - # Used to get the list of network addresses. + ## Service used to resolve wildcard addresses of the type "0.0.0.0" for IPv4 or "::" for IPv6. networkInterfaceProvider: NetworkInterfaceProvider - # An implementation of an address mapper that takes a list of listen addresses and expands each wildcard address - # to the respective list of interface addresses. As an example, if the listen address is 0.0.0.0:4001 - # and the machine has 2 interfaces with IPs 172.217.11.174 and 64.233.177.113, the address mapper will - # expand the wildcard address to 172.217.11.174:4001 and 64.233.177.113:4001. + ## Provides a list of network addresses. addressMapper: AddressMapper - # Represents the task that is scheduled to run the service. + ## An implementation of an address mapper that takes a list of listen addresses and expands each wildcard address + ## to the respective list of interface addresses. As an example, if the listen address is 0.0.0.0:4001 + ## and the machine has 2 interfaces with IPs 172.217.11.174 and 64.233.177.113, the address mapper will + ## expand the wildcard address to 172.217.11.174:4001 and 64.233.177.113:4001. scheduleHandle: Future[void] - # The interval at which the service should run. + ## Represents the task that is scheduled to run the service. scheduleInterval: Opt[Duration] + ## The interval at which the service should run. NetworkInterfaceProvider* = ref object of RootObj @@ -42,21 +42,21 @@ proc isLoopbackOrUp(networkInterface: NetworkInterface): bool = if (networkInterface.ifType == IfSoftwareLoopback) or (networkInterface.state == StatusUp): true else: false -## This method retrieves the addresses of network interfaces based on the specified address family. -## -## The `getAddresses` method filters the available network interfaces to include only -## those that are either loopback or up. It then collects all the addresses from these -## interfaces and filters them to match the provided address family. -## -## Parameters: -## - `networkInterfaceProvider`: A provider that offers access to network interfaces. -## - `addrFamily`: The address family to filter the network addresses (e.g., `AddressFamily.IPv4` or `AddressFamily.IPv6`). -## -## Returns: -## - A sequence of `InterfaceAddress` objects that match the specified address family. method getAddresses*( networkInterfaceProvider: NetworkInterfaceProvider, addrFamily: AddressFamily ): seq[InterfaceAddress] {.base.} = + ## This method retrieves the addresses of network interfaces based on the specified address family. + ## + ## The `getAddresses` method filters the available network interfaces to include only + ## those that are either loopback or up. It then collects all the addresses from these + ## interfaces and filters them to match the provided address family. + ## + ## Parameters: + ## - `networkInterfaceProvider`: A provider that offers access to network interfaces. + ## - `addrFamily`: The address family to filter the network addresses (e.g., `AddressFamily.IPv4` or `AddressFamily.IPv6`). + ## + ## Returns: + ## - A sequence of `InterfaceAddress` objects that match the specified address family. let interfaces = getInterfaces().filterIt(it.isLoopbackOrUp()) flatInterfaceAddresses = concat(interfaces.mapIt(it.addresses)) From 368ab106b03f1d485dba257c59cc3a8ae47fe7c0 Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 16 May 2024 18:39:58 +0200 Subject: [PATCH 05/34] add doc comments --- libp2p/services/wildcardresolverservice.nim | 50 +++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index 1489a7774f..7e65b5c73c 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -24,6 +24,9 @@ logScope: type WildcardAddressResolverService* = ref object of Service ## Service used to resolve wildcard addresses of the type "0.0.0.0" for IPv4 or "::" for IPv6. + ## When used with a `Switch`, this service will be automatically started and stopped + ## when the switch starts and stops. This is facilitated by adding the service to the switch's + ## list of services using the `.withServices(@[svc])` method in the `SwitchBuilder`. networkInterfaceProvider: NetworkInterfaceProvider ## Provides a list of network addresses. addressMapper: AddressMapper @@ -69,6 +72,16 @@ proc new*( scheduleInterval: Opt[Duration] = Opt.none(Duration), networkInterfaceProvider: NetworkInterfaceProvider = new(NetworkInterfaceProvider), ): T = + ## This procedure initializes a new `WildcardAddressResolverService` with the provided + ## schedule interval and network interface provider. + ## + ## Parameters: + ## - `T`: The type descriptor for `WildcardAddressResolverService`. + ## - `scheduleInterval`: An optional interval at which the service should run. Defaults to none. + ## - `networkInterfaceProvider`: A provider that offers access to network interfaces. Defaults to a new instance of `NetworkInterfaceProvider`. + ## + ## Returns: + ## - A new instance of `WildcardAddressResolverService`. return T( scheduleInterval: scheduleInterval, networkInterfaceProvider: networkInterfaceProvider, @@ -77,6 +90,15 @@ proc new*( proc schedule( service: WildcardAddressResolverService, switch: Switch, interval: Duration ) {.async.} = + ## Schedules the WildcardAddressResolverService to run at regular intervals. + ## + ## Sets up a schedule for the WildcardAddressResolverService to execute periodically based + ## on the specified interval. It continuously runs the service on the given switch at the defined time intervals. + ## + ## Parameters: + ## - `service`: The instance of the WildcardAddressResolverService that will be scheduled. + ## - `switch`: The Switch object that the service will operate on. + ## - `interval`: The Duration specifying how often the service should run. heartbeat "Scheduling WildcardAddressResolverService run", interval: await service.run(switch) @@ -177,6 +199,17 @@ proc expandWildcardAddresses( method setup*( self: WildcardAddressResolverService, switch: Switch ): Future[bool] {.async.} = + ## Sets up the `WildcardAddressResolverService`. + ## + ## This method adds the address mapper to the peer's list of address mappers and schedules the seervice to run + ## at the specified interval. + ## + ## Parameters: + ## - `self`: The instance of `WildcardAddressResolverService` being set up. + ## - `switch`: The switch context in which the service operates. + ## + ## Returns: + ## - A `Future[bool]` that resolves to `true` if the setup was successful, otherwise `false`. self.addressMapper = proc( listenAddrs: seq[MultiAddress] ): Future[seq[MultiAddress]] {.async.} = @@ -194,12 +227,29 @@ method setup*( return hasBeenSetup method run*(self: WildcardAddressResolverService, switch: Switch) {.async, public.} = + ## Runs the WildcardAddressResolverService for a given switch. + ## + ## It updates the peer information for the provided switch by running the registered address mapper. Any other + ## address mappers that are registered with the switch will also be run. + ## trace "Running WildcardAddressResolverService" await switch.peerInfo.update() method stop*( self: WildcardAddressResolverService, switch: Switch ): Future[bool] {.async, public.} = + ## Stops the WildcardAddressResolverService. + ## + ## Handles the shutdown process of the WildcardAddressResolverService for a given switch. + ## It cancels the scheduled task, if any, and removes the address mapper from the switch's list of address mappers. + ## It then updates the peer information for the provided switch. Any wildcard address wont be resolved anymore. + ## + ## Parameters: + ## - `self`: The instance of the WildcardAddressResolverService. + ## - `switch`: The Switch object associated with the service. + ## + ## Returns: + ## - A future that resolves to `true` if the service was successfully stopped, otherwise `false`. debug "Stopping WildcardAddressResolverService" let hasBeenStopped = await procCall Service(self).stop(switch) if hasBeenStopped: From d2a4e84850d384f6b0eb80df56a5e5225b31f28d Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 16 May 2024 19:20:30 +0200 Subject: [PATCH 06/34] removes scheduler and some cleanup --- libp2p/services/wildcardresolverservice.nim | 43 +++------------------ 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index 7e65b5c73c..9e86342358 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -9,14 +9,11 @@ {.push raises: [].} -import std/[deques, sequtils] +import std/sequtils import stew/[byteutils, results, endians2] -import chronos, chronos/transports/[osnet, ipnet], metrics +import chronos, chronos/transports/[osnet, ipnet], chronicles import ../[multiaddress, multicodec] import ../switch -import ../wire -import ../utils/heartbeat -import ../crypto/crypto logScope: topics = "libp2p wildcardresolverservice" @@ -24,7 +21,7 @@ logScope: type WildcardAddressResolverService* = ref object of Service ## Service used to resolve wildcard addresses of the type "0.0.0.0" for IPv4 or "::" for IPv6. - ## When used with a `Switch`, this service will be automatically started and stopped + ## When used with a `Switch`, this service will be automatically set up and stopped ## when the switch starts and stops. This is facilitated by adding the service to the switch's ## list of services using the `.withServices(@[svc])` method in the `SwitchBuilder`. networkInterfaceProvider: NetworkInterfaceProvider @@ -34,10 +31,6 @@ type ## to the respective list of interface addresses. As an example, if the listen address is 0.0.0.0:4001 ## and the machine has 2 interfaces with IPs 172.217.11.174 and 64.233.177.113, the address mapper will ## expand the wildcard address to 172.217.11.174:4001 and 64.233.177.113:4001. - scheduleHandle: Future[void] - ## Represents the task that is scheduled to run the service. - scheduleInterval: Opt[Duration] - ## The interval at which the service should run. NetworkInterfaceProvider* = ref object of RootObj @@ -72,36 +65,18 @@ proc new*( scheduleInterval: Opt[Duration] = Opt.none(Duration), networkInterfaceProvider: NetworkInterfaceProvider = new(NetworkInterfaceProvider), ): T = - ## This procedure initializes a new `WildcardAddressResolverService` with the provided - ## schedule interval and network interface provider. + ## This procedure initializes a new `WildcardAddressResolverService` with the provided network interface provider. ## ## Parameters: ## - `T`: The type descriptor for `WildcardAddressResolverService`. - ## - `scheduleInterval`: An optional interval at which the service should run. Defaults to none. ## - `networkInterfaceProvider`: A provider that offers access to network interfaces. Defaults to a new instance of `NetworkInterfaceProvider`. ## ## Returns: ## - A new instance of `WildcardAddressResolverService`. return T( - scheduleInterval: scheduleInterval, networkInterfaceProvider: networkInterfaceProvider, ) -proc schedule( - service: WildcardAddressResolverService, switch: Switch, interval: Duration -) {.async.} = - ## Schedules the WildcardAddressResolverService to run at regular intervals. - ## - ## Sets up a schedule for the WildcardAddressResolverService to execute periodically based - ## on the specified interval. It continuously runs the service on the given switch at the defined time intervals. - ## - ## Parameters: - ## - `service`: The instance of the WildcardAddressResolverService that will be scheduled. - ## - `switch`: The Switch object that the service will operate on. - ## - `interval`: The Duration specifying how often the service should run. - heartbeat "Scheduling WildcardAddressResolverService run", interval: - await service.run(switch) - proc getProtocolArgument*(ma: MultiAddress, codec: MultiCodec): MaResult[seq[byte]] = var buffer: seq[byte] for item in ma: @@ -201,8 +176,7 @@ method setup*( ): Future[bool] {.async.} = ## Sets up the `WildcardAddressResolverService`. ## - ## This method adds the address mapper to the peer's list of address mappers and schedules the seervice to run - ## at the specified interval. + ## This method adds the address mapper to the peer's list of address mappers. ## ## Parameters: ## - `self`: The instance of `WildcardAddressResolverService` being set up. @@ -221,8 +195,6 @@ method setup*( debug "Setting up WildcardAddressResolverService" let hasBeenSetup = await procCall Service(self).setup(switch) if hasBeenSetup: - self.scheduleInterval.withValue(interval): - self.scheduleHandle = schedule(self, switch, interval) switch.peerInfo.addressMappers.add(self.addressMapper) return hasBeenSetup @@ -241,7 +213,7 @@ method stop*( ## Stops the WildcardAddressResolverService. ## ## Handles the shutdown process of the WildcardAddressResolverService for a given switch. - ## It cancels the scheduled task, if any, and removes the address mapper from the switch's list of address mappers. + ## It removes the address mapper from the switch's list of address mappers. ## It then updates the peer information for the provided switch. Any wildcard address wont be resolved anymore. ## ## Parameters: @@ -253,9 +225,6 @@ method stop*( debug "Stopping WildcardAddressResolverService" let hasBeenStopped = await procCall Service(self).stop(switch) if hasBeenStopped: - if not isNil(self.scheduleHandle): - self.scheduleHandle.cancel() - self.scheduleHandle = nil switch.peerInfo.addressMappers.keepItIf(it != self.addressMapper) await switch.peerInfo.update() return hasBeenStopped From 399041a8f9d6c1cd7c5cbaaf647c1f9c4a3ebb20 Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 17 May 2024 01:19:23 +0200 Subject: [PATCH 07/34] move peer id concatenation to switch --- libp2p/multiaddress.nim | 2 +- libp2p/services/wildcardresolverservice.nim | 7 ++----- libp2p/switch.nim | 4 +++- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libp2p/multiaddress.nim b/libp2p/multiaddress.nim index c0b9f8741e..42497fc2f8 100644 --- a/libp2p/multiaddress.nim +++ b/libp2p/multiaddress.nim @@ -18,7 +18,7 @@ import tables, strutils, sets import multicodec, multihash, multibase, transcoder, vbuffer, peerid, protobuf/minprotobuf, errors, utility import stew/[base58, base32, endians2, results] -export results, minprotobuf, vbuffer, utility +export results, minprotobuf, vbuffer, utility, multicodec logScope: topics = "libp2p multiaddress" diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index 9e86342358..16bf933e64 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -163,12 +163,9 @@ proc expandWildcardAddresses( ) addresses.add(wildcardAddresses) else: - listenAddr.concat(peerIdMa).withValue(ma): - addresses.add(ma) + addresses.add(listenAddr) else: - let suffixed = listenAddr.concat(peerIdMa).valueOr: - continue - addresses.add(suffixed) + addresses.add(listenAddr) addresses method setup*( diff --git a/libp2p/switch.nim b/libp2p/switch.nim index 518a48c846..ab8feb7a44 100644 --- a/libp2p/switch.nim +++ b/libp2p/switch.nim @@ -344,10 +344,12 @@ proc start*(s: Switch) {.async, public.} = await s.stop() raise fut.error + let peerIdMa = MultiAddress.init(multiCodec("p2p"), s.peerInfo.peerId).tryGet() for t in s.transports: # for each transport if t.addrs.len > 0 or t.running: s.acceptFuts.add(s.accept(t)) - s.peerInfo.listenAddrs &= t.addrs + let addrs = t.addrs.mapIt(it.concat(peerIdMa).tryget()) + s.peerInfo.listenAddrs &= addrs await s.peerInfo.update() From 90b9734b7c299dacacca50be43745b1e1ef411fc Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 17 May 2024 01:21:11 +0200 Subject: [PATCH 08/34] remove unnecessary check --- libp2p/services/wildcardresolverservice.nim | 51 ++++++++++----------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index 16bf933e64..2cd305026e 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -138,32 +138,31 @@ proc expandWildcardAddresses( for listenAddr in listenAddrs: if TCP_IP.matchPartial(listenAddr): listenAddr.getProtocolArgument(multiCodec("tcp")).toOpt.withValue(portArg): - if len(portArg) == sizeof(uint16): - let port = Port(uint16.fromBytesBE(portArg)) - if IP4.matchPartial(listenAddr): - let wildcardAddresses = getWildcardAddress( - listenAddr, - multiCodec("ip4"), - AnyAddress.address_v4, - AddressFamily.IPv4, - port, - networkInterfaceProvider, - peerIdMa, - ) - addresses.add(wildcardAddresses) - elif IP6.matchPartial(listenAddr): - let wildcardAddresses = getWildcardAddress( - listenAddr, - multiCodec("ip6"), - AnyAddress6.address_v6, - AddressFamily.IPv6, - port, - networkInterfaceProvider, - peerIdMa, - ) - addresses.add(wildcardAddresses) - else: - addresses.add(listenAddr) + let port = Port(uint16.fromBytesBE(portArg)) + if IP4.matchPartial(listenAddr): + let wildcardAddresses = getWildcardAddress( + listenAddr, + multiCodec("ip4"), + AnyAddress.address_v4, + AddressFamily.IPv4, + port, + networkInterfaceProvider, + peerIdMa, + ) + addresses.add(wildcardAddresses) + elif IP6.matchPartial(listenAddr): + let wildcardAddresses = getWildcardAddress( + listenAddr, + multiCodec("ip6"), + AnyAddress6.address_v6, + AddressFamily.IPv6, + port, + networkInterfaceProvider, + peerIdMa, + ) + addresses.add(wildcardAddresses) + else: + addresses.add(listenAddr) else: addresses.add(listenAddr) addresses From 36ae955bf20c0f7a0f8da27f2c08d0de5ff2aa5b Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 17 May 2024 14:51:04 +0200 Subject: [PATCH 09/34] remove peer id concat --- libp2p/services/wildcardresolverservice.nim | 20 +++------ libp2p/switch.nim | 4 +- tests/testwildcardresolverservice.nim | 47 ++++++++++++++++----- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index 2cd305026e..26b723cfab 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -93,15 +93,13 @@ proc getWildcardMultiAddresses( interfaceAddresses: seq[InterfaceAddress], protocol: Protocol, port: Port, - suffix: MultiAddress, ): seq[MultiAddress] = var addresses: seq[MultiAddress] for ifaddr in interfaceAddresses: var address = ifaddr.host address.port = port - MultiAddress.init(address, protocol).toOpt.withValue(maddress): - maddress.concat(suffix).toOpt.withValue(a): - addresses.add(a) + MultiAddress.init(address, protocol).withValue(maddress): + addresses.add(maddress) addresses proc getWildcardAddress( @@ -111,28 +109,22 @@ proc getWildcardAddress( addrFamily: AddressFamily, port: Port, networkInterfaceProvider: NetworkInterfaceProvider, - peerId: MultiAddress, ): seq[MultiAddress] = var addresses: seq[MultiAddress] maddress.getProtocolArgument(multiCodec).toOpt.withValue(address): if address == anyAddr: let filteredInterfaceAddresses = networkInterfaceProvider.getAddresses(addrFamily) addresses.add( - getWildcardMultiAddresses(filteredInterfaceAddresses, IPPROTO_TCP, port, peerId) + getWildcardMultiAddresses(filteredInterfaceAddresses, IPPROTO_TCP, port) ) else: - maddress.concat(peerId).toOpt.withValue(a): - addresses.add(a) + addresses.add(maddress) return addresses proc expandWildcardAddresses( networkInterfaceProvider: NetworkInterfaceProvider, - peerId: PeerId, listenAddrs: seq[MultiAddress], ): seq[MultiAddress] = - let peerIdMa = MultiAddress.init(multiCodec("p2p"), peerId).valueOr: - return default(seq[MultiAddress]) - var addresses: seq[MultiAddress] # In this loop we expand bounded addresses like `0.0.0.0` and `::` to list of interface addresses. for listenAddr in listenAddrs: @@ -147,7 +139,6 @@ proc expandWildcardAddresses( AddressFamily.IPv4, port, networkInterfaceProvider, - peerIdMa, ) addresses.add(wildcardAddresses) elif IP6.matchPartial(listenAddr): @@ -158,7 +149,6 @@ proc expandWildcardAddresses( AddressFamily.IPv6, port, networkInterfaceProvider, - peerIdMa, ) addresses.add(wildcardAddresses) else: @@ -185,7 +175,7 @@ method setup*( ): Future[seq[MultiAddress]] {.async.} = echo listenAddrs return expandWildcardAddresses( - self.networkInterfaceProvider, switch.peerInfo.peerId, listenAddrs + self.networkInterfaceProvider, listenAddrs ) debug "Setting up WildcardAddressResolverService" diff --git a/libp2p/switch.nim b/libp2p/switch.nim index ab8feb7a44..518a48c846 100644 --- a/libp2p/switch.nim +++ b/libp2p/switch.nim @@ -344,12 +344,10 @@ proc start*(s: Switch) {.async, public.} = await s.stop() raise fut.error - let peerIdMa = MultiAddress.init(multiCodec("p2p"), s.peerInfo.peerId).tryGet() for t in s.transports: # for each transport if t.addrs.len > 0 or t.running: s.acceptFuts.add(s.accept(t)) - let addrs = t.addrs.mapIt(it.concat(peerIdMa).tryget()) - s.peerInfo.listenAddrs &= addrs + s.peerInfo.listenAddrs &= t.addrs await s.peerInfo.update() diff --git a/tests/testwildcardresolverservice.nim b/tests/testwildcardresolverservice.nim index 1e5ecaff1e..e617600339 100644 --- a/tests/testwildcardresolverservice.nim +++ b/tests/testwildcardresolverservice.nim @@ -60,21 +60,46 @@ suite "WildcardAddressResolverService": teardown: checkTrackers() - asyncTest "WildcardAddressResolverService must resolve all wildcard addresses": + proc setupWildcardService(): Future[tuple[svc: Service, switch: Switch, tcpIp4: MultiAddress, tcpIp6: MultiAddress]] {.async.} = let svc: Service = WildcardAddressResolverService.new( networkInterfaceProvider = NetworkInterfaceProviderMock.new() ) let switch = createSwitch(svc) await switch.start() - await svc.run(switch) - let peerId = MultiAddress.init(multiCodec("p2p"), switch.peerInfo.peerId).get let tcpIp4 = switch.peerInfo.addrs[0][multiCodec("tcp")].get # tcp port for ip4 - let tcpIp6 = switch.peerInfo.addrs[2][multiCodec("tcp")].get # tcp port for ip6 - check switch.peerInfo.addrs == - @[ - MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4).get.concat(peerId).get, - MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4).get.concat(peerId).get, - MultiAddress.init("/ip6/::1" & $tcpIp6).get.concat(peerId).get, - MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get.concat(peerId).get, - ] + let tcpIp6 = switch.peerInfo.addrs[1][multiCodec("tcp")].get # tcp port for ip6 + return (svc, switch, tcpIp4, tcpIp6) + + asyncTest "WildcardAddressResolverService must resolve all wildcard addresses": + let (svc, switch, tcpIp4, tcpIp6) = await setupWildcardService() + check switch.peerInfo.addrs == @[ + MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, + MultiAddress.init("/ip6/::" & $tcpIp6).get, + ] + await svc.run(switch) + check switch.peerInfo.addrs == @[ + MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4).get, + MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4).get, + MultiAddress.init("/ip6/::1" & $tcpIp6).get, + MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get, + ] + await switch.stop() + + asyncTest "WildcardAddressResolverService must stop and not resolve wildcard addresses": + let (svc, switch, tcpIp4, tcpIp6) = await setupWildcardService() + check switch.peerInfo.addrs == @[ + MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, + MultiAddress.init("/ip6/::" & $tcpIp6).get, + ] + await svc.run(switch) + check switch.peerInfo.addrs == @[ + MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4).get, + MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4).get, + MultiAddress.init("/ip6/::1" & $tcpIp6).get, + MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get, + ] await switch.stop() + check switch.peerInfo.addrs == @[ + MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, + MultiAddress.init("/ip6/::" & $tcpIp6).get, + ] From 19b827393d2ce3f2d8500718a6fbae5e3e54d8ab Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 17 May 2024 14:58:26 +0200 Subject: [PATCH 10/34] remove redundant test --- tests/testwildcardresolverservice.nim | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/tests/testwildcardresolverservice.nim b/tests/testwildcardresolverservice.nim index e617600339..5ec4ddc31a 100644 --- a/tests/testwildcardresolverservice.nim +++ b/tests/testwildcardresolverservice.nim @@ -70,22 +70,7 @@ suite "WildcardAddressResolverService": let tcpIp6 = switch.peerInfo.addrs[1][multiCodec("tcp")].get # tcp port for ip6 return (svc, switch, tcpIp4, tcpIp6) - asyncTest "WildcardAddressResolverService must resolve all wildcard addresses": - let (svc, switch, tcpIp4, tcpIp6) = await setupWildcardService() - check switch.peerInfo.addrs == @[ - MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, - MultiAddress.init("/ip6/::" & $tcpIp6).get, - ] - await svc.run(switch) - check switch.peerInfo.addrs == @[ - MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4).get, - MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4).get, - MultiAddress.init("/ip6/::1" & $tcpIp6).get, - MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get, - ] - await switch.stop() - - asyncTest "WildcardAddressResolverService must stop and not resolve wildcard addresses": + asyncTest "WildcardAddressResolverService must resolve wildcard addresses and stop doing so when stopped": let (svc, switch, tcpIp4, tcpIp6) = await setupWildcardService() check switch.peerInfo.addrs == @[ MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, From 0a2df2b6a2d820f164997bb62f04ecc7d6cd284c Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 22 May 2024 15:28:38 +0200 Subject: [PATCH 11/34] add docs --- libp2p/peerinfo.nim | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libp2p/peerinfo.nim b/libp2p/peerinfo.nim index a31f42eb5f..d82f350733 100644 --- a/libp2p/peerinfo.nim +++ b/libp2p/peerinfo.nim @@ -24,12 +24,16 @@ type AddressMapper* = proc(listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.gcsafe, raises: [].} + ## A proc that expected to resolve the listen addresses into dialable addresses PeerInfo* {.public.} = ref object peerId*: PeerId listenAddrs*: seq[MultiAddress] + ## contains addresses the node listens on, which may include wildcard and private addresses (not directly reachable). addrs: seq[MultiAddress] + ## contains resolved addresses that other peers can use to connect, including public-facing NAT and port-forwarded addresses. addressMappers*: seq[AddressMapper] + ## contains a list of procs that can be used to resolve the listen addresses into dialable addresses. protocols*: seq[string] protoVersion*: string agentVersion*: string From 4196b4af8ec1958e7af4897d0165ee8503a0aadc Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 23 May 2024 17:06:25 +0200 Subject: [PATCH 12/34] make addr provider a proc --- libp2p/services/wildcardresolverservice.nim | 11 ++++------- tests/testwildcardresolverservice.nim | 10 ++++------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index 26b723cfab..d014635181 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -32,15 +32,13 @@ type ## and the machine has 2 interfaces with IPs 172.217.11.174 and 64.233.177.113, the address mapper will ## expand the wildcard address to 172.217.11.174:4001 and 64.233.177.113:4001. - NetworkInterfaceProvider* = ref object of RootObj + NetworkInterfaceProvider* = proc (addrFamily: AddressFamily): seq[InterfaceAddress] {.gcsafe, raises: [].} proc isLoopbackOrUp(networkInterface: NetworkInterface): bool = if (networkInterface.ifType == IfSoftwareLoopback) or (networkInterface.state == StatusUp): true else: false -method getAddresses*( - networkInterfaceProvider: NetworkInterfaceProvider, addrFamily: AddressFamily -): seq[InterfaceAddress] {.base.} = +proc getAddresses(addrFamily: AddressFamily): seq[InterfaceAddress] = ## This method retrieves the addresses of network interfaces based on the specified address family. ## ## The `getAddresses` method filters the available network interfaces to include only @@ -48,7 +46,6 @@ method getAddresses*( ## interfaces and filters them to match the provided address family. ## ## Parameters: - ## - `networkInterfaceProvider`: A provider that offers access to network interfaces. ## - `addrFamily`: The address family to filter the network addresses (e.g., `AddressFamily.IPv4` or `AddressFamily.IPv6`). ## ## Returns: @@ -63,7 +60,7 @@ method getAddresses*( proc new*( T: typedesc[WildcardAddressResolverService], scheduleInterval: Opt[Duration] = Opt.none(Duration), - networkInterfaceProvider: NetworkInterfaceProvider = new(NetworkInterfaceProvider), + networkInterfaceProvider: NetworkInterfaceProvider = getAddresses, ): T = ## This procedure initializes a new `WildcardAddressResolverService` with the provided network interface provider. ## @@ -113,7 +110,7 @@ proc getWildcardAddress( var addresses: seq[MultiAddress] maddress.getProtocolArgument(multiCodec).toOpt.withValue(address): if address == anyAddr: - let filteredInterfaceAddresses = networkInterfaceProvider.getAddresses(addrFamily) + let filteredInterfaceAddresses = networkInterfaceProvider(addrFamily) addresses.add( getWildcardMultiAddresses(filteredInterfaceAddresses, IPPROTO_TCP, port) ) diff --git a/tests/testwildcardresolverservice.nim b/tests/testwildcardresolverservice.nim index 5ec4ddc31a..bc4e4f5134 100644 --- a/tests/testwildcardresolverservice.nim +++ b/tests/testwildcardresolverservice.nim @@ -18,11 +18,9 @@ import ../libp2p/services/wildcardresolverservice import ../libp2p/[multiaddress, multicodec] import ./helpers -type NetworkInterfaceProviderMock* = ref object of NetworkInterfaceProvider - -method getAddresses*( - networkInterfaceProvider: NetworkInterfaceProviderMock, addrFamily: AddressFamily -): seq[InterfaceAddress] = +proc getAddressesMock( + addrFamily: AddressFamily +): seq[InterfaceAddress] {.gcsafe, raises: [].} = try: if addrFamily == AddressFamily.IPv4: return @@ -62,7 +60,7 @@ suite "WildcardAddressResolverService": proc setupWildcardService(): Future[tuple[svc: Service, switch: Switch, tcpIp4: MultiAddress, tcpIp6: MultiAddress]] {.async.} = let svc: Service = WildcardAddressResolverService.new( - networkInterfaceProvider = NetworkInterfaceProviderMock.new() + networkInterfaceProvider = getAddressesMock ) let switch = createSwitch(svc) await switch.start() From 51339c2b34b30e3171c770add9a9d191b06bc7ba Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 23 May 2024 17:07:18 +0200 Subject: [PATCH 13/34] formatting --- libp2p/services/wildcardresolverservice.nim | 18 ++---- tests/testwildcardresolverservice.nim | 66 +++++++++++---------- 2 files changed, 41 insertions(+), 43 deletions(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index d014635181..6f407fe6f0 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -32,7 +32,8 @@ type ## and the machine has 2 interfaces with IPs 172.217.11.174 and 64.233.177.113, the address mapper will ## expand the wildcard address to 172.217.11.174:4001 and 64.233.177.113:4001. - NetworkInterfaceProvider* = proc (addrFamily: AddressFamily): seq[InterfaceAddress] {.gcsafe, raises: [].} + NetworkInterfaceProvider* = + proc(addrFamily: AddressFamily): seq[InterfaceAddress] {.gcsafe, raises: [].} proc isLoopbackOrUp(networkInterface: NetworkInterface): bool = if (networkInterface.ifType == IfSoftwareLoopback) or @@ -70,9 +71,7 @@ proc new*( ## ## Returns: ## - A new instance of `WildcardAddressResolverService`. - return T( - networkInterfaceProvider: networkInterfaceProvider, - ) + return T(networkInterfaceProvider: networkInterfaceProvider) proc getProtocolArgument*(ma: MultiAddress, codec: MultiCodec): MaResult[seq[byte]] = var buffer: seq[byte] @@ -87,9 +86,7 @@ proc getProtocolArgument*(ma: MultiAddress, codec: MultiCodec): MaResult[seq[byt err("Multiaddress codec has not been found") proc getWildcardMultiAddresses( - interfaceAddresses: seq[InterfaceAddress], - protocol: Protocol, - port: Port, + interfaceAddresses: seq[InterfaceAddress], protocol: Protocol, port: Port ): seq[MultiAddress] = var addresses: seq[MultiAddress] for ifaddr in interfaceAddresses: @@ -119,8 +116,7 @@ proc getWildcardAddress( return addresses proc expandWildcardAddresses( - networkInterfaceProvider: NetworkInterfaceProvider, - listenAddrs: seq[MultiAddress], + networkInterfaceProvider: NetworkInterfaceProvider, listenAddrs: seq[MultiAddress] ): seq[MultiAddress] = var addresses: seq[MultiAddress] # In this loop we expand bounded addresses like `0.0.0.0` and `::` to list of interface addresses. @@ -171,9 +167,7 @@ method setup*( listenAddrs: seq[MultiAddress] ): Future[seq[MultiAddress]] {.async.} = echo listenAddrs - return expandWildcardAddresses( - self.networkInterfaceProvider, listenAddrs - ) + return expandWildcardAddresses(self.networkInterfaceProvider, listenAddrs) debug "Setting up WildcardAddressResolverService" let hasBeenSetup = await procCall Service(self).setup(switch) diff --git a/tests/testwildcardresolverservice.nim b/tests/testwildcardresolverservice.nim index bc4e4f5134..e9bd270f9e 100644 --- a/tests/testwildcardresolverservice.nim +++ b/tests/testwildcardresolverservice.nim @@ -40,28 +40,29 @@ proc getAddressesMock( proc createSwitch(svc: Service): Switch = SwitchBuilder - .new() - .withRng(newRng()) - .withAddresses( - @[ - MultiAddress.init("/ip4/0.0.0.0/tcp/0/").tryGet(), - MultiAddress.init("/ip6/::/tcp/0/").tryGet(), - ] - ) - .withTcpTransport() - .withMplex() - .withNoise() - .withServices(@[svc]) - .build() + .new() + .withRng(newRng()) + .withAddresses( + @[ + MultiAddress.init("/ip4/0.0.0.0/tcp/0/").tryGet(), + MultiAddress.init("/ip6/::/tcp/0/").tryGet(), + ] + ) + .withTcpTransport() + .withMplex() + .withNoise() + .withServices(@[svc]) + .build() suite "WildcardAddressResolverService": teardown: checkTrackers() - proc setupWildcardService(): Future[tuple[svc: Service, switch: Switch, tcpIp4: MultiAddress, tcpIp6: MultiAddress]] {.async.} = - let svc: Service = WildcardAddressResolverService.new( - networkInterfaceProvider = getAddressesMock - ) + proc setupWildcardService(): Future[ + tuple[svc: Service, switch: Switch, tcpIp4: MultiAddress, tcpIp6: MultiAddress] + ] {.async.} = + let svc: Service = + WildcardAddressResolverService.new(networkInterfaceProvider = getAddressesMock) let switch = createSwitch(svc) await switch.start() let tcpIp4 = switch.peerInfo.addrs[0][multiCodec("tcp")].get # tcp port for ip4 @@ -70,19 +71,22 @@ suite "WildcardAddressResolverService": asyncTest "WildcardAddressResolverService must resolve wildcard addresses and stop doing so when stopped": let (svc, switch, tcpIp4, tcpIp6) = await setupWildcardService() - check switch.peerInfo.addrs == @[ - MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, - MultiAddress.init("/ip6/::" & $tcpIp6).get, - ] + check switch.peerInfo.addrs == + @[ + MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, + MultiAddress.init("/ip6/::" & $tcpIp6).get, + ] await svc.run(switch) - check switch.peerInfo.addrs == @[ - MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4).get, - MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4).get, - MultiAddress.init("/ip6/::1" & $tcpIp6).get, - MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get, - ] + check switch.peerInfo.addrs == + @[ + MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4).get, + MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4).get, + MultiAddress.init("/ip6/::1" & $tcpIp6).get, + MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get, + ] await switch.stop() - check switch.peerInfo.addrs == @[ - MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, - MultiAddress.init("/ip6/::" & $tcpIp6).get, - ] + check switch.peerInfo.addrs == + @[ + MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, + MultiAddress.init("/ip6/::" & $tcpIp6).get, + ] From 99dbeafd8c41915362fa1cb74067046fbb11058a Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 23 May 2024 17:09:56 +0200 Subject: [PATCH 14/34] remove toOpt --- libp2p/services/wildcardresolverservice.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index 6f407fe6f0..c857dcf608 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -105,7 +105,7 @@ proc getWildcardAddress( networkInterfaceProvider: NetworkInterfaceProvider, ): seq[MultiAddress] = var addresses: seq[MultiAddress] - maddress.getProtocolArgument(multiCodec).toOpt.withValue(address): + maddress.getProtocolArgument(multiCodec).withValue(address): if address == anyAddr: let filteredInterfaceAddresses = networkInterfaceProvider(addrFamily) addresses.add( @@ -122,7 +122,7 @@ proc expandWildcardAddresses( # In this loop we expand bounded addresses like `0.0.0.0` and `::` to list of interface addresses. for listenAddr in listenAddrs: if TCP_IP.matchPartial(listenAddr): - listenAddr.getProtocolArgument(multiCodec("tcp")).toOpt.withValue(portArg): + listenAddr.getProtocolArgument(multiCodec("tcp")).withValue(portArg): let port = Port(uint16.fromBytesBE(portArg)) if IP4.matchPartial(listenAddr): let wildcardAddresses = getWildcardAddress( From d834b3ef764b13a38ffcf92a986d26f0978acaa6 Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 23 May 2024 17:10:37 +0200 Subject: [PATCH 15/34] remove echo --- libp2p/services/wildcardresolverservice.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index c857dcf608..e2e9278fb8 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -166,7 +166,6 @@ method setup*( self.addressMapper = proc( listenAddrs: seq[MultiAddress] ): Future[seq[MultiAddress]] {.async.} = - echo listenAddrs return expandWildcardAddresses(self.networkInterfaceProvider, listenAddrs) debug "Setting up WildcardAddressResolverService" From 2216dace8a0aaea3fbc92cb68d81c5b7ebe318a5 Mon Sep 17 00:00:00 2001 From: diegomrsantos Date: Fri, 24 May 2024 14:13:35 +0200 Subject: [PATCH 16/34] Update libp2p/services/wildcardresolverservice.nim Co-authored-by: Ludovic Chenut --- libp2p/services/wildcardresolverservice.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index e2e9278fb8..aebdc1c3ac 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -119,7 +119,7 @@ proc expandWildcardAddresses( networkInterfaceProvider: NetworkInterfaceProvider, listenAddrs: seq[MultiAddress] ): seq[MultiAddress] = var addresses: seq[MultiAddress] - # In this loop we expand bounded addresses like `0.0.0.0` and `::` to list of interface addresses. + # In this loop we expand bound addresses like `0.0.0.0` and `::` to list of interface addresses. for listenAddr in listenAddrs: if TCP_IP.matchPartial(listenAddr): listenAddr.getProtocolArgument(multiCodec("tcp")).withValue(portArg): From c9e877e9547f4d7aff2734c7edbcd9cc1a336ff1 Mon Sep 17 00:00:00 2001 From: Diego Date: Sun, 26 May 2024 23:19:57 +0200 Subject: [PATCH 17/34] fix test --- libp2p/builders.nim | 3 +++ libp2p/peerinfo.nim | 3 ++- libp2p/services/autorelayservice.nim | 2 +- tests/testautorelay.nim | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libp2p/builders.nim b/libp2p/builders.nim index d16d1eb065..fa0c4d3ba3 100644 --- a/libp2p/builders.nim +++ b/libp2p/builders.nim @@ -261,6 +261,9 @@ proc build*(b: SwitchBuilder): Switch else: PeerStore.new(identify) + if b.enableWildcardResolver: + b.services.insert(WildcardAddressResolverService.new(), 0) + let switch = newSwitch( peerInfo = peerInfo, transports = transports, diff --git a/libp2p/peerinfo.nim b/libp2p/peerinfo.nim index d82f350733..cd2a413d46 100644 --- a/libp2p/peerinfo.nim +++ b/libp2p/peerinfo.nim @@ -53,7 +53,8 @@ func shortLog*(p: PeerInfo): auto = chronicles.formatIt(PeerInfo): shortLog(it) proc update*(p: PeerInfo) {.async.} = - p.addrs = p.listenAddrs + if p.addrs.len == 0: + p.addrs = p.listenAddrs for mapper in p.addressMappers: p.addrs = await mapper(p.addrs) diff --git a/libp2p/services/autorelayservice.nim b/libp2p/services/autorelayservice.nim index c94aed13da..259287e3f9 100644 --- a/libp2p/services/autorelayservice.nim +++ b/libp2p/services/autorelayservice.nim @@ -38,7 +38,7 @@ proc isRunning*(self: AutoRelayService): bool = proc addressMapper( self: AutoRelayService, listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.async.} = - return concat(toSeq(self.relayAddresses.values)) + return concat(toSeq(self.relayAddresses.values)) & listenAddrs proc reserveAndUpdate(self: AutoRelayService, relayPid: PeerId, switch: Switch) {.async.} = while self.running: diff --git a/tests/testautorelay.nim b/tests/testautorelay.nim index 09e19da86c..de2f3c02e7 100644 --- a/tests/testautorelay.nim +++ b/tests/testautorelay.nim @@ -80,7 +80,7 @@ suite "Autorelay": check: addresses == @[buildRelayMA(switchRelay, switchClient)] addresses.len() == 1 - addresses == switchClient.peerInfo.addrs + addresses[0] in switchClient.peerInfo.addrs await allFutures(switchClient.stop(), switchRelay.stop()) check addresses != switchClient.peerInfo.addrs From 0e472ef04884b926f5872422870224d8906986c6 Mon Sep 17 00:00:00 2001 From: Diego Date: Mon, 27 May 2024 04:19:51 +0200 Subject: [PATCH 18/34] fix test --- tests/commontransport.nim | 8 ++++---- tests/testtortransport.nim | 33 +++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/tests/commontransport.nim b/tests/commontransport.nim index 49b0f7f126..2a31a3b37f 100644 --- a/tests/commontransport.nim +++ b/tests/commontransport.nim @@ -45,13 +45,12 @@ template commonTransportTest*(prov: TransportProvider, ma1: string, ma2: string await conn.close() #for some protocols, closing requires actively reading, so we must close here + await handlerWait.wait(1.seconds) # when no issues will not wait that long! await allFuturesThrowing( allFinished( transport1.stop(), transport2.stop())) - await handlerWait.wait(1.seconds) # when no issues will not wait that long! - asyncTest "e2e: handle write": let ma = @[MultiAddress.init(ma1).tryGet()] @@ -72,13 +71,14 @@ template commonTransportTest*(prov: TransportProvider, ma1: string, ma2: string await conn.close() #for some protocols, closing requires actively reading, so we must close here + check string.fromBytes(msg) == "Hello!" + await handlerWait.wait(1.seconds) # when no issues will not wait that long! + await allFuturesThrowing( allFinished( transport1.stop(), transport2.stop())) - check string.fromBytes(msg) == "Hello!" - await handlerWait.wait(1.seconds) # when no issues will not wait that long! asyncTest "e2e: handle read": let ma = @[MultiAddress.init(ma1).tryGet()] diff --git a/tests/testtortransport.nim b/tests/testtortransport.nim index 7b4af7adaa..8f11f6ca30 100644 --- a/tests/testtortransport.nim +++ b/tests/testtortransport.nim @@ -23,20 +23,21 @@ import ../libp2p/[stream/connection, import ./helpers, ./stubs/torstub, ./commontransport const torServer = initTAddress("127.0.0.1", 9050.Port) -var stub: TorServerStub -var startFut: Future[void] suite "Tor transport": - setup: + var + stub {.threadvar.}: TorServerStub + startFut {.threadvar.}: Future[void] + asyncSetup: stub = TorServerStub.new() stub.registerAddr("127.0.0.1:8080", "/ip4/127.0.0.1/tcp/8080") stub.registerAddr("libp2p.nim:8080", "/ip4/127.0.0.1/tcp/8080") stub.registerAddr("::1:8080", "/ip6/::1/tcp/8080") stub.registerAddr("a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcad.onion:80", "/ip4/127.0.0.1/tcp/8080") stub.registerAddr("a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcae.onion:81", "/ip4/127.0.0.1/tcp/8081") - startFut = stub.start(torServer) - teardown: - waitFor startFut.cancelAndWait() - waitFor stub.stop() + startFut = stub.start(torServer) + asyncTeardown: + await startFut.cancelAndWait() + await stub.stop() checkTrackers() proc test(lintesAddr: string, dialAddr: string) {.async.} = @@ -66,8 +67,11 @@ suite "Tor transport": await conn.close() await server.stop() + echo "serverAcceptHandler spawning" asyncSpawn serverAcceptHandler() + echo "serverAcceptHandler spawned" await runClient() + echo "runClient done" asyncTest "test start and dial using ipv4": await test("/ip4/127.0.0.1/tcp/8080", "/ip4/127.0.0.1/tcp/8080") @@ -127,14 +131,9 @@ suite "Tor transport": await clientSwitch.stop() await startClient() - + echo "startClient done" await serverSwitch.stop() - - test "It's not possible to add another transport in TorSwitch": - let torSwitch = TorSwitch.new(torServer = torServer, rng= rng, flags = {ReuseAddr}) - expect(AssertionDefect): - torSwitch.addTransport(TcpTransport.new(upgrade = Upgrade())) - waitFor torSwitch.stop() + echo "serverSwitch done" proc transProvider(): Transport = TorTransport.new(torServer, {ReuseAddr}, Upgrade()) @@ -143,3 +142,9 @@ suite "Tor transport": transProvider, "/ip4/127.0.0.1/tcp/8080/onion3/a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcad:80", "/ip4/127.0.0.1/tcp/8081/onion3/a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcae:81") + +suite "Tor transport API": + asyncTest "It's not possible to add another transport in TorSwitch": + let torSwitch = TorSwitch.new(torServer = torServer, rng= rng, flags = {ReuseAddr}) + expect(AssertionDefect): + torSwitch.addTransport(TcpTransport.new(upgrade = Upgrade())) From 57194544beda23641f326b07948b42cf9e59ac53 Mon Sep 17 00:00:00 2001 From: Diego Date: Mon, 27 May 2024 14:45:23 +0200 Subject: [PATCH 19/34] Revert "fix test" This reverts commit 48de7c4be3ad89d75b70b90ac6f0573721d99781. --- tests/commontransport.nim | 8 ++++---- tests/testtortransport.nim | 33 ++++++++++++++------------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/tests/commontransport.nim b/tests/commontransport.nim index 2a31a3b37f..49b0f7f126 100644 --- a/tests/commontransport.nim +++ b/tests/commontransport.nim @@ -45,12 +45,13 @@ template commonTransportTest*(prov: TransportProvider, ma1: string, ma2: string await conn.close() #for some protocols, closing requires actively reading, so we must close here - await handlerWait.wait(1.seconds) # when no issues will not wait that long! await allFuturesThrowing( allFinished( transport1.stop(), transport2.stop())) + await handlerWait.wait(1.seconds) # when no issues will not wait that long! + asyncTest "e2e: handle write": let ma = @[MultiAddress.init(ma1).tryGet()] @@ -71,14 +72,13 @@ template commonTransportTest*(prov: TransportProvider, ma1: string, ma2: string await conn.close() #for some protocols, closing requires actively reading, so we must close here - check string.fromBytes(msg) == "Hello!" - await handlerWait.wait(1.seconds) # when no issues will not wait that long! - await allFuturesThrowing( allFinished( transport1.stop(), transport2.stop())) + check string.fromBytes(msg) == "Hello!" + await handlerWait.wait(1.seconds) # when no issues will not wait that long! asyncTest "e2e: handle read": let ma = @[MultiAddress.init(ma1).tryGet()] diff --git a/tests/testtortransport.nim b/tests/testtortransport.nim index 8f11f6ca30..7b4af7adaa 100644 --- a/tests/testtortransport.nim +++ b/tests/testtortransport.nim @@ -23,21 +23,20 @@ import ../libp2p/[stream/connection, import ./helpers, ./stubs/torstub, ./commontransport const torServer = initTAddress("127.0.0.1", 9050.Port) +var stub: TorServerStub +var startFut: Future[void] suite "Tor transport": - var - stub {.threadvar.}: TorServerStub - startFut {.threadvar.}: Future[void] - asyncSetup: + setup: stub = TorServerStub.new() stub.registerAddr("127.0.0.1:8080", "/ip4/127.0.0.1/tcp/8080") stub.registerAddr("libp2p.nim:8080", "/ip4/127.0.0.1/tcp/8080") stub.registerAddr("::1:8080", "/ip6/::1/tcp/8080") stub.registerAddr("a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcad.onion:80", "/ip4/127.0.0.1/tcp/8080") stub.registerAddr("a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcae.onion:81", "/ip4/127.0.0.1/tcp/8081") - startFut = stub.start(torServer) - asyncTeardown: - await startFut.cancelAndWait() - await stub.stop() + startFut = stub.start(torServer) + teardown: + waitFor startFut.cancelAndWait() + waitFor stub.stop() checkTrackers() proc test(lintesAddr: string, dialAddr: string) {.async.} = @@ -67,11 +66,8 @@ suite "Tor transport": await conn.close() await server.stop() - echo "serverAcceptHandler spawning" asyncSpawn serverAcceptHandler() - echo "serverAcceptHandler spawned" await runClient() - echo "runClient done" asyncTest "test start and dial using ipv4": await test("/ip4/127.0.0.1/tcp/8080", "/ip4/127.0.0.1/tcp/8080") @@ -131,9 +127,14 @@ suite "Tor transport": await clientSwitch.stop() await startClient() - echo "startClient done" + await serverSwitch.stop() - echo "serverSwitch done" + + test "It's not possible to add another transport in TorSwitch": + let torSwitch = TorSwitch.new(torServer = torServer, rng= rng, flags = {ReuseAddr}) + expect(AssertionDefect): + torSwitch.addTransport(TcpTransport.new(upgrade = Upgrade())) + waitFor torSwitch.stop() proc transProvider(): Transport = TorTransport.new(torServer, {ReuseAddr}, Upgrade()) @@ -142,9 +143,3 @@ suite "Tor transport": transProvider, "/ip4/127.0.0.1/tcp/8080/onion3/a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcad:80", "/ip4/127.0.0.1/tcp/8081/onion3/a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcae:81") - -suite "Tor transport API": - asyncTest "It's not possible to add another transport in TorSwitch": - let torSwitch = TorSwitch.new(torServer = torServer, rng= rng, flags = {ReuseAddr}) - expect(AssertionDefect): - torSwitch.addTransport(TcpTransport.new(upgrade = Upgrade())) From 7bbc071e7e5fde934546ee20153dc2ce783f8d49 Mon Sep 17 00:00:00 2001 From: Diego Date: Mon, 27 May 2024 14:45:23 +0200 Subject: [PATCH 20/34] Revert "fix test" This reverts commit 1470006e44ae52e7f255e18fca475610f5de7613. --- libp2p/builders.nim | 2 +- libp2p/peerinfo.nim | 3 +-- libp2p/services/autorelayservice.nim | 2 +- tests/testautorelay.nim | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libp2p/builders.nim b/libp2p/builders.nim index fa0c4d3ba3..2b2a1fa631 100644 --- a/libp2p/builders.nim +++ b/libp2p/builders.nim @@ -262,7 +262,7 @@ proc build*(b: SwitchBuilder): Switch PeerStore.new(identify) if b.enableWildcardResolver: - b.services.insert(WildcardAddressResolverService.new(), 0) + b.services.add(WildcardAddressResolverService.new()) let switch = newSwitch( peerInfo = peerInfo, diff --git a/libp2p/peerinfo.nim b/libp2p/peerinfo.nim index cd2a413d46..d82f350733 100644 --- a/libp2p/peerinfo.nim +++ b/libp2p/peerinfo.nim @@ -53,8 +53,7 @@ func shortLog*(p: PeerInfo): auto = chronicles.formatIt(PeerInfo): shortLog(it) proc update*(p: PeerInfo) {.async.} = - if p.addrs.len == 0: - p.addrs = p.listenAddrs + p.addrs = p.listenAddrs for mapper in p.addressMappers: p.addrs = await mapper(p.addrs) diff --git a/libp2p/services/autorelayservice.nim b/libp2p/services/autorelayservice.nim index 259287e3f9..c94aed13da 100644 --- a/libp2p/services/autorelayservice.nim +++ b/libp2p/services/autorelayservice.nim @@ -38,7 +38,7 @@ proc isRunning*(self: AutoRelayService): bool = proc addressMapper( self: AutoRelayService, listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.async.} = - return concat(toSeq(self.relayAddresses.values)) & listenAddrs + return concat(toSeq(self.relayAddresses.values)) proc reserveAndUpdate(self: AutoRelayService, relayPid: PeerId, switch: Switch) {.async.} = while self.running: diff --git a/tests/testautorelay.nim b/tests/testautorelay.nim index de2f3c02e7..09e19da86c 100644 --- a/tests/testautorelay.nim +++ b/tests/testautorelay.nim @@ -80,7 +80,7 @@ suite "Autorelay": check: addresses == @[buildRelayMA(switchRelay, switchClient)] addresses.len() == 1 - addresses[0] in switchClient.peerInfo.addrs + addresses == switchClient.peerInfo.addrs await allFutures(switchClient.stop(), switchRelay.stop()) check addresses != switchClient.peerInfo.addrs From 0b789754763bbc93906c8767eb0d6dc61dab43a9 Mon Sep 17 00:00:00 2001 From: Diego Date: Mon, 27 May 2024 14:45:29 +0200 Subject: [PATCH 21/34] Revert "enable resolver by default" This reverts commit 03f72a8b5cc60686bdac215b26236d333d7cb83e, reversing changes made to b11e2b0349a0ef6b15478b8d5d233c5075bd348e. --- libp2p/builders.nim | 3 --- libp2p/muxers/yamux/yamux.nim | 8 +++++--- libp2p/protocols/ping.nim | 2 +- tests/testrelayv2.nim | 1 + tests/testyamux.nim | 21 --------------------- tests/transport-interop/Dockerfile | 2 +- 6 files changed, 8 insertions(+), 29 deletions(-) diff --git a/libp2p/builders.nim b/libp2p/builders.nim index 2b2a1fa631..d16d1eb065 100644 --- a/libp2p/builders.nim +++ b/libp2p/builders.nim @@ -261,9 +261,6 @@ proc build*(b: SwitchBuilder): Switch else: PeerStore.new(identify) - if b.enableWildcardResolver: - b.services.add(WildcardAddressResolverService.new()) - let switch = newSwitch( peerInfo = peerInfo, transports = transports, diff --git a/libp2p/muxers/yamux/yamux.nim b/libp2p/muxers/yamux/yamux.nim index c052c4dc66..a65890d249 100644 --- a/libp2p/muxers/yamux/yamux.nim +++ b/libp2p/muxers/yamux/yamux.nim @@ -164,6 +164,7 @@ type closedRemotely: Future[void].Raising([]) closedLocally: bool receivedData: AsyncEvent + returnedEof: bool proc `$`(channel: YamuxChannel): string = result = if channel.conn.dir == Out: "=> " else: "<= " @@ -203,8 +204,8 @@ proc remoteClosed(channel: YamuxChannel) {.async: (raises: []).} = method closeImpl*(channel: YamuxChannel) {.async: (raises: []).} = if not channel.closedLocally: - trace "Closing yamux channel locally", streamId = channel.id, conn = channel.conn channel.closedLocally = true + channel.isEof = true if not channel.isReset and channel.sendQueue.len == 0: try: await channel.conn.write(YamuxHeader.data(channel.id, 0, {Fin})) @@ -272,7 +273,7 @@ method readOnce*( newLPStreamClosedError() else: newLPStreamConnDownError() - if channel.isEof: + if channel.returnedEof: raise newLPStreamRemoteClosedError() if channel.recvQueue.len == 0: channel.receivedData.clear() @@ -280,8 +281,9 @@ method readOnce*( discard await race(channel.closedRemotely, channel.receivedData.wait()) except ValueError: raiseAssert("Futures list is not empty") if channel.closedRemotely.completed() and channel.recvQueue.len == 0: + channel.returnedEof = true channel.isEof = true - return 0 # we return 0 to indicate that the channel is closed for reading from now on + return 0 let toRead = min(channel.recvQueue.len, nbytes) diff --git a/libp2p/protocols/ping.nim b/libp2p/protocols/ping.nim index d3274cb407..0921022b90 100644 --- a/libp2p/protocols/ping.nim +++ b/libp2p/protocols/ping.nim @@ -56,7 +56,7 @@ method init*(p: Ping) = trace "handling ping", conn var buf: array[PingSize, byte] await conn.readExactly(addr buf[0], PingSize) - trace "echoing ping", conn, pingData = @buf + trace "echoing ping", conn await conn.write(@buf) if not isNil(p.pingHandler): await p.pingHandler(conn.peerId) diff --git a/tests/testrelayv2.nim b/tests/testrelayv2.nim index 879dbbd771..83eb994713 100644 --- a/tests/testrelayv2.nim +++ b/tests/testrelayv2.nim @@ -315,6 +315,7 @@ suite "Circuit Relay V2": await sleepAsync(chronos.timer.seconds(ttl + 1)) expect(DialFailedError): + check: conn.atEof() await conn.close() await src.connect(rel.peerInfo.peerId, rel.peerInfo.addrs) conn = await src.dial(dst.peerInfo.peerId, @[ addrs ], customProtoCodec) diff --git a/tests/testyamux.nim b/tests/testyamux.nim index dd3d862834..70419c91f3 100644 --- a/tests/testyamux.nim +++ b/tests/testyamux.nim @@ -377,24 +377,3 @@ suite "Yamux": expect LPStreamClosedError: discard await streamA.readLp(100) blocker.complete() await streamA.close() - - asyncTest "Peer must be able to read from stream after closing it for writing": - mSetup() - - yamuxb.streamHandler = proc(conn: Connection) {.async: (raises: []).} = - try: - check (await conn.readLp(100)) == fromHex("1234") - except CancelledError, LPStreamError: - return - try: - await conn.writeLp(fromHex("5678")) - except CancelledError, LPStreamError: - return - await conn.close() - - let streamA = await yamuxa.newStream() - check streamA == yamuxa.getStreams()[0] - - await streamA.writeLp(fromHex("1234")) - await streamA.close() - check (await streamA.readLp(100)) == fromHex("5678") diff --git a/tests/transport-interop/Dockerfile b/tests/transport-interop/Dockerfile index e1aa31d390..7276b426a6 100644 --- a/tests/transport-interop/Dockerfile +++ b/tests/transport-interop/Dockerfile @@ -11,6 +11,6 @@ COPY . nim-libp2p/ RUN \ cd nim-libp2p && \ - nim c --skipProjCfg --skipParentCfg --NimblePath:./nimbledeps/pkgs -p:nim-libp2p -d:chronicles_log_level=WARN -d:chronicles_default_output_device=stderr --threads:off ./tests/transport-interop/main.nim + nim c --skipProjCfg --skipParentCfg --NimblePath:./nimbledeps/pkgs -p:nim-libp2p -d:chronicles_log_level=WARN --threads:off ./tests/transport-interop/main.nim ENTRYPOINT ["/app/nim-libp2p/tests/transport-interop/main"] From c11586c691b702abff4a5d27e145b698ad309af3 Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 28 May 2024 14:31:03 +0200 Subject: [PATCH 22/34] enable service by default in builder --- libp2p/builders.nim | 27 ++++++++++++++++----------- tests/testwildcardresolverservice.nim | 3 ++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/libp2p/builders.nim b/libp2p/builders.nim index d16d1eb065..f65c3279b6 100644 --- a/libp2p/builders.nim +++ b/libp2p/builders.nim @@ -19,7 +19,8 @@ runnableExamples: {.push raises: [].} import - options, tables, chronos, chronicles, sequtils, + options, tables, chronos, chronicles, sequtils +import switch, peerid, peerinfo, stream/connection, multiaddress, crypto/crypto, transports/[transport, tcptransport], muxers/[muxer, mplex/mplex, yamux/yamux], @@ -28,6 +29,7 @@ import connmanager, upgrademngrs/muxedupgrade, observedaddrmanager, nameresolving/nameresolver, errors, utility +import services/wildcardresolverservice export switch, peerid, peerinfo, connection, multiaddress, crypto, errors @@ -59,6 +61,7 @@ type rdv: RendezVous services: seq[Service] observedAddrManager: ObservedAddrManager + enableWildcardResolver: bool proc new*(T: type[SwitchBuilder]): T {.public.} = ## Creates a SwitchBuilder @@ -76,7 +79,8 @@ proc new*(T: type[SwitchBuilder]): T {.public.} = maxOut: -1, maxConnsPerPeer: MaxConnectionsPerPeer, protoVersion: ProtoVersion, - agentVersion: AgentVersion) + agentVersion: AgentVersion, + enableWildcardResolver: true) proc withPrivateKey*(b: SwitchBuilder, privateKey: PrivateKey): SwitchBuilder {.public.} = ## Set the private key of the switch. Will be used to @@ -85,20 +89,18 @@ proc withPrivateKey*(b: SwitchBuilder, privateKey: PrivateKey): SwitchBuilder {. b.privKey = some(privateKey) b -proc withAddress*(b: SwitchBuilder, address: MultiAddress): SwitchBuilder {.public.} = - ## | Set the listening address of the switch - ## | Calling it multiple time will override the value - - b.addresses = @[address] - b - -proc withAddresses*(b: SwitchBuilder, addresses: seq[MultiAddress]): SwitchBuilder {.public.} = +proc withAddresses*(b: SwitchBuilder, addresses: seq[MultiAddress], enableWildcardResolver: bool = true): SwitchBuilder {.public.} = ## | Set the listening addresses of the switch ## | Calling it multiple time will override the value - b.addresses = addresses + b.enableWildcardResolver = enableWildcardResolver b +proc withAddress*(b: SwitchBuilder, address: MultiAddress, enableWildcardResolver: bool = true): SwitchBuilder {.public.} = + ## | Set the listening address of the switch + ## | Calling it multiple time will override the value + b.withAddresses(@[address], enableWildcardResolver) + proc withSignedPeerRecord*(b: SwitchBuilder, sendIt = true): SwitchBuilder {.public.} = b.sendSignedPeerRecord = sendIt b @@ -261,6 +263,9 @@ proc build*(b: SwitchBuilder): Switch else: PeerStore.new(identify) + if b.enableWildcardResolver: + b.services.add(WildcardAddressResolverService.new()) + let switch = newSwitch( peerInfo = peerInfo, transports = transports, diff --git a/tests/testwildcardresolverservice.nim b/tests/testwildcardresolverservice.nim index e9bd270f9e..ae9c656ab9 100644 --- a/tests/testwildcardresolverservice.nim +++ b/tests/testwildcardresolverservice.nim @@ -46,7 +46,8 @@ proc createSwitch(svc: Service): Switch = @[ MultiAddress.init("/ip4/0.0.0.0/tcp/0/").tryGet(), MultiAddress.init("/ip6/::/tcp/0/").tryGet(), - ] + ], + false ) .withTcpTransport() .withMplex() From edf91dd9a29abec090eb5e7cc7bbe29d8fce055f Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 28 May 2024 14:31:14 +0200 Subject: [PATCH 23/34] remove stale field --- libp2p/services/wildcardresolverservice.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index aebdc1c3ac..d89e172872 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -60,7 +60,6 @@ proc getAddresses(addrFamily: AddressFamily): seq[InterfaceAddress] = proc new*( T: typedesc[WildcardAddressResolverService], - scheduleInterval: Opt[Duration] = Opt.none(Duration), networkInterfaceProvider: NetworkInterfaceProvider = getAddresses, ): T = ## This procedure initializes a new `WildcardAddressResolverService` with the provided network interface provider. From 54dbf1fdfd98b39f239904bae3192d54cd0a6b52 Mon Sep 17 00:00:00 2001 From: Diego Date: Sun, 26 May 2024 23:19:57 +0200 Subject: [PATCH 24/34] fix test --- libp2p/builders.nim | 2 +- libp2p/peerinfo.nim | 3 ++- libp2p/services/autorelayservice.nim | 2 +- tests/testautorelay.nim | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libp2p/builders.nim b/libp2p/builders.nim index f65c3279b6..f5293573c4 100644 --- a/libp2p/builders.nim +++ b/libp2p/builders.nim @@ -264,7 +264,7 @@ proc build*(b: SwitchBuilder): Switch PeerStore.new(identify) if b.enableWildcardResolver: - b.services.add(WildcardAddressResolverService.new()) + b.services.insert(WildcardAddressResolverService.new(), 0) let switch = newSwitch( peerInfo = peerInfo, diff --git a/libp2p/peerinfo.nim b/libp2p/peerinfo.nim index d82f350733..cd2a413d46 100644 --- a/libp2p/peerinfo.nim +++ b/libp2p/peerinfo.nim @@ -53,7 +53,8 @@ func shortLog*(p: PeerInfo): auto = chronicles.formatIt(PeerInfo): shortLog(it) proc update*(p: PeerInfo) {.async.} = - p.addrs = p.listenAddrs + if p.addrs.len == 0: + p.addrs = p.listenAddrs for mapper in p.addressMappers: p.addrs = await mapper(p.addrs) diff --git a/libp2p/services/autorelayservice.nim b/libp2p/services/autorelayservice.nim index c94aed13da..259287e3f9 100644 --- a/libp2p/services/autorelayservice.nim +++ b/libp2p/services/autorelayservice.nim @@ -38,7 +38,7 @@ proc isRunning*(self: AutoRelayService): bool = proc addressMapper( self: AutoRelayService, listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.async.} = - return concat(toSeq(self.relayAddresses.values)) + return concat(toSeq(self.relayAddresses.values)) & listenAddrs proc reserveAndUpdate(self: AutoRelayService, relayPid: PeerId, switch: Switch) {.async.} = while self.running: diff --git a/tests/testautorelay.nim b/tests/testautorelay.nim index 09e19da86c..de2f3c02e7 100644 --- a/tests/testautorelay.nim +++ b/tests/testautorelay.nim @@ -80,7 +80,7 @@ suite "Autorelay": check: addresses == @[buildRelayMA(switchRelay, switchClient)] addresses.len() == 1 - addresses == switchClient.peerInfo.addrs + addresses[0] in switchClient.peerInfo.addrs await allFutures(switchClient.stop(), switchRelay.stop()) check addresses != switchClient.peerInfo.addrs From 8c19cace3ee1d049978dcc7611d6e1b3bac1d412 Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 28 May 2024 16:03:09 +0200 Subject: [PATCH 25/34] fix autonatservice test --- libp2p/peerinfo.nim | 6 +++--- tests/testautonatservice.nim | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libp2p/peerinfo.nim b/libp2p/peerinfo.nim index cd2a413d46..834fd1b4ba 100644 --- a/libp2p/peerinfo.nim +++ b/libp2p/peerinfo.nim @@ -30,7 +30,7 @@ type peerId*: PeerId listenAddrs*: seq[MultiAddress] ## contains addresses the node listens on, which may include wildcard and private addresses (not directly reachable). - addrs: seq[MultiAddress] + addrs*: seq[MultiAddress] ## contains resolved addresses that other peers can use to connect, including public-facing NAT and port-forwarded addresses. addressMappers*: seq[AddressMapper] ## contains a list of procs that can be used to resolve the listen addresses into dialable addresses. @@ -53,8 +53,8 @@ func shortLog*(p: PeerInfo): auto = chronicles.formatIt(PeerInfo): shortLog(it) proc update*(p: PeerInfo) {.async.} = - if p.addrs.len == 0: - p.addrs = p.listenAddrs + # if p.addrs.len == 0: + p.addrs = p.listenAddrs for mapper in p.addressMappers: p.addrs = await mapper(p.addrs) diff --git a/tests/testautonatservice.nim b/tests/testautonatservice.nim index ad5e8bf45b..eb68538b54 100644 --- a/tests/testautonatservice.nim +++ b/tests/testautonatservice.nim @@ -110,12 +110,12 @@ suite "Autonat Service": check autonatService.networkReachability == NetworkReachability.Reachable check libp2p_autonat_reachability_confidence.value(["Reachable"]) == 0.3 - check switch1.peerInfo.addrs == switch1.peerInfo.listenAddrs.mapIt(switch1.peerStore.guessDialableAddr(it)) + check switch1.peerInfo.addrs == switch1.peerInfo.addrs.mapIt(switch1.peerStore.guessDialableAddr(it)) await allFuturesThrowing( switch1.stop(), switch2.stop(), switch3.stop(), switch4.stop()) - check switch1.peerInfo.addrs == switch1.peerInfo.listenAddrs + check switch1.peerInfo.addrs == switch1.peerInfo.addrs asyncTest "Peer must be not reachable and then reachable": @@ -261,7 +261,6 @@ suite "Autonat Service": let autonatService = AutonatService.new(AutonatClient.new(), newRng(), Opt.some(1.seconds), maxQueueSize = 1) let switch1 = createSwitch(autonatService, maxConnsPerPeer = 0) - await switch1.setDNSAddr() let switch2 = createSwitch(maxConnsPerPeer = 0, nameResolver = MockResolver.default()) @@ -277,6 +276,8 @@ suite "Autonat Service": autonatService.statusAndConfidenceHandler(statusAndConfidenceHandler) await switch1.start() + switch1.peerInfo.addrs.add([ MultiAddress.init("/dns4/localhost/").tryGet() & switch1.peerInfo.addrs[0][1].tryGet() ]) + await switch2.start() await switch1.connect(switch2.peerInfo.peerId, switch2.peerInfo.addrs) From 1bb1c1a2e1ba75f3c58e39eec4c56327542988c1 Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 28 May 2024 20:39:47 +0200 Subject: [PATCH 26/34] removing code that end up here by accident during reverts and cherry-pick --- libp2p/muxers/yamux/yamux.nim | 8 +++----- libp2p/protocols/ping.nim | 2 +- tests/testrelayv2.nim | 1 - tests/testyamux.nim | 21 +++++++++++++++++++++ tests/transport-interop/Dockerfile | 2 +- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/libp2p/muxers/yamux/yamux.nim b/libp2p/muxers/yamux/yamux.nim index a65890d249..c052c4dc66 100644 --- a/libp2p/muxers/yamux/yamux.nim +++ b/libp2p/muxers/yamux/yamux.nim @@ -164,7 +164,6 @@ type closedRemotely: Future[void].Raising([]) closedLocally: bool receivedData: AsyncEvent - returnedEof: bool proc `$`(channel: YamuxChannel): string = result = if channel.conn.dir == Out: "=> " else: "<= " @@ -204,8 +203,8 @@ proc remoteClosed(channel: YamuxChannel) {.async: (raises: []).} = method closeImpl*(channel: YamuxChannel) {.async: (raises: []).} = if not channel.closedLocally: + trace "Closing yamux channel locally", streamId = channel.id, conn = channel.conn channel.closedLocally = true - channel.isEof = true if not channel.isReset and channel.sendQueue.len == 0: try: await channel.conn.write(YamuxHeader.data(channel.id, 0, {Fin})) @@ -273,7 +272,7 @@ method readOnce*( newLPStreamClosedError() else: newLPStreamConnDownError() - if channel.returnedEof: + if channel.isEof: raise newLPStreamRemoteClosedError() if channel.recvQueue.len == 0: channel.receivedData.clear() @@ -281,9 +280,8 @@ method readOnce*( discard await race(channel.closedRemotely, channel.receivedData.wait()) except ValueError: raiseAssert("Futures list is not empty") if channel.closedRemotely.completed() and channel.recvQueue.len == 0: - channel.returnedEof = true channel.isEof = true - return 0 + return 0 # we return 0 to indicate that the channel is closed for reading from now on let toRead = min(channel.recvQueue.len, nbytes) diff --git a/libp2p/protocols/ping.nim b/libp2p/protocols/ping.nim index 0921022b90..d3274cb407 100644 --- a/libp2p/protocols/ping.nim +++ b/libp2p/protocols/ping.nim @@ -56,7 +56,7 @@ method init*(p: Ping) = trace "handling ping", conn var buf: array[PingSize, byte] await conn.readExactly(addr buf[0], PingSize) - trace "echoing ping", conn + trace "echoing ping", conn, pingData = @buf await conn.write(@buf) if not isNil(p.pingHandler): await p.pingHandler(conn.peerId) diff --git a/tests/testrelayv2.nim b/tests/testrelayv2.nim index 83eb994713..879dbbd771 100644 --- a/tests/testrelayv2.nim +++ b/tests/testrelayv2.nim @@ -315,7 +315,6 @@ suite "Circuit Relay V2": await sleepAsync(chronos.timer.seconds(ttl + 1)) expect(DialFailedError): - check: conn.atEof() await conn.close() await src.connect(rel.peerInfo.peerId, rel.peerInfo.addrs) conn = await src.dial(dst.peerInfo.peerId, @[ addrs ], customProtoCodec) diff --git a/tests/testyamux.nim b/tests/testyamux.nim index 70419c91f3..dd3d862834 100644 --- a/tests/testyamux.nim +++ b/tests/testyamux.nim @@ -377,3 +377,24 @@ suite "Yamux": expect LPStreamClosedError: discard await streamA.readLp(100) blocker.complete() await streamA.close() + + asyncTest "Peer must be able to read from stream after closing it for writing": + mSetup() + + yamuxb.streamHandler = proc(conn: Connection) {.async: (raises: []).} = + try: + check (await conn.readLp(100)) == fromHex("1234") + except CancelledError, LPStreamError: + return + try: + await conn.writeLp(fromHex("5678")) + except CancelledError, LPStreamError: + return + await conn.close() + + let streamA = await yamuxa.newStream() + check streamA == yamuxa.getStreams()[0] + + await streamA.writeLp(fromHex("1234")) + await streamA.close() + check (await streamA.readLp(100)) == fromHex("5678") diff --git a/tests/transport-interop/Dockerfile b/tests/transport-interop/Dockerfile index 7276b426a6..e1aa31d390 100644 --- a/tests/transport-interop/Dockerfile +++ b/tests/transport-interop/Dockerfile @@ -11,6 +11,6 @@ COPY . nim-libp2p/ RUN \ cd nim-libp2p && \ - nim c --skipProjCfg --skipParentCfg --NimblePath:./nimbledeps/pkgs -p:nim-libp2p -d:chronicles_log_level=WARN --threads:off ./tests/transport-interop/main.nim + nim c --skipProjCfg --skipParentCfg --NimblePath:./nimbledeps/pkgs -p:nim-libp2p -d:chronicles_log_level=WARN -d:chronicles_default_output_device=stderr --threads:off ./tests/transport-interop/main.nim ENTRYPOINT ["/app/nim-libp2p/tests/transport-interop/main"] From e0a380ee8f4d1033c9d53742a083cd551ec02e34 Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 28 May 2024 20:57:19 +0200 Subject: [PATCH 27/34] uncomment line --- libp2p/peerinfo.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/peerinfo.nim b/libp2p/peerinfo.nim index 834fd1b4ba..be780a7c73 100644 --- a/libp2p/peerinfo.nim +++ b/libp2p/peerinfo.nim @@ -53,8 +53,8 @@ func shortLog*(p: PeerInfo): auto = chronicles.formatIt(PeerInfo): shortLog(it) proc update*(p: PeerInfo) {.async.} = - # if p.addrs.len == 0: - p.addrs = p.listenAddrs + if p.addrs.len == 0: + p.addrs = p.listenAddrs for mapper in p.addressMappers: p.addrs = await mapper(p.addrs) From 2a1e1f0bd8f7bf12d77f1b72c86b23067bb624b1 Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 28 May 2024 20:57:37 +0200 Subject: [PATCH 28/34] fix hpservice test and remove proc --- tests/helpers.nim | 6 ------ tests/testhpservice.nim | 10 +++------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/tests/helpers.nim b/tests/helpers.nim index a0dd5bda59..41a0afbb97 100644 --- a/tests/helpers.nim +++ b/tests/helpers.nim @@ -215,9 +215,3 @@ proc default*(T: typedesc[MockResolver]): T = resolver.ipResponses[("localhost", false)] = @["127.0.0.1"] resolver.ipResponses[("localhost", true)] = @["::1"] resolver - -proc setDNSAddr*(switch: Switch) {.async.} = - proc addressMapper(listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.async.} = - return @[MultiAddress.init("/dns4/localhost/").tryGet() & listenAddrs[0][1].tryGet()] - switch.peerInfo.addressMappers.add(addressMapper) - await switch.peerInfo.update() diff --git a/tests/testhpservice.nim b/tests/testhpservice.nim index 7cf59a745d..2d9d9f625a 100644 --- a/tests/testhpservice.nim +++ b/tests/testhpservice.nim @@ -65,11 +65,6 @@ suite "Hole Punching": let publicPeerSwitch = createSwitch(RelayClient.new()) - proc addressMapper(listenAddrs: seq[MultiAddress]): Future[seq[MultiAddress]] {.async.} = - return @[MultiAddress.init("/dns4/localhost/").tryGet() & listenAddrs[0][1].tryGet()] - publicPeerSwitch.peerInfo.addressMappers.add(addressMapper) - await publicPeerSwitch.peerInfo.update() - proc checkMA(address: seq[MultiAddress]) = if not privatePeerRelayAddr.completed(): privatePeerRelayAddr.complete(address) @@ -83,6 +78,7 @@ suite "Hole Punching": let switchRelay = createSwitch(Relay.new()) await allFuturesThrowing(switchRelay.start(), privatePeerSwitch.start(), publicPeerSwitch.start(), peerSwitch.start()) + publicPeerSwitch.peerInfo.addrs.add([ MultiAddress.init("/dns4/localhost/").tryGet() & publicPeerSwitch.peerInfo.addrs[0][1].tryGet() ]) await privatePeerSwitch.connect(switchRelay.peerInfo.peerId, switchRelay.peerInfo.addrs) await privatePeerSwitch.connect(peerSwitch.peerInfo.peerId, peerSwitch.peerInfo.addrs) # for autonat @@ -106,7 +102,6 @@ suite "Hole Punching": let privatePeerRelayAddr = newFuture[seq[MultiAddress]]() let publicPeerSwitch = createSwitch(RelayClient.new()) - await publicPeerSwitch.setDNSAddr() proc checkMA(address: seq[MultiAddress]) = if not privatePeerRelayAddr.completed(): @@ -121,6 +116,7 @@ suite "Hole Punching": let switchRelay = createSwitch(Relay.new()) await allFuturesThrowing(switchRelay.start(), privatePeerSwitch.start(), publicPeerSwitch.start(), peerSwitch.start()) + publicPeerSwitch.peerInfo.addrs.add([ MultiAddress.init("/dns4/localhost/").tryGet() & publicPeerSwitch.peerInfo.addrs[0][1].tryGet() ]) await privatePeerSwitch.connect(switchRelay.peerInfo.peerId, switchRelay.peerInfo.addrs) await privatePeerSwitch.connect(peerSwitch.peerInfo.peerId, peerSwitch.peerInfo.addrs) # for autonat @@ -162,7 +158,7 @@ suite "Hole Punching": let privatePeerSwitch1 = SwitchStub.new(createSwitch(relayClient1, hpservice1, nameresolver = MockResolver.default())) let privatePeerSwitch2 = SwitchStub.new(createSwitch(relayClient2, hpservice2)) - await privatePeerSwitch2.setDNSAddr() + let switchRelay = createSwitch(Relay.new()) let switchAux = createSwitch() let switchAux2 = createSwitch() From 7b803ad5a95d1f2ffe8b3654c10e8f856a010c09 Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 28 May 2024 21:37:26 +0200 Subject: [PATCH 29/34] fix identify test --- libp2p/peerinfo.nim | 2 +- tests/testidentify.nim | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/libp2p/peerinfo.nim b/libp2p/peerinfo.nim index be780a7c73..53a1f4af23 100644 --- a/libp2p/peerinfo.nim +++ b/libp2p/peerinfo.nim @@ -53,7 +53,7 @@ func shortLog*(p: PeerInfo): auto = chronicles.formatIt(PeerInfo): shortLog(it) proc update*(p: PeerInfo) {.async.} = - if p.addrs.len == 0: + if p.addrs.len == 0 or p.addressMappers.len == 0: p.addrs = p.listenAddrs for mapper in p.addressMappers: p.addrs = await mapper(p.addrs) diff --git a/tests/testidentify.nim b/tests/testidentify.nim index 38605d9e50..e516ad3f13 100644 --- a/tests/testidentify.nim +++ b/tests/testidentify.nim @@ -210,8 +210,7 @@ suite "Identify": asyncTest "simple push identify": switch2.peerInfo.protocols.add("/newprotocol/") - switch2.peerInfo.listenAddrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet()) - await switch2.peerInfo.update() + switch2.peerInfo.addrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet()) check: switch1.peerStore[AddressBook][switch2.peerInfo.peerId] != switch2.peerInfo.addrs @@ -224,16 +223,9 @@ suite "Identify": await closeAll() - # Wait the very end to be sure that the push has been processed - check: - switch1.peerStore[ProtoBook][switch2.peerInfo.peerId] == switch2.peerInfo.protocols - switch1.peerStore[AddressBook][switch2.peerInfo.peerId] == switch2.peerInfo.addrs - - asyncTest "wrong peer id push identify": switch2.peerInfo.protocols.add("/newprotocol/") - switch2.peerInfo.listenAddrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet()) - await switch2.peerInfo.update() + switch2.peerInfo.addrs.add(MultiAddress.init("/ip4/127.0.0.1/tcp/5555").tryGet()) check: switch1.peerStore[AddressBook][switch2.peerInfo.peerId] != switch2.peerInfo.addrs From 385a595a8f044ae978ce3e8131e49660643f75b5 Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 28 May 2024 21:37:38 +0200 Subject: [PATCH 30/34] improve test --- tests/testwildcardresolverservice.nim | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/testwildcardresolverservice.nim b/tests/testwildcardresolverservice.nim index ae9c656ab9..e9c40cd4d9 100644 --- a/tests/testwildcardresolverservice.nim +++ b/tests/testwildcardresolverservice.nim @@ -44,6 +44,7 @@ proc createSwitch(svc: Service): Switch = .withRng(newRng()) .withAddresses( @[ + MultiAddress.init("/ip4/127.0.0.1/tcp/0/").tryGet(), MultiAddress.init("/ip4/0.0.0.0/tcp/0/").tryGet(), MultiAddress.init("/ip6/::/tcp/0/").tryGet(), ], @@ -59,35 +60,34 @@ suite "WildcardAddressResolverService": teardown: checkTrackers() - proc setupWildcardService(): Future[ - tuple[svc: Service, switch: Switch, tcpIp4: MultiAddress, tcpIp6: MultiAddress] - ] {.async.} = + asyncTest "WildcardAddressResolverService must resolve wildcard addresses and stop doing so when stopped": let svc: Service = WildcardAddressResolverService.new(networkInterfaceProvider = getAddressesMock) let switch = createSwitch(svc) await switch.start() - let tcpIp4 = switch.peerInfo.addrs[0][multiCodec("tcp")].get # tcp port for ip4 - let tcpIp6 = switch.peerInfo.addrs[1][multiCodec("tcp")].get # tcp port for ip6 - return (svc, switch, tcpIp4, tcpIp6) + let tcpIp4Locahost = switch.peerInfo.addrs[0][multiCodec("tcp")].get + let tcpIp4Wildcard = switch.peerInfo.addrs[1][multiCodec("tcp")].get + let tcpIp6 = switch.peerInfo.addrs[2][multiCodec("tcp")].get # tcp port for ip6 - asyncTest "WildcardAddressResolverService must resolve wildcard addresses and stop doing so when stopped": - let (svc, switch, tcpIp4, tcpIp6) = await setupWildcardService() check switch.peerInfo.addrs == @[ - MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, + MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4Locahost).get, + MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4Wildcard).get, MultiAddress.init("/ip6/::" & $tcpIp6).get, ] await svc.run(switch) check switch.peerInfo.addrs == @[ - MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4).get, - MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4).get, + MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4Locahost).get, + MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4Wildcard).get, + MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4Wildcard).get, MultiAddress.init("/ip6/::1" & $tcpIp6).get, MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get, ] await switch.stop() check switch.peerInfo.addrs == @[ - MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4).get, + MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4Locahost).get, + MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4Wildcard).get, MultiAddress.init("/ip6/::" & $tcpIp6).get, ] From 65c3e88ab47b5480156dea4d03dfc4f34ef34aa2 Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 29 May 2024 15:29:48 +0200 Subject: [PATCH 31/34] unnecessary --- libp2p/multiaddress.nim | 2 +- libp2p/multicodec.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/multiaddress.nim b/libp2p/multiaddress.nim index 42497fc2f8..c0b9f8741e 100644 --- a/libp2p/multiaddress.nim +++ b/libp2p/multiaddress.nim @@ -18,7 +18,7 @@ import tables, strutils, sets import multicodec, multihash, multibase, transcoder, vbuffer, peerid, protobuf/minprotobuf, errors, utility import stew/[base58, base32, endians2, results] -export results, minprotobuf, vbuffer, utility, multicodec +export results, minprotobuf, vbuffer, utility logScope: topics = "libp2p multiaddress" diff --git a/libp2p/multicodec.nim b/libp2p/multicodec.nim index a873e5fd57..c080fb35d3 100644 --- a/libp2p/multicodec.nim +++ b/libp2p/multicodec.nim @@ -12,7 +12,7 @@ {.push raises: [].} import tables, hashes -import varint, vbuffer +import vbuffer import stew/results export results From ea342244989066f1b44300fd558ae826de428c58 Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 6 Jun 2024 11:48:39 +0200 Subject: [PATCH 32/34] fix doc --- libp2p/services/wildcardresolverservice.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/services/wildcardresolverservice.nim b/libp2p/services/wildcardresolverservice.nim index d89e172872..78e81b9203 100644 --- a/libp2p/services/wildcardresolverservice.nim +++ b/libp2p/services/wildcardresolverservice.nim @@ -40,9 +40,9 @@ proc isLoopbackOrUp(networkInterface: NetworkInterface): bool = (networkInterface.state == StatusUp): true else: false proc getAddresses(addrFamily: AddressFamily): seq[InterfaceAddress] = - ## This method retrieves the addresses of network interfaces based on the specified address family. + ## Retrieves the addresses of network interfaces based on the specified address family. ## - ## The `getAddresses` method filters the available network interfaces to include only + ## It filters the available network interfaces to include only ## those that are either loopback or up. It then collects all the addresses from these ## interfaces and filters them to match the provided address family. ## From c4bcd53ed6e404bdfb28e1ad050dd67a6bf2c336 Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 6 Jun 2024 11:56:33 +0200 Subject: [PATCH 33/34] add comment --- libp2p/peerinfo.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libp2p/peerinfo.nim b/libp2p/peerinfo.nim index 53a1f4af23..c290894edf 100644 --- a/libp2p/peerinfo.nim +++ b/libp2p/peerinfo.nim @@ -53,6 +53,9 @@ func shortLog*(p: PeerInfo): auto = chronicles.formatIt(PeerInfo): shortLog(it) proc update*(p: PeerInfo) {.async.} = + # p.addrs.len == 0 overrides addrs only if it is the first time update is being executed or if the field is empty. + # p.addressMappers.len == 0 is for when all addressMappers have been removed, + # and we wish to have addrs in its initial state, i.e., a copy of listenAddrs. if p.addrs.len == 0 or p.addressMappers.len == 0: p.addrs = p.listenAddrs for mapper in p.addressMappers: From 90bc65ff16ee5ab20f7c2c69b8e5cd0ec4af57c6 Mon Sep 17 00:00:00 2001 From: Diego Date: Thu, 6 Jun 2024 12:25:04 +0200 Subject: [PATCH 34/34] show addrs in "Dialing peer" log --- libp2p/dialer.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/dialer.nim b/libp2p/dialer.nim index d3cb926b7f..ade169bdf3 100644 --- a/libp2p/dialer.nim +++ b/libp2p/dialer.nim @@ -137,7 +137,7 @@ proc dialAndUpgrade( dir = Direction.Out): Future[Muxer] {.async.} = - debug "Dialing peer", peerId = peerId.get(default(PeerId)) + debug "Dialing peer", peerId = peerId.get(default(PeerId)), addrs for rawAddress in addrs: # resolve potential dnsaddr