github.com/status-im/status-go@v1.1.0/nodecfg/node_config.go (about)

     1  package nodecfg
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  
     7  	"github.com/ethereum/go-ethereum/common/hexutil"
     8  	"github.com/ethereum/go-ethereum/p2p/discv5"
     9  	"github.com/status-im/status-go/eth-node/crypto"
    10  	"github.com/status-im/status-go/params"
    11  	"github.com/status-im/status-go/sqlite"
    12  )
    13  
    14  const StaticNodes = "static"
    15  const BootNodes = "boot"
    16  const TrustedMailServers = "trusted_mailserver"
    17  const PushNotificationsServers = "pushnotification"
    18  const RendezvousNodes = "rendezvous"
    19  const DiscV5BootstrapNodes = "discV5boot"
    20  const WakuNodes = "waku"
    21  
    22  func nodeConfigWasMigrated(tx *sql.Tx) (migrated bool, err error) {
    23  	row := tx.QueryRow("SELECT exists(SELECT 1 FROM node_config)")
    24  	switch err := row.Scan(&migrated); err {
    25  	case sql.ErrNoRows, nil:
    26  		return migrated, nil
    27  	default:
    28  		return migrated, err
    29  	}
    30  }
    31  
    32  type insertFn func(tx *sql.Tx, c *params.NodeConfig) error
    33  
    34  func insertNodeConfig(tx *sql.Tx, c *params.NodeConfig) error {
    35  	_, err := tx.Exec(`
    36  	INSERT OR REPLACE INTO node_config (
    37  		network_id, data_dir, keystore_dir, node_key, no_discovery, 
    38  		listen_addr, advertise_addr, name, version, api_modules, tls_enabled,
    39  		max_peers, max_pending_peers, enable_status_service, enable_ntp_sync,
    40  		bridge_enabled, wallet_enabled, local_notifications_enabled,
    41  		browser_enabled, permissions_enabled, mailservers_enabled,
    42  		swarm_enabled, mailserver_registry_address, web3provider_enabled, connector_enabled,
    43  		synthetic_id
    44  	) VALUES (
    45  		?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
    46  		?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
    47  		?, ?, ?, ?, ?, 'id'
    48  	)`,
    49  		c.NetworkID, c.DataDir, c.KeyStoreDir, c.NodeKey, c.NoDiscovery,
    50  		c.ListenAddr, c.AdvertiseAddr, c.Name, c.Version, c.APIModules,
    51  		c.TLSEnabled, c.MaxPeers, c.MaxPendingPeers,
    52  		c.EnableStatusService, true,
    53  		c.BridgeConfig.Enabled, c.WalletConfig.Enabled, c.LocalNotificationsConfig.Enabled,
    54  		c.BrowsersConfig.Enabled, c.PermissionsConfig.Enabled, c.MailserversConfig.Enabled,
    55  		c.SwarmConfig.Enabled, c.MailServerRegistryAddress, c.Web3ProviderConfig.Enabled,
    56  		c.ConnectorConfig.Enabled,
    57  	)
    58  	return err
    59  }
    60  
    61  func insertHTTPConfig(tx *sql.Tx, c *params.NodeConfig) error {
    62  	if _, err := tx.Exec(`INSERT OR REPLACE INTO http_config (enabled, host, port, synthetic_id) VALUES (?, ?, ?, 'id')`, c.HTTPEnabled, c.HTTPHost, c.HTTPPort); err != nil {
    63  		return err
    64  	}
    65  
    66  	if _, err := tx.Exec(`DELETE FROM http_virtual_hosts WHERE synthetic_id = 'id'`); err != nil {
    67  		return err
    68  	}
    69  
    70  	for _, httpVirtualHost := range c.HTTPVirtualHosts {
    71  		if _, err := tx.Exec(`INSERT OR REPLACE INTO http_virtual_hosts (host, synthetic_id) VALUES (?, 'id')`, httpVirtualHost); err != nil {
    72  			return err
    73  		}
    74  	}
    75  
    76  	if _, err := tx.Exec(`DELETE FROM http_cors WHERE synthetic_id = 'id'`); err != nil {
    77  		return err
    78  	}
    79  
    80  	for _, httpCors := range c.HTTPCors {
    81  		if _, err := tx.Exec(`INSERT OR REPLACE INTO http_cors (cors, synthetic_id) VALUES (?, 'id')`, httpCors); err != nil {
    82  			return err
    83  		}
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  func insertLogConfig(tx *sql.Tx, c *params.NodeConfig) error {
    90  	_, err := tx.Exec(`
    91  	INSERT OR REPLACE INTO log_config (
    92  		enabled, mobile_system, log_dir, log_level, max_backups, max_size,
    93  		file, compress_rotated, log_to_stderr, synthetic_id
    94  	) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'id'	)`,
    95  		c.LogEnabled, c.LogMobileSystem, c.LogDir, c.LogLevel, c.LogMaxBackups, c.LogMaxSize,
    96  		c.LogFile, c.LogCompressRotated, c.LogToStderr,
    97  	)
    98  
    99  	return err
   100  }
   101  
   102  func insertLightETHConfigTrustedNodes(tx *sql.Tx, c *params.NodeConfig) error {
   103  	if _, err := tx.Exec(`DELETE FROM light_eth_trusted_nodes WHERE synthetic_id = 'id'`); err != nil {
   104  		return err
   105  	}
   106  
   107  	for _, node := range c.LightEthConfig.TrustedNodes {
   108  		_, err := tx.Exec(`INSERT OR REPLACE INTO light_eth_trusted_nodes (node, synthetic_id) VALUES (?, 'id')`, node)
   109  		if err != nil {
   110  			return err
   111  		}
   112  	}
   113  	return nil
   114  }
   115  
   116  func insertRegisterTopics(tx *sql.Tx, c *params.NodeConfig) error {
   117  	if _, err := tx.Exec(`DELETE FROM register_topics WHERE synthetic_id = 'id'`); err != nil {
   118  		return err
   119  	}
   120  
   121  	for _, topic := range c.RegisterTopics {
   122  		_, err := tx.Exec(`INSERT OR REPLACE INTO register_topics (topic, synthetic_id) VALUES (?, 'id')`, topic)
   123  		if err != nil {
   124  			return err
   125  		}
   126  	}
   127  	return nil
   128  }
   129  
   130  func insertRequireTopics(tx *sql.Tx, c *params.NodeConfig) error {
   131  	if _, err := tx.Exec(`DELETE FROM require_topics WHERE synthetic_id = 'id'`); err != nil {
   132  		return err
   133  	}
   134  
   135  	for topic, limits := range c.RequireTopics {
   136  		_, err := tx.Exec(`INSERT OR REPLACE INTO require_topics (topic, min, max, synthetic_id) VALUES (?, ?, ?, 'id')`, topic, limits.Min, limits.Max)
   137  		if err != nil {
   138  			return err
   139  		}
   140  	}
   141  	return nil
   142  }
   143  
   144  func insertIPCConfig(tx *sql.Tx, c *params.NodeConfig) error {
   145  	_, err := tx.Exec(`INSERT OR REPLACE INTO ipc_config (enabled, file, synthetic_id) VALUES (?, ?, 'id')`, c.IPCEnabled, c.IPCFile)
   146  	return err
   147  }
   148  
   149  func insertClusterConfig(tx *sql.Tx, c *params.NodeConfig) error {
   150  	_, err := tx.Exec(`INSERT OR REPLACE INTO cluster_config (enabled, fleet, synthetic_id) VALUES (?, ?, 'id')`, c.ClusterConfig.Enabled, c.ClusterConfig.Fleet)
   151  	return err
   152  }
   153  
   154  func insertUpstreamConfig(tx *sql.Tx, c *params.NodeConfig) error {
   155  	_, err := tx.Exec(`INSERT OR REPLACE INTO upstream_config (enabled, url, synthetic_id) VALUES (?, ?, 'id')`, c.UpstreamConfig.Enabled, c.UpstreamConfig.URL)
   156  	return err
   157  }
   158  
   159  func insertLightETHConfig(tx *sql.Tx, c *params.NodeConfig) error {
   160  	_, err := tx.Exec(`INSERT OR REPLACE INTO light_eth_config (enabled, database_cache, min_trusted_fraction, synthetic_id) VALUES (?, ?, ?, 'id')`, c.LightEthConfig.Enabled, c.LightEthConfig.DatabaseCache, c.LightEthConfig.MinTrustedFraction)
   161  	return err
   162  }
   163  
   164  func insertShhExtConfig(tx *sql.Tx, c *params.NodeConfig) error {
   165  	_, err := tx.Exec(`
   166  	INSERT OR REPLACE INTO shhext_config (
   167  		pfs_enabled, installation_id, mailserver_confirmations, enable_connection_manager,
   168  		enable_last_used_monitor, connection_target, request_delay, max_server_failures, max_message_delivery_attempts,
   169  		whisper_cache_dir, disable_generic_discovery_topic, send_v1_messages, data_sync_enabled, verify_transaction_url,
   170  		verify_ens_url, verify_ens_contract_address, verify_transaction_chain_id, anon_metrics_server_enabled,
   171  		anon_metrics_send_id, anon_metrics_server_postgres_uri, bandwidth_stats_enabled, synthetic_id
   172  	) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'id')`,
   173  		c.ShhextConfig.PFSEnabled, c.ShhextConfig.InstallationID, c.ShhextConfig.MailServerConfirmations, c.ShhextConfig.EnableConnectionManager,
   174  		c.ShhextConfig.EnableLastUsedMonitor, c.ShhextConfig.ConnectionTarget, c.ShhextConfig.RequestsDelay, c.ShhextConfig.MaxServerFailures, c.ShhextConfig.MaxMessageDeliveryAttempts,
   175  		c.ShhextConfig.WhisperCacheDir, c.ShhextConfig.DisableGenericDiscoveryTopic, c.ShhextConfig.SendV1Messages, c.ShhextConfig.DataSyncEnabled, c.ShhextConfig.VerifyTransactionURL,
   176  		c.ShhextConfig.VerifyENSURL, c.ShhextConfig.VerifyENSContractAddress, c.ShhextConfig.VerifyTransactionChainID, c.ShhextConfig.AnonMetricsServerEnabled,
   177  		c.ShhextConfig.AnonMetricsSendID, c.ShhextConfig.AnonMetricsServerPostgresURI, c.ShhextConfig.BandwidthStatsEnabled)
   178  	if err != nil {
   179  		return err
   180  	}
   181  
   182  	if _, err := tx.Exec(`DELETE FROM shhext_default_push_notification_servers WHERE synthetic_id = 'id'`); err != nil {
   183  		return err
   184  	}
   185  
   186  	for _, pushNotifServ := range c.ShhextConfig.DefaultPushNotificationsServers {
   187  		hexpubk := hexutil.Encode(crypto.FromECDSAPub(pushNotifServ.PublicKey))
   188  		_, err := tx.Exec(`INSERT OR REPLACE INTO shhext_default_push_notification_servers (public_key, synthetic_id) VALUES (?, 'id')`, hexpubk)
   189  		if err != nil {
   190  			return err
   191  		}
   192  	}
   193  	return nil
   194  }
   195  
   196  func insertTorrentConfig(tx *sql.Tx, c *params.NodeConfig) error {
   197  	_, err := tx.Exec(`
   198    INSERT OR REPLACE INTO torrent_config (
   199      enabled, port, data_dir, torrent_dir, synthetic_id
   200    ) VALUES (?, ?, ?, ?, 'id')`,
   201  		c.TorrentConfig.Enabled, c.TorrentConfig.Port, c.TorrentConfig.DataDir, c.TorrentConfig.TorrentDir,
   202  	)
   203  	return err
   204  }
   205  
   206  func insertWakuV2ConfigPreMigration(tx *sql.Tx, c *params.NodeConfig) error {
   207  	_, err := tx.Exec(`
   208  	INSERT OR REPLACE INTO wakuv2_config (
   209  		enabled, host, port, light_client, full_node, discovery_limit, data_dir,
   210  		max_message_size, enable_confirmations, peer_exchange, enable_discv5, udp_port,  auto_update, synthetic_id
   211  	) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'id')`,
   212  		c.WakuV2Config.Enabled, c.WakuV2Config.Host, c.WakuV2Config.Port, c.WakuV2Config.LightClient, c.WakuV2Config.FullNode, c.WakuV2Config.DiscoveryLimit, c.WakuV2Config.DataDir,
   213  		c.WakuV2Config.MaxMessageSize, c.WakuV2Config.EnableConfirmations, c.WakuV2Config.PeerExchange, c.WakuV2Config.EnableDiscV5, c.WakuV2Config.UDPPort, c.WakuV2Config.AutoUpdate,
   214  	)
   215  	if err != nil {
   216  		return err
   217  	}
   218  
   219  	return setWakuV2CustomNodes(tx, c.WakuV2Config.CustomNodes)
   220  }
   221  
   222  func setWakuV2CustomNodes(tx *sql.Tx, customNodes map[string]string) error {
   223  	if _, err := tx.Exec(`DELETE FROM wakuv2_custom_nodes WHERE synthetic_id = 'id'`); err != nil {
   224  		return err
   225  	}
   226  
   227  	for name, multiaddress := range customNodes {
   228  		// NOTE: synthetic id is redundant, name is effectively the primary key
   229  		_, err := tx.Exec(`INSERT OR REPLACE INTO wakuv2_custom_nodes (name, multiaddress, synthetic_id) VALUES (?, ?, 'id')`, name, multiaddress)
   230  		if err != nil {
   231  			return err
   232  		}
   233  	}
   234  	return nil
   235  }
   236  
   237  func insertWakuV2ConfigPostMigration(tx *sql.Tx, c *params.NodeConfig) error {
   238  	_, err := tx.Exec(`
   239  	UPDATE wakuv2_config
   240  	SET enable_store = ?,
   241  		store_capacity = ?,
   242  		store_seconds = ?,
   243  		enable_missing_message_verification = ?,
   244  		enable_store_confirmation_for_messages_sent = ?
   245  	WHERE synthetic_id = 'id'`,
   246  		c.WakuV2Config.EnableStore, c.WakuV2Config.StoreCapacity, c.WakuV2Config.StoreSeconds,
   247  		c.WakuV2Config.EnableMissingMessageVerification, c.WakuV2Config.EnableStoreConfirmationForMessagesSent,
   248  	)
   249  
   250  	if err != nil {
   251  		return err
   252  	}
   253  
   254  	_, err = tx.Exec(`
   255  	UPDATE cluster_config
   256  	SET cluster_id = ?
   257  	WHERE synthetic_id = 'id'`,
   258  		c.ClusterConfig.ClusterID,
   259  	)
   260  
   261  	return err
   262  }
   263  
   264  func insertWakuV1Config(tx *sql.Tx, c *params.NodeConfig) error {
   265  	_, err := tx.Exec(`
   266  	INSERT OR REPLACE INTO waku_config (
   267  		enabled, light_client, full_node, enable_mailserver, data_dir, minimum_pow, mailserver_password, mailserver_rate_limit, mailserver_data_retention,
   268  		ttl, max_message_size, enable_rate_limiter, packet_rate_limit_ip, packet_rate_limit_peer_id, bytes_rate_limit_ip, bytes_rate_limit_peer_id,
   269  		rate_limit_tolerance, bloom_filter_mode, enable_confirmations, synthetic_id
   270  	) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'id')`,
   271  		c.WakuConfig.Enabled, c.WakuConfig.LightClient, c.WakuConfig.FullNode, c.WakuConfig.EnableMailServer, c.WakuConfig.DataDir, c.WakuConfig.MinimumPoW,
   272  		c.WakuConfig.MailServerPassword, c.WakuConfig.MailServerRateLimit, c.WakuConfig.MailServerDataRetention, c.WakuConfig.TTL, c.WakuConfig.MaxMessageSize,
   273  		c.WakuConfig.EnableRateLimiter, c.WakuConfig.PacketRateLimitIP, c.WakuConfig.PacketRateLimitPeerID, c.WakuConfig.BytesRateLimitIP, c.WakuConfig.BytesRateLimitPeerID,
   274  		c.WakuConfig.RateLimitTolerance, c.WakuConfig.BloomFilterMode, c.WakuConfig.EnableConfirmations,
   275  	)
   276  	if err != nil {
   277  		return err
   278  	}
   279  
   280  	if _, err := tx.Exec(`INSERT OR REPLACE INTO waku_config_db_pg (enabled, uri, synthetic_id) VALUES (?, ?, 'id')`, c.WakuConfig.DatabaseConfig.PGConfig.Enabled, c.WakuConfig.DatabaseConfig.PGConfig.URI); err != nil {
   281  		return err
   282  	}
   283  
   284  	if _, err := tx.Exec(`DELETE FROM waku_softblacklisted_peers WHERE synthetic_id = 'id'`); err != nil {
   285  		return err
   286  	}
   287  
   288  	for _, peerID := range c.WakuConfig.SoftBlacklistedPeerIDs {
   289  		_, err := tx.Exec(`INSERT OR REPLACE INTO waku_softblacklisted_peers (peer_id, synthetic_id) VALUES (?, 'id')`, peerID)
   290  		if err != nil {
   291  			return err
   292  		}
   293  	}
   294  	return nil
   295  }
   296  
   297  func insertPushNotificationsServerConfig(tx *sql.Tx, c *params.NodeConfig) error {
   298  	hexPrivKey := ""
   299  	if c.PushNotificationServerConfig.Identity != nil {
   300  		hexPrivKey = hexutil.Encode(crypto.FromECDSA(c.PushNotificationServerConfig.Identity))
   301  	}
   302  	_, err := tx.Exec(`INSERT OR REPLACE INTO push_notifications_server_config (enabled, identity, gorush_url, synthetic_id) VALUES (?, ?, ?, 'id')`, c.PushNotificationServerConfig.Enabled, hexPrivKey, c.PushNotificationServerConfig.GorushURL)
   303  	return err
   304  }
   305  
   306  func insertClusterConfigNodes(tx *sql.Tx, c *params.NodeConfig) error {
   307  	if _, err := tx.Exec(`DELETE FROM cluster_nodes WHERE synthetic_id = 'id'`); err != nil {
   308  		return err
   309  	}
   310  
   311  	nodeMap := make(map[string][]string)
   312  	nodeMap[StaticNodes] = c.ClusterConfig.StaticNodes
   313  	nodeMap[BootNodes] = c.ClusterConfig.BootNodes
   314  	nodeMap[TrustedMailServers] = c.ClusterConfig.TrustedMailServers
   315  	nodeMap[PushNotificationsServers] = c.ClusterConfig.PushNotificationsServers
   316  	nodeMap[DiscV5BootstrapNodes] = c.ClusterConfig.DiscV5BootstrapNodes
   317  	nodeMap[WakuNodes] = c.ClusterConfig.WakuNodes
   318  
   319  	for nodeType, nodes := range nodeMap {
   320  		for _, node := range nodes {
   321  			_, err := tx.Exec(`INSERT OR REPLACE INTO cluster_nodes (node, type, synthetic_id) VALUES (?, ?, 'id')`, node, nodeType)
   322  			if err != nil {
   323  				return err
   324  			}
   325  		}
   326  	}
   327  
   328  	return nil
   329  }
   330  
   331  // List of inserts to be executed when upgrading a node
   332  // These INSERT queries should not be modified
   333  func nodeConfigUpgradeInserts() []insertFn {
   334  	return []insertFn{
   335  		insertNodeConfig,
   336  		insertHTTPConfig,
   337  		insertIPCConfig,
   338  		insertLogConfig,
   339  		insertUpstreamConfig,
   340  		insertClusterConfig,
   341  		insertClusterConfigNodes,
   342  		insertLightETHConfig,
   343  		insertLightETHConfigTrustedNodes,
   344  		insertRegisterTopics,
   345  		insertRequireTopics,
   346  		insertPushNotificationsServerConfig,
   347  		insertShhExtConfig,
   348  		insertWakuV1Config,
   349  		insertWakuV2ConfigPreMigration,
   350  	}
   351  }
   352  
   353  func nodeConfigNormalInserts() []insertFn {
   354  	// WARNING: if you are modifying one of the node config tables
   355  	// you need to edit `nodeConfigUpgradeInserts` to guarantee that
   356  	// the selects being used there are not affected.
   357  
   358  	return []insertFn{
   359  		insertNodeConfig,
   360  		insertHTTPConfig,
   361  		insertIPCConfig,
   362  		insertLogConfig,
   363  		insertUpstreamConfig,
   364  		insertClusterConfig,
   365  		insertClusterConfigNodes,
   366  		insertLightETHConfig,
   367  		insertLightETHConfigTrustedNodes,
   368  		insertRegisterTopics,
   369  		insertRequireTopics,
   370  		insertPushNotificationsServerConfig,
   371  		insertShhExtConfig,
   372  		insertWakuV1Config,
   373  		insertWakuV2ConfigPreMigration,
   374  		insertTorrentConfig,
   375  		insertWakuV2ConfigPostMigration,
   376  	}
   377  }
   378  
   379  func execInsertFns(inFn []insertFn, tx *sql.Tx, c *params.NodeConfig) error {
   380  	for _, fn := range inFn {
   381  		err := fn(tx, c)
   382  		if err != nil {
   383  			return err
   384  		}
   385  	}
   386  
   387  	return nil
   388  }
   389  
   390  func insertNodeConfigUpgrade(tx *sql.Tx, c *params.NodeConfig) error {
   391  	return execInsertFns(nodeConfigUpgradeInserts(), tx, c)
   392  }
   393  
   394  func SaveConfigWithTx(tx *sql.Tx, c *params.NodeConfig) error {
   395  	insertFNs := nodeConfigNormalInserts()
   396  	return execInsertFns(insertFNs, tx, c)
   397  }
   398  
   399  func SaveNodeConfig(db *sql.DB, c *params.NodeConfig) error {
   400  	tx, err := db.BeginTx(context.Background(), &sql.TxOptions{})
   401  	if err != nil {
   402  		return err
   403  	}
   404  
   405  	defer func() {
   406  		if err == nil {
   407  			err = tx.Commit()
   408  			return
   409  		}
   410  		// don't shadow original error
   411  		_ = tx.Rollback()
   412  	}()
   413  
   414  	return SaveConfigWithTx(tx, c)
   415  }
   416  
   417  func migrateNodeConfig(tx *sql.Tx) error {
   418  	nodecfg := &params.NodeConfig{}
   419  	err := tx.QueryRow("SELECT node_config FROM settings WHERE synthetic_id = 'id'").Scan(&sqlite.JSONBlob{Data: nodecfg})
   420  
   421  	if err != nil && err != sql.ErrNoRows {
   422  		return err
   423  	}
   424  
   425  	if err == sql.ErrNoRows {
   426  		// Can't migrate because there's no data
   427  		return nil
   428  	}
   429  
   430  	err = insertNodeConfigUpgrade(tx, nodecfg)
   431  	if err != nil {
   432  		return err
   433  	}
   434  
   435  	return nil
   436  }
   437  
   438  func loadNodeConfig(tx *sql.Tx) (*params.NodeConfig, error) {
   439  	nodecfg := &params.NodeConfig{}
   440  
   441  	err := tx.QueryRow(`
   442  	SELECT
   443  		network_id, data_dir, keystore_dir, node_key, no_discovery,
   444  		listen_addr, advertise_addr, name, version, api_modules, tls_enabled, max_peers, max_pending_peers,
   445  		enable_status_service, bridge_enabled, wallet_enabled, local_notifications_enabled,
   446  		browser_enabled, permissions_enabled, mailservers_enabled, swarm_enabled,
   447  		mailserver_registry_address, web3provider_enabled, connector_enabled FROM node_config
   448  		WHERE synthetic_id = 'id'
   449  	`).Scan(
   450  		&nodecfg.NetworkID, &nodecfg.DataDir, &nodecfg.KeyStoreDir, &nodecfg.NodeKey, &nodecfg.NoDiscovery,
   451  		&nodecfg.ListenAddr, &nodecfg.AdvertiseAddr, &nodecfg.Name, &nodecfg.Version, &nodecfg.APIModules, &nodecfg.TLSEnabled, &nodecfg.MaxPeers, &nodecfg.MaxPendingPeers,
   452  		&nodecfg.EnableStatusService, &nodecfg.BridgeConfig.Enabled, &nodecfg.WalletConfig.Enabled, &nodecfg.LocalNotificationsConfig.Enabled,
   453  		&nodecfg.BrowsersConfig.Enabled, &nodecfg.PermissionsConfig.Enabled, &nodecfg.MailserversConfig.Enabled, &nodecfg.SwarmConfig.Enabled,
   454  		&nodecfg.MailServerRegistryAddress, &nodecfg.Web3ProviderConfig.Enabled, &nodecfg.ConnectorConfig.Enabled,
   455  	)
   456  	if err != nil && err != sql.ErrNoRows {
   457  		return nil, err
   458  	}
   459  
   460  	err = tx.QueryRow(`SELECT enabled, host, port FROM http_config WHERE synthetic_id = 'id'`).Scan(&nodecfg.HTTPEnabled, &nodecfg.HTTPHost, &nodecfg.HTTPPort)
   461  	if err != nil && err != sql.ErrNoRows {
   462  		return nil, err
   463  	}
   464  
   465  	rows, err := tx.Query("SELECT host FROM http_virtual_hosts WHERE synthetic_id = 'id' ORDER BY host ASC")
   466  	if err != nil && err != sql.ErrNoRows {
   467  		return nil, err
   468  	}
   469  	defer rows.Close()
   470  	for rows.Next() {
   471  		var host string
   472  		err = rows.Scan(&host)
   473  		if err != nil {
   474  			return nil, err
   475  		}
   476  		nodecfg.HTTPVirtualHosts = append(nodecfg.HTTPVirtualHosts, host)
   477  	}
   478  
   479  	rows, err = tx.Query("SELECT cors FROM http_cors WHERE synthetic_id = 'id' ORDER BY cors ASC")
   480  	if err != nil && err != sql.ErrNoRows {
   481  		return nil, err
   482  	}
   483  	defer rows.Close()
   484  	for rows.Next() {
   485  		var cors string
   486  		err = rows.Scan(&cors)
   487  		if err != nil {
   488  			return nil, err
   489  		}
   490  		nodecfg.HTTPCors = append(nodecfg.HTTPCors, cors)
   491  	}
   492  
   493  	err = tx.QueryRow("SELECT enabled, file FROM ipc_config WHERE synthetic_id = 'id'").Scan(&nodecfg.IPCEnabled, &nodecfg.IPCFile)
   494  	if err != nil && err != sql.ErrNoRows {
   495  		return nil, err
   496  	}
   497  
   498  	err = tx.QueryRow("SELECT enabled, mobile_system, log_dir, log_level, file, max_backups, max_size, compress_rotated, log_to_stderr FROM log_config WHERE synthetic_id = 'id'").Scan(
   499  		&nodecfg.LogEnabled, &nodecfg.LogMobileSystem, &nodecfg.LogDir, &nodecfg.LogLevel, &nodecfg.LogFile, &nodecfg.LogMaxBackups, &nodecfg.LogMaxSize, &nodecfg.LogCompressRotated, &nodecfg.LogToStderr)
   500  	if err != nil && err != sql.ErrNoRows {
   501  		return nil, err
   502  	}
   503  
   504  	err = tx.QueryRow("SELECT enabled, url FROM upstream_config WHERE synthetic_id = 'id'").Scan(&nodecfg.UpstreamConfig.Enabled, &nodecfg.UpstreamConfig.URL)
   505  	if err != nil && err != sql.ErrNoRows {
   506  		return nil, err
   507  	}
   508  
   509  	rows, err = tx.Query(`SELECT
   510                  chain_id, chain_name, rpc_url, block_explorer_url, icon_url, native_currency_name,
   511                  native_currency_symbol, native_currency_decimals, is_test, layer, enabled, chain_color, short_name
   512          FROM networks ORDER BY chain_id ASC`)
   513  	if err != nil && err != sql.ErrNoRows {
   514  		return nil, err
   515  	}
   516  	defer rows.Close()
   517  	for rows.Next() {
   518  		var n params.Network
   519  		err = rows.Scan(&n.ChainID, &n.ChainName, &n.RPCURL, &n.BlockExplorerURL, &n.IconURL,
   520  			&n.NativeCurrencyName, &n.NativeCurrencySymbol, &n.NativeCurrencyDecimals, &n.IsTest,
   521  			&n.Layer, &n.Enabled, &n.ChainColor, &n.ShortName,
   522  		)
   523  		if err != nil {
   524  			return nil, err
   525  		}
   526  		nodecfg.Networks = append(nodecfg.Networks, n)
   527  	}
   528  
   529  	err = tx.QueryRow("SELECT enabled, fleet, cluster_id FROM cluster_config WHERE synthetic_id = 'id'").Scan(&nodecfg.ClusterConfig.Enabled, &nodecfg.ClusterConfig.Fleet, &nodecfg.ClusterConfig.ClusterID)
   530  	if err != nil && err != sql.ErrNoRows {
   531  		return nil, err
   532  	}
   533  
   534  	nodeMap := make(map[string]*[]string)
   535  	nodeMap[StaticNodes] = &nodecfg.ClusterConfig.StaticNodes
   536  	nodeMap[BootNodes] = &nodecfg.ClusterConfig.BootNodes
   537  	nodeMap[TrustedMailServers] = &nodecfg.ClusterConfig.TrustedMailServers
   538  	nodeMap[PushNotificationsServers] = &nodecfg.ClusterConfig.PushNotificationsServers
   539  	nodeMap[WakuNodes] = &nodecfg.ClusterConfig.WakuNodes
   540  	nodeMap[DiscV5BootstrapNodes] = &nodecfg.ClusterConfig.DiscV5BootstrapNodes
   541  	rows, err = tx.Query(`SELECT node, type	FROM cluster_nodes WHERE synthetic_id = 'id' ORDER BY node ASC`)
   542  	if err != nil && err != sql.ErrNoRows {
   543  		return nil, err
   544  	}
   545  	defer rows.Close()
   546  	for rows.Next() {
   547  		var node string
   548  		var nodeType string
   549  		err = rows.Scan(&node, &nodeType)
   550  		if err != nil {
   551  			return nil, err
   552  		}
   553  		if nodeList, ok := nodeMap[nodeType]; ok {
   554  			*nodeList = append(*nodeList, node)
   555  		}
   556  	}
   557  
   558  	err = tx.QueryRow("SELECT enabled, database_cache, min_trusted_fraction FROM light_eth_config WHERE synthetic_id = 'id'").Scan(&nodecfg.LightEthConfig.Enabled, &nodecfg.LightEthConfig.DatabaseCache, &nodecfg.LightEthConfig.MinTrustedFraction)
   559  	if err != nil && err != sql.ErrNoRows {
   560  		return nil, err
   561  	}
   562  
   563  	rows, err = tx.Query(`SELECT node FROM light_eth_trusted_nodes WHERE synthetic_id = 'id' ORDER BY node ASC`)
   564  	if err != nil && err != sql.ErrNoRows {
   565  		return nil, err
   566  	}
   567  	defer rows.Close()
   568  	for rows.Next() {
   569  		var node string
   570  		err = rows.Scan(&node)
   571  		if err != nil {
   572  			return nil, err
   573  		}
   574  		nodecfg.LightEthConfig.TrustedNodes = append(nodecfg.LightEthConfig.TrustedNodes, node)
   575  	}
   576  
   577  	rows, err = tx.Query(`SELECT topic FROM register_topics WHERE synthetic_id = 'id' ORDER BY topic ASC`)
   578  	if err != nil && err != sql.ErrNoRows {
   579  		return nil, err
   580  	}
   581  	defer rows.Close()
   582  	for rows.Next() {
   583  		var topic discv5.Topic
   584  		err = rows.Scan(&topic)
   585  		if err != nil {
   586  			return nil, err
   587  		}
   588  		nodecfg.RegisterTopics = append(nodecfg.RegisterTopics, topic)
   589  	}
   590  
   591  	rows, err = tx.Query(`SELECT topic, min, max FROM require_topics WHERE synthetic_id = 'id' ORDER BY topic ASC`)
   592  	if err != nil && err != sql.ErrNoRows {
   593  		return nil, err
   594  	}
   595  	defer rows.Close()
   596  	nodecfg.RequireTopics = make(map[discv5.Topic]params.Limits)
   597  	for rows.Next() {
   598  		var topic discv5.Topic
   599  		var limit params.Limits
   600  		err = rows.Scan(&topic, &limit.Min, &limit.Max)
   601  		if err != nil {
   602  			return nil, err
   603  		}
   604  		nodecfg.RequireTopics[topic] = limit
   605  	}
   606  
   607  	var pushNotifHexIdentity string
   608  	err = tx.QueryRow("SELECT enabled, identity, gorush_url FROM push_notifications_server_config WHERE synthetic_id = 'id'").Scan(&nodecfg.PushNotificationServerConfig.Enabled, &pushNotifHexIdentity, &nodecfg.PushNotificationServerConfig.GorushURL)
   609  	if err != nil && err != sql.ErrNoRows {
   610  		return nil, err
   611  	}
   612  	if pushNotifHexIdentity != "" {
   613  		b, err := hexutil.Decode(pushNotifHexIdentity)
   614  		if err != nil {
   615  			return nil, err
   616  		}
   617  		nodecfg.PushNotificationServerConfig.Identity, err = crypto.ToECDSA(b)
   618  		if err != nil {
   619  			return nil, err
   620  		}
   621  	}
   622  
   623  	err = tx.QueryRow(`
   624  	SELECT pfs_enabled, installation_id, mailserver_confirmations, enable_connection_manager,
   625  	enable_last_used_monitor, connection_target, request_delay, max_server_failures, max_message_delivery_attempts,
   626  	whisper_cache_dir, disable_generic_discovery_topic, send_v1_messages, data_sync_enabled, verify_transaction_url,
   627  	verify_ens_url, verify_ens_contract_address, verify_transaction_chain_id, anon_metrics_server_enabled,
   628  	anon_metrics_send_id, anon_metrics_server_postgres_uri, bandwidth_stats_enabled FROM shhext_config WHERE synthetic_id = 'id'
   629  	`).Scan(
   630  		&nodecfg.ShhextConfig.PFSEnabled, &nodecfg.ShhextConfig.InstallationID, &nodecfg.ShhextConfig.MailServerConfirmations, &nodecfg.ShhextConfig.EnableConnectionManager,
   631  		&nodecfg.ShhextConfig.EnableLastUsedMonitor, &nodecfg.ShhextConfig.ConnectionTarget, &nodecfg.ShhextConfig.RequestsDelay, &nodecfg.ShhextConfig.MaxServerFailures, &nodecfg.ShhextConfig.MaxMessageDeliveryAttempts,
   632  		&nodecfg.ShhextConfig.WhisperCacheDir, &nodecfg.ShhextConfig.DisableGenericDiscoveryTopic, &nodecfg.ShhextConfig.SendV1Messages, &nodecfg.ShhextConfig.DataSyncEnabled, &nodecfg.ShhextConfig.VerifyTransactionURL,
   633  		&nodecfg.ShhextConfig.VerifyENSURL, &nodecfg.ShhextConfig.VerifyENSContractAddress, &nodecfg.ShhextConfig.VerifyTransactionChainID, &nodecfg.ShhextConfig.AnonMetricsServerEnabled,
   634  		&nodecfg.ShhextConfig.AnonMetricsSendID, &nodecfg.ShhextConfig.AnonMetricsServerPostgresURI, &nodecfg.ShhextConfig.BandwidthStatsEnabled,
   635  	)
   636  	if err != nil && err != sql.ErrNoRows {
   637  		return nil, err
   638  	}
   639  
   640  	rows, err = tx.Query(`SELECT public_key FROM shhext_default_push_notification_servers WHERE synthetic_id = 'id' ORDER BY public_key ASC`)
   641  	if err != nil && err != sql.ErrNoRows {
   642  		return nil, err
   643  	}
   644  	defer rows.Close()
   645  	for rows.Next() {
   646  		var pubKeyStr string
   647  		err = rows.Scan(&pubKeyStr)
   648  		if err != nil {
   649  			return nil, err
   650  		}
   651  
   652  		if pubKeyStr != "" {
   653  			b, err := hexutil.Decode(pubKeyStr)
   654  			if err != nil {
   655  				return nil, err
   656  			}
   657  
   658  			pubKey, err := crypto.UnmarshalPubkey(b)
   659  			if err != nil {
   660  				return nil, err
   661  			}
   662  			nodecfg.ShhextConfig.DefaultPushNotificationsServers = append(nodecfg.ShhextConfig.DefaultPushNotificationsServers, &params.PushNotificationServer{PublicKey: pubKey})
   663  		}
   664  	}
   665  
   666  	err = tx.QueryRow(`
   667    SELECT enabled, port, data_dir, torrent_dir
   668    FROM torrent_config WHERE synthetic_id = 'id'
   669    `).Scan(
   670  		&nodecfg.TorrentConfig.Enabled, &nodecfg.TorrentConfig.Port, &nodecfg.TorrentConfig.DataDir, &nodecfg.TorrentConfig.TorrentDir,
   671  	)
   672  	if err != nil && err != sql.ErrNoRows {
   673  		return nil, err
   674  	}
   675  
   676  	err = tx.QueryRow(`
   677  	SELECT enabled, host, port, light_client, full_node, discovery_limit, data_dir,
   678  	max_message_size, enable_confirmations, peer_exchange, enable_discv5, udp_port, auto_update,
   679  	enable_store, store_capacity, store_seconds, enable_missing_message_verification,
   680  	enable_store_confirmation_for_messages_sent
   681  	FROM wakuv2_config WHERE synthetic_id = 'id'
   682  	`).Scan(
   683  		&nodecfg.WakuV2Config.Enabled, &nodecfg.WakuV2Config.Host, &nodecfg.WakuV2Config.Port, &nodecfg.WakuV2Config.LightClient, &nodecfg.WakuV2Config.FullNode,
   684  		&nodecfg.WakuV2Config.DiscoveryLimit, &nodecfg.WakuV2Config.DataDir, &nodecfg.WakuV2Config.MaxMessageSize, &nodecfg.WakuV2Config.EnableConfirmations,
   685  		&nodecfg.WakuV2Config.PeerExchange, &nodecfg.WakuV2Config.EnableDiscV5, &nodecfg.WakuV2Config.UDPPort, &nodecfg.WakuV2Config.AutoUpdate,
   686  		&nodecfg.WakuV2Config.EnableStore, &nodecfg.WakuV2Config.StoreCapacity, &nodecfg.WakuV2Config.StoreSeconds,
   687  		&nodecfg.WakuV2Config.EnableMissingMessageVerification, &nodecfg.WakuV2Config.EnableStoreConfirmationForMessagesSent,
   688  	)
   689  	if err != nil && err != sql.ErrNoRows {
   690  		return nil, err
   691  	}
   692  
   693  	rows, err = tx.Query(`SELECT name, multiaddress FROM wakuv2_custom_nodes WHERE synthetic_id = 'id' ORDER BY name ASC`)
   694  	if err != nil && err != sql.ErrNoRows {
   695  		return nil, err
   696  	}
   697  	defer rows.Close()
   698  	nodecfg.WakuV2Config.CustomNodes = make(map[string]string)
   699  	for rows.Next() {
   700  		var name string
   701  		var multiaddress string
   702  		err = rows.Scan(&name, &multiaddress)
   703  		if err != nil {
   704  			return nil, err
   705  		}
   706  		nodecfg.WakuV2Config.CustomNodes[name] = multiaddress
   707  	}
   708  
   709  	err = tx.QueryRow(`
   710  	SELECT enabled, light_client, full_node, enable_mailserver, data_dir, minimum_pow, mailserver_password, mailserver_rate_limit, mailserver_data_retention,
   711  	ttl, max_message_size, enable_rate_limiter, packet_rate_limit_ip, packet_rate_limit_peer_id, bytes_rate_limit_ip, bytes_rate_limit_peer_id,
   712  	rate_limit_tolerance, bloom_filter_mode, enable_confirmations
   713  	FROM waku_config WHERE synthetic_id = 'id'
   714  	`).Scan(
   715  		&nodecfg.WakuConfig.Enabled, &nodecfg.WakuConfig.LightClient, &nodecfg.WakuConfig.FullNode, &nodecfg.WakuConfig.EnableMailServer, &nodecfg.WakuConfig.DataDir, &nodecfg.WakuConfig.MinimumPoW,
   716  		&nodecfg.WakuConfig.MailServerPassword, &nodecfg.WakuConfig.MailServerRateLimit, &nodecfg.WakuConfig.MailServerDataRetention, &nodecfg.WakuConfig.TTL, &nodecfg.WakuConfig.MaxMessageSize,
   717  		&nodecfg.WakuConfig.EnableRateLimiter, &nodecfg.WakuConfig.PacketRateLimitIP, &nodecfg.WakuConfig.PacketRateLimitPeerID, &nodecfg.WakuConfig.BytesRateLimitIP, &nodecfg.WakuConfig.BytesRateLimitPeerID,
   718  		&nodecfg.WakuConfig.RateLimitTolerance, &nodecfg.WakuConfig.BloomFilterMode, &nodecfg.WakuConfig.EnableConfirmations,
   719  	)
   720  	if err != nil && err != sql.ErrNoRows {
   721  		return nil, err
   722  	}
   723  
   724  	err = tx.QueryRow("SELECT enabled, uri FROM waku_config_db_pg WHERE synthetic_id = 'id'").Scan(&nodecfg.WakuConfig.DatabaseConfig.PGConfig.Enabled, &nodecfg.WakuConfig.DatabaseConfig.PGConfig.URI)
   725  	if err != nil && err != sql.ErrNoRows {
   726  		return nil, err
   727  	}
   728  
   729  	rows, err = tx.Query(`SELECT peer_id FROM waku_softblacklisted_peers WHERE synthetic_id = 'id' ORDER BY peer_id ASC`)
   730  	if err != nil && err != sql.ErrNoRows {
   731  		return nil, err
   732  	}
   733  	defer rows.Close()
   734  	for rows.Next() {
   735  		var peerID string
   736  		err = rows.Scan(&peerID)
   737  		if err != nil {
   738  			return nil, err
   739  		}
   740  		nodecfg.WakuConfig.SoftBlacklistedPeerIDs = append(nodecfg.WakuConfig.SoftBlacklistedPeerIDs, peerID)
   741  	}
   742  
   743  	return nodecfg, nil
   744  }
   745  
   746  func MigrateNodeConfig(db *sql.DB) error {
   747  	tx, err := db.BeginTx(context.Background(), &sql.TxOptions{})
   748  	if err != nil {
   749  		return err
   750  	}
   751  
   752  	defer func() {
   753  		if err == nil {
   754  			err = tx.Commit()
   755  			return
   756  		}
   757  		// don't shadow original error
   758  		_ = tx.Rollback()
   759  	}()
   760  
   761  	migrated, err := nodeConfigWasMigrated(tx)
   762  	if err != nil {
   763  		return err
   764  	}
   765  
   766  	if !migrated {
   767  		return migrateNodeConfig(tx)
   768  	}
   769  
   770  	return nil
   771  }
   772  
   773  func GetNodeConfigFromDB(db *sql.DB) (*params.NodeConfig, error) {
   774  	tx, err := db.BeginTx(context.Background(), &sql.TxOptions{})
   775  	if err != nil {
   776  		return nil, err
   777  	}
   778  
   779  	defer func() {
   780  		if err == nil {
   781  			err = tx.Commit()
   782  			return
   783  		}
   784  		// don't shadow original error
   785  		_ = tx.Rollback()
   786  	}()
   787  
   788  	return loadNodeConfig(tx)
   789  }
   790  
   791  func SetLightClient(db *sql.DB, enabled bool) error {
   792  	_, err := db.Exec(`UPDATE wakuv2_config SET light_client = ?`, enabled)
   793  	return err
   794  }
   795  
   796  func SetStoreConfirmationForMessagesSent(db *sql.DB, enabled bool) error {
   797  	_, err := db.Exec(`UPDATE wakuv2_config SET enable_store_confirmation_for_messages_sent = ?`, enabled)
   798  	return err
   799  }
   800  
   801  func SetLogLevel(db *sql.DB, logLevel string) error {
   802  	_, err := db.Exec(`UPDATE log_config SET log_level = ?`, logLevel)
   803  	return err
   804  }
   805  
   806  func SetMaxLogBackups(db *sql.DB, maxLogBackups uint) error {
   807  	_, err := db.Exec(`UPDATE log_config SET max_backups = ?`, maxLogBackups)
   808  	return err
   809  }
   810  
   811  func SaveNewWakuNode(db *sql.DB, nodeAddress string) error {
   812  	_, err := db.Exec(`INSERT OR REPLACE INTO cluster_nodes (node, type, synthetic_id) VALUES (?, ?, 'id')`, nodeAddress, WakuNodes)
   813  	return err
   814  }
   815  
   816  func SetWakuV2CustomNodes(db *sql.DB, customNodes map[string]string) error {
   817  	tx, err := db.BeginTx(context.Background(), &sql.TxOptions{})
   818  	if err != nil {
   819  		return err
   820  	}
   821  
   822  	defer func() {
   823  		if err == nil {
   824  			err = tx.Commit()
   825  			return
   826  		}
   827  		// don't shadow original error
   828  		_ = tx.Rollback()
   829  	}()
   830  	return setWakuV2CustomNodes(tx, customNodes)
   831  }