Skip to content

Commit f7b1b63

Browse files
authored
feat(kad): client mode (#1908)
1 parent 7d59b2b commit f7b1b63

File tree

2 files changed

+67
-32
lines changed

2 files changed

+67
-32
lines changed

libp2p/protocols/kademlia.nim

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ proc new*(
7878
bootstrapNodes: seq[(PeerId, seq[MultiAddress])] = @[],
7979
config: KadDHTConfig = KadDHTConfig.new(),
8080
rng: ref HmacDrbgContext = newRng(),
81+
client: bool = false,
8182
): T {.raises: [].} =
8283
var rtable = RoutingTable.new(
8384
switch.peerInfo.peerId.toKey(),
@@ -94,40 +95,41 @@ proc new*(
9495
)
9596

9697
kad.codec = KadCodec
97-
kad.handler = proc(
98-
conn: Connection, proto: string
99-
) {.async: (raises: [CancelledError]).} =
100-
defer:
101-
await conn.close()
102-
while not conn.atEof:
103-
let buf =
104-
try:
105-
await conn.readLp(MaxMsgSize)
106-
except LPStreamEOFError:
98+
if not client:
99+
kad.handler = proc(
100+
conn: Connection, proto: string
101+
) {.async: (raises: [CancelledError]).} =
102+
defer:
103+
await conn.close()
104+
while not conn.atEof:
105+
let buf =
106+
try:
107+
await conn.readLp(MaxMsgSize)
108+
except LPStreamEOFError:
109+
return
110+
except LPStreamError as exc:
111+
debug "Read error when handling kademlia RPC", conn = conn, err = exc.msg
112+
return
113+
let msg = Message.decode(buf).valueOr:
114+
debug "Failed to decode message", err = error
107115
return
108-
except LPStreamError as exc:
109-
debug "Read error when handling kademlia RPC", conn = conn, err = exc.msg
116+
117+
case msg.msgType
118+
of MessageType.findNode:
119+
await kad.handleFindNode(conn, msg)
120+
of MessageType.putValue:
121+
await kad.handlePutValue(conn, msg)
122+
of MessageType.getValue:
123+
await kad.handleGetValue(conn, msg)
124+
of MessageType.addProvider:
125+
await kad.handleAddProvider(conn, msg)
126+
of MessageType.getProviders:
127+
await kad.handleGetProviders(conn, msg)
128+
of MessageType.ping:
129+
await kad.handlePing(conn, msg)
130+
else:
131+
error "Unhandled kad-dht message type", msg = msg
110132
return
111-
let msg = Message.decode(buf).valueOr:
112-
debug "Failed to decode message", err = error
113-
return
114-
115-
case msg.msgType
116-
of MessageType.findNode:
117-
await kad.handleFindNode(conn, msg)
118-
of MessageType.putValue:
119-
await kad.handlePutValue(conn, msg)
120-
of MessageType.getValue:
121-
await kad.handleGetValue(conn, msg)
122-
of MessageType.addProvider:
123-
await kad.handleAddProvider(conn, msg)
124-
of MessageType.getProviders:
125-
await kad.handleGetProviders(conn, msg)
126-
of MessageType.ping:
127-
await kad.handlePing(conn, msg)
128-
else:
129-
error "Unhandled kad-dht message type", msg = msg
130-
return
131133
return kad
132134

133135
method start*(kad: KadDHT) {.async: (raises: [CancelledError]).} =

tests/kademlia/test_builder.nim

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import chronos
1313
import ../../libp2p/[switch, builders]
14+
import ../../libp2p/protocols/kademlia
1415
import ../tools/[unittest]
1516
import ./utils.nim
1617

@@ -46,3 +47,35 @@ suite "KadDHT - Builder":
4647
await allFutures(switch1.stop(), switch2.stop())
4748
check:
4849
switch1.ms.handlers[1].protos[0] == "/ipfs/kad/1.0.0"
50+
51+
asyncTest "Use Kad as a client only":
52+
var switch1 = SwitchBuilder
53+
.new()
54+
.withRng(newRng())
55+
.withAddresses(@[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()])
56+
.withTcpTransport()
57+
.withMplex()
58+
.withNoise()
59+
.withKademlia()
60+
.build()
61+
62+
var switch2 = SwitchBuilder
63+
.new()
64+
.withRng(newRng())
65+
.withAddresses(@[MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet()])
66+
.withTcpTransport()
67+
.withMplex()
68+
.withNoise()
69+
.build()
70+
71+
let kad2 = KadDHT.new(
72+
switch2,
73+
bootstrapNodes = @[(switch1.peerInfo.peerId, switch1.peerInfo.addrs)],
74+
client = true,
75+
)
76+
77+
await allFutures(switch1.start(), switch2.start())
78+
defer:
79+
await allFutures(switch1.stop(), switch2.stop())
80+
81+
check (await kad2.putValue(kad2.rtable.selfId, @[1.byte, 2, 3, 4, 5])).isOk()

0 commit comments

Comments
 (0)