Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/db: Add inspect enode db #649

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions cmd/ronin/dbcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package main

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"os"
Expand All @@ -33,9 +34,14 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/console/prompt"
"github.com/ethereum/go-ethereum/core/forkid"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/urfave/cli/v2"
)
Expand Down Expand Up @@ -69,6 +75,7 @@ Remove blockchain and state databases`,
dbDumpFreezerIndex,
dbImportCmd,
dbExportCmd,
dbInspectEnodeDBCmd,
},
}
dbInspectCmd = &cli.Command{
Expand Down Expand Up @@ -243,8 +250,93 @@ WARNING: This is a low-level operation which may cause database corruption!`,
},
Description: "Exports the specified chain data to an RLP encoded stream, optionally gzip-compressed.",
}
dbInspectEnodeDBCmd = &cli.Command{
Action: dbInspectEnodeDB,
Name: "inspect-enodedb",
Usage: "Inspect nodes in enode db",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "enodedb",
Usage: "Path to the enode database directory",
Required: true,
},
&cli.StringFlag{
Name: "peersfile",
Usage: "File containing a list of peers from admin.peers",
},
},
Category: "DATABASE COMMANDS",
}
)

func dbInspectEnodeDB(ctx *cli.Context) error {
path := ctx.String("enodedb")
db, err := enode.OpenDB(path)
sonhv0212 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}

nodeCount := 0
inspectedNodes := make(map[string]*enode.Node)
unknownNodes := []*enode.Node{}
db.IterateNodes(func(n *enode.Node) error {
nodeCount++
var eth struct {
ForkID forkid.ID
Tail []rlp.RawValue `rlp:"tail"`
}
if n.Record().Load(enr.WithEntry("eth", &eth)) == nil {
log.Info("Node", "ID", n.ID(), "IP", n.IP(), "UDP", n.UDP(), "TCP", n.TCP(), "eth", eth)
} else {
unknownNodes = append(unknownNodes, n)
}
inspectedNodes[n.ID().String()] = n
return nil
})

for _, n := range unknownNodes {
log.Info("Unknown node", "ID", n.ID(), "IP", n.IP(), "UDP", n.UDP(), "TCP", n.TCP())
}
log.Info("Total nodes", "count", nodeCount, "unknown", len(unknownNodes))

// Peers file is optional to calculate the rate of peers in Enode DB
if ctx.IsSet("peersfile") {
f, err := os.Open(ctx.String("peersfile"))
if err != nil {
return err
}

peersInfo := []*p2p.PeerInfo{}
decoder := json.NewDecoder(f)
err = decoder.Decode(&peersInfo)
if err != nil {
return err
}

foundInEnodeDB := 0
outbound := 0
for _, peerInfo := range peersInfo {
if peerInfo.Network.Inbound {
sonhv0212 marked this conversation as resolved.
Show resolved Hide resolved
continue
}

outbound++
if _, ok := inspectedNodes[peerInfo.ID]; ok {
foundInEnodeDB++
log.Info("Found peer in EnodeDB", "ID", peerInfo.ID, "Network", peerInfo.Network)
} else {
log.Info("Peer not found in EnodeDB", "ID", peerInfo.ID, "Network", peerInfo.Network)
}
}

log.Info("Peers in EnodeDB", "total", len(peersInfo), "found", foundInEnodeDB,
"not_found", outbound-foundInEnodeDB, "rate", float64(foundInEnodeDB)/float64(outbound),
"inbound", len(peersInfo)-outbound, "outbound", outbound)
}

return nil
}

func removeDB(ctx *cli.Context) error {
stack, config := makeConfigNode(ctx)

Expand Down
23 changes: 23 additions & 0 deletions p2p/enode/nodedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"sync"
"time"

"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/errors"
Expand Down Expand Up @@ -481,6 +482,28 @@ seek:
return nodes
}

// Testing purposes only.
func (db *DB) IterateNodes(f func(n *Node) error) {
it := db.lvl.NewIterator(util.BytesPrefix([]byte(dbNodePrefix)), nil)
defer it.Release()

for it.Next() {
id, rest := splitNodeKey(it.Key())
if string(rest) != dbDiscoverRoot {
continue
}
node := mustDecodeNode(id[:], it.Value())
if node == nil {
return
}

if err := f(node); err != nil {
log.Error("error during node iteration", "err", err)
return
}
}
}

// reads the next node record from the iterator, skipping over other
// database entries.
func nextNode(it iterator.Iterator) *Node {
Expand Down
Loading