Use chronicles in discovery
This commit is contained in:
parent
66ff278f33
commit
b4d343805a
|
@ -15,6 +15,7 @@ requires "nim > 0.18.0",
|
||||||
"ranges",
|
"ranges",
|
||||||
"stint",
|
"stint",
|
||||||
"byteutils",
|
"byteutils",
|
||||||
|
"chronicles",
|
||||||
"https://github.com/status-im/nim-asyncdispatch2"
|
"https://github.com/status-im/nim-asyncdispatch2"
|
||||||
|
|
||||||
proc runTest(name: string, lang = "c") = exec "nim " & lang & " -r tests/" & name
|
proc runTest(name: string, lang = "c") = exec "nim " & lang & " -r tests/" & name
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from strutils import nil
|
from strutils import nil
|
||||||
import times, algorithm, logging
|
import times, algorithm, chronicles
|
||||||
import asyncdispatch2, eth_keys, ranges, stint, nimcrypto, rlp
|
import asyncdispatch2, eth_keys, ranges, stint, nimcrypto, rlp
|
||||||
import kademlia, enode
|
import kademlia, enode
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ proc sendNeighbours*(d: DiscoveryProtocol, node: Node, neighbours: seq[Node]) =
|
||||||
block:
|
block:
|
||||||
let payload = rlp.encode((nodes, expiration()))
|
let payload = rlp.encode((nodes, expiration()))
|
||||||
let msg = pack(cmdNeighbours, payload, d.privkey)
|
let msg = pack(cmdNeighbours, payload, d.privkey)
|
||||||
debug ">>> neighbours to ", node, ": ", nodes
|
debug ">>> neighbours", to = node, neightbours = nodes
|
||||||
d.send(node, msg)
|
d.send(node, msg)
|
||||||
nodes.setLen(0)
|
nodes.setLen(0)
|
||||||
|
|
||||||
|
@ -231,11 +231,11 @@ proc receive(d: DiscoveryProtocol, a: Address, msg: Bytes) =
|
||||||
else:
|
else:
|
||||||
echo "Unknown command: ", cmdId
|
echo "Unknown command: ", cmdId
|
||||||
else:
|
else:
|
||||||
debug "Received msg ", cmdId, " from ", a, " already expired"
|
debug "Received msg is expired", cmdId, "from" = a
|
||||||
else:
|
else:
|
||||||
error "Wrong public key from ", a
|
error "Wrong public key ", "from" = a
|
||||||
else:
|
else:
|
||||||
error "Wrong msg mac from ", a
|
error "Wrong msg mac", "from" = a
|
||||||
|
|
||||||
proc processClient(transp: DatagramTransport,
|
proc processClient(transp: DatagramTransport,
|
||||||
raddr: TransportAddress): Future[void] {.async, gcsafe.} =
|
raddr: TransportAddress): Future[void] {.async, gcsafe.} =
|
||||||
|
@ -249,7 +249,7 @@ proc processClient(transp: DatagramTransport,
|
||||||
let a = Address(ip: raddr.address, udpPort: raddr.port, tcpPort: raddr.port)
|
let a = Address(ip: raddr.address, udpPort: raddr.port, tcpPort: raddr.port)
|
||||||
proto.receive(a, buf)
|
proto.receive(a, buf)
|
||||||
except:
|
except:
|
||||||
error "receive failed: ", getCurrentExceptionMsg()
|
error "receive failed: " & getCurrentExceptionMsg()
|
||||||
|
|
||||||
proc open*(d: DiscoveryProtocol) =
|
proc open*(d: DiscoveryProtocol) =
|
||||||
let ta = initTAddress(d.address.ip, d.address.udpPort)
|
let ta = initTAddress(d.address.ip, d.address.udpPort)
|
||||||
|
|
|
@ -8,12 +8,15 @@
|
||||||
# MIT license (LICENSE-MIT)
|
# MIT license (LICENSE-MIT)
|
||||||
#
|
#
|
||||||
|
|
||||||
import uri, logging, tables, hashes, times, algorithm, sets, sequtils, random
|
import uri, tables, hashes, times, algorithm, sets, sequtils, random
|
||||||
from strutils import parseInt
|
from strutils import parseInt
|
||||||
import asyncdispatch2, eth_keys, stint, nimcrypto, enode
|
import asyncdispatch2, eth_keys, stint, nimcrypto, chronicles, enode
|
||||||
|
|
||||||
export sets # TODO: This should not be needed, but compilation fails otherwise
|
export sets # TODO: This should not be needed, but compilation fails otherwise
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topic = "discovery"
|
||||||
|
|
||||||
type
|
type
|
||||||
KademliaProtocol* [Wire] = ref object
|
KademliaProtocol* [Wire] = ref object
|
||||||
wire: Wire
|
wire: Wire
|
||||||
|
@ -331,6 +334,7 @@ proc bond(k: KademliaProtocol, n: Node): Future[bool] {.async.} =
|
||||||
# the remote remembers us.
|
# the remote remembers us.
|
||||||
discard await k.waitPing(n)
|
discard await k.waitPing(n)
|
||||||
|
|
||||||
|
echo "bonding completed successfully with"
|
||||||
debug "bonding completed successfully with ", n
|
debug "bonding completed successfully with ", n
|
||||||
k.updateRoutingTable(n)
|
k.updateRoutingTable(n)
|
||||||
return true
|
return true
|
||||||
|
@ -352,7 +356,7 @@ proc lookup*(k: KademliaProtocol, nodeId: NodeId): Future[seq[Node]] {.async.} =
|
||||||
k.wire.sendFindNode(remote, nodeId)
|
k.wire.sendFindNode(remote, nodeId)
|
||||||
var candidates = await k.waitNeighbours(remote)
|
var candidates = await k.waitNeighbours(remote)
|
||||||
if candidates.len == 0:
|
if candidates.len == 0:
|
||||||
debug "got no candidates from ", remote, ", returning"
|
debug "got no candidates, returning ", "from" = remote
|
||||||
result = candidates
|
result = candidates
|
||||||
else:
|
else:
|
||||||
# The following line:
|
# The following line:
|
||||||
|
@ -361,12 +365,12 @@ proc lookup*(k: KademliaProtocol, nodeId: NodeId): Future[seq[Node]] {.async.} =
|
||||||
# 2. Removes all previously seen nodes from candidates
|
# 2. Removes all previously seen nodes from candidates
|
||||||
# 3. Deduplicates candidates
|
# 3. Deduplicates candidates
|
||||||
candidates.keepItIf(not nodesSeen.containsOrIncl(it))
|
candidates.keepItIf(not nodesSeen.containsOrIncl(it))
|
||||||
debug "got ", candidates.len, " new candidates"
|
debug "got new candidates", count = candidates.len
|
||||||
let bonded = await all(candidates.mapIt(k.bond(it)))
|
let bonded = await all(candidates.mapIt(k.bond(it)))
|
||||||
for i in 0 ..< bonded.len:
|
for i in 0 ..< bonded.len:
|
||||||
if not bonded[i]: candidates[i] = nil
|
if not bonded[i]: candidates[i] = nil
|
||||||
candidates.keepItIf(not it.isNil)
|
candidates.keepItIf(not it.isNil)
|
||||||
debug "bonded with ", candidates.len, " candidates"
|
debug "bonded with candidates", count = candidates.len
|
||||||
result = candidates
|
result = candidates
|
||||||
|
|
||||||
proc excludeIfAsked(nodes: seq[Node]): seq[Node] =
|
proc excludeIfAsked(nodes: seq[Node]): seq[Node] =
|
||||||
|
@ -385,7 +389,7 @@ proc lookup*(k: KademliaProtocol, nodeId: NodeId): Future[seq[Node]] {.async.} =
|
||||||
sortByDistance(closest, nodeId, BUCKET_SIZE)
|
sortByDistance(closest, nodeId, BUCKET_SIZE)
|
||||||
nodesToAsk = excludeIfAsked(closest)
|
nodesToAsk = excludeIfAsked(closest)
|
||||||
|
|
||||||
info "lookup finished for ", nodeId.toHex, ": ", closest
|
info "lookup finished", forNode = nodeId.toHex, closest
|
||||||
result = closest
|
result = closest
|
||||||
|
|
||||||
proc lookupRandom*(k: KademliaProtocol): Future[seq[Node]] =
|
proc lookupRandom*(k: KademliaProtocol): Future[seq[Node]] =
|
||||||
|
@ -401,19 +405,19 @@ proc resolve*(k: KademliaProtocol, id: NodeId): Future[Node] {.async.} =
|
||||||
proc bootstrap*(k: KademliaProtocol, bootstrapNodes: seq[Node]) {.async.} =
|
proc bootstrap*(k: KademliaProtocol, bootstrapNodes: seq[Node]) {.async.} =
|
||||||
let bonded = await all(bootstrapNodes.mapIt(k.bond(it)))
|
let bonded = await all(bootstrapNodes.mapIt(k.bond(it)))
|
||||||
if true notin bonded:
|
if true notin bonded:
|
||||||
info "Failed to bond with bootstrap nodes "
|
info "Failed to bond with bootstrap nodes"
|
||||||
return
|
return
|
||||||
discard await k.lookupRandom()
|
discard await k.lookupRandom()
|
||||||
|
|
||||||
proc recvPong*(k: KademliaProtocol, n: Node, token: seq[byte]) =
|
proc recvPong*(k: KademliaProtocol, n: Node, token: seq[byte]) =
|
||||||
debug "<<< pong from ", n
|
debug "<<< pong", "from" = n
|
||||||
let pingid = token & @(n.node.pubkey.data)
|
let pingid = token & @(n.node.pubkey.data)
|
||||||
var future: Future[bool]
|
var future: Future[bool]
|
||||||
if k.pongFutures.take(pingid, future):
|
if k.pongFutures.take(pingid, future):
|
||||||
future.complete(true)
|
future.complete(true)
|
||||||
|
|
||||||
proc recvPing*(k: KademliaProtocol, n: Node, msgHash: any) =
|
proc recvPing*(k: KademliaProtocol, n: Node, msgHash: any) =
|
||||||
debug "<<< ping from ", n
|
debug "<<< ping", "from" = n
|
||||||
k.updateRoutingTable(n)
|
k.updateRoutingTable(n)
|
||||||
k.wire.sendPong(n, msgHash)
|
k.wire.sendPong(n, msgHash)
|
||||||
|
|
||||||
|
@ -428,12 +432,12 @@ proc recvNeighbours*(k: KademliaProtocol, remote: Node, neighbours: seq[Node]) =
|
||||||
## done as part of node lookup, so the actual processing is left to the callback from
|
## done as part of node lookup, so the actual processing is left to the callback from
|
||||||
## neighbours_callbacks, which is added (and removed after it's done or timed out) in
|
## neighbours_callbacks, which is added (and removed after it's done or timed out) in
|
||||||
## wait_neighbours().
|
## wait_neighbours().
|
||||||
debug "<<< neighbours from ", remote, ": ", neighbours
|
debug "<<< neighbours", "from" = remote, neighbours
|
||||||
let cb = k.neighboursCallbacks.getOrDefault(remote)
|
let cb = k.neighboursCallbacks.getOrDefault(remote)
|
||||||
if not cb.isNil:
|
if not cb.isNil:
|
||||||
cb(neighbours)
|
cb(neighbours)
|
||||||
else:
|
else:
|
||||||
debug "unexpected neighbours from ", remote, ", probably came too late"
|
debug "unexpected neighbours, probably came too late", "from" = remote
|
||||||
|
|
||||||
proc recvFindNode*(k: KademliaProtocol, remote: Node, nodeId: NodeId) =
|
proc recvFindNode*(k: KademliaProtocol, remote: Node, nodeId: NodeId) =
|
||||||
if remote notin k.routing:
|
if remote notin k.routing:
|
||||||
|
@ -449,10 +453,10 @@ proc recvFindNode*(k: KademliaProtocol, remote: Node, nodeId: NodeId) =
|
||||||
|
|
||||||
proc randomNodes*(k: KademliaProtocol, count: int): seq[Node] =
|
proc randomNodes*(k: KademliaProtocol, count: int): seq[Node] =
|
||||||
var count = count
|
var count = count
|
||||||
let sz = k.routing.len
|
let availableNodes = k.routing.len
|
||||||
if count > sz:
|
if count > availableNodes:
|
||||||
warn "Cannot get ", count, " nodes as RoutingTable contains only ", sz, " nodes"
|
warn "Cannot get enough nodes", requestedNodes = count, availableNodes
|
||||||
count = sz
|
count = availableNodes
|
||||||
|
|
||||||
result = newSeqOfCap[Node](count)
|
result = newSeqOfCap[Node](count)
|
||||||
var seen = initSet[Node]()
|
var seen = initSet[Node]()
|
||||||
|
|
Loading…
Reference in New Issue