github.com/MetalBlockchain/subnet-evm@v0.4.9/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 "os" 32 "path/filepath" 33 34 "github.com/MetalBlockchain/subnet-evm/accounts" 35 "github.com/MetalBlockchain/subnet-evm/accounts/external" 36 "github.com/MetalBlockchain/subnet-evm/accounts/keystore" 37 "github.com/MetalBlockchain/subnet-evm/rpc" 38 "github.com/ethereum/go-ethereum/log" 39 ) 40 41 // Config represents a small collection of configuration values to fine tune the 42 // P2P network layer of a protocol stack. These values can be further extended by 43 // all registered services. 44 type Config struct { 45 // KeyStoreDir is the file system folder that contains private keys. The directory can 46 // be specified as a relative path, in which case it is resolved relative to the 47 // current directory. 48 // 49 // If KeyStoreDir is empty, the default location is the "keystore" subdirectory of 50 // DataDir. If DataDir is unspecified and KeyStoreDir is empty, an ephemeral directory 51 // is created by New and destroyed when the node is stopped. 52 KeyStoreDir string `toml:",omitempty"` 53 54 // ExternalSigner specifies an external URI for a clef-type signer 55 ExternalSigner string `toml:",omitempty"` 56 57 // UseLightweightKDF lowers the memory and CPU requirements of the key store 58 // scrypt KDF at the expense of security. 59 UseLightweightKDF bool `toml:",omitempty"` 60 61 // InsecureUnlockAllowed allows user to unlock accounts in unsafe http environment. 62 InsecureUnlockAllowed bool `toml:",omitempty"` 63 64 // HTTPHost is the host interface on which to start the HTTP RPC server. If this 65 // field is empty, no HTTP API endpoint will be started. 66 HTTPHost string 67 68 // HTTPPort is the TCP port number on which to start the HTTP RPC server. The 69 // default zero value is/ valid and will pick a port number randomly (useful 70 // for ephemeral nodes). 71 HTTPPort int `toml:",omitempty"` 72 73 // HTTPCors is the Cross-Origin Resource Sharing header to send to requesting 74 // clients. Please be aware that CORS is a browser enforced security, it's fully 75 // useless for custom HTTP clients. 76 HTTPCors []string `toml:",omitempty"` 77 78 // HTTPVirtualHosts is the list of virtual hostnames which are allowed on incoming requests. 79 // This is by default {'localhost'}. Using this prevents attacks like 80 // DNS rebinding, which bypasses SOP by simply masquerading as being within the same 81 // origin. These attacks do not utilize CORS, since they are not cross-domain. 82 // By explicitly checking the Host-header, the server will not allow requests 83 // made against the server with a malicious host domain. 84 // Requests using ip address directly are not affected 85 HTTPVirtualHosts []string `toml:",omitempty"` 86 87 // HTTPModules is a list of API modules to expose via the HTTP RPC interface. 88 // If the module list is empty, all RPC API endpoints designated public will be 89 // exposed. 90 HTTPModules []string 91 92 // HTTPTimeouts allows for customization of the timeout values used by the HTTP RPC 93 // interface. 94 HTTPTimeouts rpc.HTTPTimeouts 95 96 // WSHost is the host interface on which to start the websocket RPC server. If 97 // this field is empty, no websocket API endpoint will be started. 98 WSHost string 99 100 // WSPort is the TCP port number on which to start the websocket RPC server. The 101 // default zero value is/ valid and will pick a port number randomly (useful for 102 // ephemeral nodes). 103 WSPort int `toml:",omitempty"` 104 105 // WSOrigins is the list of domain to accept websocket requests from. Please be 106 // aware that the server can only act upon the HTTP request the client sends and 107 // cannot verify the validity of the request header. 108 WSOrigins []string `toml:",omitempty"` 109 110 // WSModules is a list of API modules to expose via the websocket RPC interface. 111 // If the module list is empty, all RPC API endpoints designated public will be 112 // exposed. 113 WSModules []string 114 115 // WSExposeAll exposes all API modules via the WebSocket RPC interface rather 116 // than just the public ones. 117 // 118 // *WARNING* Only set this if the node is running in a trusted network, exposing 119 // private APIs to untrusted users is a major security risk. 120 WSExposeAll bool `toml:",omitempty"` 121 122 // GraphQLCors is the Cross-Origin Resource Sharing header to send to requesting 123 // clients. Please be aware that CORS is a browser enforced security, it's fully 124 // useless for custom HTTP clients. 125 GraphQLCors []string `toml:",omitempty"` 126 127 // GraphQLVirtualHosts is the list of virtual hostnames which are allowed on incoming requests. 128 // This is by default {'localhost'}. Using this prevents attacks like 129 // DNS rebinding, which bypasses SOP by simply masquerading as being within the same 130 // origin. These attacks do not utilize CORS, since they are not cross-domain. 131 // By explicitly checking the Host-header, the server will not allow requests 132 // made against the server with a malicious host domain. 133 // Requests using ip address directly are not affected 134 GraphQLVirtualHosts []string `toml:",omitempty"` 135 136 SubnetEVMVersion string 137 } 138 139 // HTTPEndpoint resolves an HTTP endpoint based on the configured host interface 140 // and port parameters. 141 func (c *Config) HTTPEndpoint() string { 142 if c.HTTPHost == "" { 143 return "" 144 } 145 return fmt.Sprintf("%s:%d", c.HTTPHost, c.HTTPPort) 146 } 147 148 // DefaultHTTPEndpoint returns the HTTP endpoint used by default. 149 func DefaultHTTPEndpoint() string { 150 config := &Config{HTTPHost: DefaultHTTPHost, HTTPPort: DefaultHTTPPort} 151 return config.HTTPEndpoint() 152 } 153 154 // WSEndpoint resolves a websocket endpoint based on the configured host interface 155 // and port parameters. 156 func (c *Config) WSEndpoint() string { 157 if c.WSHost == "" { 158 return "" 159 } 160 return fmt.Sprintf("%s:%d", c.WSHost, c.WSPort) 161 } 162 163 // DefaultWSEndpoint returns the websocket endpoint used by default. 164 func DefaultWSEndpoint() string { 165 config := &Config{WSHost: DefaultWSHost, WSPort: DefaultWSPort} 166 return config.WSEndpoint() 167 } 168 169 // ExtRPCEnabled returns the indicator whether node enables the external 170 // RPC(http, ws or graphql). 171 func (c *Config) ExtRPCEnabled() bool { 172 return c.HTTPHost != "" || c.WSHost != "" 173 } 174 175 // KeyDirConfig determines the settings for keydirectory 176 func (c *Config) KeyDirConfig() (string, error) { 177 var ( 178 keydir string 179 err error 180 ) 181 switch { 182 case filepath.IsAbs(c.KeyStoreDir): 183 keydir = c.KeyStoreDir 184 case c.KeyStoreDir != "": 185 keydir, err = filepath.Abs(c.KeyStoreDir) 186 } 187 return keydir, err 188 } 189 190 // getKeyStoreDir retrieves the key directory and will create 191 // and ephemeral one if necessary. 192 func getKeyStoreDir(conf *Config) (string, bool, error) { 193 keydir, err := conf.KeyDirConfig() 194 if err != nil { 195 return "", false, err 196 } 197 isEphemeral := false 198 if keydir == "" { 199 // There is no datadir. 200 keydir, err = os.MkdirTemp("", "subnet-evm-keystore") 201 isEphemeral = true 202 } 203 204 if err != nil { 205 return "", false, err 206 } 207 if err := os.MkdirAll(keydir, 0700); err != nil { 208 return "", false, err 209 } 210 211 return keydir, isEphemeral, nil 212 } 213 214 func makeAccountManager(conf *Config) (*accounts.Manager, error) { 215 scryptN := keystore.StandardScryptN 216 scryptP := keystore.StandardScryptP 217 if conf.UseLightweightKDF { 218 scryptN = keystore.LightScryptN 219 scryptP = keystore.LightScryptP 220 } 221 222 keydir, _, err := getKeyStoreDir(conf) 223 if err != nil { 224 return nil, err 225 } 226 // Assemble the account manager and supported backends 227 var backends []accounts.Backend 228 if len(conf.ExternalSigner) > 0 { 229 log.Info("Using external signer", "url", conf.ExternalSigner) 230 if extapi, err := external.NewExternalBackend(conf.ExternalSigner); err == nil { 231 backends = append(backends, extapi) 232 } else { 233 return nil, fmt.Errorf("error connecting to external signer: %v", err) 234 } 235 } 236 if len(backends) == 0 { 237 // For now, we're using EITHER external signer OR local signers. 238 // If/when we implement some form of lockfile for USB and keystore wallets, 239 // we can have both, but it's very confusing for the user to see the same 240 // accounts in both externally and locally, plus very racey. 241 backends = append(backends, keystore.NewKeyStore(keydir, scryptN, scryptP)) 242 } 243 244 return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), nil 245 }