mirror of
https://github.com/arnaucube/go-dht.git
synced 2026-02-06 19:06:44 +01:00
add admin RPC find call, add kademlia NodeLookup interactive
This commit is contained in:
@@ -2,6 +2,7 @@ package kademlia
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/bits"
|
||||
"net/rpc"
|
||||
"strconv"
|
||||
@@ -50,8 +51,12 @@ func (kad Kademlia) String() string {
|
||||
return r
|
||||
}
|
||||
|
||||
func (kad Kademlia) FindClosestKBucket(id ID) (int, error) {
|
||||
func (kad Kademlia) GetClosestKBucket(id ID) (int, error) {
|
||||
kb := kad.KBucket(id)
|
||||
if kb == 0 {
|
||||
// is this node
|
||||
return kb, nil
|
||||
}
|
||||
if len(kad.KBuckets[kb]) != 0 {
|
||||
return kb, nil
|
||||
}
|
||||
@@ -118,7 +123,7 @@ func (kad *Kademlia) Update(o ListedNode) {
|
||||
}
|
||||
|
||||
func (kad *Kademlia) PingOldNode(k int, o ListedNode) {
|
||||
// TODO when rpc layer is done
|
||||
// TODO
|
||||
// ping the n.KBuckets[k][0] (using goroutine)
|
||||
// if no response (timeout), delete it and add 'o'
|
||||
// n.KBuckets[k][0] = o
|
||||
@@ -177,3 +182,76 @@ func moveToBottom(kb []ListedNode, k int) []ListedNode {
|
||||
kb = append(kb[:], e)
|
||||
return kb
|
||||
}
|
||||
func removeFromListedNodes(lns []ListedNode, k int) []ListedNode {
|
||||
lns = append(lns[:k], lns[k+1:]...)
|
||||
return lns
|
||||
}
|
||||
|
||||
func (kad Kademlia) CallFindNode(id ID, o ListedNode) ([]ListedNode, error) {
|
||||
client, err := rpc.DialHTTP("tcp", o.Addr+":"+o.Port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var lns []ListedNode
|
||||
err = client.Call("Node.FindNode", id, &lns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return lns, nil
|
||||
}
|
||||
|
||||
func (kad Kademlia) NodeLookup(id ID) ([]ListedNode, error) {
|
||||
log.Debug("[NodeLookup] get closest KBucket for ", id)
|
||||
// find closest kbucket for this current node
|
||||
k, err := kad.GetClosestKBucket(id)
|
||||
if err != nil {
|
||||
return []ListedNode{}, fmt.Errorf("No KBuckets")
|
||||
}
|
||||
log.Debug("[NodeLookup] closest KBucket", k)
|
||||
|
||||
var closest ListedNode
|
||||
var newClosest ListedNode
|
||||
closest = kad.N
|
||||
var lns []ListedNode
|
||||
lns = kad.KBuckets[k]
|
||||
for !closest.ID.Equal(newClosest.ID) { // TODO
|
||||
// call each ListedNode from the kbucket, asking for their list of closest kbucket
|
||||
var newLns []ListedNode
|
||||
closest = newClosest
|
||||
for k, ln := range lns {
|
||||
// TODO TMP for the moment is synchronous
|
||||
fmt.Println("calling node", ln)
|
||||
flns, err := kad.CallFindNode(id, ln)
|
||||
if err != nil {
|
||||
log.Debug(err)
|
||||
}
|
||||
removeFromListedNodes(lns, k)
|
||||
// newLns = append(newLns, flns...)
|
||||
for _, fln := range flns {
|
||||
exist, _ := existsInListedNodes(newLns, fln)
|
||||
if !exist {
|
||||
fmt.Println("ln", fln.ID, " not exists")
|
||||
newLns = append(newLns, fln)
|
||||
}
|
||||
}
|
||||
}
|
||||
lns = newLns
|
||||
newClosest = updateClosest(id, lns, closest)
|
||||
}
|
||||
return lns, nil
|
||||
}
|
||||
|
||||
func updateClosest(id ID, lns []ListedNode, closest ListedNode) ListedNode {
|
||||
d := id.Distance(closest.ID)
|
||||
closestZ := countZeroes(d[:])
|
||||
for _, ln := range lns {
|
||||
d := id.Distance(ln.ID)
|
||||
z := countZeroes(d[:])
|
||||
if z < closestZ {
|
||||
closest = ln
|
||||
closestZ = z
|
||||
}
|
||||
}
|
||||
return closest
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ func TestFindClosestKBucket(t *testing.T) {
|
||||
idB, err := IDFromString("0fd85ddddf15aeec2d5d8b01b013dbca030a18d5")
|
||||
assert.Nil(t, err)
|
||||
|
||||
k, err := kademlia.FindClosestKBucket(idB)
|
||||
k, err := kademlia.GetClosestKBucket(idB)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, k)
|
||||
|
||||
@@ -164,7 +164,7 @@ func TestFindClosestKBucket(t *testing.T) {
|
||||
assert.Equal(t, 3, k)
|
||||
|
||||
// while the real KBucket (as the 3 is empty), should be 2
|
||||
k, err = kademlia.FindClosestKBucket(idB)
|
||||
k, err = kademlia.GetClosestKBucket(idB)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, k)
|
||||
|
||||
@@ -176,7 +176,7 @@ func TestFindClosestKBucket(t *testing.T) {
|
||||
assert.Equal(t, 5, k)
|
||||
|
||||
// while the real KBucket (as the 3 is empty), should be 2
|
||||
k, err = kademlia.FindClosestKBucket(idB)
|
||||
k, err = kademlia.GetClosestKBucket(idB)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 7, k)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user