gitlab.com/flarenetwork/coreth@v0.1.1/node/config.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2014 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package node
    28  
    29  import (
    30  	"fmt"
    31  	"io/ioutil"
    32  	"os"
    33  	"path/filepath"
    34  
    35  	"gitlab.com/flarenetwork/coreth/accounts"
    36  	"gitlab.com/flarenetwork/coreth/accounts/external"
    37  	"gitlab.com/flarenetwork/coreth/accounts/keystore"
    38  
    39  	"github.com/ethereum/go-ethereum/log"
    40  	"gitlab.com/flarenetwork/coreth/rpc"
    41  )
    42  
    43  // Config represents a small collection of configuration values to fine tune the
    44  // P2P network layer of a protocol stack. These values can be further extended by
    45  // all registered services.
    46  type Config struct {
    47  	// KeyStoreDir is the file system folder that contains private keys. The directory can
    48  	// be specified as a relative path, in which case it is resolved relative to the
    49  	// current directory.
    50  	//
    51  	// If KeyStoreDir is empty, the default location is the "keystore" subdirectory of
    52  	// DataDir. If DataDir is unspecified and KeyStoreDir is empty, an ephemeral directory
    53  	// is created by New and destroyed when the node is stopped.
    54  	KeyStoreDir string `toml:",omitempty"`
    55  
    56  	// ExternalSigner specifies an external URI for a clef-type signer
    57  	ExternalSigner string `toml:",omitempty"`
    58  
    59  	// UseLightweightKDF lowers the memory and CPU requirements of the key store
    60  	// scrypt KDF at the expense of security.
    61  	UseLightweightKDF bool `toml:",omitempty"`
    62  
    63  	// InsecureUnlockAllowed allows user to unlock accounts in unsafe http environment.
    64  	InsecureUnlockAllowed bool `toml:",omitempty"`
    65  
    66  	// HTTPHost is the host interface on which to start the HTTP RPC server. If this
    67  	// field is empty, no HTTP API endpoint will be started.
    68  	HTTPHost string
    69  
    70  	// HTTPPort is the TCP port number on which to start the HTTP RPC server. The
    71  	// default zero value is/ valid and will pick a port number randomly (useful
    72  	// for ephemeral nodes).
    73  	HTTPPort int `toml:",omitempty"`
    74  
    75  	// HTTPCors is the Cross-Origin Resource Sharing header to send to requesting
    76  	// clients. Please be aware that CORS is a browser enforced security, it's fully
    77  	// useless for custom HTTP clients.
    78  	HTTPCors []string `toml:",omitempty"`
    79  
    80  	// HTTPVirtualHosts is the list of virtual hostnames which are allowed on incoming requests.
    81  	// This is by default {'localhost'}. Using this prevents attacks like
    82  	// DNS rebinding, which bypasses SOP by simply masquerading as being within the same
    83  	// origin. These attacks do not utilize CORS, since they are not cross-domain.
    84  	// By explicitly checking the Host-header, the server will not allow requests
    85  	// made against the server with a malicious host domain.
    86  	// Requests using ip address directly are not affected
    87  	HTTPVirtualHosts []string `toml:",omitempty"`
    88  
    89  	// HTTPModules is a list of API modules to expose via the HTTP RPC interface.
    90  	// If the module list is empty, all RPC API endpoints designated public will be
    91  	// exposed.
    92  	HTTPModules []string
    93  
    94  	// HTTPTimeouts allows for customization of the timeout values used by the HTTP RPC
    95  	// interface.
    96  	HTTPTimeouts rpc.HTTPTimeouts
    97  
    98  	// WSHost is the host interface on which to start the websocket RPC server. If
    99  	// this field is empty, no websocket API endpoint will be started.
   100  	WSHost string
   101  
   102  	// WSPort is the TCP port number on which to start the websocket RPC server. The
   103  	// default zero value is/ valid and will pick a port number randomly (useful for
   104  	// ephemeral nodes).
   105  	WSPort int `toml:",omitempty"`
   106  
   107  	// WSOrigins is the list of domain to accept websocket requests from. Please be
   108  	// aware that the server can only act upon the HTTP request the client sends and
   109  	// cannot verify the validity of the request header.
   110  	WSOrigins []string `toml:",omitempty"`
   111  
   112  	// WSModules is a list of API modules to expose via the websocket RPC interface.
   113  	// If the module list is empty, all RPC API endpoints designated public will be
   114  	// exposed.
   115  	WSModules []string
   116  
   117  	// WSExposeAll exposes all API modules via the WebSocket RPC interface rather
   118  	// than just the public ones.
   119  	//
   120  	// *WARNING* Only set this if the node is running in a trusted network, exposing
   121  	// private APIs to untrusted users is a major security risk.
   122  	WSExposeAll bool `toml:",omitempty"`
   123  
   124  	// GraphQLCors is the Cross-Origin Resource Sharing header to send to requesting
   125  	// clients. Please be aware that CORS is a browser enforced security, it's fully
   126  	// useless for custom HTTP clients.
   127  	GraphQLCors []string `toml:",omitempty"`
   128  
   129  	// GraphQLVirtualHosts is the list of virtual hostnames which are allowed on incoming requests.
   130  	// This is by default {'localhost'}. Using this prevents attacks like
   131  	// DNS rebinding, which bypasses SOP by simply masquerading as being within the same
   132  	// origin. These attacks do not utilize CORS, since they are not cross-domain.
   133  	// By explicitly checking the Host-header, the server will not allow requests
   134  	// made against the server with a malicious host domain.
   135  	// Requests using ip address directly are not affected
   136  	GraphQLVirtualHosts []string `toml:",omitempty"`
   137  
   138  	CorethVersion string
   139  }
   140  
   141  // HTTPEndpoint resolves an HTTP endpoint based on the configured host interface
   142  // and port parameters.
   143  func (c *Config) HTTPEndpoint() string {
   144  	if c.HTTPHost == "" {
   145  		return ""
   146  	}
   147  	return fmt.Sprintf("%s:%d", c.HTTPHost, c.HTTPPort)
   148  }
   149  
   150  // DefaultHTTPEndpoint returns the HTTP endpoint used by default.
   151  func DefaultHTTPEndpoint() string {
   152  	config := &Config{HTTPHost: DefaultHTTPHost, HTTPPort: DefaultHTTPPort}
   153  	return config.HTTPEndpoint()
   154  }
   155  
   156  // WSEndpoint resolves a websocket endpoint based on the configured host interface
   157  // and port parameters.
   158  func (c *Config) WSEndpoint() string {
   159  	if c.WSHost == "" {
   160  		return ""
   161  	}
   162  	return fmt.Sprintf("%s:%d", c.WSHost, c.WSPort)
   163  }
   164  
   165  // DefaultWSEndpoint returns the websocket endpoint used by default.
   166  func DefaultWSEndpoint() string {
   167  	config := &Config{WSHost: DefaultWSHost, WSPort: DefaultWSPort}
   168  	return config.WSEndpoint()
   169  }
   170  
   171  // ExtRPCEnabled returns the indicator whether node enables the external
   172  // RPC(http, ws or graphql).
   173  func (c *Config) ExtRPCEnabled() bool {
   174  	return c.HTTPHost != "" || c.WSHost != ""
   175  }
   176  
   177  // AccountConfig determines the settings for scrypt and keydirectory
   178  func (c *Config) AccountConfig() (int, int, string, error) {
   179  	scryptN := keystore.StandardScryptN
   180  	scryptP := keystore.StandardScryptP
   181  	if c.UseLightweightKDF {
   182  		scryptN = keystore.LightScryptN
   183  		scryptP = keystore.LightScryptP
   184  	}
   185  
   186  	var (
   187  		keydir string
   188  		err    error
   189  	)
   190  	switch {
   191  	case filepath.IsAbs(c.KeyStoreDir):
   192  		keydir = c.KeyStoreDir
   193  	case c.KeyStoreDir != "":
   194  		keydir, err = filepath.Abs(c.KeyStoreDir)
   195  	}
   196  	return scryptN, scryptP, keydir, err
   197  }
   198  
   199  func makeAccountManager(conf *Config) (*accounts.Manager, error) {
   200  	scryptN, scryptP, keydir, err := conf.AccountConfig()
   201  	// var ephemeral string
   202  	if keydir == "" {
   203  		// There is no datadir.
   204  		keydir, err = ioutil.TempDir("", "coreth-keystore")
   205  	}
   206  
   207  	if err != nil {
   208  		return nil, err
   209  	}
   210  	if err := os.MkdirAll(keydir, 0700); err != nil {
   211  		return nil, err
   212  	}
   213  	// Assemble the account manager and supported backends
   214  	var backends []accounts.Backend
   215  	if len(conf.ExternalSigner) > 0 {
   216  		log.Info("Using external signer", "url", conf.ExternalSigner)
   217  		if extapi, err := external.NewExternalBackend(conf.ExternalSigner); err == nil {
   218  			backends = append(backends, extapi)
   219  		} else {
   220  			return nil, fmt.Errorf("error connecting to external signer: %v", err)
   221  		}
   222  	}
   223  	if len(backends) == 0 {
   224  		// For now, we're using EITHER external signer OR local signers.
   225  		// If/when we implement some form of lockfile for USB and keystore wallets,
   226  		// we can have both, but it's very confusing for the user to see the same
   227  		// accounts in both externally and locally, plus very racey.
   228  		backends = append(backends, keystore.NewKeyStore(keydir, scryptN, scryptP))
   229  	}
   230  
   231  	return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), nil
   232  }