erigon-pulse/ethdb/remote/remotedbserver/ethbackend.go
mempirate ca926ce94d
net_peerCount for remote sentries (#2192)
* net_peerCount for remote sentries

* cleanup

* Simplify NetPeerCount using SentryClient

* Refactor id -> count
2021-06-18 14:34:15 +01:00

118 lines
3.7 KiB
Go

package remotedbserver
import (
"bytes"
"context"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/gointerfaces"
"github.com/ledgerwatch/erigon/gointerfaces/remote"
types2 "github.com/ledgerwatch/erigon/gointerfaces/types"
"github.com/ledgerwatch/erigon/log"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/rlp"
"google.golang.org/protobuf/types/known/emptypb"
)
// EthBackendAPIVersion
// 2.0.0 - move all mining-related methods to 'txpool/mining' server
// 2.1.0 - add NetPeerCount function
var EthBackendAPIVersion = &types2.VersionReply{Major: 2, Minor: 1, Patch: 0}
type EthBackendServer struct {
remote.UnimplementedETHBACKENDServer // must be embedded to have forward compatible implementations.
eth EthBackend
events *Events
}
type EthBackend interface {
Etherbase() (common.Address, error)
NetVersion() (uint64, error)
NetPeerCount() (uint64, error)
}
func NewEthBackendServer(eth EthBackend, events *Events) *EthBackendServer {
return &EthBackendServer{eth: eth, events: events}
}
func (s *EthBackendServer) Version(context.Context, *emptypb.Empty) (*types2.VersionReply, error) {
return EthBackendAPIVersion, nil
}
func (s *EthBackendServer) Etherbase(_ context.Context, _ *remote.EtherbaseRequest) (*remote.EtherbaseReply, error) {
out := &remote.EtherbaseReply{Address: gointerfaces.ConvertAddressToH160(common.Address{})}
base, err := s.eth.Etherbase()
if err != nil {
return out, err
}
out.Address = gointerfaces.ConvertAddressToH160(base)
return out, nil
}
func (s *EthBackendServer) NetVersion(_ context.Context, _ *remote.NetVersionRequest) (*remote.NetVersionReply, error) {
id, err := s.eth.NetVersion()
if err != nil {
return &remote.NetVersionReply{}, err
}
return &remote.NetVersionReply{Id: id}, nil
}
func (s *EthBackendServer) NetPeerCount(_ context.Context, _ *remote.NetPeerCountRequest) (*remote.NetPeerCountReply, error) {
id, err := s.eth.NetPeerCount()
if err != nil {
return &remote.NetPeerCountReply{}, err
}
return &remote.NetPeerCountReply{Count: id}, nil
}
func (s *EthBackendServer) Subscribe(r *remote.SubscribeRequest, subscribeServer remote.ETHBACKEND_SubscribeServer) error {
log.Debug("establishing event subscription channel with the RPC daemon")
s.events.AddHeaderSubscription(func(h *types.Header) error {
select {
case <-subscribeServer.Context().Done():
return subscribeServer.Context().Err()
default:
}
var buf bytes.Buffer
if err := rlp.Encode(&buf, h); err != nil {
log.Warn("error while marshaling a header", "err", err)
return err
}
payload := buf.Bytes()
err := subscribeServer.Send(&remote.SubscribeReply{
Type: remote.Event_HEADER,
Data: payload,
})
// we only close the wg on error because if we successfully sent an event,
// that means that the channel wasn't closed and is ready to
// receive more events.
// if rpcdaemon disconnects, we will receive an error here
// next time we try to send an event
if err != nil {
log.Info("event subscription channel was closed", "reason", err)
}
return err
})
log.Info("event subscription channel established with the RPC daemon")
<-subscribeServer.Context().Done()
log.Info("event subscription channel closed with the RPC daemon")
return nil
}
func (s *EthBackendServer) ProtocolVersion(_ context.Context, _ *remote.ProtocolVersionRequest) (*remote.ProtocolVersionReply, error) {
// Hardcoding to avoid import cycle
return &remote.ProtocolVersionReply{Id: 66}, nil
}
func (s *EthBackendServer) ClientVersion(_ context.Context, _ *remote.ClientVersionRequest) (*remote.ClientVersionReply, error) {
return &remote.ClientVersionReply{NodeName: common.MakeName("Erigon", params.VersionWithCommit(params.GitCommit, ""))}, nil
}