github.com/klaytn/klaytn@v1.12.1/node/service.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2014 The go-ethereum Authors
     3  // This file is part of go-ethereum.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from node/service.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package node
    22  
    23  import (
    24  	"crypto/ecdsa"
    25  	"reflect"
    26  
    27  	"github.com/klaytn/klaytn/accounts"
    28  	"github.com/klaytn/klaytn/common"
    29  	"github.com/klaytn/klaytn/crypto/bls"
    30  	"github.com/klaytn/klaytn/event"
    31  	"github.com/klaytn/klaytn/networks/p2p"
    32  	"github.com/klaytn/klaytn/networks/rpc"
    33  	"github.com/klaytn/klaytn/storage/database"
    34  )
    35  
    36  type ServiceContext struct {
    37  	config         *Config
    38  	services       map[reflect.Type]Service
    39  	EventMux       *event.TypeMux
    40  	AccountManager *accounts.Manager
    41  }
    42  
    43  func NewServiceContext(conf *Config, srv map[reflect.Type]Service, mux *event.TypeMux, am *accounts.Manager) *ServiceContext {
    44  	return &ServiceContext{conf, srv, mux, am}
    45  }
    46  
    47  // OpenDatabase opens an existing database with the given name (or creates one
    48  // if no previous can be found) from within the node's data directory. If the
    49  // node is an ephemeral one, a memory database is returned.
    50  func (ctx *ServiceContext) OpenDatabase(dbc *database.DBConfig) database.DBManager {
    51  	if ctx.config.DataDir == "" {
    52  		return database.NewMemoryDBManager()
    53  	}
    54  	dbc.Dir = ctx.config.ResolvePath(dbc.Dir)
    55  	return database.NewDBManager(dbc)
    56  }
    57  
    58  // ResolvePath resolves a user path into the data directory if that was relative
    59  // and if the user actually uses persistent storage. It will return an empty string
    60  // for emphemeral storage and the user's own input for absolute paths.
    61  func (ctx *ServiceContext) ResolvePath(path string) string {
    62  	return ctx.config.ResolvePath(path)
    63  }
    64  
    65  // Service retrieves a currently running service registered of a specific type.
    66  func (ctx *ServiceContext) Service(service interface{}) error {
    67  	element := reflect.ValueOf(service).Elem()
    68  	if running, ok := ctx.services[element.Type()]; ok {
    69  		element.Set(reflect.ValueOf(running))
    70  		return nil
    71  	}
    72  	return ErrServiceUnknown
    73  }
    74  
    75  // NodeKey returns node key from config
    76  func (ctx *ServiceContext) NodeKey() *ecdsa.PrivateKey {
    77  	return ctx.config.NodeKey()
    78  }
    79  
    80  func (ctx *ServiceContext) BlsNodeKey() bls.SecretKey {
    81  	return ctx.config.BlsNodeKey()
    82  }
    83  
    84  func (ctx *ServiceContext) NodeType() common.ConnType {
    85  	return ctx.config.P2P.ConnectionType
    86  }
    87  
    88  // ServiceConstructor is the function signature of the constructors needed to be
    89  // registered for service instantiation.
    90  type ServiceConstructor func(ctx *ServiceContext) (Service, error)
    91  
    92  // Service is an individual protocol that can be registered into a node.
    93  //
    94  // Notes:
    95  //
    96  // • Service life-cycle management is delegated to the node. The service is allowed to
    97  // initialize itself upon creation, but no goroutines should be spun up outside of the
    98  // Start method.
    99  //
   100  // • Restart logic is not required as the node will create a fresh instance
   101  // every time a service is started.
   102  type Service interface {
   103  	// Protocols retrieves the P2P protocols the service wishes to start.
   104  	Protocols() []p2p.Protocol
   105  
   106  	// APIs retrieves the list of RPC descriptors the service provides
   107  	APIs() []rpc.API
   108  
   109  	// Start is called after all services have been constructed and the networking
   110  	// layer was also initialized to spawn any goroutines required by the service.
   111  	Start(server p2p.Server) error
   112  
   113  	// Stop terminates all goroutines belonging to the service, blocking until they
   114  	// are all terminated.
   115  	Stop() error
   116  
   117  	// retrieve components (blockchain, txpool, ..) from core service
   118  	Components() []interface{}
   119  
   120  	// set components (blockchain, txpool, ..) in core service
   121  	SetComponents(components []interface{})
   122  }