From cc6a32c75b930f0d2254d286693b2fc5e3722730 Mon Sep 17 00:00:00 2001 From: Marcin Czenko Date: Mon, 4 May 2026 05:52:18 +0200 Subject: [PATCH] use proper dialable addresses for mix nodes --- .gitignore | 2 +- mix_ping.nim => mix_ping_tcp.nim | 49 +++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 15 deletions(-) rename mix_ping.nim => mix_ping_tcp.nim (71%) diff --git a/.gitignore b/.gitignore index 9e548e2..e74f804 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -mix_ping +mix_ping_tcp mix_ping_quic nimcache/ nimbledeps/ diff --git a/mix_ping.nim b/mix_ping_tcp.nim similarity index 71% rename from mix_ping.nim rename to mix_ping_tcp.nim index bd27ce5..915ef57 100644 --- a/mix_ping.nim +++ b/mix_ping_tcp.nim @@ -1,21 +1,20 @@ -# SPDX-License-Identifier: Apache-2.0 OR MIT -# Copyright (c) Status Research & Development GmbH +# SPDX-License-Identifier: MIT -## Mix Protocol Ping Example +## Mix Protocol Ping Example with TCP Transport ## ## This example demonstrates using the Mix protocol with the Ping protocol. ## It creates a set of mix nodes that form an anonymous overlay network, ## then sends a ping through the mix network to a destination node and ## receives the response via Single Use Reply Blocks (SURBs). +## This example uses TCP transport for all nodes. {.used.} import chronicles, chronos, results -import std/[strformat, sequtils] +import std/[sequtils, sugar] import libp2p/[ protocols/mix, protocols/mix/mix_protocol, - protocols/mix/curve25519, protocols/ping, peerid, multiaddress, @@ -40,24 +39,47 @@ proc mixPingSimulation() {.async: (raises: [Exception]).} = var switches: seq[Switch] = @[] var mixProtos: seq[MixProtocol] = @[] - # Set up mix protocols on each mix node + # Start switches first so wildcard listen addresses are resolved to dialable addresses. for nodeInfo in mixNodeInfos: var switch = createSwitch(nodeInfo.multiAddr, Opt.some(nodeInfo.libp2pPrivKey)) + await switch.start() + info "Mix node switch", + peerId = switch.peerInfo.peerId, + addrs = switch.peerInfo.addrs, + listenAddrs = switch.peerInfo.listenAddrs + + switches.add(switch) + + defer: + await switches.mapIt(it.stop()).allFutures() + + let resolvedInfos = collect: + for i, nodeInfo in mixNodeInfos: + initMixNodeInfo( + nodeInfo.peerId, + switches[i].peerInfo.addrs[0], + nodeInfo.mixPubKey, + nodeInfo.mixPrivKey, + nodeInfo.libp2pPubKey, + nodeInfo.libp2pPrivKey, + ) + + # Mount Mix protocols using the resolved, dialable node addresses. + for i, nodeInfo in resolvedInfos: + var switch = switches[i] let proto = MixProtocol.new(nodeInfo, switch) + await proto.start() + # Populate nodePool with all other nodes' public info - proto.nodePool.add(mixNodeInfos.includeAllExcept(nodeInfo)) + proto.nodePool.add(resolvedInfos.includeAllExcept(nodeInfo)) # Register how to read ping responses (32 bytes exactly) proto.registerDestReadBehavior(PingCodec, readExactly(32)) switch.mount(proto) - switches.add(switch) mixProtos.add(proto) - defer: - await switches.mapIt(it.stop()).allFutures() - # Create a destination node (not part of the mix network) let destNode = createSwitch(MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()) defer: @@ -66,8 +88,7 @@ proc mixPingSimulation() {.async: (raises: [Exception]).} = let pingProto = Ping.new() destNode.mount(pingProto) - # Start all switches - await switches.mapIt(it.start()).allFutures() + # Start destination switch after mounting Ping. await destNode.start() # Pick sender (first mix node) and send ping through the mix network @@ -93,4 +114,4 @@ proc mixPingSimulation() {.async: (raises: [Exception]).} = info "Ping response received through mix network", rtt = response when isMainModule: - waitFor(mixPingSimulation()) \ No newline at end of file + waitFor(mixPingSimulation())