mirror of
https://github.com/vacp2p/nim-libp2p.git
synced 2025-03-01 16:40:32 +00:00
[skip ci] Debug new discovery tuto
This commit is contained in:
parent
8d1c81776e
commit
429dc8e71b
@ -6,8 +6,8 @@
|
|||||||
## we'll try to discover a specific peer to ping on the network.
|
## we'll try to discover a specific peer to ping on the network.
|
||||||
##
|
##
|
||||||
## First, as usual, we import the dependencies:
|
## First, as usual, we import the dependencies:
|
||||||
import sequtils
|
|
||||||
import chronos
|
import chronos
|
||||||
|
import stew/byteutils
|
||||||
|
|
||||||
import libp2p
|
import libp2p
|
||||||
import libp2p/protocols/rendezvous
|
import libp2p/protocols/rendezvous
|
||||||
@ -30,63 +30,138 @@ proc createSwitch(rdv: RendezVous = RendezVous.new()): Switch =
|
|||||||
.withRendezVous(rdv)
|
.withRendezVous(rdv)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
const DumbCodec = "/dumb/proto/1.0.0"
|
||||||
|
type DumbProto = ref object of LPProtocol
|
||||||
|
proc new(T: typedesc[DumbProto], nodeNumber: int): T =
|
||||||
|
proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
|
||||||
|
echo "Node", nodeNumber, " received: ", string.fromBytes(await conn.readLp(1024))
|
||||||
|
await conn.close()
|
||||||
|
|
||||||
|
return T(codecs: @[DumbCodec], handler: handle)
|
||||||
|
|
||||||
## We can create our main procedure:
|
## We can create our main procedure:
|
||||||
proc main() {.async, gcsafe.} =
|
proc main() {.async, gcsafe.} =
|
||||||
# Create a "network" of six nodes looking like that:
|
# First of all, we'll create and start a boot node that'll be
|
||||||
# node0 <-> node1 <-> node2 <-> node3 <-> node4 <-> node5
|
# used as an information hub on the network
|
||||||
|
let bootNode = createSwitch()
|
||||||
|
await bootNode.start()
|
||||||
|
|
||||||
var
|
var
|
||||||
switches: seq[Switch] = @[]
|
switches: seq[Switch] = @[]
|
||||||
discManagers: seq[DiscoveryManager] = @[]
|
discManagers: seq[DiscoveryManager] = @[]
|
||||||
for _ in 0..5:
|
|
||||||
|
for i in 0..5:
|
||||||
# Create a RendezVous Protocol
|
# Create a RendezVous Protocol
|
||||||
let rdv = RendezVous.new()
|
let rdv = RendezVous.new()
|
||||||
# Create a switch, mount the RendezVous protocol to it, start it and
|
# Create a switch, mount the RendezVous protocol to it, start it and
|
||||||
# enventually connect it to the previous node in the sequence
|
# eventually connect it to the bootNode
|
||||||
let switch = createSwitch(rdv)
|
let switch = createSwitch(rdv)
|
||||||
|
switch.mount(DumbProto.new(i))
|
||||||
await switch.start()
|
await switch.start()
|
||||||
if switches.len > 0:
|
await switch.connect(bootNode.peerInfo.peerId, bootNode.peerInfo.addrs)
|
||||||
await switches[^1].connect(switch.peerInfo.peerId, switch.peerInfo.addrs)
|
|
||||||
switches.add(switch)
|
switches.add(switch)
|
||||||
|
|
||||||
# A discovery manager is a simple tool, you setup it by adding discovery
|
# A discovery manager is a simple tool, you set it up by adding discovery
|
||||||
# interfaces (such as RendezVousInterface) then you can use it to advertise
|
# interfaces (such as RendezVousInterface) then you can use it to advertise
|
||||||
# something on the network or to request something from it.
|
# something on the network or to request something from it.
|
||||||
let dm = DiscoveryManager()
|
let dm = DiscoveryManager()
|
||||||
# A RendezVousInterface is a RendezVous protocol wrapped to be usable by the
|
# A RendezVousInterface is a RendezVous protocol wrapped to be usable by the
|
||||||
# DiscoveryManager. You can initialize a time to advertise/request (tta/ttr)
|
# DiscoveryManager. You can initialize a time to advertise/request (tta/ttr)
|
||||||
# for advertise/request every x seconds.
|
# for advertise/request every x seconds.
|
||||||
dm.add(RendezVousInterface.new(rdv, ttr = 250.milliseconds))
|
dm.add(RendezVousInterface.new(rdv))
|
||||||
|
# Each nodes of the network'll advertise on some topics (even gang or odd club)
|
||||||
|
if i mod 2 == 0:
|
||||||
|
dm.advertise(RdvNamespace("Even Gang"))
|
||||||
|
else:
|
||||||
|
dm.advertise(RdvNamespace("Odd Club"))
|
||||||
discManagers.add(dm)
|
discManagers.add(dm)
|
||||||
|
|
||||||
# The first node of the network advertise on someTopic
|
|
||||||
discManagers[0].advertise(RdvNamespace("someTopic"))
|
|
||||||
for i in 1..4:
|
|
||||||
# All the four "middle" nodes request informations on someTopic
|
|
||||||
# to make the message spread. With a time to request of 250ms, it should
|
|
||||||
# spread on the four nodes in a little over 1 second.
|
|
||||||
discard discManagers[i].request(RdvNamespace("someTopic"))
|
|
||||||
let
|
let
|
||||||
# The ending node request on someTopic aswell and await for information.
|
rdv = RendezVous.new()
|
||||||
query = discManagers[5].request(RdvNamespace("someTopic"))
|
newcomer = createSwitch(rdv)
|
||||||
# getPeer give you a PeerAttribute containing informations about the peer.
|
dm = DiscoveryManager()
|
||||||
# The most useful are the PeerId and the MultiAddresses
|
await newcomer.start()
|
||||||
res = await query.getPeer()
|
await newcomer.connect(bootNode.peerInfo.peerId, bootNode.peerInfo.addrs)
|
||||||
|
dm.add(RendezVousInterface.new(rdv, ttr = 250.milliseconds))
|
||||||
|
|
||||||
doAssert(res[PeerId] == switches[0].peerInfo.peerId)
|
let query = dm.request(RdvNamespace("Odd Club"))
|
||||||
let resMa = res.getAll(MultiAddress)
|
for _ in 0..2:
|
||||||
for ma in resMa:
|
echo "start"
|
||||||
doAssert(ma in switches[0].peerInfo.addrs)
|
let
|
||||||
echo "Peer Found: ", res[PeerId], " ", resMa
|
res = await query.getPeer()
|
||||||
# The peer Id and the address of the node0 is discovered by the node5 after
|
echo "0 ", res[PeerId], " ", res.getAll(MultiAddress)
|
||||||
# being pass by all the intermediate node.
|
let
|
||||||
|
conn = await newcomer.dial(res[PeerId], res.getAll(MultiAddress), DumbCodec)
|
||||||
|
echo "1"
|
||||||
|
await conn.writeLp("Odd Club suuuucks! Even Gang is better!")
|
||||||
|
echo "2"
|
||||||
|
await sleepAsync(300.milliseconds)
|
||||||
|
await conn.close()
|
||||||
|
echo "stop"
|
||||||
|
query.stop()
|
||||||
|
|
||||||
# The node5 can connect the node0 to talk about someTopic directly.
|
|
||||||
|
|
||||||
# Stop all the DiscoveryManagers
|
|
||||||
for dm in discManagers: dm.stop()
|
|
||||||
|
|
||||||
# Stop all the switches
|
# # Create a "network" of six nodes looking like that:
|
||||||
let futStop = switches.mapIt(it.stop())
|
# # node0 <-> node1 <-> node2 <-> node3 <-> node4 <-> node5
|
||||||
await allFutures(futStop)
|
# var
|
||||||
|
# switches: seq[Switch] = @[]
|
||||||
|
# discManagers: seq[DiscoveryManager] = @[]
|
||||||
|
# for _ in 0..5:
|
||||||
|
# # Create a RendezVous Protocol
|
||||||
|
# let rdv = RendezVous.new()
|
||||||
|
# # Create a switch, mount the RendezVous protocol to it, start it and
|
||||||
|
# # enventually connect it to the previous node in the sequence
|
||||||
|
# let switch = createSwitch(rdv)
|
||||||
|
# if switches.len == 0:
|
||||||
|
#
|
||||||
|
# await switch.start()
|
||||||
|
# if switches.len > 0:
|
||||||
|
# await switches[^1].connect(switch.peerInfo.peerId, switch.peerInfo.addrs)
|
||||||
|
# switches.add(switch)
|
||||||
|
#
|
||||||
|
# # A discovery manager is a simple tool, you setup it by adding discovery
|
||||||
|
# # interfaces (such as RendezVousInterface) then you can use it to advertise
|
||||||
|
# # something on the network or to request something from it.
|
||||||
|
# let dm = DiscoveryManager()
|
||||||
|
# # A RendezVousInterface is a RendezVous protocol wrapped to be usable by the
|
||||||
|
# # DiscoveryManager. You can initialize a time to advertise/request (tta/ttr)
|
||||||
|
# # for advertise/request every x seconds.
|
||||||
|
# dm.add(RendezVousInterface.new(rdv, ttr = 250.milliseconds))
|
||||||
|
# discManagers.add(dm)
|
||||||
|
#
|
||||||
|
# # The first node of the network advertise on someTopic
|
||||||
|
# discManagers[0].advertise(RdvNamespace("someTopic"))
|
||||||
|
# for i in 1..4:
|
||||||
|
# # All the four "middle" nodes request informations on someTopic
|
||||||
|
# # to make the message spread. With a time to request of 250ms, it should
|
||||||
|
# # spread on the four nodes in a little over 1 second.
|
||||||
|
# discard discManagers[i].request(RdvNamespace("someTopic"))
|
||||||
|
# let
|
||||||
|
# # The ending node request on someTopic aswell and await for information.
|
||||||
|
# query = discManagers[5].request(RdvNamespace("someTopic"))
|
||||||
|
# # getPeer give you a PeerAttribute containing informations about the peer.
|
||||||
|
# # The most useful are the PeerId and the MultiAddresses
|
||||||
|
# res = await query.getPeer()
|
||||||
|
#
|
||||||
|
# # Now that a peer have been found, we can stop the query
|
||||||
|
# query.stop()
|
||||||
|
#
|
||||||
|
# doAssert(res[PeerId] == switches[0].peerInfo.peerId)
|
||||||
|
# let resMa = res.getAll(MultiAddress)
|
||||||
|
# for ma in resMa:
|
||||||
|
# doAssert(ma in switches[0].peerInfo.addrs)
|
||||||
|
# echo "Peer Found: ", res[PeerId], " ", resMa
|
||||||
|
# # The peer Id and the address of the node0 is discovered by the node5 after
|
||||||
|
# # being pass by all the intermediate node.
|
||||||
|
#
|
||||||
|
# # The node5 can connect the node0 to talk about someTopic directly.
|
||||||
|
#
|
||||||
|
# # Stop all the DiscoveryManagers
|
||||||
|
# for dm in discManagers: dm.stop()
|
||||||
|
#
|
||||||
|
# # Stop all the switches
|
||||||
|
# let futStop = switches.mapIt(it.stop())
|
||||||
|
# await allFutures(futStop)
|
||||||
|
|
||||||
waitFor(main())
|
waitFor(main())
|
||||||
|
@ -90,6 +90,7 @@ task website, "Build the website":
|
|||||||
tutorialToMd("examples/tutorial_1_connect.nim")
|
tutorialToMd("examples/tutorial_1_connect.nim")
|
||||||
tutorialToMd("examples/tutorial_2_customproto.nim")
|
tutorialToMd("examples/tutorial_2_customproto.nim")
|
||||||
tutorialToMd("examples/tutorial_3_protobuf.nim")
|
tutorialToMd("examples/tutorial_3_protobuf.nim")
|
||||||
|
tutorialToMd("examples/tutorial_5_discovery.nim")
|
||||||
tutorialToMd("examples/circuitrelay.nim")
|
tutorialToMd("examples/circuitrelay.nim")
|
||||||
exec "mkdocs build"
|
exec "mkdocs build"
|
||||||
|
|
||||||
|
@ -71,25 +71,36 @@ proc select*(m: MultistreamSelect,
|
|||||||
else:
|
else:
|
||||||
trace "multistream handshake success", conn
|
trace "multistream handshake success", conn
|
||||||
|
|
||||||
|
echo " 0 ", proto
|
||||||
if proto.len() == 0: # no protocols, must be a handshake call
|
if proto.len() == 0: # no protocols, must be a handshake call
|
||||||
return Codec
|
return Codec
|
||||||
else:
|
else:
|
||||||
|
echo " 1"
|
||||||
s = string.fromBytes(await conn.readLp(MsgSize)) # read the first proto
|
s = string.fromBytes(await conn.readLp(MsgSize)) # read the first proto
|
||||||
|
echo " 2"
|
||||||
validateSuffix(s)
|
validateSuffix(s)
|
||||||
|
echo " 3"
|
||||||
trace "reading first requested proto", conn
|
trace "reading first requested proto", conn
|
||||||
if s == proto[0]:
|
if s == proto[0]:
|
||||||
|
echo " 4.1"
|
||||||
trace "successfully selected ", conn, proto = proto[0]
|
trace "successfully selected ", conn, proto = proto[0]
|
||||||
conn.protocol = proto[0]
|
conn.protocol = proto[0]
|
||||||
|
echo " 4.2 ", proto[0]
|
||||||
return proto[0]
|
return proto[0]
|
||||||
elif proto.len > 1:
|
elif proto.len > 1:
|
||||||
|
echo " 5.1"
|
||||||
# Try to negotiate alternatives
|
# Try to negotiate alternatives
|
||||||
let protos = proto[1..<proto.len()]
|
let protos = proto[1..<proto.len()]
|
||||||
trace "selecting one of several protos", conn, protos = protos
|
trace "selecting one of several protos", conn, protos = protos
|
||||||
|
echo " 5.2"
|
||||||
for p in protos:
|
for p in protos:
|
||||||
|
echo " 5.2.1"
|
||||||
trace "selecting proto", conn, proto = p
|
trace "selecting proto", conn, proto = p
|
||||||
await conn.writeLp((p & "\n")) # select proto
|
await conn.writeLp((p & "\n")) # select proto
|
||||||
|
echo " 5.2.2"
|
||||||
s = string.fromBytes(await conn.readLp(MsgSize)) # read the first proto
|
s = string.fromBytes(await conn.readLp(MsgSize)) # read the first proto
|
||||||
validateSuffix(s)
|
validateSuffix(s)
|
||||||
|
echo " 5.2.3"
|
||||||
if s == p:
|
if s == p:
|
||||||
trace "selected protocol", conn, protocol = s
|
trace "selected protocol", conn, protocol = s
|
||||||
conn.protocol = s
|
conn.protocol = s
|
||||||
@ -102,6 +113,7 @@ proc select*(m: MultistreamSelect,
|
|||||||
proc select*(m: MultistreamSelect,
|
proc select*(m: MultistreamSelect,
|
||||||
conn: Connection,
|
conn: Connection,
|
||||||
proto: string): Future[bool] {.async.} =
|
proto: string): Future[bool] {.async.} =
|
||||||
|
echo proto
|
||||||
if proto.len > 0:
|
if proto.len > 0:
|
||||||
return (await m.select(conn, @[proto])) == proto
|
return (await m.select(conn, @[proto])) == proto
|
||||||
else:
|
else:
|
||||||
|
@ -76,7 +76,9 @@ proc identify*(
|
|||||||
conn: Connection) {.async, gcsafe.} =
|
conn: Connection) {.async, gcsafe.} =
|
||||||
## identify the connection
|
## identify the connection
|
||||||
|
|
||||||
|
echo "==>0", self.identity.codec
|
||||||
if (await self.ms.select(conn, self.identity.codec)):
|
if (await self.ms.select(conn, self.identity.codec)):
|
||||||
|
echo "==>1"
|
||||||
let
|
let
|
||||||
info = await self.identity.identify(conn, conn.peerId)
|
info = await self.identity.identify(conn, conn.peerId)
|
||||||
peerStore = self.connManager.peerStore
|
peerStore = self.connManager.peerStore
|
||||||
|
Loading…
x
Reference in New Issue
Block a user