diff options
author | joe <joe@jerkface.net> | 2017-07-16 17:27:43 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-07-16 17:27:43 -0400 |
commit | c554d48acb6861160480711d299f22f857daec97 (patch) | |
tree | 94b662acab4c8c98f4bdb521eb916166c0e3a06c /src/Network/DHT/Routing.hs | |
parent | 5164740e20d24bffb177337bcbbbe12b4d88adf0 (diff) |
Added timestamps to kademlia replacement queues.
Diffstat (limited to 'src/Network/DHT/Routing.hs')
-rw-r--r-- | src/Network/DHT/Routing.hs | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/src/Network/DHT/Routing.hs b/src/Network/DHT/Routing.hs index 2521f7b9..7f0e1c94 100644 --- a/src/Network/DHT/Routing.hs +++ b/src/Network/DHT/Routing.hs | |||
@@ -172,10 +172,10 @@ bucketQ = seqQ | |||
172 | -- table tree. Size of the bucket should be choosen such that it's | 172 | -- table tree. Size of the bucket should be choosen such that it's |
173 | -- very unlikely that all nodes in bucket fail within an hour of | 173 | -- very unlikely that all nodes in bucket fail within an hour of |
174 | -- each other. | 174 | -- each other. |
175 | -- | 175 | data Bucket ni = Bucket |
176 | data Bucket ni = Bucket { bktNodes :: !(PSQ ni Timestamp) -- current routing nodes | 176 | { bktNodes :: !(PSQ ni Timestamp) -- current routing nodes |
177 | , bktQ :: !(BucketQueue ni) -- replacements pending time-outs | 177 | , bktQ :: !(BucketQueue (Timestamp,ni)) -- replacements pending time-outs |
178 | } deriving Generic | 178 | } deriving Generic |
179 | 179 | ||
180 | deriving instance Show ni => Show (Bucket ni) | 180 | deriving instance Show ni => Show (Bucket ni) |
181 | 181 | ||
@@ -249,7 +249,7 @@ updateBucketForInbound curTime info bucket | |||
249 | , bucket { -- Update timestamps so that we don't redundantly ping. | 249 | , bucket { -- Update timestamps so that we don't redundantly ping. |
250 | bktNodes = updateStamps curTime stales $ bktNodes bucket | 250 | bktNodes = updateStamps curTime stales $ bktNodes bucket |
251 | -- Update queue with the pending NodeInfo in case of ping fail. | 251 | -- Update queue with the pending NodeInfo in case of ping fail. |
252 | , bktQ = runIdentity $ pushBack bucketQ info $ bktQ bucket } ) | 252 | , bktQ = runIdentity $ pushBack bucketQ (curTime,info) $ bktQ bucket } ) |
253 | -- When the bucket is full of good nodes, the new node is simply discarded. | 253 | -- When the bucket is full of good nodes, the new node is simply discarded. |
254 | -- We must return 'A.empty' here to ensure that bucket splitting happens | 254 | -- We must return 'A.empty' here to ensure that bucket splitting happens |
255 | -- inside 'modifyBucket'. | 255 | -- inside 'modifyBucket'. |
@@ -270,7 +270,7 @@ updateBucketForInbound curTime info bucket | |||
270 | map_ns f = bucket { bktNodes = f (bktNodes bucket) } | 270 | map_ns f = bucket { bktNodes = f (bktNodes bucket) } |
271 | -- map_q f = bucket { bktQ = runIdentity \$ f (bktQ bucket) } | 271 | -- map_q f = bucket { bktQ = runIdentity \$ f (bktQ bucket) } |
272 | 272 | ||
273 | updateBucketForPingResult curTime bad_node got_response bucket | 273 | updateBucketForPingResult bad_node got_response bucket |
274 | = pure ( replacements | 274 | = pure ( replacements |
275 | , Bucket (foldr replace | 275 | , Bucket (foldr replace |
276 | (bktNodes bucket) | 276 | (bktNodes bucket) |
@@ -286,17 +286,8 @@ updateBucketForPingResult curTime bad_node got_response bucket | |||
286 | return (bad_node, info) | 286 | return (bad_node, info) |
287 | | otherwise = [] | 287 | | otherwise = [] |
288 | 288 | ||
289 | replace (bad_node, info) = | 289 | replace (bad_node, (tm, info)) = |
290 | PSQ.insert info curTime | 290 | PSQ.insert info tm |
291 | -- XXX: curTime is the time somebody pinged out, not the time | ||
292 | -- of which the popped node was originally queued. That's not | ||
293 | -- quite right. | ||
294 | -- | ||
295 | -- It's the best we can do atm since the overflow BucketQueue | ||
296 | -- does not include timestamps. | ||
297 | -- | ||
298 | -- This means that initial time-outs for replacement nodes are up to | ||
299 | -- twice as long as for the originals. | ||
300 | . PSQ.delete bad_node | 291 | . PSQ.delete bad_node |
301 | 292 | ||
302 | 293 | ||
@@ -330,7 +321,7 @@ split :: -- ( Eq ip , Ord (NodeId) , FiniteBits (NodeId)) => | |||
330 | split testNodeIdBit i b = (Bucket ns qs, Bucket ms rs) | 321 | split testNodeIdBit i b = (Bucket ns qs, Bucket ms rs) |
331 | where | 322 | where |
332 | (ns,ms) = (PSQ.fromList *** PSQ.fromList) . partition (spanBit . key) . PSQ.toList $ bktNodes b | 323 | (ns,ms) = (PSQ.fromList *** PSQ.fromList) . partition (spanBit . key) . PSQ.toList $ bktNodes b |
333 | (qs,rs) = runIdentity $ partitionQ bucketQ spanBit $ bktQ b | 324 | (qs,rs) = runIdentity $ partitionQ bucketQ (spanBit . snd) $ bktQ b |
334 | 325 | ||
335 | spanBit :: ni -> Bool | 326 | spanBit :: ni -> Bool |
336 | spanBit entry = testNodeIdBit entry i | 327 | spanBit entry = testNodeIdBit entry i |
@@ -659,21 +650,20 @@ updateForInbound testIdBit nodeId tm ni tbl = | |||
659 | 650 | ||
660 | -- | Update the routing table with the results of a ping. | 651 | -- | Update the routing table with the results of a ping. |
661 | -- | 652 | -- |
662 | -- Each (a,b) in the returned list indicates that the node /a/ was deleted from the | 653 | -- Each (a,(tm,b)) in the returned list indicates that the node /a/ was deleted from the |
663 | -- routing table and the node /b/ has taken its place. | 654 | -- routing table and the node /b/, with timestamp /tm/, has taken its place. |
664 | updateForPingResult :: Ord ni => | 655 | updateForPingResult :: Ord ni => |
665 | (nid -> Word -> Bool) | 656 | (nid -> Word -> Bool) |
666 | -> (ni -> nid) | 657 | -> (ni -> nid) |
667 | -> Timestamp | ||
668 | -> ni -- ^ The pinged node. | 658 | -> ni -- ^ The pinged node. |
669 | -> Bool -- ^ True if we got a reply, False if it timed out. | 659 | -> Bool -- ^ True if we got a reply, False if it timed out. |
670 | -> Table ni nid -- ^ The routing table. | 660 | -> Table ni nid -- ^ The routing table. |
671 | -> ( [(ni,ni)], Table ni nid ) | 661 | -> ( [(ni,(Timestamp, ni))], Table ni nid ) |
672 | updateForPingResult testIdBit nodeId tm ni got_reply tbl = | 662 | updateForPingResult testIdBit nodeId ni got_reply tbl = |
673 | fromMaybe ([],tbl) | 663 | fromMaybe ([],tbl) |
674 | $ modifyBucket testIdBit (\ni -> testIdBit $ nodeId ni) | 664 | $ modifyBucket testIdBit (\ni -> testIdBit $ nodeId ni) |
675 | (nodeId ni) | 665 | (nodeId ni) |
676 | (updateBucketForPingResult tm ni got_reply) | 666 | (updateBucketForPingResult ni got_reply) |
677 | tbl | 667 | tbl |
678 | 668 | ||
679 | 669 | ||