mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 13:16:42 +00:00
kademlia: added callback on short bucket + tests
This commit is contained in:
parent
436b22e1ac
commit
a6818c4300
2 changed files with 54 additions and 8 deletions
|
|
@ -34,6 +34,8 @@ type Kademlia struct {
|
||||||
nodeDB [][]*nodeRecord
|
nodeDB [][]*nodeRecord
|
||||||
nodeIndex map[Address]*nodeRecord
|
nodeIndex map[Address]*nodeRecord
|
||||||
|
|
||||||
|
GetNode func(int)
|
||||||
|
|
||||||
// state
|
// state
|
||||||
proxLimit int
|
proxLimit int
|
||||||
proxSize int
|
proxSize int
|
||||||
|
|
@ -52,6 +54,7 @@ type Node interface {
|
||||||
Addr() Address
|
Addr() Address
|
||||||
// Url()
|
// Url()
|
||||||
LastActive() time.Time
|
LastActive() time.Time
|
||||||
|
Drop()
|
||||||
}
|
}
|
||||||
|
|
||||||
type nodeRecord struct {
|
type nodeRecord struct {
|
||||||
|
|
@ -159,7 +162,9 @@ func (self *Kademlia) RemoveNode(node Node) (err error) {
|
||||||
}
|
}
|
||||||
// async callback to notify user that bucket needs filling
|
// async callback to notify user that bucket needs filling
|
||||||
// action is left to the user
|
// action is left to the user
|
||||||
// go self.getNode(index)
|
if self.GetNode != nil {
|
||||||
|
go self.GetNode(index)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"testing/quick"
|
"testing/quick"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -40,6 +39,9 @@ func (n *testNode) Addr() Address {
|
||||||
return n.addr
|
return n.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *testNode) Drop() {
|
||||||
|
}
|
||||||
|
|
||||||
func (n *testNode) LastActive() time.Time {
|
func (n *testNode) LastActive() time.Time {
|
||||||
return time.Now()
|
return time.Now()
|
||||||
}
|
}
|
||||||
|
|
@ -154,12 +156,10 @@ func TestProxAdjust(t *testing.T) {
|
||||||
a := gen(Address{}, r).(Address)
|
a := gen(Address{}, r).(Address)
|
||||||
addresses = append(addresses, a)
|
addresses = append(addresses, a)
|
||||||
err = kad.AddNode(&testNode{addr: a})
|
err = kad.AddNode(&testNode{addr: a})
|
||||||
fmt.Printf("add node: %x (%v)\n", a, kad.proximityBin(a))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("backend not accepting node")
|
t.Errorf("backend not accepting node")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("MaxProxBinSize: %d, proxSize: %d, proxLimit: %d, count: %d\n", kad.MaxProxBinSize, kad.proxSize, kad.proxLimit, kad.count)
|
|
||||||
if !kad.proxCheck(t) {
|
if !kad.proxCheck(t) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -167,15 +167,11 @@ func TestProxAdjust(t *testing.T) {
|
||||||
|
|
||||||
test := func(test *proxTest) bool {
|
test := func(test *proxTest) bool {
|
||||||
node := &testNode{test.address}
|
node := &testNode{test.address}
|
||||||
a := test.address
|
|
||||||
if test.add {
|
if test.add {
|
||||||
kad.AddNode(node)
|
kad.AddNode(node)
|
||||||
fmt.Printf("add node: %x (%v)\n", a, kad.proximityBin(a))
|
|
||||||
} else {
|
} else {
|
||||||
kad.RemoveNode(node)
|
kad.RemoveNode(node)
|
||||||
fmt.Printf("remove node: %x (%v)\n", common.ToHex(a[:]), kad.proximityBin(a))
|
|
||||||
}
|
}
|
||||||
fmt.Printf("MaxProxBinSize: %d, proxSize: %d, proxLimit: %d, count: %d\n", kad.MaxProxBinSize, kad.proxSize, kad.proxLimit, kad.count)
|
|
||||||
return kad.proxCheck(t)
|
return kad.proxCheck(t)
|
||||||
}
|
}
|
||||||
if err := quick.Check(test, quickcfg); err != nil {
|
if err := quick.Check(test, quickcfg); err != nil {
|
||||||
|
|
@ -183,6 +179,51 @@ func TestProxAdjust(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCallback(t *testing.T) {
|
||||||
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
self := gen(Address{}, r).(Address)
|
||||||
|
kad := New(self)
|
||||||
|
var bucket int
|
||||||
|
var called chan bool
|
||||||
|
kad.MaxProx = 5
|
||||||
|
kad.BucketSize = 2
|
||||||
|
kad.GetNode = func(b int) {
|
||||||
|
bucket = b
|
||||||
|
close(called)
|
||||||
|
}
|
||||||
|
kad.Start()
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
a := gen(Address{}, r).(Address)
|
||||||
|
addresses = append(addresses, a)
|
||||||
|
err = kad.AddNode(&testNode{addr: a})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("backend not accepting node")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, a := range addresses {
|
||||||
|
called = make(chan bool)
|
||||||
|
kad.RemoveNode(&testNode{a})
|
||||||
|
b := kad.proximityBin(a)
|
||||||
|
select {
|
||||||
|
case <-called:
|
||||||
|
if bucket != b {
|
||||||
|
t.Errorf("GetNode callback called with incorrect bucket, expected %v, got %v", b, bucket)
|
||||||
|
}
|
||||||
|
case <-time.After(100 * time.Millisecond):
|
||||||
|
l := len(kad.buckets[b].nodes)
|
||||||
|
if l < kad.BucketSize {
|
||||||
|
t.Errorf("GetNode not called on bucket %v although size is %v < %v", b, l, kad.BucketSize)
|
||||||
|
} else {
|
||||||
|
t.Logf("bucket callback ok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestSaveLoad(t *testing.T) {
|
func TestSaveLoad(t *testing.T) {
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
addresses := gen([]Address{}, r).([]Address)
|
addresses := gen([]Address{}, r).([]Address)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue