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
privKey: PrivateKey
address: Address
bootstrapNodes: seq[Node]
bootstrapNodes*: seq[Node]
thisNode: Node
kademlia: KademliaProtocol[DiscoveryProtocol]
socket: AsyncSocket
@ -266,6 +266,12 @@ proc bootstrap*(d: DiscoveryProtocol) {.async.} =
proc resolve*(d: DiscoveryProtocol, n: NodeId): Future[Node] =
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:
import logging, byteutils

View File

@ -1,5 +1,5 @@
import asyncdispatch, net, uri, logging, tables, hashes, times, algorithm, sets,
sequtils
sequtils, random
from strutils import parseInt
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:
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] =
result.new()
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)
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:
proc randomNode(): Node =
newNode("enode://aa36fdf33dd030378a0168efe6ed7d5cc587fafa3cdd375854fe735a2e11ea3650ba29644e2db48368c46e1f60e716300ba49396cd63778bf8a818c09bded46f@13.93.211.84:30303")