mirror of https://github.com/status-im/nim-eth.git
discv4: fix ping pong time removal algorithm
This commit is contained in:
parent
58d7e98c5c
commit
5885f638e4
|
@ -64,6 +64,8 @@ const
|
||||||
ID_SIZE = 256
|
ID_SIZE = 256
|
||||||
BOND_EXPIRATION = initDuration(hours = 12)
|
BOND_EXPIRATION = initDuration(hours = 12)
|
||||||
|
|
||||||
|
proc len(r: RoutingTable): int
|
||||||
|
|
||||||
proc toNodeId*(pk: PublicKey): NodeId =
|
proc toNodeId*(pk: PublicKey): NodeId =
|
||||||
readUintBE[256](keccak256.digest(pk.toRaw()).data)
|
readUintBE[256](keccak256.digest(pk.toRaw()).data)
|
||||||
|
|
||||||
|
@ -125,25 +127,47 @@ proc cmp(x, y: (TimeKey, int64)): int =
|
||||||
|
|
||||||
proc removeTooOldPingPongTime(k: KademliaProtocol) =
|
proc removeTooOldPingPongTime(k: KademliaProtocol) =
|
||||||
const
|
const
|
||||||
MaxEntries = 128
|
MinEntries = 128
|
||||||
MaxRC = 5
|
MaxRC = MinEntries div 8
|
||||||
|
|
||||||
if k.pingPongTime.len < MaxEntries:
|
# instead of using fixed limit, we use dynamic limit
|
||||||
|
# with minimum entries = 128.
|
||||||
|
# remove 25% of too old entries if we need more space.
|
||||||
|
# the reason maxEntries is twice routing table because we
|
||||||
|
# store ping and pong time.
|
||||||
|
let
|
||||||
|
maxEntries = max(k.routing.len * 2, MinEntries)
|
||||||
|
maxRemove = maxEntries div 4
|
||||||
|
|
||||||
|
if k.pingPongTime.len < maxEntries:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# it is safe to remove this table sort?
|
||||||
|
# because we already using ordered table to store time from
|
||||||
|
# older value to newer value
|
||||||
|
when false:
|
||||||
k.pingPongTime.sort(cmp, order = SortOrder.Descending)
|
k.pingPongTime.sort(cmp, order = SortOrder.Descending)
|
||||||
|
|
||||||
var
|
var
|
||||||
num = 0
|
rci = 0
|
||||||
rc: array[MaxRC, TimeKey]
|
numRemoved = 0
|
||||||
|
rc: array[MaxRC, TimeKey] # 784 bytes(MinEntries/8*sizeof(TimeKey))
|
||||||
|
|
||||||
|
# using fixed size temp on stack possibly
|
||||||
|
# requires multiple iteration to remove
|
||||||
|
# old entries
|
||||||
|
while numRemoved < maxRemove:
|
||||||
for v in keys(k.pingPongTime):
|
for v in keys(k.pingPongTime):
|
||||||
if num < MaxRC:
|
rc[rci] = v
|
||||||
rc[num] = v
|
inc rci
|
||||||
inc num
|
inc numRemoved
|
||||||
|
if rci >= MaxRC or numRemoved >= maxRemove: break
|
||||||
|
|
||||||
for i in 0..<num:
|
for i in 0..<rci:
|
||||||
k.pingPongTime.del(rc[i])
|
k.pingPongTime.del(rc[i])
|
||||||
|
|
||||||
|
rci = 0
|
||||||
|
|
||||||
proc updateLastPingReceived(k: KademliaProtocol, n: Node, t: Time) =
|
proc updateLastPingReceived(k: KademliaProtocol, n: Node, t: Time) =
|
||||||
k.removeTooOldPingPongTime()
|
k.removeTooOldPingPongTime()
|
||||||
k.pingPongTime[n.timeKeyPing] = t.toUnix
|
k.pingPongTime[n.timeKeyPing] = t.toUnix
|
||||||
|
|
Loading…
Reference in New Issue