mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-09 02:35:08 +00:00
Improve the populating of the routing table (#886)
- Search for the node on an incoming portal message and try to add it to the routing table - Don't rely on discv5 nodes for bootstrapping portal networks for now. - Attempt to repopulate the routing table when it is at 0 or drops to 0.
This commit is contained in:
parent
7066b48303
commit
414fdafab9
@ -93,11 +93,6 @@ func localNode*(p: PortalProtocol): Node = p.baseProtocol.localNode
|
|||||||
proc neighbours*(p: PortalProtocol, id: NodeId, seenOnly = false): seq[Node] =
|
proc neighbours*(p: PortalProtocol, id: NodeId, seenOnly = false): seq[Node] =
|
||||||
p.routingTable.neighbours(id = id, seenOnly = seenOnly)
|
p.routingTable.neighbours(id = id, seenOnly = seenOnly)
|
||||||
|
|
||||||
# TODO:
|
|
||||||
# - On incoming portal ping of unknown node: add node to routing table by
|
|
||||||
# grabbing ENR from discv5 routing table (might not have it)?
|
|
||||||
# - ENRs with portal protocol capabilities as field?
|
|
||||||
|
|
||||||
proc handlePing(p: PortalProtocol, ping: PingMessage):
|
proc handlePing(p: PortalProtocol, ping: PingMessage):
|
||||||
seq[byte] =
|
seq[byte] =
|
||||||
let customPayload = CustomPayload(dataRadius: p.dataRadius)
|
let customPayload = CustomPayload(dataRadius: p.dataRadius)
|
||||||
@ -189,6 +184,15 @@ proc messageHandler*(protocol: TalkProtocol, request: seq[byte],
|
|||||||
if decoded.isOk():
|
if decoded.isOk():
|
||||||
let message = decoded.get()
|
let message = decoded.get()
|
||||||
trace "Received message request", srcId, srcUdpAddress, kind = message.kind
|
trace "Received message request", srcId, srcUdpAddress, kind = message.kind
|
||||||
|
# Received a proper Portal message, check if this node exists in the base
|
||||||
|
# routing table and add if so.
|
||||||
|
# TODO: Could add a findNodes with distance 0 call when not, and perhaps,
|
||||||
|
# optionally pass ENRs if the message was a discv5 handshake containing the
|
||||||
|
# ENR.
|
||||||
|
let node = p.baseProtocol.getNode(srcId)
|
||||||
|
if node.isSome():
|
||||||
|
discard p.routingTable.addNode(node.get())
|
||||||
|
|
||||||
case message.kind
|
case message.kind
|
||||||
of MessageKind.ping:
|
of MessageKind.ping:
|
||||||
p.handlePing(message.ping)
|
p.handlePing(message.ping)
|
||||||
@ -540,25 +544,15 @@ proc queryRandom*(p: PortalProtocol): Future[seq[Node]] =
|
|||||||
p.query(NodeId.random(p.baseProtocol.rng[]))
|
p.query(NodeId.random(p.baseProtocol.rng[]))
|
||||||
|
|
||||||
proc seedTable*(p: PortalProtocol) =
|
proc seedTable*(p: PortalProtocol) =
|
||||||
## Seed the table with nodes from the discv5 table and with specifically
|
## Seed the table with specifically provided Portal bootstrap nodes. These are
|
||||||
## provided bootstrap nodes. The latter are then supposed to be nodes
|
## nodes that must support the wire protocol for the specific content network.
|
||||||
## supporting the wire protocol for the specific content network.
|
|
||||||
# Note: We allow replacing the bootstrap nodes in the routing table as it is
|
# Note: We allow replacing the bootstrap nodes in the routing table as it is
|
||||||
# possible that some of these are not supporting the specific portal network.
|
# possible that some of these are not supporting the specific portal network.
|
||||||
|
# Other note: One could also pick nodes from the discv5 routing table to
|
||||||
|
# bootstrap the portal networks, however it would require a flag in the ENR to
|
||||||
|
# be added and there might be none in the routing table due to low amount of
|
||||||
|
# Portal nodes versus other nodes.
|
||||||
|
|
||||||
# TODO: Picking some nodes from discv5 routing table now. Should definitely
|
|
||||||
# add supported Portal network info in a k:v pair in the ENRs and filter on
|
|
||||||
# that.
|
|
||||||
let closestNodes = p.baseProtocol.neighbours(
|
|
||||||
NodeId.random(p.baseProtocol.rng[]), seenOnly = true)
|
|
||||||
|
|
||||||
for node in closestNodes:
|
|
||||||
if p.routingTable.addNode(node) == Added:
|
|
||||||
debug "Added node from discv5 routing table", uri = toURI(node.record)
|
|
||||||
else:
|
|
||||||
debug "Node from discv5 routing table could not be added", uri = toURI(node.record)
|
|
||||||
|
|
||||||
# Seed the table with bootstrap nodes.
|
|
||||||
for record in p.bootstrapRecords:
|
for record in p.bootstrapRecords:
|
||||||
if p.addNode(record):
|
if p.addNode(record):
|
||||||
debug "Added bootstrap node", uri = toURI(record),
|
debug "Added bootstrap node", uri = toURI(record),
|
||||||
@ -612,9 +606,14 @@ proc refreshLoop(p: PortalProtocol) {.async.} =
|
|||||||
## no queries were done since `refreshInterval` or more.
|
## no queries were done since `refreshInterval` or more.
|
||||||
## It also refreshes the majority address voted for via pong responses.
|
## It also refreshes the majority address voted for via pong responses.
|
||||||
try:
|
try:
|
||||||
await p.populateTable()
|
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
|
# TODO: It would be nicer and more secure if this was event based and/or
|
||||||
|
# steered from the routing table.
|
||||||
|
while p.routingTable.len() == 0:
|
||||||
|
p.seedTable()
|
||||||
|
await p.populateTable()
|
||||||
|
await sleepAsync(5.seconds)
|
||||||
|
|
||||||
let currentTime = now(chronos.Moment)
|
let currentTime = now(chronos.Moment)
|
||||||
if currentTime > (p.lastLookup + RefreshInterval):
|
if currentTime > (p.lastLookup + RefreshInterval):
|
||||||
let randomQuery = await p.queryRandom()
|
let randomQuery = await p.queryRandom()
|
||||||
@ -626,8 +625,6 @@ proc refreshLoop(p: PortalProtocol) {.async.} =
|
|||||||
trace "refreshLoop canceled"
|
trace "refreshLoop canceled"
|
||||||
|
|
||||||
proc start*(p: PortalProtocol) =
|
proc start*(p: PortalProtocol) =
|
||||||
p.seedTable()
|
|
||||||
|
|
||||||
p.refreshLoop = refreshLoop(p)
|
p.refreshLoop = refreshLoop(p)
|
||||||
p.revalidateLoop = revalidateLoop(p)
|
p.revalidateLoop = revalidateLoop(p)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user