Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/interop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,28 @@ jobs:
go run testautonatv2.go &
cd ../nim-peer
nim r src/nim_peer.nim $(cat ../go-peer/peer.id)

run-kad-interop:
name: Run Kademlia DHT interoperability tests
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable

- name: Set up Nim
uses: jiro4989/setup-nim-action@v1
with:
nim-version: "stable"

- name: Run Nim and Rust together
run: |
nimble install
cd interop/kad/rust-peer
cargo run &

cd ../nim-peer
nim r src/nim_peer.nim $(cat ../rust-peer/peer.id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why $(cat ../rust-peer/peer.id) ?

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ examples/*.md
nimble.develop
nimble.paths
go-libp2p-daemon/
*.id
*.key
interop/kad/rust-peer/target/*
interop/kad/nim-peer/src/nim_peer
Comment on lines +22 to +23
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider having .gitignore file in interop/kad dir or,
.gitignore in interop/kad/nim-peer and other in interop/kad/rust-peer - every dir can git ignore individually.


# Ignore all test build files in tests folder (auto generated when running tests).
# First rule (`tests/**/test*[^.]*`) will ignore all binaries: has prefix test + does not have dot in name.
Expand Down
4 changes: 4 additions & 0 deletions interop/kad/nim-peer/config.nims
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# begin Nimble config (version 2)
when withDir(thisDir(), system.fileExists("nimble.paths")):
include "nimble.paths"
# end Nimble config
10 changes: 10 additions & 0 deletions interop/kad/nim-peer/nim_peer.nimble
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version = "0.1.0"
author = "Status Research & Development Gmb"
description = "AutoNATv2 peer for interop testing"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

description ?

license = "MIT"
srcDir = "src"
bin = @["nim_peer"]

# Dependencies

requires "nim >= 2.3.1", "libp2p"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does requires "libp2p" pulls from master (or uses the release version) or uses source from current branch?

73 changes: 73 additions & 0 deletions interop/kad/nim-peer/src/nim_peer.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Nim-LibP2P
# Copyright (c) 2023-2025 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 net, chronos, libp2p, sequtils
import libp2p/protocols/kademlia

proc waitForService(
host: string, port: Port, retries: int = 20, delay: Duration = 500.milliseconds
): Future[bool] {.async.} =
for i in 0 ..< retries:
try:
var s = newSocket()
s.connect(host, port)
s.close()
return true
except OSError:
discard
await sleepAsync(delay)
return false
Comment on lines +13 to +25
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code keeps repeating. please have it as shared utility.


proc main() {.async.} =
var switch = SwitchBuilder
.new()
.withRng(newRng())
.withAddresses(@[MultiAddress.init("/ip4/127.0.0.1/tcp/3131").tryGet()])
.withTcpTransport()
.withYamux()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if rust has mplex can we use that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should try to reduce yamux usage in codebase becasue #1635 might be around the corner

.withNoise()
.build()

let
peerId = PeerId.init(readFile("../rust-peer/peer.id")).get()
peerMa = MultiAddress.init("/ip4/127.0.0.1/tcp/4141").get()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems bit mixed decisions... peer id is not hardcoded but address is. why not have both in file? or hardcode both?

kad = KadDHT.new(
switch,
bootstrapNodes = @[(peerId, @[peerMa])],
config = KadDHTConfig.new(quorum = 1),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quorum = 1 does quorum counts self or just other nodes?

)

switch.mount(kad)
await sleepAsync(5.seconds)

await switch.start()
defer:
await switch.stop()

let key: Key = "key".mapIt(byte(it))

let value = @[1.byte, 2, 3, 4, 5]
Comment on lines +53 to +55
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let key: Key = "key".mapIt(byte(it))
let value = @[1.byte, 2, 3, 4, 5]
let key: Key = "key".mapIt(byte(it))
let value = @[1.byte, 2, 3, 4, 5]


let res = await kad.putValue(key, value)
if res.isErr():
echo "putValue failed: ", res.error
quit(1)

await sleepAsync(2.seconds)

# try to get the inserted value from peer
if (await kad.getValue(key)).get().value != value:
echo "Get value did not return correct value"
quit(1)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we get value that this node does not have but rust node does have?

when isMainModule:
if waitFor(waitForService("127.0.0.1", Port(4141))):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"127.0.0.1", Port(4141)) value should come from same constant as value on line 39:
peerMa = MultiAddress.init("/ip4/127.0.0.1/tcp/4141").get()

waitFor(main())
else:
quit("timeout waiting for service", 1)
Loading
Loading