github.com/zhiqiangxu/go-ethereum@v1.9.16-0.20210824055606-be91cfdebc48/node/node.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  	"context"
    21  	"errors"
    22  	"fmt"
    23  	"net"
    24  	"net/http"
    25  	"os"
    26  	"path/filepath"
    27  	"reflect"
    28  	"strings"
    29  	"sync"
    30  
    31  	"github.com/prometheus/tsdb/fileutil"
    32  	"github.com/zhiqiangxu/go-ethereum/accounts"
    33  	"github.com/zhiqiangxu/go-ethereum/core/rawdb"
    34  	"github.com/zhiqiangxu/go-ethereum/ethdb"
    35  	"github.com/zhiqiangxu/go-ethereum/event"
    36  	"github.com/zhiqiangxu/go-ethereum/internal/debug"
    37  	"github.com/zhiqiangxu/go-ethereum/log"
    38  	"github.com/zhiqiangxu/go-ethereum/p2p"
    39  	"github.com/zhiqiangxu/go-ethereum/rpc"
    40  )
    41  
    42  // Node is a container on which services can be registered.
    43  type Node struct {
    44  	eventmux *event.TypeMux // Event multiplexer used between the services of a stack
    45  	config   *Config
    46  	accman   *accounts.Manager
    47  
    48  	ephemeralKeystore string            // if non-empty, the key directory that will be removed by Stop
    49  	instanceDirLock   fileutil.Releaser // prevents concurrent use of instance directory
    50  
    51  	serverConfig p2p.Config
    52  	server       *p2p.Server // Currently running P2P networking layer
    53  
    54  	serviceFuncs []ServiceConstructor     // Service constructors (in dependency order)
    55  	services     map[reflect.Type]Service // Currently running services
    56  
    57  	rpcAPIs       []rpc.API   // List of APIs currently provided by the node
    58  	inprocHandler *rpc.Server // In-process RPC request handler to process the API requests
    59  
    60  	ipcEndpoint string       // IPC endpoint to listen at (empty = IPC disabled)
    61  	ipcListener net.Listener // IPC RPC listener socket to serve API requests
    62  	ipcHandler  *rpc.Server  // IPC RPC request handler to process the API requests
    63  
    64  	httpEndpoint     string       // HTTP endpoint (interface + port) to listen at (empty = HTTP disabled)
    65  	httpWhitelist    []string     // HTTP RPC modules to allow through this endpoint
    66  	httpListenerAddr net.Addr     // Address of HTTP RPC listener socket serving API requests
    67  	httpServer       *http.Server // HTTP RPC HTTP server
    68  	httpHandler      *rpc.Server  // HTTP RPC request handler to process the API requests
    69  
    70  	wsEndpoint     string       // WebSocket endpoint (interface + port) to listen at (empty = WebSocket disabled)
    71  	wsListenerAddr net.Addr     // Address of WebSocket RPC listener socket serving API requests
    72  	wsHTTPServer   *http.Server // WebSocket RPC HTTP server
    73  	wsHandler      *rpc.Server  // WebSocket RPC request handler to process the API requests
    74  
    75  	stop chan struct{} // Channel to wait for termination notifications
    76  	lock sync.RWMutex
    77  
    78  	log log.Logger
    79  }
    80  
    81  // New creates a new P2P node, ready for protocol registration.
    82  func New(conf *Config) (*Node, error) {
    83  	// Copy config and resolve the datadir so future changes to the current
    84  	// working directory don't affect the node.
    85  	confCopy := *conf
    86  	conf = &confCopy
    87  	if conf.DataDir != "" {
    88  		absdatadir, err := filepath.Abs(conf.DataDir)
    89  		if err != nil {
    90  			return nil, err
    91  		}
    92  		conf.DataDir = absdatadir
    93  	}
    94  	// Ensure that the instance name doesn't cause weird conflicts with
    95  	// other files in the data directory.
    96  	if strings.ContainsAny(conf.Name, `/\`) {
    97  		return nil, errors.New(`Config.Name must not contain '/' or '\'`)
    98  	}
    99  	if conf.Name == datadirDefaultKeyStore {
   100  		return nil, errors.New(`Config.Name cannot be "` + datadirDefaultKeyStore + `"`)
   101  	}
   102  	if strings.HasSuffix(conf.Name, ".ipc") {
   103  		return nil, errors.New(`Config.Name cannot end in ".ipc"`)
   104  	}
   105  	// Ensure that the AccountManager method works before the node has started.
   106  	// We rely on this in cmd/geth.
   107  	am, ephemeralKeystore, err := makeAccountManager(conf)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  	if conf.Logger == nil {
   112  		conf.Logger = log.New()
   113  	}
   114  	// Note: any interaction with Config that would create/touch files
   115  	// in the data directory or instance directory is delayed until Start.
   116  	return &Node{
   117  		accman:            am,
   118  		ephemeralKeystore: ephemeralKeystore,
   119  		config:            conf,
   120  		serviceFuncs:      []ServiceConstructor{},
   121  		ipcEndpoint:       conf.IPCEndpoint(),
   122  		httpEndpoint:      conf.HTTPEndpoint(),
   123  		wsEndpoint:        conf.WSEndpoint(),
   124  		eventmux:          new(event.TypeMux),
   125  		log:               conf.Logger,
   126  	}, nil
   127  }
   128  
   129  // Close stops the Node and releases resources acquired in
   130  // Node constructor New.
   131  func (n *Node) Close() error {
   132  	var errs []error
   133  
   134  	// Terminate all subsystems and collect any errors
   135  	if err := n.Stop(); err != nil && err != ErrNodeStopped {
   136  		errs = append(errs, err)
   137  	}
   138  	if err := n.accman.Close(); err != nil {
   139  		errs = append(errs, err)
   140  	}
   141  	// Report any errors that might have occurred
   142  	switch len(errs) {
   143  	case 0:
   144  		return nil
   145  	case 1:
   146  		return errs[0]
   147  	default:
   148  		return fmt.Errorf("%v", errs)
   149  	}
   150  }
   151  
   152  // Register injects a new service into the node's stack. The service created by
   153  // the passed constructor must be unique in its type with regard to sibling ones.
   154  func (n *Node) Register(constructor ServiceConstructor) error {
   155  	n.lock.Lock()
   156  	defer n.lock.Unlock()
   157  
   158  	if n.server != nil {
   159  		return ErrNodeRunning
   160  	}
   161  	n.serviceFuncs = append(n.serviceFuncs, constructor)
   162  	return nil
   163  }
   164  
   165  // Start creates a live P2P node and starts running it.
   166  func (n *Node) Start() error {
   167  	n.lock.Lock()
   168  	defer n.lock.Unlock()
   169  
   170  	// Short circuit if the node's already running
   171  	if n.server != nil {
   172  		return ErrNodeRunning
   173  	}
   174  	if err := n.openDataDir(); err != nil {
   175  		return err
   176  	}
   177  
   178  	// Initialize the p2p server. This creates the node key and
   179  	// discovery databases.
   180  	n.serverConfig = n.config.P2P
   181  	n.serverConfig.PrivateKey = n.config.NodeKey()
   182  	n.serverConfig.Name = n.config.NodeName()
   183  	n.serverConfig.Logger = n.log
   184  	if n.serverConfig.StaticNodes == nil {
   185  		n.serverConfig.StaticNodes = n.config.StaticNodes()
   186  	}
   187  	if n.serverConfig.TrustedNodes == nil {
   188  		n.serverConfig.TrustedNodes = n.config.TrustedNodes()
   189  	}
   190  	if n.serverConfig.NodeDatabase == "" {
   191  		n.serverConfig.NodeDatabase = n.config.NodeDB()
   192  	}
   193  	running := &p2p.Server{Config: n.serverConfig}
   194  	n.log.Info("Starting peer-to-peer node", "instance", n.serverConfig.Name)
   195  
   196  	// Otherwise copy and specialize the P2P configuration
   197  	services := make(map[reflect.Type]Service)
   198  	for _, constructor := range n.serviceFuncs {
   199  		// Create a new context for the particular service
   200  		ctx := &ServiceContext{
   201  			Config:         *n.config,
   202  			services:       make(map[reflect.Type]Service),
   203  			EventMux:       n.eventmux,
   204  			AccountManager: n.accman,
   205  		}
   206  		for kind, s := range services { // copy needed for threaded access
   207  			ctx.services[kind] = s
   208  		}
   209  		// Construct and save the service
   210  		service, err := constructor(ctx)
   211  		if err != nil {
   212  			return err
   213  		}
   214  		kind := reflect.TypeOf(service)
   215  		if _, exists := services[kind]; exists {
   216  			return &DuplicateServiceError{Kind: kind}
   217  		}
   218  		services[kind] = service
   219  	}
   220  	// Gather the protocols and start the freshly assembled P2P server
   221  	for _, service := range services {
   222  		running.Protocols = append(running.Protocols, service.Protocols()...)
   223  	}
   224  	if err := running.Start(); err != nil {
   225  		return convertFileLockError(err)
   226  	}
   227  	// Start each of the services
   228  	var started []reflect.Type
   229  	for kind, service := range services {
   230  		// Start the next service, stopping all previous upon failure
   231  		if err := service.Start(running); err != nil {
   232  			for _, kind := range started {
   233  				services[kind].Stop()
   234  			}
   235  			running.Stop()
   236  
   237  			return err
   238  		}
   239  		// Mark the service started for potential cleanup
   240  		started = append(started, kind)
   241  	}
   242  	// Lastly, start the configured RPC interfaces
   243  	if err := n.startRPC(services); err != nil {
   244  		for _, service := range services {
   245  			service.Stop()
   246  		}
   247  		running.Stop()
   248  		return err
   249  	}
   250  	// Finish initializing the startup
   251  	n.services = services
   252  	n.server = running
   253  	n.stop = make(chan struct{})
   254  	return nil
   255  }
   256  
   257  // Config returns the configuration of node.
   258  func (n *Node) Config() *Config {
   259  	return n.config
   260  }
   261  
   262  func (n *Node) openDataDir() error {
   263  	if n.config.DataDir == "" {
   264  		return nil // ephemeral
   265  	}
   266  
   267  	instdir := filepath.Join(n.config.DataDir, n.config.name())
   268  	if err := os.MkdirAll(instdir, 0700); err != nil {
   269  		return err
   270  	}
   271  	// Lock the instance directory to prevent concurrent use by another instance as well as
   272  	// accidental use of the instance directory as a database.
   273  	release, _, err := fileutil.Flock(filepath.Join(instdir, "LOCK"))
   274  	if err != nil {
   275  		return convertFileLockError(err)
   276  	}
   277  	n.instanceDirLock = release
   278  	return nil
   279  }
   280  
   281  // startRPC is a helper method to start all the various RPC endpoints during node
   282  // startup. It's not meant to be called at any time afterwards as it makes certain
   283  // assumptions about the state of the node.
   284  func (n *Node) startRPC(services map[reflect.Type]Service) error {
   285  	// Gather all the possible APIs to surface
   286  	apis := n.apis()
   287  	for _, service := range services {
   288  		apis = append(apis, service.APIs()...)
   289  	}
   290  	// Start the various API endpoints, terminating all in case of errors
   291  	if err := n.startInProc(apis); err != nil {
   292  		return err
   293  	}
   294  	if err := n.startIPC(apis); err != nil {
   295  		n.stopInProc()
   296  		return err
   297  	}
   298  	if err := n.startHTTP(n.httpEndpoint, apis, n.config.HTTPModules, n.config.HTTPCors, n.config.HTTPVirtualHosts, n.config.HTTPTimeouts, n.config.WSOrigins); err != nil {
   299  		n.stopIPC()
   300  		n.stopInProc()
   301  		return err
   302  	}
   303  	// if endpoints are not the same, start separate servers
   304  	if n.httpEndpoint != n.wsEndpoint {
   305  		if err := n.startWS(n.wsEndpoint, apis, n.config.WSModules, n.config.WSOrigins, n.config.WSExposeAll); err != nil {
   306  			n.stopHTTP()
   307  			n.stopIPC()
   308  			n.stopInProc()
   309  			return err
   310  		}
   311  	}
   312  
   313  	// All API endpoints started successfully
   314  	n.rpcAPIs = apis
   315  	return nil
   316  }
   317  
   318  // startInProc initializes an in-process RPC endpoint.
   319  func (n *Node) startInProc(apis []rpc.API) error {
   320  	// Register all the APIs exposed by the services
   321  	handler := rpc.NewServer()
   322  	for _, api := range apis {
   323  		if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
   324  			return err
   325  		}
   326  		n.log.Debug("InProc registered", "namespace", api.Namespace)
   327  	}
   328  	n.inprocHandler = handler
   329  	return nil
   330  }
   331  
   332  // stopInProc terminates the in-process RPC endpoint.
   333  func (n *Node) stopInProc() {
   334  	if n.inprocHandler != nil {
   335  		n.inprocHandler.Stop()
   336  		n.inprocHandler = nil
   337  	}
   338  }
   339  
   340  // startIPC initializes and starts the IPC RPC endpoint.
   341  func (n *Node) startIPC(apis []rpc.API) error {
   342  	if n.ipcEndpoint == "" {
   343  		return nil // IPC disabled.
   344  	}
   345  	listener, handler, err := rpc.StartIPCEndpoint(n.ipcEndpoint, apis)
   346  	if err != nil {
   347  		return err
   348  	}
   349  	n.ipcListener = listener
   350  	n.ipcHandler = handler
   351  	n.log.Info("IPC endpoint opened", "url", n.ipcEndpoint)
   352  	return nil
   353  }
   354  
   355  // stopIPC terminates the IPC RPC endpoint.
   356  func (n *Node) stopIPC() {
   357  	if n.ipcListener != nil {
   358  		n.ipcListener.Close()
   359  		n.ipcListener = nil
   360  
   361  		n.log.Info("IPC endpoint closed", "url", n.ipcEndpoint)
   362  	}
   363  	if n.ipcHandler != nil {
   364  		n.ipcHandler.Stop()
   365  		n.ipcHandler = nil
   366  	}
   367  }
   368  
   369  // startHTTP initializes and starts the HTTP RPC endpoint.
   370  func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts, wsOrigins []string) error {
   371  	// Short circuit if the HTTP endpoint isn't being exposed
   372  	if endpoint == "" {
   373  		return nil
   374  	}
   375  	// register apis and create handler stack
   376  	srv := rpc.NewServer()
   377  	err := RegisterApisFromWhitelist(apis, modules, srv, false)
   378  	if err != nil {
   379  		return err
   380  	}
   381  	handler := NewHTTPHandlerStack(srv, cors, vhosts)
   382  	// wrap handler in WebSocket handler only if WebSocket port is the same as http rpc
   383  	if n.httpEndpoint == n.wsEndpoint {
   384  		handler = NewWebsocketUpgradeHandler(handler, srv.WebsocketHandler(wsOrigins))
   385  	}
   386  	httpServer, addr, err := StartHTTPEndpoint(endpoint, timeouts, handler)
   387  	if err != nil {
   388  		return err
   389  	}
   390  	n.log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%v/", addr),
   391  		"cors", strings.Join(cors, ","),
   392  		"vhosts", strings.Join(vhosts, ","))
   393  	if n.httpEndpoint == n.wsEndpoint {
   394  		n.log.Info("WebSocket endpoint opened", "url", fmt.Sprintf("ws://%v", addr))
   395  	}
   396  	// All listeners booted successfully
   397  	n.httpEndpoint = endpoint
   398  	n.httpListenerAddr = addr
   399  	n.httpServer = httpServer
   400  	n.httpHandler = srv
   401  
   402  	return nil
   403  }
   404  
   405  // stopHTTP terminates the HTTP RPC endpoint.
   406  func (n *Node) stopHTTP() {
   407  	if n.httpServer != nil {
   408  		// Don't bother imposing a timeout here.
   409  		n.httpServer.Shutdown(context.Background())
   410  		n.log.Info("HTTP endpoint closed", "url", fmt.Sprintf("http://%v/", n.httpListenerAddr))
   411  	}
   412  	if n.httpHandler != nil {
   413  		n.httpHandler.Stop()
   414  		n.httpHandler = nil
   415  	}
   416  }
   417  
   418  // startWS initializes and starts the WebSocket RPC endpoint.
   419  func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrigins []string, exposeAll bool) error {
   420  	// Short circuit if the WS endpoint isn't being exposed
   421  	if endpoint == "" {
   422  		return nil
   423  	}
   424  
   425  	srv := rpc.NewServer()
   426  	handler := srv.WebsocketHandler(wsOrigins)
   427  	err := RegisterApisFromWhitelist(apis, modules, srv, exposeAll)
   428  	if err != nil {
   429  		return err
   430  	}
   431  	httpServer, addr, err := startWSEndpoint(endpoint, handler)
   432  	if err != nil {
   433  		return err
   434  	}
   435  	n.log.Info("WebSocket endpoint opened", "url", fmt.Sprintf("ws://%v", addr))
   436  	// All listeners booted successfully
   437  	n.wsEndpoint = endpoint
   438  	n.wsListenerAddr = addr
   439  	n.wsHTTPServer = httpServer
   440  	n.wsHandler = srv
   441  
   442  	return nil
   443  }
   444  
   445  // stopWS terminates the WebSocket RPC endpoint.
   446  func (n *Node) stopWS() {
   447  	if n.wsHTTPServer != nil {
   448  		// Don't bother imposing a timeout here.
   449  		n.wsHTTPServer.Shutdown(context.Background())
   450  		n.log.Info("WebSocket endpoint closed", "url", fmt.Sprintf("ws://%v", n.wsListenerAddr))
   451  	}
   452  	if n.wsHandler != nil {
   453  		n.wsHandler.Stop()
   454  		n.wsHandler = nil
   455  	}
   456  }
   457  
   458  // Stop terminates a running node along with all it's services. In the node was
   459  // not started, an error is returned.
   460  func (n *Node) Stop() error {
   461  	n.lock.Lock()
   462  	defer n.lock.Unlock()
   463  
   464  	// Short circuit if the node's not running
   465  	if n.server == nil {
   466  		return ErrNodeStopped
   467  	}
   468  
   469  	// Terminate the API, services and the p2p server.
   470  	n.stopWS()
   471  	n.stopHTTP()
   472  	n.stopIPC()
   473  	n.rpcAPIs = nil
   474  	failure := &StopError{
   475  		Services: make(map[reflect.Type]error),
   476  	}
   477  	for kind, service := range n.services {
   478  		if err := service.Stop(); err != nil {
   479  			failure.Services[kind] = err
   480  		}
   481  	}
   482  	n.server.Stop()
   483  	n.services = nil
   484  	n.server = nil
   485  
   486  	// Release instance directory lock.
   487  	if n.instanceDirLock != nil {
   488  		if err := n.instanceDirLock.Release(); err != nil {
   489  			n.log.Error("Can't release datadir lock", "err", err)
   490  		}
   491  		n.instanceDirLock = nil
   492  	}
   493  
   494  	// unblock n.Wait
   495  	close(n.stop)
   496  
   497  	// Remove the keystore if it was created ephemerally.
   498  	var keystoreErr error
   499  	if n.ephemeralKeystore != "" {
   500  		keystoreErr = os.RemoveAll(n.ephemeralKeystore)
   501  	}
   502  
   503  	if len(failure.Services) > 0 {
   504  		return failure
   505  	}
   506  	if keystoreErr != nil {
   507  		return keystoreErr
   508  	}
   509  	return nil
   510  }
   511  
   512  // Wait blocks the thread until the node is stopped. If the node is not running
   513  // at the time of invocation, the method immediately returns.
   514  func (n *Node) Wait() {
   515  	n.lock.RLock()
   516  	if n.server == nil {
   517  		n.lock.RUnlock()
   518  		return
   519  	}
   520  	stop := n.stop
   521  	n.lock.RUnlock()
   522  
   523  	<-stop
   524  }
   525  
   526  // Restart terminates a running node and boots up a new one in its place. If the
   527  // node isn't running, an error is returned.
   528  func (n *Node) Restart() error {
   529  	if err := n.Stop(); err != nil {
   530  		return err
   531  	}
   532  	if err := n.Start(); err != nil {
   533  		return err
   534  	}
   535  	return nil
   536  }
   537  
   538  // Attach creates an RPC client attached to an in-process API handler.
   539  func (n *Node) Attach() (*rpc.Client, error) {
   540  	n.lock.RLock()
   541  	defer n.lock.RUnlock()
   542  
   543  	if n.server == nil {
   544  		return nil, ErrNodeStopped
   545  	}
   546  	return rpc.DialInProc(n.inprocHandler), nil
   547  }
   548  
   549  // RPCHandler returns the in-process RPC request handler.
   550  func (n *Node) RPCHandler() (*rpc.Server, error) {
   551  	n.lock.RLock()
   552  	defer n.lock.RUnlock()
   553  
   554  	if n.inprocHandler == nil {
   555  		return nil, ErrNodeStopped
   556  	}
   557  	return n.inprocHandler, nil
   558  }
   559  
   560  // Server retrieves the currently running P2P network layer. This method is meant
   561  // only to inspect fields of the currently running server, life cycle management
   562  // should be left to this Node entity.
   563  func (n *Node) Server() *p2p.Server {
   564  	n.lock.RLock()
   565  	defer n.lock.RUnlock()
   566  
   567  	return n.server
   568  }
   569  
   570  // Service retrieves a currently running service registered of a specific type.
   571  func (n *Node) Service(service interface{}) error {
   572  	n.lock.RLock()
   573  	defer n.lock.RUnlock()
   574  
   575  	// Short circuit if the node's not running
   576  	if n.server == nil {
   577  		return ErrNodeStopped
   578  	}
   579  	// Otherwise try to find the service to return
   580  	element := reflect.ValueOf(service).Elem()
   581  	if running, ok := n.services[element.Type()]; ok {
   582  		element.Set(reflect.ValueOf(running))
   583  		return nil
   584  	}
   585  	return ErrServiceUnknown
   586  }
   587  
   588  // DataDir retrieves the current datadir used by the protocol stack.
   589  // Deprecated: No files should be stored in this directory, use InstanceDir instead.
   590  func (n *Node) DataDir() string {
   591  	return n.config.DataDir
   592  }
   593  
   594  // InstanceDir retrieves the instance directory used by the protocol stack.
   595  func (n *Node) InstanceDir() string {
   596  	return n.config.instanceDir()
   597  }
   598  
   599  // AccountManager retrieves the account manager used by the protocol stack.
   600  func (n *Node) AccountManager() *accounts.Manager {
   601  	return n.accman
   602  }
   603  
   604  // IPCEndpoint retrieves the current IPC endpoint used by the protocol stack.
   605  func (n *Node) IPCEndpoint() string {
   606  	return n.ipcEndpoint
   607  }
   608  
   609  // HTTPEndpoint retrieves the current HTTP endpoint used by the protocol stack.
   610  func (n *Node) HTTPEndpoint() string {
   611  	n.lock.Lock()
   612  	defer n.lock.Unlock()
   613  
   614  	if n.httpListenerAddr != nil {
   615  		return n.httpListenerAddr.String()
   616  	}
   617  	return n.httpEndpoint
   618  }
   619  
   620  // WSEndpoint retrieves the current WS endpoint used by the protocol stack.
   621  func (n *Node) WSEndpoint() string {
   622  	n.lock.Lock()
   623  	defer n.lock.Unlock()
   624  
   625  	if n.wsListenerAddr != nil {
   626  		return n.wsListenerAddr.String()
   627  	}
   628  	return n.wsEndpoint
   629  }
   630  
   631  // EventMux retrieves the event multiplexer used by all the network services in
   632  // the current protocol stack.
   633  func (n *Node) EventMux() *event.TypeMux {
   634  	return n.eventmux
   635  }
   636  
   637  // OpenDatabase opens an existing database with the given name (or creates one if no
   638  // previous can be found) from within the node's instance directory. If the node is
   639  // ephemeral, a memory database is returned.
   640  func (n *Node) OpenDatabase(name string, cache, handles int, namespace string) (ethdb.Database, error) {
   641  	if n.config.DataDir == "" {
   642  		return rawdb.NewMemoryDatabase(), nil
   643  	}
   644  	return rawdb.NewLevelDBDatabase(n.config.ResolvePath(name), cache, handles, namespace)
   645  }
   646  
   647  // OpenDatabaseWithFreezer opens an existing database with the given name (or
   648  // creates one if no previous can be found) from within the node's data directory,
   649  // also attaching a chain freezer to it that moves ancient chain data from the
   650  // database to immutable append-only files. If the node is an ephemeral one, a
   651  // memory database is returned.
   652  func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, freezer, namespace string) (ethdb.Database, error) {
   653  	if n.config.DataDir == "" {
   654  		return rawdb.NewMemoryDatabase(), nil
   655  	}
   656  	root := n.config.ResolvePath(name)
   657  
   658  	switch {
   659  	case freezer == "":
   660  		freezer = filepath.Join(root, "ancient")
   661  	case !filepath.IsAbs(freezer):
   662  		freezer = n.config.ResolvePath(freezer)
   663  	}
   664  	return rawdb.NewLevelDBDatabaseWithFreezer(root, cache, handles, freezer, namespace)
   665  }
   666  
   667  // ResolvePath returns the absolute path of a resource in the instance directory.
   668  func (n *Node) ResolvePath(x string) string {
   669  	return n.config.ResolvePath(x)
   670  }
   671  
   672  // apis returns the collection of RPC descriptors this node offers.
   673  func (n *Node) apis() []rpc.API {
   674  	return []rpc.API{
   675  		{
   676  			Namespace: "admin",
   677  			Version:   "1.0",
   678  			Service:   NewPrivateAdminAPI(n),
   679  		}, {
   680  			Namespace: "admin",
   681  			Version:   "1.0",
   682  			Service:   NewPublicAdminAPI(n),
   683  			Public:    true,
   684  		}, {
   685  			Namespace: "debug",
   686  			Version:   "1.0",
   687  			Service:   debug.Handler,
   688  		}, {
   689  			Namespace: "web3",
   690  			Version:   "1.0",
   691  			Service:   NewPublicWeb3API(n),
   692  			Public:    true,
   693  		},
   694  	}
   695  }
   696  
   697  // RegisterApisFromWhitelist checks the given modules' availability, generates a whitelist based on the allowed modules,
   698  // and then registers all of the APIs exposed by the services.
   699  func RegisterApisFromWhitelist(apis []rpc.API, modules []string, srv *rpc.Server, exposeAll bool) error {
   700  	if bad, available := checkModuleAvailability(modules, apis); len(bad) > 0 {
   701  		log.Error("Unavailable modules in HTTP API list", "unavailable", bad, "available", available)
   702  	}
   703  	// Generate the whitelist based on the allowed modules
   704  	whitelist := make(map[string]bool)
   705  	for _, module := range modules {
   706  		whitelist[module] = true
   707  	}
   708  	// Register all the APIs exposed by the services
   709  	for _, api := range apis {
   710  		if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
   711  			if err := srv.RegisterName(api.Namespace, api.Service); err != nil {
   712  				return err
   713  			}
   714  		}
   715  	}
   716  	return nil
   717  }