mirror of
https://github.com/logos-storage/libp2p-mix-ping-example.git
synced 2026-05-19 09:19:33 +00:00
initial commit
This commit is contained in:
commit
6750b2340f
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
mix_ping
|
||||||
|
mix_ping_quic
|
||||||
|
nimcache/
|
||||||
|
nimbledeps/
|
||||||
|
.agents/
|
||||||
|
.codex
|
||||||
|
nimble.paths
|
||||||
|
nimble.develop
|
||||||
47
README.md
Normal file
47
README.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# libp2p Mix Example
|
||||||
|
|
||||||
|
Standalone Nim example for running a libp2p Mix protocol ping simulation.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
|
||||||
|
- Nim 2.0 or newer
|
||||||
|
- Nimble
|
||||||
|
- Git
|
||||||
|
|
||||||
|
From a fresh clone:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nimble setup -l
|
||||||
|
nim c -r mix_ping.nim
|
||||||
|
```
|
||||||
|
|
||||||
|
`nimble setup -l` enables project-local dependency mode, installs dependencies
|
||||||
|
under `nimbledeps/`, and generates `nimble.paths` and `nimble.develop`.
|
||||||
|
|
||||||
|
## Local Files
|
||||||
|
|
||||||
|
The repository uses `config.nims` to keep Nim build output in the local
|
||||||
|
`nimcache/` directory and to include `nimble.paths` when it exists.
|
||||||
|
|
||||||
|
These files and directories are local artifacts and should not be committed:
|
||||||
|
|
||||||
|
- `nimbledeps/`
|
||||||
|
- `nimble.paths`
|
||||||
|
- `nimble.develop`
|
||||||
|
- `nimcache/`
|
||||||
|
- `mix_ping`
|
||||||
|
|
||||||
|
## Clean Rebuild
|
||||||
|
|
||||||
|
To verify the project can be rebuilt from committed files:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf nimbledeps nimble.paths nimble.develop nimcache mix_ping
|
||||||
|
nimble setup -l
|
||||||
|
nim c -r mix_ping.nim
|
||||||
|
```
|
||||||
|
|
||||||
|
If `nimble setup -l` reports that it cannot determine the VCS revision, make at
|
||||||
|
least one Git commit first, then rerun the command.
|
||||||
6
config.nims
Normal file
6
config.nims
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
switch("nimcache", "nimcache")
|
||||||
|
|
||||||
|
# begin Nimble config (version 2)
|
||||||
|
when withDir(thisDir(), system.fileExists("nimble.paths")):
|
||||||
|
include "nimble.paths"
|
||||||
|
# end Nimble config
|
||||||
11
libp2p_mix_example.nimble
Normal file
11
libp2p_mix_example.nimble
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
version = "0.1.0"
|
||||||
|
author = "local"
|
||||||
|
description = "Standalone libp2p mix protocol example"
|
||||||
|
license = "MIT"
|
||||||
|
srcDir = "."
|
||||||
|
|
||||||
|
requires "nim >= 2.0.0"
|
||||||
|
requires "libp2p >= 1.15.3"
|
||||||
|
requires "chronicles >= 0.11.0"
|
||||||
|
requires "chronos >= 4.2.2"
|
||||||
|
requires "results >= 0.5.0"
|
||||||
96
mix_ping.nim
Normal file
96
mix_ping.nim
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||||
|
# Copyright (c) Status Research & Development GmbH
|
||||||
|
|
||||||
|
## Mix Protocol Ping Example
|
||||||
|
##
|
||||||
|
## 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).
|
||||||
|
|
||||||
|
{.used.}
|
||||||
|
|
||||||
|
import chronicles, chronos, results
|
||||||
|
import std/[strformat, sequtils]
|
||||||
|
import libp2p/[
|
||||||
|
protocols/mix,
|
||||||
|
protocols/mix/mix_protocol,
|
||||||
|
protocols/mix/curve25519,
|
||||||
|
protocols/ping,
|
||||||
|
peerid,
|
||||||
|
multiaddress,
|
||||||
|
switch,
|
||||||
|
builders,
|
||||||
|
crypto/crypto,
|
||||||
|
crypto/secp,
|
||||||
|
]
|
||||||
|
|
||||||
|
const NumMixNodes = 10
|
||||||
|
|
||||||
|
proc createSwitch(
|
||||||
|
multiAddr: MultiAddress, libp2pPrivKey: Opt[SkPrivateKey] = Opt.none(SkPrivateKey)
|
||||||
|
): Switch =
|
||||||
|
var rng = newRng()
|
||||||
|
let skkey = libp2pPrivKey.valueOr(SkKeyPair.random(rng[]).seckey)
|
||||||
|
let privKey = PrivateKey(scheme: Secp256k1, skkey: skkey)
|
||||||
|
newStandardSwitchBuilder(privKey = Opt.some(privKey), addrs = multiAddr).build()
|
||||||
|
|
||||||
|
proc mixPingSimulation() {.async: (raises: [Exception]).} =
|
||||||
|
let mixNodeInfos = MixNodeInfo.generateRandomMany(NumMixNodes)
|
||||||
|
var switches: seq[Switch] = @[]
|
||||||
|
var mixProtos: seq[MixProtocol] = @[]
|
||||||
|
|
||||||
|
# Set up mix protocols on each mix node
|
||||||
|
for nodeInfo in mixNodeInfos:
|
||||||
|
var switch = createSwitch(nodeInfo.multiAddr, Opt.some(nodeInfo.libp2pPrivKey))
|
||||||
|
let proto = MixProtocol.new(nodeInfo, switch)
|
||||||
|
|
||||||
|
# Populate nodePool with all other nodes' public info
|
||||||
|
proto.nodePool.add(mixNodeInfos.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:
|
||||||
|
await destNode.stop()
|
||||||
|
|
||||||
|
let pingProto = Ping.new()
|
||||||
|
destNode.mount(pingProto)
|
||||||
|
|
||||||
|
# Start all switches
|
||||||
|
await switches.mapIt(it.start()).allFutures()
|
||||||
|
await destNode.start()
|
||||||
|
|
||||||
|
# Pick sender (first mix node) and send ping through the mix network
|
||||||
|
let senderIndex = 0
|
||||||
|
|
||||||
|
info "Sending ping through mix network",
|
||||||
|
sender = switches[senderIndex].peerInfo.peerId,
|
||||||
|
destination = destNode.peerInfo.peerId
|
||||||
|
|
||||||
|
# Create a connection through the mix network
|
||||||
|
let conn = mixProtos[senderIndex]
|
||||||
|
.toConnection(
|
||||||
|
MixDestination.init(destNode.peerInfo.peerId, destNode.peerInfo.addrs[0]),
|
||||||
|
PingCodec,
|
||||||
|
MixParameters(expectReply: Opt.some(true), numSurbs: Opt.some(byte(1))),
|
||||||
|
)
|
||||||
|
.expect("could not build connection")
|
||||||
|
|
||||||
|
# Send ping and wait for response through the mix network
|
||||||
|
let response = await pingProto.ping(conn)
|
||||||
|
await conn.close()
|
||||||
|
|
||||||
|
info "Ping response received through mix network", rtt = response
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
waitFor(mixPingSimulation())
|
||||||
Loading…
x
Reference in New Issue
Block a user