Some bits required for PeerPool

This commit is contained in:
Yuriy Glukhov 2018-04-19 19:47:19 +03:00
parent 8050440614
commit 732b7941c4
2 changed files with 32 additions and 2 deletions

View File

@ -35,7 +35,7 @@ type
DiscoveryProtocol* = ref object DiscoveryProtocol* = ref object
privKey: PrivateKey privKey: PrivateKey
address: Address address: Address
bootstrapNodes: seq[Node] bootstrapNodes*: seq[Node]
thisNode: Node thisNode: Node
kademlia: KademliaProtocol[DiscoveryProtocol] kademlia: KademliaProtocol[DiscoveryProtocol]
socket: AsyncSocket socket: AsyncSocket
@ -266,6 +266,12 @@ proc bootstrap*(d: DiscoveryProtocol) {.async.} =
proc resolve*(d: DiscoveryProtocol, n: NodeId): Future[Node] = proc resolve*(d: DiscoveryProtocol, n: NodeId): Future[Node] =
d.kademlia.resolve(n) d.kademlia.resolve(n)
proc lookupRandom*(d: DiscoveryProtocol): Future[seq[Node]] {.inline.} =
d.kademlia.lookupRandom()
proc randomNodes*(d: DiscoveryProtocol, count: int): seq[Node] {.inline.} =
d.kademlia.randomNodes(count)
when isMainModule: when isMainModule:
import logging, byteutils import logging, byteutils

View File

@ -1,5 +1,5 @@
import asyncdispatch, net, uri, logging, tables, hashes, times, algorithm, sets, import asyncdispatch, net, uri, logging, tables, hashes, times, algorithm, sets,
sequtils sequtils, random
from strutils import parseInt from strutils import parseInt
export sets # TODO: This should not be needed, but compilation fails otherwise export sets # TODO: This should not be needed, but compilation fails otherwise
@ -214,6 +214,9 @@ proc neighbours(r: RoutingTable, id: NodeId, k: int = BUCKET_SIZE): seq[Node] =
if result.len > k: if result.len > k:
result.setLen(k) result.setLen(k)
proc len(r: RoutingTable): int =
for b in r.buckets: result += b.len
proc newKademliaProtocol*[Wire](thisNode: Node, wire: Wire): KademliaProtocol[Wire] = proc newKademliaProtocol*[Wire](thisNode: Node, wire: Wire): KademliaProtocol[Wire] =
result.new() result.new()
result.thisNode = thisNode result.thisNode = thisNode
@ -440,6 +443,27 @@ proc recvFindNode*(k: KademliaProtocol, remote: Node, nodeId: NodeId) =
found.sort() do(x, y: Node) -> int: cmp(x.id, y.id) found.sort() do(x, y: Node) -> int: cmp(x.id, y.id)
k.wire.sendNeighbours(remote, found) k.wire.sendNeighbours(remote, found)
proc randomNodes*(k: KademliaProtocol, count: int): seq[Node] =
var count = count
let sz = k.routing.len
if count > sz:
warn "Cannot get ", count, " nodes as RoutingTable contains only ", sz, " nodes"
count = sz
result = newSeqOfCap[Node](count)
var seen = initSet[Node]()
# This is a rather inneficient way of randomizing nodes from all buckets, but even if we
# iterate over all nodes in the routing table, the time it takes would still be
# insignificant compared to the time it takes for the network roundtrips when connecting
# to nodes.
while len(seen) < count:
let bucket = k.routing.buckets.rand()
let node = bucket.nodes.rand()
if node notin seen:
result.add(node)
seen.incl(node)
when isMainModule: when isMainModule:
proc randomNode(): Node = proc randomNode(): Node =
newNode("enode://aa36fdf33dd030378a0168efe6ed7d5cc587fafa3cdd375854fe735a2e11ea3650ba29644e2db48368c46e1f60e716300ba49396cd63778bf8a818c09bded46f@13.93.211.84:30303") newNode("enode://aa36fdf33dd030378a0168efe6ed7d5cc587fafa3cdd375854fe735a2e11ea3650ba29644e2db48368c46e1f60e716300ba49396cd63778bf8a818c09bded46f@13.93.211.84:30303")