go-ethereum/command/server/service.go
2021-12-02 12:28:26 +05:30

145 lines
3.8 KiB
Go

package server
import (
"context"
"encoding/hex"
"fmt"
"strings"
"github.com/ethereum/go-ethereum/command/server/pprof"
"github.com/ethereum/go-ethereum/command/server/proto"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
)
func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.PprofResponse, error) {
var payload []byte
var headers map[string]string
var err error
switch req.Type {
case proto.PprofRequest_CPU:
payload, headers, err = pprof.CPUProfile(ctx, int(req.Seconds))
case proto.PprofRequest_TRACE:
payload, headers, err = pprof.Trace(ctx, int(req.Seconds))
case proto.PprofRequest_LOOKUP:
payload, headers, err = pprof.Profile(req.Profile, 0, 0)
}
if err != nil {
return nil, err
}
resp := &proto.PprofResponse{
Payload: hex.EncodeToString(payload),
Headers: headers,
}
return resp, nil
}
func (s *Server) PeersAdd(ctx context.Context, req *proto.PeersAddRequest) (*proto.PeersAddResponse, error) {
node, err := enode.Parse(enode.ValidSchemes, req.Enode)
if err != nil {
return nil, fmt.Errorf("invalid enode: %v", err)
}
srv := s.node.Server()
if req.Trusted {
srv.AddTrustedPeer(node)
} else {
srv.AddPeer(node)
}
return &proto.PeersAddResponse{}, nil
}
func (s *Server) PeersRemove(ctx context.Context, req *proto.PeersRemoveRequest) (*proto.PeersRemoveResponse, error) {
node, err := enode.Parse(enode.ValidSchemes, req.Enode)
if err != nil {
return nil, fmt.Errorf("invalid enode: %v", err)
}
srv := s.node.Server()
if req.Trusted {
srv.RemoveTrustedPeer(node)
} else {
srv.RemovePeer(node)
}
return &proto.PeersRemoveResponse{}, nil
}
func (s *Server) PeersList(ctx context.Context, req *proto.PeersListRequest) (*proto.PeersListResponse, error) {
resp := &proto.PeersListResponse{}
peers := s.node.Server().PeersInfo()
for _, p := range peers {
resp.Peers = append(resp.Peers, peerInfoToPeer(p))
}
return resp, nil
}
func (s *Server) PeersStatus(ctx context.Context, req *proto.PeersStatusRequest) (*proto.PeersStatusResponse, error) {
var peerInfo *p2p.PeerInfo
for _, p := range s.node.Server().PeersInfo() {
if strings.HasPrefix(p.ID, req.Enode) {
if peerInfo != nil {
return nil, fmt.Errorf("more than one peer with the same prefix")
}
peerInfo = p
}
}
resp := &proto.PeersStatusResponse{}
if peerInfo != nil {
resp.Peer = peerInfoToPeer(peerInfo)
}
return resp, nil
}
func peerInfoToPeer(info *p2p.PeerInfo) *proto.Peer {
return &proto.Peer{
Id: info.ID,
Enode: info.Enode,
Enr: info.ENR,
Caps: info.Caps,
Name: info.Name,
Trusted: info.Network.Trusted,
Static: info.Network.Static,
}
}
func (s *Server) ChainSetHead(ctx context.Context, req *proto.ChainSetHeadRequest) (*proto.ChainSetHeadResponse, error) {
s.backend.APIBackend.SetHead(req.Number)
return &proto.ChainSetHeadResponse{}, nil
}
func ConvertBlockToBlockStub(blocks []*types.Block) []*proto.BlockStub {
var blockStubs []*proto.BlockStub
for _, block := range blocks {
blockStub := &proto.BlockStub{
Hash: block.Hash().String(),
Number: block.NumberU64(),
}
blockStubs = append(blockStubs, blockStub)
}
return blockStubs
}
func (s *Server) ChainWatch(req *proto.ChainWatchRequest, reply proto.Bor_ChainWatchServer) error {
// 1. start the feed to the blcokchain events
// 2. for each event send a proto.ChainWatchResponse
chain2HeadChanSize := 10
chain2HeadCh := make(chan core.Chain2HeadEvent, chain2HeadChanSize)
s.headSub = s.backend.APIBackend.SubscribeChain2HeadEvent(chain2HeadCh)
for {
msg := <-chain2HeadCh
fmt.Print(msg)
reply.Send(&proto.ChainWatchResponse{Type: msg.Type,
Newchain: ConvertBlockToBlockStub(msg.NewChain),
Oldchain: ConvertBlockToBlockStub(msg.OldChain),
})
}
}