Description
Stream ordering of buckets.streamClosestPeers(targetId) does not follow the xor ordering (Spec Mismatch)
Acceptance Criteria
- Stream ordering should exactly adhere to xor distance
Steps to Reproduce (Bug)
- Call buckets.streamClosestPeers(targetId), after that sort the stream and compare it to your previous stream - Notice the discrepancy
Implementation notes
Vocab:
- Move left - Move from a distance d to d-1.
- Move right - Move from a distance d to d+1
Currently, we start off at the target xor distance, and then simultaneous move left and right and add them to our iterator. But that is wrong. We should Prioritize left buckets, then move right, if we don't get enough peers. Moving left guarantees that atleast cpl bits match
go-libp2p-kbucket follows the exact rationale described above. (Except for them left is right (logDistance vs common prefix length))
geth does and n^2 traversal - gets all the peers from all buckets and sorts them.
Preferred implementation:
if we worry about optimization: Node table is a centrally used data structure, so we have to design it as efficient as possible. We can add an additional parameter n, and stream and add to buckets in the above mentioned order. We stop scanning for extra buckets hasMoreBucketsToScan when we have grabbed and put more than n to a tree set ordered by xor distance comparator
if we don't worry about optimization: Stream all peers and add a .sorted() at the end of the stream. we may use a simple hashset instead of a treeset since we are already sorting at the end.
But as it is going to be 16*256, I'm not exactly sure on how approach 1 would help us. (Again since most of the calls would fall on Bucket 256 anyway)
Description
Stream ordering of buckets.streamClosestPeers(targetId) does not follow the xor ordering (Spec Mismatch)
Acceptance Criteria
Steps to Reproduce (Bug)
Implementation notes
Vocab:
Currently, we start off at the target xor distance, and then simultaneous move left and right and add them to our iterator. But that is wrong. We should Prioritize left buckets, then move right, if we don't get enough peers. Moving left guarantees that atleast cpl bits match
go-libp2p-kbucketfollows the exact rationale described above. (Except for them left is right (logDistance vs common prefix length))gethdoes and n^2 traversal - gets all the peers from all buckets and sorts them.Preferred implementation:
if we worry about optimization: Node table is a centrally used data structure, so we have to design it as efficient as possible. We can add an additional parameter
n, and stream and add to buckets in the above mentioned order. We stop scanning for extra bucketshasMoreBucketsToScanwhen we have grabbed and put more thannto a tree set ordered byxor distance comparatorif we don't worry about optimization: Stream all peers and add a .sorted() at the end of the stream. we may use a simple hashset instead of a treeset since we are already sorting at the end.
But as it is going to be
16*256, I'm not exactly sure on how approach 1 would help us. (Again since most of the calls would fall on Bucket 256 anyway)