mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
swarm/network: kademlia health check for discovery test
This commit is contained in:
parent
30aee9e3d6
commit
6de0d73449
4 changed files with 77 additions and 11 deletions
|
|
@ -55,6 +55,7 @@ type Overlay interface {
|
||||||
|
|
||||||
String() string
|
String() string
|
||||||
BaseAddr() []byte
|
BaseAddr() []byte
|
||||||
|
Healthy([][]byte) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// HiveParams holds the config options to hive
|
// HiveParams holds the config options to hive
|
||||||
|
|
@ -191,14 +192,6 @@ func (self *Hive) PeerInfo(id discover.NodeID) interface{} {
|
||||||
return interface{}(addr)
|
return interface{}(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Healthy reports the health state of the kademlia connectivity
|
|
||||||
//
|
|
||||||
func (self *Hive) Healthy() bool {
|
|
||||||
// TODO: determine if we have enough peers to consider the network
|
|
||||||
// to be healthy
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Hive) Register(peers chan OverlayAddr) error {
|
func (self *Hive) Register(peers chan OverlayAddr) error {
|
||||||
defer self.wake()
|
defer self.wake()
|
||||||
return self.Overlay.Register(peers)
|
return self.Overlay.Register(peers)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
||||||
"github.com/ethereum/go-ethereum/pot"
|
"github.com/ethereum/go-ethereum/pot"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -499,3 +501,66 @@ func (self *Kademlia) Prune(c <-chan time.Time) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewPeerPot(kadMinProxSize int, ids ...*adapters.NodeId) map[discover.NodeID][][]byte {
|
||||||
|
// create a table of all nodes for health check
|
||||||
|
np := pot.NewPot(nil, 0)
|
||||||
|
for _, id := range ids {
|
||||||
|
o := ToOverlayAddr(id)
|
||||||
|
np, _, _ = pot.Add(np, pot.NewBytesVal(o, nil))
|
||||||
|
}
|
||||||
|
nnmap := make(map[discover.NodeID][][]byte)
|
||||||
|
|
||||||
|
for _, id := range ids {
|
||||||
|
pl := 0
|
||||||
|
var nns [][]byte
|
||||||
|
np.EachNeighbour(pot.NewBytesVal(id.Bytes(), nil), func(val pot.PotVal, po int) bool {
|
||||||
|
a := val.(pot.BytesAddress).Address()
|
||||||
|
nns = append(nns, a)
|
||||||
|
if len(nns) >= kadMinProxSize {
|
||||||
|
pl = po
|
||||||
|
}
|
||||||
|
return pl == 0 || pl == po
|
||||||
|
})
|
||||||
|
nnmap[id.NodeID] = nns
|
||||||
|
}
|
||||||
|
return nnmap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Kademlia) FirstEmptyBin() (i int) {
|
||||||
|
i = -1
|
||||||
|
self.conns.EachBin(pot.NewBytesVal(self.base, nil), 0, func(po, size int, f func(func(val pot.PotVal, i int) bool) bool) bool {
|
||||||
|
if po > i+1 {
|
||||||
|
i = po
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
i = po
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Kademlia) Full() bool {
|
||||||
|
return self.FirstEmptyBin() >= self.Depth()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Healthy reports the health state of the kademlia connectivity
|
||||||
|
//
|
||||||
|
func (self *Kademlia) Healthy(peers [][]byte) bool {
|
||||||
|
return self.gotNearestNeighbours(peers) && self.Full()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Kademlia) gotNearestNeighbours(peers [][]byte) (got bool) {
|
||||||
|
pm := make(map[string]bool)
|
||||||
|
for _, p := range peers {
|
||||||
|
pm[string(p)] = true
|
||||||
|
}
|
||||||
|
self.EachConn(nil, 255, func(p OverlayConn, po int, nn bool) bool {
|
||||||
|
if !nn {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, got = pm[string(p.Address())]
|
||||||
|
return got
|
||||||
|
})
|
||||||
|
return got
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ type Addr interface {
|
||||||
Over() []byte
|
Over() []byte
|
||||||
Under() []byte
|
Under() []byte
|
||||||
String() string
|
String() string
|
||||||
|
Update(OverlayAddr) OverlayAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Peer interface represents an live peer connection
|
// Peer interface represents an live peer connection
|
||||||
|
|
@ -349,7 +350,12 @@ func NewNodeIdFromAddr(addr Addr) *adapters.NodeId {
|
||||||
func NewAddrFromNodeId(n *adapters.NodeId) *bzzAddr {
|
func NewAddrFromNodeId(n *adapters.NodeId) *bzzAddr {
|
||||||
id := n.NodeID
|
id := n.NodeID
|
||||||
return &bzzAddr{
|
return &bzzAddr{
|
||||||
OAddr: crypto.Keccak256(id[:]),
|
OAddr: ToOverlayAddr(n),
|
||||||
UAddr: []byte(discover.NewNode(id, net.IP{127, 0, 0, 1}, 30303, 30303).String()),
|
UAddr: []byte(discover.NewNode(id, net.IP{127, 0, 0, 1}, 30303, 30303).String()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToOverlayAddr creates an overlayaddress from NodeID
|
||||||
|
func ToOverlayAddr(id *adapters.NodeId) []byte {
|
||||||
|
return crypto.Keccak256(id.Bytes())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import (
|
||||||
// serviceName is used with the exec adapter so the exec'd binary knows which
|
// serviceName is used with the exec adapter so the exec'd binary knows which
|
||||||
// service to execute
|
// service to execute
|
||||||
const serviceName = "discovery"
|
const serviceName = "discovery"
|
||||||
|
const testMinProxBinSize = 2
|
||||||
|
|
||||||
var services = adapters.Services{
|
var services = adapters.Services{
|
||||||
serviceName: newService,
|
serviceName: newService,
|
||||||
|
|
@ -94,6 +95,7 @@ func testDiscoverySimulation(t *testing.T, adapter adapters.NodeAdapter) {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
nnmap := network.NewPeerPot(testMinProxBinSize, ids...)
|
||||||
check := func(ctx context.Context, id *adapters.NodeId) (bool, error) {
|
check := func(ctx context.Context, id *adapters.NodeId) (bool, error) {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
|
@ -110,7 +112,7 @@ func testDiscoverySimulation(t *testing.T, adapter adapters.NodeAdapter) {
|
||||||
return false, fmt.Errorf("error getting node client: %s", err)
|
return false, fmt.Errorf("error getting node client: %s", err)
|
||||||
}
|
}
|
||||||
var healthy bool
|
var healthy bool
|
||||||
if err := client.Call(&healthy, "hive_healthy", nil); err != nil {
|
if err := client.Call(&healthy, "hive_healthy", nnmap[id.NodeID]); err != nil {
|
||||||
return false, fmt.Errorf("error getting node health: %s", err)
|
return false, fmt.Errorf("error getting node health: %s", err)
|
||||||
}
|
}
|
||||||
return healthy, nil
|
return healthy, nil
|
||||||
|
|
@ -180,7 +182,7 @@ func newService(id *adapters.NodeId, snapshot []byte) node.Service {
|
||||||
addr := network.NewAddrFromNodeId(id)
|
addr := network.NewAddrFromNodeId(id)
|
||||||
|
|
||||||
kp := network.NewKadParams()
|
kp := network.NewKadParams()
|
||||||
kp.MinProxBinSize = 2
|
kp.MinProxBinSize = testMinProxBinSize
|
||||||
kp.MaxBinSize = 3
|
kp.MaxBinSize = 3
|
||||||
kp.MinBinSize = 1
|
kp.MinBinSize = 1
|
||||||
kp.MaxRetries = 1000
|
kp.MaxRetries = 1000
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue