Help us understand the problem. What is going on with this article?

go-ethereumを読む(6) 補足 Service

More than 1 year has passed since last update.

gethではPluggableな実装になっており、serviceという単位でプログラム内では扱われています。
EthServiceがEthereumのコア機能をになっています。
v1.8.15ベースに解説します

具体例 サービスを登録しているプログラム

// cmd/utils/flags.go
// RegisterEthService adds an Ethereum client to the stack.
func RegisterEthService(stack *node.Node, cfg *eth.Config) {
    var err error
    if cfg.SyncMode == downloader.LightSync {
        err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
            return les.New(ctx, cfg)
        })
    } else {
        err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
            fullNode, err := eth.New(ctx, cfg)
            if fullNode != nil && cfg.LightServ > 0 {
                ls, _ := les.NewLesServer(fullNode, cfg)
                fullNode.AddLesServer(ls)
            }
            return fullNode, err
        })
    }
    if err != nil {
        Fatalf("Failed to register the Ethereum service: %v", err)
    }
}

// RegisterDashboardService adds a dashboard to the stack.
func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) {
    stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
        return dashboard.New(cfg, commit, ctx.ResolvePath("logs")), nil
    })
}

// RegisterShhService configures Whisper and adds it to the given node.
func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
    if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
        return whisper.New(cfg), nil
    }); err != nil {
        Fatalf("Failed to register the Whisper service: %v", err)
    }
}

ServiceContext

ServiceContextがservicesをmapで保持している

type ServiceContext struct {
    config         *Config
    services       map[reflect.Type]Service // Index of the already constructed services
    EventMux       *event.TypeMux           // Event multiplexer used for decoupled notifications
    AccountManager *accounts.Manager        // Account manager created by the node.
}

func (ctx *ServiceContext) Service(service interface{}) error {
    element := reflect.ValueOf(service).Elem()
    if running, ok := ctx.services[element.Type()]; ok {
        element.Set(reflect.ValueOf(running))
        return nil
    }
    return ErrServiceUnknown
}

type ServiceConstructor func(ctx *ServiceContext) (Service, error)

// Serviceに必要なinterface
type Service interface {
    // Protocols retrieves the P2P protocols the service wishes to start.
    Protocols() []p2p.Protocol

    // APIs retrieves the list of RPC descriptors the service provides
    APIs() []rpc.API

    // Start is called after all services have been constructed and the networking
    // layer was also initialized to spawn any goroutines required by the service.
    Start(server *p2p.Server) error

    // Stop terminates all goroutines belonging to the service, blocking until they
    // are all terminated.
    Stop() error
}
t10471
mercari
フリマアプリ「メルカリ」を、グローバルで開発しています。
https://tech.mercari.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away