github.com/status-im/status-go@v1.1.0/params/config.go (about) 1 package params 2 3 import ( 4 "crypto/ecdsa" 5 "encoding/hex" 6 "encoding/json" 7 "fmt" 8 "io/ioutil" 9 "net/url" 10 "os" 11 "path/filepath" 12 "strings" 13 "time" 14 15 validator "gopkg.in/go-playground/validator.v9" 16 17 "github.com/ethereum/go-ethereum/common" 18 "github.com/ethereum/go-ethereum/log" 19 "github.com/ethereum/go-ethereum/p2p/discv5" 20 "github.com/ethereum/go-ethereum/params" 21 22 "github.com/status-im/status-go/eth-node/crypto" 23 "github.com/status-im/status-go/eth-node/types" 24 "github.com/status-im/status-go/static" 25 wakucommon "github.com/status-im/status-go/waku/common" 26 wakuv2common "github.com/status-im/status-go/wakuv2/common" 27 ) 28 29 // ---------- 30 // LightEthConfig 31 // ---------- 32 33 // LightEthConfig holds LES-related configuration 34 // Status nodes are always lightweight clients (due to mobile platform constraints) 35 type LightEthConfig struct { 36 // Enabled flag specifies whether protocol is enabled 37 Enabled bool 38 39 // DatabaseCache is memory (in MBs) allocated to internal caching (min 16MB / database forced) 40 DatabaseCache int 41 42 // TrustedNodes is a list of trusted servers 43 TrustedNodes []string 44 45 //MinTrustedFraction is minimum percentage of connected trusted servers to validate header(1-100) 46 MinTrustedFraction int 47 } 48 49 // ---------- 50 // DatabaseConfig 51 // ---------- 52 53 type DatabaseConfig struct { 54 PGConfig PGConfig 55 } 56 57 // ---------- 58 // PGConfig 59 // ---------- 60 61 type PGConfig struct { 62 // Enabled whether we should use a Postgres instance 63 Enabled bool 64 // The URI of the server 65 URI string 66 } 67 68 // ---------- 69 // WakuConfig 70 // ---------- 71 72 // WakuConfig provides a configuration for Waku service. 73 type WakuConfig struct { 74 // Enabled set to true enables Waku subprotocol. 75 Enabled bool 76 77 // LightClient should be true if the node should start with an empty bloom filter and not forward messages from other nodes 78 LightClient bool 79 80 // FullNode should be true if waku should always acta as a full node 81 FullNode bool 82 83 // EnableMailServer is mode when node is capable of delivering expired messages on demand 84 EnableMailServer bool 85 86 // DataDir is the file system folder Waku should use for any data storage needs. 87 // For instance, MailServer will use this directory to store its data. 88 DataDir string 89 90 // MinimumPoW minimum PoW for Waku messages 91 // We enforce a minimum as a bland spam prevention mechanism. 92 MinimumPoW float64 93 94 // MailServerPassword for symmetric encryption of waku message history requests. 95 // (if no account file selected, then this password is used for symmetric encryption). 96 MailServerPassword string 97 98 // MailServerRateLimit minimum time between queries to mail server per peer. 99 MailServerRateLimit int 100 101 // MailServerDataRetention is a number of days data should be stored by MailServer. 102 MailServerDataRetention int 103 104 // TTL time to live for messages, in seconds 105 TTL int 106 107 // MaxMessageSize is a maximum size of a devp2p packet handled by the Waku protocol, 108 // not only the size of envelopes sent in that packet. 109 MaxMessageSize uint32 110 111 // DatabaseConfig is configuration for which data store we use. 112 DatabaseConfig DatabaseConfig 113 114 // EnableRateLimiter set to true enables IP and peer ID rate limiting. 115 EnableRateLimiter bool 116 117 // PacketRateLimitIP sets the limit on the number of packets per second 118 // from a given IP. 119 PacketRateLimitIP int64 120 121 // PacketRateLimitPeerID sets the limit on the number of packets per second 122 // from a given peer ID. 123 PacketRateLimitPeerID int64 124 125 // BytesRateLimitIP sets the limit on the number of bytes per second 126 // from a given IP. 127 BytesRateLimitIP int64 128 129 // BytesRateLimitPeerID sets the limit on the number of bytes per second 130 // from a given peer ID. 131 BytesRateLimitPeerID int64 132 133 // RateLimitTolerance is a number of how many a limit must be exceeded 134 // in order to drop a peer. 135 // If equal to 0, the peers are never dropped. 136 RateLimitTolerance int64 137 138 // BloomFilterMode tells us whether we should be sending a bloom 139 // filter rather than TopicInterest 140 BloomFilterMode bool 141 142 // SoftBlacklistedPeerIDs is a list of peer ids that should be soft-blacklisted (messages should be dropped but connection kept) 143 SoftBlacklistedPeerIDs []string 144 145 // EnableConfirmations when true, instructs that confirmation should be sent for received messages 146 EnableConfirmations bool 147 } 148 149 // ---------- 150 // WakuV2Config 151 // ---------- 152 153 // WakuConfig provides a configuration for Waku service. 154 type WakuV2Config struct { 155 // Enabled set to true enables Waku subprotocol. 156 Enabled bool 157 158 // Host interface in which to start libp2p protocol 159 Host string 160 161 // Port number in which to start libp2p protocol (0 for random) 162 Port int 163 164 // LightClient should be true if the node will not relay messages and only rely on lightpush/filter nodes 165 LightClient bool 166 167 // FullNode should be true if waku should always acta as a full node 168 FullNode bool 169 170 // DiscoveryLimit indicates the maximum number of peers to discover 171 DiscoveryLimit int 172 173 // DataDir is the file system folder Waku should use for any data storage needs. 174 // For instance, MailServer will use this directory to store its data. 175 DataDir string 176 177 // MaxMessageSize is a maximum size of a devp2p packet handled by the Waku protocol, 178 // not only the size of envelopes sent in that packet. 179 MaxMessageSize uint32 180 181 // EnableConfirmations when true, instructs that confirmation should be sent for received messages 182 EnableConfirmations bool 183 184 // A name->libp2p_addr map for Wakuv2 custom nodes 185 CustomNodes map[string]string 186 187 // PeerExchange determines whether WakuV2 Peer Exchange is enabled or not 188 // Deprecated: will be calculated based on LightClient 189 PeerExchange bool 190 191 // Nameserver determines which nameserver will be used for dns discovery 192 Nameserver string 193 194 // EnableDiscV5 indicates if DiscoveryV5 is enabled or not 195 // Deprecated: will be calculated based on LightClient 196 EnableDiscV5 bool 197 198 // UDPPort number to start discovery v5 199 UDPPort int 200 201 // AutoUpdate instructs the node to update their own ip address and port with the values seen by other nodes 202 AutoUpdate bool 203 204 // EnableStore indicates if WakuStore protocol should be enabled or not 205 EnableStore bool 206 207 // StoreCapacity indicates the max number of messages to store 208 StoreCapacity int 209 210 // StoreSeconds indicates the maximum number of seconds before a message is removed from the store 211 StoreSeconds int 212 213 TelemetryServerURL string 214 215 // EnableMissingMessageVerification indicates whether the storenodes must be queried periodically to retrieve any missing message 216 EnableMissingMessageVerification bool 217 218 // EnableMissingMessageVerification indicates whether storenodes must be queried periodically to confirm if messages sent are actually propagated in the network 219 EnableStoreConfirmationForMessagesSent bool 220 } 221 222 // ---------- 223 // SwarmConfig 224 // ---------- 225 226 // SwarmConfig holds Swarm-related configuration 227 type SwarmConfig struct { 228 // Enabled flag specifies whether protocol is enabled 229 Enabled bool 230 } 231 232 // String dumps config object as nicely indented JSON 233 func (c *SwarmConfig) String() string { 234 data, _ := json.MarshalIndent(c, "", " ") // nolint: gas 235 return string(data) 236 } 237 238 // ---------- 239 // ClusterConfig 240 // ---------- 241 242 // ClusterConfig holds configuration for supporting cluster peers, which is a temporary 243 // means for mobile devices to get connected to Ethereum network (UDP-based discovery 244 // may not be available, so we need means to discover the network manually). 245 type ClusterConfig struct { 246 // Enabled flag specifies that nodes in this configuration are taken into account. 247 Enabled bool 248 249 // Fleet is a name of a selected fleet. If it has a value, nodes are loaded 250 // from a file, namely `fleet-*.{{ .Fleet }}.json`. Nodes can be added to any list 251 // in `ClusterConfig`. 252 Fleet string 253 254 // StaticNodes is a list of static nodes. 255 StaticNodes []string 256 257 // BootNodes is a list of bootnodes. 258 // Deprecated: won't be used at all in wakuv2 259 BootNodes []string 260 261 // TrustedMailServers is a list of verified and trusted Mail Server nodes. 262 TrustedMailServers []string 263 264 // PushNotificationsServers is a list of default push notification servers. 265 PushNotificationsServers []string 266 267 // WakuNodes is a list of waku2 multiaddresses 268 WakuNodes []string 269 270 // DiscV5Nodes is a list of enr to be used for ambient discovery 271 DiscV5BootstrapNodes []string 272 273 //Waku network identifier 274 ClusterID uint16 275 } 276 277 // String dumps config object as nicely indented JSON 278 func (c *ClusterConfig) String() string { 279 data, _ := json.MarshalIndent(c, "", " ") // nolint: gas 280 return string(data) 281 } 282 283 // Limits represent min and max amount of peers 284 type Limits struct { 285 Min, Max int 286 } 287 288 // NewLimits creates new Limits config with given min and max values. 289 func NewLimits(min, max int) Limits { 290 return Limits{ 291 Min: min, 292 Max: max, 293 } 294 } 295 296 // ---------- 297 // UpstreamRPCConfig 298 // ---------- 299 300 // UpstreamRPCConfig stores configuration for upstream rpc connection. 301 type UpstreamRPCConfig struct { 302 // Enabled flag specifies whether feature is enabled 303 Enabled bool 304 305 // URL sets the rpc upstream host address for communication with 306 // a non-local infura endpoint. 307 URL string 308 } 309 310 type ProviderConfig struct { 311 // Enabled flag specifies whether feature is enabled 312 Enabled bool `validate:"required"` 313 314 // To identify provider 315 Name string `validate:"required"` 316 317 // URL sets the rpc upstream host address for communication with 318 // a non-local infura endpoint. 319 User string `json:",omitempty"` 320 Password string `json:",omitempty"` 321 APIKey string `json:"APIKey,omitempty"` 322 APIKeySecret string `json:"APIKeySecret,omitempty"` 323 } 324 325 // ---------- 326 // NodeConfig 327 // ---------- 328 329 // NodeConfig stores configuration options for a node 330 type NodeConfig struct { 331 // NetworkID sets network to use for selecting peers to connect to 332 NetworkID uint64 `json:"NetworkId" validate:"required"` 333 334 RootDataDir string `json:",omitempty"` 335 336 // DataDir is the file system folder the node should use for any data storage needs. 337 DataDir string `validate:"required"` 338 339 // KeyStoreDir is the file system folder that contains private keys. 340 KeyStoreDir string `validate:"required"` 341 342 // KeycardPairingDataFile is the file where we keep keycard pairings data. 343 // It's specified by clients (and not in status-go) when creating a new account, 344 // because this file is initialized by status-keycard-go and we need to use it before initializing the node. 345 // I guess proper way would be to ask status-go for the file path, or just duplicate the file path in both backend and client. 346 // note: this field won't be saved into db, it's local to the device. 347 KeycardPairingDataFile string 348 349 // NodeKey is the hex-encoded node ID (private key). Should be a valid secp256k1 private key that will be used for both 350 // remote peer identification as well as network traffic encryption. 351 NodeKey string 352 353 // NoDiscovery set to true will disable discovery protocol. 354 // Deprecated: won't be used at all in wakuv2 355 NoDiscovery bool 356 357 // ListenAddr is an IP address and port of this node (e.g. 127.0.0.1:30303). 358 ListenAddr string 359 360 // AdvertiseAddr is a public IP address the node wants to be found with. 361 // It is especially useful when using floating IPs attached to a server. 362 // This configuration value is used by rendezvous protocol, and it's optional 363 // If no value is specified, it will attempt to determine the node's external 364 // IP address. A value can be specified in case the returned address is incorrect 365 AdvertiseAddr string 366 367 // Name sets the instance name of the node. It must not contain the / character. 368 Name string `validate:"excludes=/"` 369 370 // Version exposes program's version. It is used in the devp2p node identifier. 371 Version string 372 373 // APIModules is a comma-separated list of API modules exposed via *any* (HTTP/WS/IPC) RPC interface. 374 APIModules string `validate:"required"` 375 376 // HTTPEnabled specifies whether the http RPC server is to be enabled by default. 377 HTTPEnabled bool 378 379 // HTTPHost is the host interface on which to start the HTTP RPC server. 380 // Pass empty string if no HTTP RPC interface needs to be started. 381 HTTPHost string 382 383 // HTTPPort is the TCP port number on which to start the Geth's HTTP RPC server. 384 HTTPPort int 385 386 // WSEnabled specifies whether the Websocket RPC server is to be enabled by default. 387 WSEnabled bool 388 389 // WSHost is the host interface on which to start Geth's Websocket RPC server. 390 WSHost string 391 392 // WSPort is the TCP port number on which to start the Geth's Websocket RPC server. 393 WSPort int 394 395 // HTTPVirtualHosts is the list of virtual hostnames which are allowed on incoming requests. 396 // This is by default {'localhost'}. Using this prevents attacks like 397 // DNS rebinding, which bypasses SOP by simply masquerading as being within the same 398 // origin. These attacks do not utilize CORS, since they are not cross-domain. 399 // By explicitly checking the Host-header, the server will not allow requests 400 // made against the server with a malicious host domain. 401 // Requests using an IP address directly are not affected. 402 HTTPVirtualHosts []string 403 404 // HTTPCors is the Cross-Origin Resource Sharing header to send to requesting 405 // clients. Please be aware that CORS is a browser enforced security, it's fully 406 // useless for custom HTTP clients. 407 HTTPCors []string 408 409 // IPCEnabled specifies whether IPC-RPC Server is enabled or not 410 IPCEnabled bool 411 412 // IPCFile is filename of exposed IPC RPC Server 413 IPCFile string 414 415 // TLSEnabled specifies whether TLS support should be enabled on node or not 416 // TLS support is only planned in go-ethereum, so we are using our own patch. 417 TLSEnabled bool 418 419 // MaxPeers is the maximum number of (global) peers that can be connected. 420 // Set to zero, if only static or trusted peers are allowed to connect. 421 MaxPeers int 422 423 // MaxPendingPeers is the maximum number of peers that can be pending in the 424 // handshake phase, counted separately for inbound and outbound connections. 425 MaxPendingPeers int 426 427 log log.Logger 428 429 // LogEnabled enables the logger 430 LogEnabled bool `json:"LogEnabled"` 431 432 // LogMobileSystem enables log redirection to android/ios system logger. 433 LogMobileSystem bool 434 435 // LogFile is a folder which contains LogFile 436 LogDir string 437 438 // LogFile is filename where exposed logs get written to 439 LogFile string 440 441 // RuntimeLoglevel defines minimum log level for this session only, not affecting the db-stored node configuration 442 RuntimeLogLevel string `validate:"omitempty,eq=ERROR|eq=WARN|eq=INFO|eq=DEBUG|eq=TRACE"` 443 444 // LogLevel defines minimum log level. Valid names are "ERROR", "WARN", "INFO", "DEBUG", and "TRACE". 445 LogLevel string `validate:"eq=ERROR|eq=WARN|eq=INFO|eq=DEBUG|eq=TRACE"` 446 447 // LogMaxBackups defines number of rotated log files that will be stored. 448 LogMaxBackups int 449 450 // LogMaxSize in megabytes after current size is reached log file will be rotated. 451 LogMaxSize int 452 453 // LogCompressRotated if true all rotated files will be gzipped. 454 LogCompressRotated bool 455 456 // LogToStderr defines whether logged info should also be output to os.Stderr 457 LogToStderr bool 458 459 // EnableStatusService should be true to enable methods under status namespace. 460 EnableStatusService bool 461 462 // UpstreamConfig extra config for providing upstream infura server. 463 UpstreamConfig UpstreamRPCConfig `json:"UpstreamConfig"` 464 465 // Initial networks to load 466 Networks []Network 467 468 // ClusterConfig extra configuration for supporting cluster peers. 469 ClusterConfig ClusterConfig `json:"ClusterConfig," validate:"structonly"` 470 471 // LightEthConfig extra configuration for LES 472 LightEthConfig LightEthConfig `json:"LightEthConfig," validate:"structonly"` 473 474 // WakuConfig provides a configuration for Waku subprotocol. 475 WakuConfig WakuConfig `json:"WakuConfig" validate:"structonly"` 476 477 // WakuV2Config provides a configuration for WakuV2 protocol. 478 WakuV2Config WakuV2Config `json:"WakuV2Config" validate:"structonly"` 479 480 // BridgeConfig provides a configuration for Whisper-Waku bridge. 481 BridgeConfig BridgeConfig `json:"BridgeConfig" validate:"structonly"` 482 483 // ShhextConfig extra configuration for service running under shhext namespace. 484 ShhextConfig ShhextConfig `json:"ShhextConfig," validate:"structonly"` 485 486 // WalletConfig extra configuration for wallet.Service. 487 WalletConfig WalletConfig 488 489 // WalleLocalNotificationsConfig extra configuration for localnotifications.Service. 490 LocalNotificationsConfig LocalNotificationsConfig 491 492 // BrowsersConfig extra configuration for browsers.Service. 493 BrowsersConfig BrowsersConfig 494 495 // PermissionsConfig extra configuration for permissions.Service. 496 PermissionsConfig PermissionsConfig 497 498 // MailserversConfig extra configuration for mailservers.Service 499 // (persistent storage of user's mailserver records). 500 MailserversConfig MailserversConfig 501 502 // Web3ProviderConfig extra configuration for provider.Service 503 // (desktop provider API) 504 Web3ProviderConfig Web3ProviderConfig 505 506 // ConnectorConfig extra configuration for connector.Service 507 ConnectorConfig ConnectorConfig 508 509 // SwarmConfig extra configuration for Swarm and ENS 510 SwarmConfig SwarmConfig `json:"SwarmConfig," validate:"structonly"` 511 512 TorrentConfig TorrentConfig 513 514 // RegisterTopics a list of specific topics where the peer wants to be 515 // discoverable. 516 RegisterTopics []discv5.Topic `json:"RegisterTopics"` 517 518 // RequiredTopics list of topics where a client wants to search for 519 // discoverable peers with the discovery limits. 520 RequireTopics map[discv5.Topic]Limits `json:"RequireTopics"` 521 522 // MailServerRegistryAddress is the MailServerRegistry contract address 523 MailServerRegistryAddress string 524 525 // PushNotificationServerConfig is the config for the push notification server 526 PushNotificationServerConfig PushNotificationServerConfig `json:"PushNotificationServerConfig"` 527 528 OutputMessageCSVEnabled bool 529 530 // ProcessBackedupMessages should be set to true when user follows recovery (using seed phrase or keycard) onboarding flow 531 ProcessBackedupMessages bool 532 } 533 534 type TokenOverride struct { 535 Symbol string `json:"symbol"` 536 Address common.Address `json:"address"` 537 } 538 539 type Network struct { 540 ChainID uint64 `json:"chainId"` 541 ChainName string `json:"chainName"` 542 DefaultRPCURL string `json:"defaultRpcUrl"` // proxy rpc url 543 DefaultFallbackURL string `json:"defaultFallbackURL"` // proxy fallback url 544 RPCURL string `json:"rpcUrl"` 545 OriginalRPCURL string `json:"originalRpcUrl"` 546 FallbackURL string `json:"fallbackURL"` 547 OriginalFallbackURL string `json:"originalFallbackURL"` 548 BlockExplorerURL string `json:"blockExplorerUrl,omitempty"` 549 IconURL string `json:"iconUrl,omitempty"` 550 NativeCurrencyName string `json:"nativeCurrencyName,omitempty"` 551 NativeCurrencySymbol string `json:"nativeCurrencySymbol,omitempty"` 552 NativeCurrencyDecimals uint64 `json:"nativeCurrencyDecimals"` 553 IsTest bool `json:"isTest"` 554 Layer uint64 `json:"layer"` 555 Enabled bool `json:"enabled"` 556 ChainColor string `json:"chainColor"` 557 ShortName string `json:"shortName"` 558 TokenOverrides []TokenOverride `json:"tokenOverrides"` 559 RelatedChainID uint64 `json:"relatedChainId"` 560 } 561 562 // WalletConfig extra configuration for wallet.Service. 563 type WalletConfig struct { 564 Enabled bool 565 OpenseaAPIKey string `json:"OpenseaAPIKey"` 566 RaribleMainnetAPIKey string `json:"RaribleMainnetAPIKey"` 567 RaribleTestnetAPIKey string `json:"RaribleTestnetAPIKey"` 568 AlchemyAPIKeys map[uint64]string `json:"AlchemyAPIKeys"` 569 InfuraAPIKey string `json:"InfuraAPIKey"` 570 InfuraAPIKeySecret string `json:"InfuraAPIKeySecret"` 571 StatusProxyMarketUser string `json:"StatusProxyMarketUser"` 572 StatusProxyMarketPassword string `json:"StatusProxyMarketPassword"` 573 StatusProxyBlockchainUser string `json:"StatusProxyBlockchainUser"` 574 StatusProxyBlockchainPassword string `json:"StatusProxyBlockchainPassword"` 575 StatusProxyEnabled bool `json:"StatusProxyEnabled"` 576 StatusProxyStageName string `json:"StatusProxyStageName"` 577 EnableCelerBridge bool `json:"EnableCelerBridge"` 578 } 579 580 // MarshalJSON custom marshalling to avoid exposing sensitive data in log, 581 // there's a function called `startNode` will log NodeConfig which include WalletConfig 582 func (wc WalletConfig) MarshalJSON() ([]byte, error) { 583 return json.Marshal(struct { 584 Enabled bool `json:"Enabled"` 585 StatusProxyEnabled bool `json:"StatusProxyEnabled"` 586 EnableCelerBridge bool `json:"EnableCelerBridge"` 587 }{ 588 Enabled: wc.Enabled, 589 StatusProxyEnabled: wc.StatusProxyEnabled, 590 EnableCelerBridge: wc.EnableCelerBridge, 591 }) 592 } 593 594 // LocalNotificationsConfig extra configuration for localnotifications.Service. 595 type LocalNotificationsConfig struct { 596 Enabled bool 597 } 598 599 // BrowsersConfig extra configuration for browsers.Service. 600 type BrowsersConfig struct { 601 Enabled bool 602 } 603 604 // PermissionsConfig extra configuration for permissions.Service. 605 type PermissionsConfig struct { 606 Enabled bool 607 } 608 609 // MailserversConfig extra configuration for mailservers.Service. 610 type MailserversConfig struct { 611 Enabled bool 612 } 613 614 // ProviderConfig extra configuration for provider.Service 615 type Web3ProviderConfig struct { 616 Enabled bool 617 } 618 619 // ConnectorConfig extra configuration for provider.Service 620 type ConnectorConfig struct { 621 Enabled bool 622 } 623 624 // BridgeConfig provides configuration for Whisper-Waku bridge. 625 type BridgeConfig struct { 626 Enabled bool 627 } 628 629 type PushNotificationServer struct { 630 *ecdsa.PublicKey 631 } 632 633 func (p *PushNotificationServer) MarshalText() ([]byte, error) { 634 return []byte(hex.EncodeToString(crypto.FromECDSAPub(p.PublicKey))), nil 635 } 636 637 func (p *PushNotificationServer) UnmarshalText(data []byte) error { 638 pubKeyBytes, err := hex.DecodeString(string(data)) 639 if err != nil { 640 return err 641 } 642 643 pk, err := crypto.UnmarshalPubkey(pubKeyBytes) 644 if err != nil { 645 return err 646 } 647 648 p.PublicKey = pk 649 return nil 650 } 651 652 type PushNotificationServerConfig struct { 653 Enabled bool 654 Identity *ecdsa.PrivateKey 655 GorushURL string 656 } 657 658 // ShhextConfig defines options used by shhext service. 659 type ShhextConfig struct { 660 PFSEnabled bool 661 // InstallationId id of the current installation 662 InstallationID string 663 // MailServerConfirmations should be true if client wants to receive confirmatons only from a selected mail servers. 664 MailServerConfirmations bool 665 // EnableConnectionManager turns on management of the mail server connections if true. 666 EnableConnectionManager bool 667 // EnableLastUsedMonitor guarantees that last used mail server will be tracked and persisted into the storage. 668 EnableLastUsedMonitor bool 669 // ConnectionTarget will be used by connection manager. It will ensure that we connected with configured number of servers. 670 ConnectionTarget int 671 // RequestsDelay used to ensure that no similar requests are sent within short periods of time. 672 RequestsDelay time.Duration 673 // MaxServerFailures defines maximum allowed expired requests before server will be swapped to another one. 674 MaxServerFailures int 675 676 // MaxMessageDeliveryAttempts defines how many times we will try to deliver not-acknowledged envelopes. 677 MaxMessageDeliveryAttempts int 678 679 // WhisperCacheDir is a folder where whisper filters may persist messages before delivering them 680 // to a client. 681 WhisperCacheDir string 682 683 // DisableGenericDiscoveryTopic indicates whether we should be listening on the old discovery 684 DisableGenericDiscoveryTopic bool 685 686 // SendV1Messages indicates whether we should be sending v1-compatible only messages 687 SendV1Messages bool 688 689 // DatasyncEnabled indicates whether we should enable dataasync 690 DataSyncEnabled bool 691 692 // VerifyTransactionURL is the URL for verifying transactions. 693 // IMPORTANT: It should always be mainnet unless used for testing 694 VerifyTransactionURL string 695 696 // VerifyENSURL is the URL for verifying ens names. 697 // IMPORTANT: It should always be mainnet unless used for testing 698 VerifyENSURL string 699 700 // VerifyENSContractAddress is the address of the contract used to verify ENS 701 // No default is provided and if not set ENS resolution is disabled 702 VerifyENSContractAddress string 703 704 VerifyTransactionChainID int64 705 706 // DefaultPushNotificationsServers is the default-status run push notification servers 707 DefaultPushNotificationsServers []*PushNotificationServer 708 709 // AnonMetricsSendID is the public key used by a metrics node to decrypt metrics protobufs 710 AnonMetricsSendID string 711 712 // AnonMetricsServerEnabled indicates whether or not the 713 AnonMetricsServerEnabled bool 714 715 // AnonMetricsServerPostgresURI is the uri used to connect to a postgres db 716 AnonMetricsServerPostgresURI string 717 718 // BandwidthStatsEnabled indicates if a signal is going to be emitted to indicate the upload and download rate 719 BandwidthStatsEnabled bool 720 } 721 722 // TorrentConfig provides configuration for the BitTorrent client used for message history archives. 723 type TorrentConfig struct { 724 // Enabled set to true enables Community History Archive protocol 725 Enabled bool 726 // Port number which the BitTorrent client will listen to for conntections 727 Port int 728 // DataDir is the file system folder Status should use for message archive torrent data. 729 DataDir string 730 // TorrentDir is the file system folder Status should use for storing torrent metadata files. 731 TorrentDir string 732 } 733 734 // Validate validates the ShhextConfig struct and returns an error if inconsistent values are found 735 func (c *ShhextConfig) Validate(validate *validator.Validate) error { 736 if err := validate.Struct(c); err != nil { 737 return err 738 } 739 return nil 740 } 741 742 // Option is an additional setting when creating a NodeConfig 743 // using NewNodeConfigWithDefaults. 744 type Option func(*NodeConfig) error 745 746 // WithFleet loads one of the preconfigured Status fleets. 747 func WithFleet(fleet string) Option { 748 return func(c *NodeConfig) error { 749 if fleet == FleetUndefined { 750 return nil 751 } 752 c.NoDiscovery = false 753 c.ClusterConfig.Enabled = true 754 return loadConfigFromAsset(fmt.Sprintf("../config/cli/fleet-%s.json", fleet), c) 755 } 756 } 757 758 // WithLES enabled LES protocol. 759 func WithLES() Option { 760 return func(c *NodeConfig) error { 761 return loadConfigFromAsset("../config/cli/les-enabled.json", c) 762 } 763 } 764 765 // WithMailserver enables MailServer. 766 func WithMailserver() Option { 767 return func(c *NodeConfig) error { 768 return loadConfigFromAsset("../config/cli/mailserver-enabled.json", c) 769 } 770 } 771 772 func WithDiscV5BootstrapNodes(nodes []string) Option { 773 return func(c *NodeConfig) error { 774 c.ClusterConfig.DiscV5BootstrapNodes = nodes 775 return nil 776 } 777 } 778 779 func WithWakuNodes(nodes []string) Option { 780 return func(c *NodeConfig) error { 781 c.ClusterConfig.WakuNodes = nodes 782 return nil 783 } 784 } 785 786 // NewNodeConfigWithDefaults creates new node configuration object 787 // with some defaults suitable for adhoc use. 788 func NewNodeConfigWithDefaults(dataDir string, networkID uint64, opts ...Option) (*NodeConfig, error) { 789 c, err := NewNodeConfig(dataDir, networkID) 790 if err != nil { 791 return nil, err 792 } 793 794 c.NoDiscovery = true 795 c.HTTPHost = "" 796 c.ListenAddr = ":30303" 797 c.LogEnabled = true 798 c.LogLevel = "INFO" 799 c.LogMaxSize = 100 800 c.LogCompressRotated = true 801 c.LogMaxBackups = 3 802 c.LogToStderr = true 803 c.WakuConfig.Enabled = true 804 805 for _, opt := range opts { 806 if err := opt(c); err != nil { 807 return nil, err 808 } 809 } 810 811 c.updatePeerLimits() 812 813 if err := c.Validate(); err != nil { 814 return nil, err 815 } 816 817 return c, nil 818 } 819 820 func (c *NodeConfig) setDefaultPushNotificationsServers() error { 821 if c.ClusterConfig.Fleet == FleetUndefined { 822 return nil 823 } 824 825 // If empty load defaults from the fleet 826 if len(c.ClusterConfig.PushNotificationsServers) == 0 { 827 log.Debug("empty push notification servers, setting", "fleet", c.ClusterConfig.Fleet) 828 defaultConfig := &NodeConfig{} 829 err := loadConfigFromAsset(fmt.Sprintf("../config/cli/fleet-%s.json", c.ClusterConfig.Fleet), defaultConfig) 830 if err != nil { 831 return err 832 } 833 c.ClusterConfig.PushNotificationsServers = defaultConfig.ClusterConfig.PushNotificationsServers 834 } 835 836 // If empty set the default servers 837 if len(c.ShhextConfig.DefaultPushNotificationsServers) == 0 { 838 log.Debug("setting default push notification servers", "cluster servers", c.ClusterConfig.PushNotificationsServers) 839 for _, pk := range c.ClusterConfig.PushNotificationsServers { 840 keyBytes, err := hex.DecodeString("04" + pk) 841 if err != nil { 842 return err 843 } 844 845 key, err := crypto.UnmarshalPubkey(keyBytes) 846 if err != nil { 847 return err 848 } 849 c.ShhextConfig.DefaultPushNotificationsServers = append(c.ShhextConfig.DefaultPushNotificationsServers, &PushNotificationServer{PublicKey: key}) 850 } 851 } 852 return nil 853 } 854 855 // UpdateWithDefaults updates config with missing default values, as 856 // the config is only generated once and is thereafter pulled from the database. 857 // The way it is stored in the database makes this step necessary as it's stored as a blob and can't be easily migrated. 858 func (c *NodeConfig) UpdateWithDefaults() error { 859 // Empty APIModules will fallback to services' APIs definition. 860 // If any API is defined as public, it will be exposed. 861 // We disallow empty APIModules to avoid confusion 862 // when some APIs suddenly become available for Dapps. 863 // More: https://github.com/status-im/status-go/issues/1870. 864 if c.APIModules == "" { 865 c.APIModules = "net,web3,eth" 866 } 867 868 // Override defaultMinPoW passed by the client 869 if c.WakuConfig.Enabled { 870 c.WakuConfig.MinimumPoW = WakuMinimumPoW 871 } 872 873 // Ensure TorrentConfig is valid 874 if c.TorrentConfig.Enabled { 875 if c.TorrentConfig.DataDir == "" { 876 c.TorrentConfig.DataDir = filepath.Join(c.RootDataDir, ArchivesRelativePath) 877 } 878 if c.TorrentConfig.TorrentDir == "" { 879 c.TorrentConfig.TorrentDir = filepath.Join(c.RootDataDir, TorrentTorrentsRelativePath) 880 } 881 } 882 883 return c.setDefaultPushNotificationsServers() 884 } 885 886 // NewNodeConfigWithDefaultsAndFiles creates new node configuration object 887 // with some defaults suitable for adhoc use and applies config files on top. 888 func NewNodeConfigWithDefaultsAndFiles( 889 dataDir string, networkID uint64, opts []Option, files []string, 890 ) (*NodeConfig, error) { 891 c, err := NewNodeConfigWithDefaults(dataDir, networkID, opts...) 892 if err != nil { 893 return nil, err 894 } 895 896 for _, file := range files { 897 if err := loadConfigConfigFromFile(file, c); err != nil { 898 return nil, err 899 } 900 } 901 902 c.updatePeerLimits() 903 904 if err := c.Validate(); err != nil { 905 return nil, err 906 } 907 908 return c, nil 909 } 910 911 // updatePeerLimits will set default peer limits expectations based on enabled services. 912 func (c *NodeConfig) updatePeerLimits() { 913 if c.NoDiscovery { 914 return 915 } 916 if c.LightEthConfig.Enabled { 917 c.RequireTopics[discv5.Topic(LesTopic(int(c.NetworkID)))] = LesDiscoveryLimits 918 } 919 } 920 921 // NewNodeConfig creates new node configuration object with bare-minimum defaults. 922 // Important: the returned config is not validated. 923 func NewNodeConfig(dataDir string, networkID uint64) (*NodeConfig, error) { 924 var keyStoreDir, keycardPairingDataFile, wakuDir, wakuV2Dir string 925 926 if dataDir != "" { 927 keyStoreDir = filepath.Join(dataDir, "keystore") 928 keycardPairingDataFile = filepath.Join(dataDir, "keycard", "pairings.json") 929 930 wakuDir = filepath.Join(dataDir, "waku") 931 wakuV2Dir = filepath.Join(dataDir, "wakuv2") 932 } 933 934 config := &NodeConfig{ 935 NetworkID: networkID, 936 RootDataDir: dataDir, 937 DataDir: dataDir, 938 KeyStoreDir: keyStoreDir, 939 KeycardPairingDataFile: keycardPairingDataFile, 940 Version: Version, 941 HTTPHost: "localhost", 942 HTTPPort: 8545, 943 HTTPVirtualHosts: []string{"localhost"}, 944 ListenAddr: ":0", 945 APIModules: "eth,net,web3,peer,wallet", 946 MaxPeers: 25, 947 MaxPendingPeers: 0, 948 IPCFile: "geth.ipc", 949 log: log.New("package", "status-go/params.NodeConfig"), 950 LogFile: "", 951 LogLevel: "ERROR", 952 NoDiscovery: true, 953 UpstreamConfig: UpstreamRPCConfig{ 954 URL: getUpstreamURL(networkID), 955 }, 956 LightEthConfig: LightEthConfig{ 957 DatabaseCache: 16, 958 }, 959 WakuConfig: WakuConfig{ 960 DataDir: wakuDir, 961 MinimumPoW: WakuMinimumPoW, 962 TTL: WakuTTL, 963 MaxMessageSize: wakucommon.DefaultMaxMessageSize, 964 }, 965 WakuV2Config: WakuV2Config{ 966 Host: "0.0.0.0", 967 Port: 0, 968 DataDir: wakuV2Dir, 969 MaxMessageSize: wakuv2common.DefaultMaxMessageSize, 970 }, 971 ShhextConfig: ShhextConfig{}, 972 SwarmConfig: SwarmConfig{}, 973 TorrentConfig: TorrentConfig{ 974 Enabled: false, 975 Port: 9025, 976 DataDir: dataDir + "/archivedata", 977 TorrentDir: dataDir + "/torrents", 978 }, 979 RegisterTopics: []discv5.Topic{}, 980 RequireTopics: map[discv5.Topic]Limits{}, 981 } 982 983 return config, nil 984 } 985 986 // NewConfigFromJSON parses incoming JSON and returned it as Config 987 func NewConfigFromJSON(configJSON string) (*NodeConfig, error) { 988 config, err := NewNodeConfig("", 0) 989 if err != nil { 990 return nil, err 991 } 992 993 if err := loadConfigFromJSON(configJSON, config); err != nil { 994 return nil, err 995 } 996 997 if err := config.Validate(); err != nil { 998 return nil, err 999 } 1000 1001 return config, nil 1002 } 1003 1004 func LoadClusterConfigFromFleet(fleet string) (*ClusterConfig, error) { 1005 nodeConfig := &NodeConfig{} 1006 err := loadConfigFromAsset(fmt.Sprintf("../config/cli/fleet-%s.json", fleet), nodeConfig) 1007 if err != nil { 1008 return nil, err 1009 } 1010 1011 return &nodeConfig.ClusterConfig, nil 1012 } 1013 1014 func loadConfigFromJSON(configJSON string, nodeConfig *NodeConfig) error { 1015 decoder := json.NewDecoder(strings.NewReader(configJSON)) 1016 // override default configuration with values by JSON input 1017 return decoder.Decode(&nodeConfig) 1018 } 1019 1020 func loadConfigConfigFromFile(path string, config *NodeConfig) error { 1021 jsonConfig, err := ioutil.ReadFile(path) 1022 if err != nil { 1023 return err 1024 } 1025 return loadConfigFromJSON(string(jsonConfig), config) 1026 } 1027 1028 func loadConfigFromAsset(name string, config *NodeConfig) error { 1029 data, err := static.Asset(name) 1030 if err != nil { 1031 return err 1032 } 1033 return loadConfigFromJSON(string(data), config) 1034 } 1035 1036 // Validate checks if NodeConfig fields have valid values. 1037 // 1038 // It returns nil if there are no errors, otherwise one or more errors 1039 // can be returned. Multiple errors are joined with a new line. 1040 // 1041 // A single error for a struct: 1042 // 1043 // type TestStruct struct { 1044 // TestField string `validate:"required"` 1045 // } 1046 // 1047 // has the following format: 1048 // 1049 // Key: 'TestStruct.TestField' Error:Field validation for 'TestField' failed on the 'required' tag 1050 func (c *NodeConfig) Validate() error { 1051 validate := NewValidator() 1052 1053 if err := validate.Struct(c); err != nil { 1054 return err 1055 } 1056 1057 if c.NodeKey != "" { 1058 if _, err := crypto.HexToECDSA(c.NodeKey); err != nil { 1059 return fmt.Errorf("NodeKey is invalid (%s): %v", c.NodeKey, err) 1060 } 1061 } 1062 1063 if c.UpstreamConfig.Enabled && c.LightEthConfig.Enabled { 1064 return fmt.Errorf("both UpstreamConfig and LightEthConfig are enabled, but they are mutually exclusive") 1065 } 1066 1067 if err := c.validateChildStructs(validate); err != nil { 1068 return err 1069 } 1070 1071 if c.WakuConfig.Enabled && c.WakuV2Config.Enabled && c.WakuConfig.DataDir == c.WakuV2Config.DataDir { 1072 return fmt.Errorf("both Waku and WakuV2 are enabled and use the same data dir") 1073 } 1074 1075 // Waku's data directory must be relative to the main data directory 1076 // if EnableMailServer is true. 1077 if c.WakuConfig.Enabled && c.WakuConfig.EnableMailServer { 1078 if !strings.HasPrefix(c.WakuConfig.DataDir, c.DataDir) { 1079 return fmt.Errorf("WakuConfig.DataDir must start with DataDir fragment") 1080 } 1081 } 1082 1083 if !c.NoDiscovery && len(c.ClusterConfig.BootNodes) == 0 { 1084 // No point in running discovery if we don't have bootnodes. 1085 // In case we do have bootnodes, NoDiscovery should be true. 1086 return fmt.Errorf("NoDiscovery is false, but ClusterConfig.BootNodes is empty") 1087 } 1088 1089 if c.ShhextConfig.PFSEnabled && len(c.ShhextConfig.InstallationID) == 0 { 1090 return fmt.Errorf("PFSEnabled is true, but InstallationID is empty") 1091 } 1092 1093 return nil 1094 } 1095 1096 func (c *NodeConfig) validateChildStructs(validate *validator.Validate) error { 1097 // Validate child structs 1098 if err := c.UpstreamConfig.Validate(validate); err != nil { 1099 return err 1100 } 1101 if err := c.ClusterConfig.Validate(validate); err != nil { 1102 return err 1103 } 1104 if err := c.LightEthConfig.Validate(validate); err != nil { 1105 return err 1106 } 1107 if err := c.SwarmConfig.Validate(validate); err != nil { 1108 return err 1109 } 1110 if err := c.ShhextConfig.Validate(validate); err != nil { 1111 return err 1112 } 1113 if err := c.TorrentConfig.Validate(validate); err != nil { 1114 return err 1115 } 1116 return nil 1117 } 1118 1119 // Validate validates the UpstreamRPCConfig struct and returns an error if inconsistent values are found 1120 func (c *UpstreamRPCConfig) Validate(validate *validator.Validate) error { 1121 if !c.Enabled { 1122 return nil 1123 } 1124 1125 if err := validate.Struct(c); err != nil { 1126 return err 1127 } 1128 1129 if _, err := url.ParseRequestURI(c.URL); err != nil { 1130 return fmt.Errorf("UpstreamRPCConfig.URL '%s' is invalid: %v", c.URL, err.Error()) 1131 } 1132 1133 return nil 1134 } 1135 1136 // Validate validates the ClusterConfig struct and returns an error if inconsistent values are found 1137 func (c *ClusterConfig) Validate(validate *validator.Validate) error { 1138 if !c.Enabled { 1139 return nil 1140 } 1141 1142 if err := validate.Struct(c); err != nil { 1143 return err 1144 } 1145 1146 return nil 1147 } 1148 1149 // Validate validates the LightEthConfig struct and returns an error if inconsistent values are found 1150 func (c *LightEthConfig) Validate(validate *validator.Validate) error { 1151 if !c.Enabled { 1152 return nil 1153 } 1154 1155 if err := validate.Struct(c); err != nil { 1156 return err 1157 } 1158 1159 return nil 1160 } 1161 1162 // Validate validates the SwarmConfig struct and returns an error if inconsistent values are found 1163 func (c *SwarmConfig) Validate(validate *validator.Validate) error { 1164 if !c.Enabled { 1165 return nil 1166 } 1167 1168 if err := validate.Struct(c); err != nil { 1169 return err 1170 } 1171 1172 return nil 1173 } 1174 1175 func (c *TorrentConfig) Validate(validate *validator.Validate) error { 1176 if !c.Enabled { 1177 return nil 1178 } 1179 1180 if err := validate.Struct(c); err != nil { 1181 return err 1182 } 1183 1184 if c.Enabled && (c.DataDir == "" || c.TorrentDir == "") { 1185 return fmt.Errorf("TorrentConfig.DataDir and TorrentConfig.TorrentDir cannot be \"\"") 1186 } 1187 return nil 1188 } 1189 1190 func getUpstreamURL(networkID uint64) string { 1191 switch networkID { 1192 case MainNetworkID: 1193 return MainnetEthereumNetworkURL 1194 case GoerliNetworkID: 1195 return GoerliEthereumNetworkURL 1196 } 1197 1198 return "" 1199 } 1200 1201 // Save dumps configuration to the disk 1202 func (c *NodeConfig) Save() error { 1203 data, err := json.MarshalIndent(c, "", " ") 1204 if err != nil { 1205 return err 1206 } 1207 1208 if err := os.MkdirAll(c.DataDir, os.ModePerm); err != nil { 1209 return err 1210 } 1211 1212 configFilePath := filepath.Join(c.DataDir, "config.json") 1213 if err := ioutil.WriteFile(configFilePath, data, os.ModePerm); err != nil { 1214 return err 1215 } 1216 1217 c.log.Info("config file saved", "path", configFilePath) 1218 return nil 1219 } 1220 1221 // String dumps config object as nicely indented JSON 1222 func (c *NodeConfig) String() string { 1223 data, _ := json.MarshalIndent(c, "", " ") 1224 return string(data) 1225 } 1226 1227 // FormatAPIModules returns a slice of APIModules. 1228 func (c *NodeConfig) FormatAPIModules() []string { 1229 if len(c.APIModules) == 0 { 1230 return nil 1231 } 1232 1233 return strings.Split(c.APIModules, ",") 1234 } 1235 1236 // AddAPIModule adds a mobule to APIModules 1237 func (c *NodeConfig) AddAPIModule(m string) { 1238 c.APIModules = fmt.Sprintf("%s,%s", c.APIModules, m) 1239 } 1240 1241 // LesTopic returns discovery v5 topic derived from genesis of the provided network. 1242 // 1 - mainnet, 5 - goerli 1243 func LesTopic(netid int) string { 1244 switch netid { 1245 case 1: 1246 return LESDiscoveryIdentifier + types.Bytes2Hex(params.MainnetGenesisHash.Bytes()[:8]) 1247 case 5: 1248 return LESDiscoveryIdentifier + types.Bytes2Hex(params.RinkebyGenesisHash.Bytes()[:8]) 1249 default: 1250 return "" 1251 } 1252 }