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 }