LoginSignup
1
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-09-11

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
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0