From cc43dfe7ccb0d2a1ce65cdcd515d1587152a71e1 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Fri, 19 Jul 2019 12:57:57 +0200 Subject: [PATCH 1/2] network: structured output for kademlia table --- api/inspector.go | 23 +++++++++++------- network/kademlia.go | 59 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/api/inspector.go b/api/inspector.go index ab80568995..cb01b00b63 100644 --- a/api/inspector.go +++ b/api/inspector.go @@ -39,19 +39,24 @@ func NewInspector(api *API, hive *network.Hive, netStore *storage.NetStore) *Ins } // Hive prints the kademlia table -func (inspector *Inspector) Hive() string { - return inspector.hive.String() +func (i *Inspector) Hive() string { + return i.hive.String() } -func (inspector *Inspector) ListKnown() []string { +// KademliaInfo returns structured output of the Kademlia state that we can check for equality +func (i *Inspector) KademliaInfo() network.KademliaInfo { + return i.hive.KademliaInfo() +} + +func (i *Inspector) ListKnown() []string { res := []string{} - for _, v := range inspector.hive.Kademlia.ListKnown() { + for _, v := range i.hive.Kademlia.ListKnown() { res = append(res, fmt.Sprintf("%v", v)) } return res } -func (inspector *Inspector) IsPullSyncing() bool { +func (i *Inspector) IsPullSyncing() bool { lastReceivedChunksMsg := metrics.GetOrRegisterGauge("network.stream.received_chunks", nil) // last received chunks msg time @@ -63,11 +68,11 @@ func (inspector *Inspector) IsPullSyncing() bool { return lrct.After(time.Now().Add(-15 * time.Second)) } -func (inspector *Inspector) DeliveriesPerPeer() map[string]int64 { +func (i *Inspector) DeliveriesPerPeer() map[string]int64 { res := map[string]int64{} // iterate connection in kademlia - inspector.hive.Kademlia.EachConn(nil, 255, func(p *network.Peer, po int) bool { + i.hive.Kademlia.EachConn(nil, 255, func(p *network.Peer, po int) bool { // get how many chunks we receive for retrieve requests per peer peermetric := fmt.Sprintf("chunk.delivery.%x", p.Over()[:16]) @@ -82,10 +87,10 @@ func (inspector *Inspector) DeliveriesPerPeer() map[string]int64 { // Has checks whether each chunk address is present in the underlying datastore, // the bool in the returned structs indicates if the underlying datastore has // the chunk stored with the given address (true), or not (false) -func (inspector *Inspector) Has(chunkAddresses []storage.Address) string { +func (i *Inspector) Has(chunkAddresses []storage.Address) string { hostChunks := []string{} for _, addr := range chunkAddresses { - has, err := inspector.netStore.Has(context.Background(), addr) + has, err := i.netStore.Has(context.Background(), addr) if err != nil { log.Error(err.Error()) } diff --git a/network/kademlia.go b/network/kademlia.go index 984669a9c0..a502203c32 100644 --- a/network/kademlia.go +++ b/network/kademlia.go @@ -20,6 +20,7 @@ import ( "bytes" "fmt" "math/rand" + "sort" "strings" "sync" "time" @@ -93,6 +94,14 @@ type Kademlia struct { nDepthSig []chan struct{} // signals when neighbourhood depth nDepth is changed } +type KademliaInfo struct { + Depth int `json:"depth"` + TotalConnections int `json:"total_connections"` + TotalKnown int `json:"total_known"` + Connections [][]string `json:"connections"` + Known [][]string `json:"known"` +} + // NewKademlia creates a Kademlia table for base address addr // with parameters as in params // if params is nil, it uses default values @@ -576,6 +585,56 @@ func (k *Kademlia) BaseAddr() []byte { return k.base } +func (k *Kademlia) KademliaInfo() KademliaInfo { + k.lock.RLock() + defer k.lock.RUnlock() + return k.kademliaInfo() +} + +func (k *Kademlia) kademliaInfo() (ki KademliaInfo) { + ki.Depth = depthForPot(k.conns, k.NeighbourhoodSize, k.base) + ki.TotalConnections = k.conns.Size() + ki.TotalKnown = k.addrs.Size() + ki.Connections = make([][]string, k.MaxProxDisplay) + ki.Known = make([][]string, k.MaxProxDisplay) + + k.conns.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val) bool) bool) bool { + if po >= k.MaxProxDisplay { + po = k.MaxProxDisplay - 1 + } + + row := []string{} + f(func(val pot.Val) bool { + e := val.(*Peer) + row = append(row, fmt.Sprintf("%x", e.Address())) + return true + }) + sort.Strings(row) + ki.Connections[po] = row + + return true + }) + + k.addrs.EachBin(k.base, Pof, 0, func(po, size int, f func(func(val pot.Val) bool) bool) bool { + if po >= k.MaxProxDisplay { + po = k.MaxProxDisplay - 1 + } + + row := []string{} + f(func(val pot.Val) bool { + e := val.(*entry) + row = append(row, fmt.Sprintf("%x", e.Address())) + return true + }) + sort.Strings(row) + ki.Known[po] = row + + return true + }) + + return +} + // String returns kademlia table + kaddb table displayed with ascii func (k *Kademlia) String() string { k.lock.RLock() From ba8f41a3d8b5074dbab9236dd9fb76508974f4c0 Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Fri, 19 Jul 2019 13:06:04 +0200 Subject: [PATCH 2/2] api: remove ListKnown, as it is a subset of KademliaInfo --- api/inspector.go | 9 +-------- network/kademlia.go | 12 ------------ 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/api/inspector.go b/api/inspector.go index cb01b00b63..5fffc16b25 100644 --- a/api/inspector.go +++ b/api/inspector.go @@ -48,14 +48,6 @@ func (i *Inspector) KademliaInfo() network.KademliaInfo { return i.hive.KademliaInfo() } -func (i *Inspector) ListKnown() []string { - res := []string{} - for _, v := range i.hive.Kademlia.ListKnown() { - res = append(res, fmt.Sprintf("%v", v)) - } - return res -} - func (i *Inspector) IsPullSyncing() bool { lastReceivedChunksMsg := metrics.GetOrRegisterGauge("network.stream.received_chunks", nil) @@ -68,6 +60,7 @@ func (i *Inspector) IsPullSyncing() bool { return lrct.After(time.Now().Add(-15 * time.Second)) } +// DeliveriesPerPeer returns the sum of chunks we received from a given peer func (i *Inspector) DeliveriesPerPeer() map[string]int64 { res := map[string]int64{} diff --git a/network/kademlia.go b/network/kademlia.go index a502203c32..6af58d6a74 100644 --- a/network/kademlia.go +++ b/network/kademlia.go @@ -431,18 +431,6 @@ func (k *Kademlia) Off(p *Peer) { } } -func (k *Kademlia) ListKnown() []*BzzAddr { - res := []*BzzAddr{} - - k.addrs.Each(func(val pot.Val) bool { - e := val.(*entry) - res = append(res, e.BzzAddr) - return true - }) - - return res -} - // EachConn is an iterator with args (base, po, f) applies f to each live peer // that has proximity order po or less as measured from the base // if base is nil, kademlia base address is used