github.com/gochain-io/gochain@v2.2.26+incompatible/node/service.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package node
    18  
    19  import (
    20  	"reflect"
    21  
    22  	"github.com/gochain-io/gochain/accounts"
    23  	"github.com/gochain-io/gochain/common"
    24  	"github.com/gochain-io/gochain/ethdb"
    25  	"github.com/gochain-io/gochain/ethdb/s3"
    26  	"github.com/gochain-io/gochain/event"
    27  	"github.com/gochain-io/gochain/log"
    28  	"github.com/gochain-io/gochain/p2p"
    29  	"github.com/gochain-io/gochain/rpc"
    30  )
    31  
    32  // ServiceContext is a collection of service independent options inherited from
    33  // the protocol stack, that is passed to all constructors to be optionally used;
    34  // as well as utility methods to operate on the service environment.
    35  type ServiceContext struct {
    36  	config         *Config
    37  	services       map[reflect.Type]Service // Index of the already constructed services
    38  	EventMux       *event.TypeMux           // Event multiplexer used for decoupled notifications
    39  	AccountManager *accounts.Manager        // Account manager created by the node.
    40  }
    41  
    42  // OpenDatabase opens an existing database with the given name (or creates one
    43  // if no previous can be found) from within the node's data directory. If the
    44  // node is an ephemeral one, a memory database is returned.
    45  func (ctx *ServiceContext) OpenDatabase(name string, cache int, handles int) (common.Database, error) {
    46  	if ctx.config.DataDir == "" {
    47  		return ethdb.NewMemDatabase(), nil
    48  	}
    49  	db := ethdb.NewDB(ctx.config.resolvePath(name))
    50  	if err := s3.ConfigureDB(db, ctx.config.Ethdb); err != nil {
    51  		return nil, err
    52  	}
    53  	if err := db.Open(); err != nil {
    54  		log.Error("Cannot open database in service context", "err", err)
    55  		return nil, err
    56  	}
    57  	return db, nil
    58  }
    59  
    60  // ResolvePath resolves a user path into the data directory if that was relative
    61  // and if the user actually uses persistent storage. It will return an empty string
    62  // for emphemeral storage and the user's own input for absolute paths.
    63  func (ctx *ServiceContext) ResolvePath(path string) string {
    64  	return ctx.config.resolvePath(path)
    65  }
    66  
    67  // Service retrieves a currently running service registered of a specific type.
    68  func (ctx *ServiceContext) Service(service interface{}) error {
    69  	element := reflect.ValueOf(service).Elem()
    70  	if running, ok := ctx.services[element.Type()]; ok {
    71  		element.Set(reflect.ValueOf(running))
    72  		return nil
    73  	}
    74  	return ErrServiceUnknown
    75  }
    76  
    77  // ServiceConstructor is the function signature of the constructors needed to be
    78  // registered for service instantiation.
    79  type ServiceConstructor func(ctx *ServiceContext) (Service, error)
    80  
    81  // Service is an individual protocol that can be registered into a node.
    82  //
    83  // Notes:
    84  //
    85  // • Service life-cycle management is delegated to the node. The service is allowed to
    86  // initialize itself upon creation, but no goroutines should be spun up outside of the
    87  // Start method.
    88  //
    89  // • Restart logic is not required as the node will create a fresh instance
    90  // every time a service is started.
    91  type Service interface {
    92  	// Protocols retrieves the P2P protocols the service wishes to start.
    93  	Protocols() []p2p.Protocol
    94  
    95  	// APIs retrieves the list of RPC descriptors the service provides
    96  	APIs() []rpc.API
    97  
    98  	// Start is called after all services have been constructed and the networking
    99  	// layer was also initialized to spawn any goroutines required by the service.
   100  	Start(server *p2p.Server) error
   101  
   102  	// Stop terminates all goroutines belonging to the service, blocking until they
   103  	// are all terminated.
   104  	Stop() error
   105  }