From e2fec2a0814a3fc3b97ef88611502a20c98c8cd0 Mon Sep 17 00:00:00 2001 From: Enrique Jose Avila Asapche Date: Mon, 25 Apr 2022 15:57:54 +0300 Subject: [PATCH 1/2] got rid of the automatic usage of net api (#3952) * got rid of the automatic usage of net api * less confusing comment * ops * ops2 * important * ops --- cmd/rpcdaemon/cli/config.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go index 69a80dcd49d..6c505fc00f6 100644 --- a/cmd/rpcdaemon/cli/config.go +++ b/cmd/rpcdaemon/cli/config.go @@ -288,6 +288,7 @@ func RemoteServices(ctx context.Context, cfg httpcfg.HttpCfg, logger log.Logger, } log.Info("if you run RPCDaemon on same machine with Erigon add --datadir option") } + if db != nil { var cc *params.ChainConfig if err := db.View(context.Background(), func(tx kv.Tx) error { @@ -313,11 +314,10 @@ func RemoteServices(ctx context.Context, cfg httpcfg.HttpCfg, logger log.Logger, cfg.Snapshot = ethconfig.NewSnapshotCfg(cfg.Snapshot.Enabled, cfg.Snapshot.KeepBlocks) } - // if chain config has terminal total difficulty then rpc has to have these API's to function + // if chain config has terminal total difficulty then rpc must have eth and engine APIs enableds if cc.TerminalTotalDifficulty != nil { hasEthApiEnabled := false hasEngineApiEnabled := false - hasNetApiEnabled := false for _, api := range cfg.API { switch api { @@ -325,8 +325,6 @@ func RemoteServices(ctx context.Context, cfg httpcfg.HttpCfg, logger log.Logger, hasEthApiEnabled = true case "engine": hasEngineApiEnabled = true - case "net": - hasNetApiEnabled = true } } @@ -337,11 +335,6 @@ func RemoteServices(ctx context.Context, cfg httpcfg.HttpCfg, logger log.Logger, if !hasEngineApiEnabled { cfg.API = append(cfg.API, "engine") } - - if !hasNetApiEnabled { - cfg.API = append(cfg.API, "net") - } - } } From fc3eecae5e054010b4a39c3ed88996006e156fa9 Mon Sep 17 00:00:00 2001 From: battlmonstr Date: Mon, 25 Apr 2022 15:40:04 +0200 Subject: [PATCH 2/2] RPC: admin.peers() (#3960) * RPC: admin.peers() This RPC method returns information about the connected remote nodes. https://geth.ethereum.org/docs/rpc/ns-admin#admin_peers The peers are collected from all configured sentries. See: https://github.com/ledgerwatch/interfaces/pull/102 Test with: curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "admin_peers", "params": [], "id":1}' localhost:8545 * save * liner fix Co-authored-by: alex.sharov --- cmd/downloader/downloader/downloader.go | 13 --------- cmd/rpcdaemon/commands/admin_api.go | 8 ++++++ cmd/rpcdaemon/services/eth_backend.go | 38 +++++++++++++++++++++++++ cmd/sentry/sentry/sentry.go | 33 +++++++++++++++++++-- eth/backend.go | 13 +++++++++ ethdb/privateapi/ethbackend.go | 5 ++++ go.mod | 2 +- go.sum | 4 +-- 8 files changed, 97 insertions(+), 19 deletions(-) diff --git a/cmd/downloader/downloader/downloader.go b/cmd/downloader/downloader/downloader.go index 374cd455e00..ac417a7d3f7 100644 --- a/cmd/downloader/downloader/downloader.go +++ b/cmd/downloader/downloader/downloader.go @@ -163,19 +163,6 @@ type AggStats struct { bytesWritten int64 } -func min(a, b int) int { - if a < b { - return a - } - return b -} -func max(a, b int) int { - if a > b { - return a - } - return b -} - func CalcStats(prevStats AggStats, interval time.Duration, client *torrent.Client) (result AggStats) { var aggBytesCompleted, aggLen int64 //var aggCompletedPieces, aggNumPieces, aggPartialPieces int diff --git a/cmd/rpcdaemon/commands/admin_api.go b/cmd/rpcdaemon/commands/admin_api.go index abf8518a105..990e6cfe364 100644 --- a/cmd/rpcdaemon/commands/admin_api.go +++ b/cmd/rpcdaemon/commands/admin_api.go @@ -13,6 +13,10 @@ import ( type AdminAPI interface { // NodeInfo returns a collection of metadata known about the host. NodeInfo(ctx context.Context) (*p2p.NodeInfo, error) + + // Peers returns information about the connected remote nodes. + // https://geth.ethereum.org/docs/rpc/ns-admin#admin_peers + Peers(ctx context.Context) ([]*p2p.PeerInfo, error) } // AdminAPIImpl data structure to store things needed for admin_* commands. @@ -39,3 +43,7 @@ func (api *AdminAPIImpl) NodeInfo(ctx context.Context) (*p2p.NodeInfo, error) { return &nodes[0], nil } + +func (api *AdminAPIImpl) Peers(ctx context.Context) ([]*p2p.PeerInfo, error) { + return api.ethBackend.Peers(ctx) +} diff --git a/cmd/rpcdaemon/services/eth_backend.go b/cmd/rpcdaemon/services/eth_backend.go index 6ae6e0fc466..6df611b839e 100644 --- a/cmd/rpcdaemon/services/eth_backend.go +++ b/cmd/rpcdaemon/services/eth_backend.go @@ -39,6 +39,7 @@ type ApiBackend interface { EngineForkchoiceUpdatedV1(ctx context.Context, request *remote.EngineForkChoiceUpdatedRequest) (*remote.EngineForkChoiceUpdatedReply, error) EngineGetPayloadV1(ctx context.Context, payloadId uint64) (*types2.ExecutionPayload, error) NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) + Peers(ctx context.Context) ([]*p2p.PeerInfo, error) } type RemoteBackend struct { @@ -245,3 +246,40 @@ func (back *RemoteBackend) NodeInfo(ctx context.Context, limit uint32) ([]p2p.No return ret, nil } + +func (back *RemoteBackend) Peers(ctx context.Context) ([]*p2p.PeerInfo, error) { + rpcPeers, err := back.remoteEthBackend.Peers(ctx, &emptypb.Empty{}) + if err != nil { + return nil, fmt.Errorf("ETHBACKENDClient.Peers() error: %w", err) + } + + peers := make([]*p2p.PeerInfo, 0, len(rpcPeers.Peers)) + + for _, rpcPeer := range rpcPeers.Peers { + peer := p2p.PeerInfo{ + ENR: rpcPeer.Enr, + Enode: rpcPeer.Enode, + ID: rpcPeer.Id, + Name: rpcPeer.Name, + Caps: rpcPeer.Caps, + Network: struct { + LocalAddress string `json:"localAddress"` + RemoteAddress string `json:"remoteAddress"` + Inbound bool `json:"inbound"` + Trusted bool `json:"trusted"` + Static bool `json:"static"` + }{ + LocalAddress: rpcPeer.ConnLocalAddr, + RemoteAddress: rpcPeer.ConnRemoteAddr, + Inbound: rpcPeer.ConnIsInbound, + Trusted: rpcPeer.ConnIsTrusted, + Static: rpcPeer.ConnIsStatic, + }, + Protocols: nil, + } + + peers = append(peers, &peer) + } + + return peers, nil +} diff --git a/cmd/sentry/sentry/sentry.go b/cmd/sentry/sentry/sentry.go index 679e90739fc..fd46ff2a7ab 100644 --- a/cmd/sentry/sentry/sentry.go +++ b/cmd/sentry/sentry/sentry.go @@ -564,9 +564,7 @@ func NewSentryServer(ctx context.Context, dialCandidates enode.Iterator, readNod return readNodeInfo() }, PeerInfo: func(peerID [64]byte) interface{} { - if peerInfo := ss.getPeer(peerID); peerInfo != nil { - return peerInfo.peer.Info() - } + // TODO: remember handshake reply per peer ID and return eth-related Status info (see ethPeerInfo in geth) return nil }, //Attributes: []enr.Entry{eth.CurrentENREntry(chainConfig, genesisHash, headHeight)}, @@ -871,6 +869,35 @@ func (ss *SentryServerImpl) SetStatus(ctx context.Context, statusData *proto_sen return reply, nil } +func (ss *SentryServerImpl) Peers(_ context.Context, _ *emptypb.Empty) (*proto_sentry.PeersReply, error) { + if ss.P2pServer == nil { + return nil, errors.New("p2p server was not started") + } + + peers := ss.P2pServer.PeersInfo() + + var reply proto_sentry.PeersReply + reply.Peers = make([]*proto_types.PeerInfo, 0, len(peers)) + + for _, peer := range peers { + rpcPeer := proto_types.PeerInfo{ + Id: peer.ID, + Name: peer.Name, + Enode: peer.Enode, + Enr: peer.ENR, + Caps: peer.Caps, + ConnLocalAddr: peer.Network.LocalAddress, + ConnRemoteAddr: peer.Network.RemoteAddress, + ConnIsInbound: peer.Network.Inbound, + ConnIsTrusted: peer.Network.Trusted, + ConnIsStatic: peer.Network.Static, + } + reply.Peers = append(reply.Peers, &rpcPeer) + } + + return &reply, nil +} + func (ss *SentryServerImpl) SimplePeerCount() (pc int) { ss.rangePeers(func(peerInfo *PeerInfo) bool { pc++ diff --git a/eth/backend.go b/eth/backend.go index 2b641ca6afc..7e946ce153a 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -21,6 +21,7 @@ import ( "context" "errors" "fmt" + "google.golang.org/protobuf/types/known/emptypb" "math/big" "os" "path/filepath" @@ -770,6 +771,18 @@ func (s *Ethereum) NodesInfo(limit int) (*remote.NodesInfoReply, error) { return nodesInfo, nil } +func (s *Ethereum) Peers(ctx context.Context) (*remote.PeersReply, error) { + var reply remote.PeersReply + for _, sentryClient := range s.sentries { + peers, err := sentryClient.Peers(ctx, &emptypb.Empty{}) + if err != nil { + return nil, fmt.Errorf("Ethereum backend SentryClient.Peers error: %w", err) + } + reply.Peers = append(reply.Peers, peers.Peers...) + } + return &reply, nil +} + // Protocols returns all the currently configured // network protocols to start. func (s *Ethereum) Protocols() []p2p.Protocol { diff --git a/ethdb/privateapi/ethbackend.go b/ethdb/privateapi/ethbackend.go index db65aa023bd..54abefc743d 100644 --- a/ethdb/privateapi/ethbackend.go +++ b/ethdb/privateapi/ethbackend.go @@ -70,6 +70,7 @@ type EthBackend interface { NetVersion() (uint64, error) NetPeerCount() (uint64, error) NodesInfo(limit int) (*remote.NodesInfoReply, error) + Peers(ctx context.Context) (*remote.PeersReply, error) } // This is the status of a newly execute block. @@ -616,6 +617,10 @@ func (s *EthBackendServer) NodeInfo(_ context.Context, r *remote.NodesInfoReques return nodesInfo, nil } +func (s *EthBackendServer) Peers(ctx context.Context, _ *emptypb.Empty) (*remote.PeersReply, error) { + return s.eth.Peers(ctx) +} + func (s *EthBackendServer) SubscribeLogs(server remote.ETHBACKEND_SubscribeLogsServer) (err error) { if s.logsFilter != nil { return s.logsFilter.subscribeLogs(server) diff --git a/go.mod b/go.mod index fdca244b31c..7810754ea32 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220423144324-c3b480409230 + github.com/ledgerwatch/erigon-lib v0.0.0-20220425121849-c73165f269e0 github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/pelletier/go-toml v1.9.5 diff --git a/go.sum b/go.sum index f23cf873e64..004977ff62b 100644 --- a/go.sum +++ b/go.sum @@ -454,8 +454,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220423144324-c3b480409230 h1:zcnLesdHt2/hLmCPo21zSzMcmhupkZfYp4GyesmodiY= -github.com/ledgerwatch/erigon-lib v0.0.0-20220423144324-c3b480409230/go.mod h1:0VKhW10UjEr7I6DaV+N0KNbXvMygC99qmRl2CfaN9gw= +github.com/ledgerwatch/erigon-lib v0.0.0-20220425121849-c73165f269e0 h1:nDbzAEItEqkoxjJrnegSGUrxJjuJatATww5QZT40hmo= +github.com/ledgerwatch/erigon-lib v0.0.0-20220425121849-c73165f269e0/go.mod h1:0VKhW10UjEr7I6DaV+N0KNbXvMygC99qmRl2CfaN9gw= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ=