// Copyright 2019 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . package api import ( "context" "fmt" "strings" "time" "github.com/ethereum/go-ethereum/metrics" "github.com/ethersphere/swarm/log" "github.com/ethersphere/swarm/network" "github.com/ethersphere/swarm/storage" ) type Inspector struct { api *API hive *network.Hive netStore *storage.NetStore } func NewInspector(api *API, hive *network.Hive, netStore *storage.NetStore) *Inspector { return &Inspector{api, hive, netStore} } // Hive prints the kademlia table func (i *Inspector) Hive() string { return i.hive.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) IsPullSyncing() bool { lastReceivedChunksMsg := metrics.GetOrRegisterGauge("network.stream.received_chunks", nil) // last received chunks msg time lrct := time.Unix(0, lastReceivedChunksMsg.Value()) // if last received chunks msg time is after now-15sec. (i.e. within the last 15sec.) then we say that the node is still syncing // technically this is not correct, because this might have been a retrieve request, but for the time being it works for our purposes // because we know we are not making retrieve requests on the node while checking this 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{} // iterate connection in kademlia 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]) res[fmt.Sprintf("%x", p.Over()[:16])] = metrics.GetOrRegisterCounter(peermetric, nil).Count() return true }) return res } // 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 (i *Inspector) Has(chunkAddresses []storage.Address) string { hostChunks := []string{} for _, addr := range chunkAddresses { has, err := i.netStore.Has(context.Background(), addr) if err != nil { log.Error(err.Error()) } if has { hostChunks = append(hostChunks, "1") } else { hostChunks = append(hostChunks, "0") } } return strings.Join(hostChunks, "") }