2021-09-09 16:28:54 +02:00
|
|
|
package network
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
2022-05-16 09:58:36 +02:00
|
|
|
"fmt"
|
2021-09-09 16:28:54 +02:00
|
|
|
|
2023-10-03 15:27:42 +02:00
|
|
|
"github.com/status-im/status-go/multiaccounts/accounts"
|
2024-12-05 17:48:51 +04:00
|
|
|
|
2022-01-12 20:04:43 +00:00
|
|
|
"github.com/status-im/status-go/params"
|
2024-12-05 17:48:51 +04:00
|
|
|
"github.com/status-im/status-go/params/networkhelper"
|
|
|
|
persistence "github.com/status-im/status-go/rpc/network/db"
|
2022-01-12 20:04:43 +00:00
|
|
|
)
|
2021-09-09 16:28:54 +02:00
|
|
|
|
2023-07-13 16:03:49 +02:00
|
|
|
type CombinedNetwork struct {
|
|
|
|
Prod *params.Network
|
|
|
|
Test *params.Network
|
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
type ManagerInterface interface {
|
|
|
|
InitEmbeddedNetworks(networks []params.Network) error
|
2021-09-09 16:28:54 +02:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
Upsert(network *params.Network) error
|
|
|
|
Delete(chainID uint64) error
|
|
|
|
Find(chainID uint64) *params.Network
|
2021-09-09 16:28:54 +02:00
|
|
|
|
2024-06-27 23:27:09 +02:00
|
|
|
Get(onlyEnabled bool) ([]*params.Network, error)
|
|
|
|
GetAll() ([]*params.Network, error)
|
2024-12-05 17:48:51 +04:00
|
|
|
GetActiveNetworks() ([]*params.Network, error)
|
|
|
|
GetCombinedNetworks() ([]*CombinedNetwork, error)
|
2024-06-27 23:27:09 +02:00
|
|
|
GetConfiguredNetworks() []params.Network
|
|
|
|
GetTestNetworksEnabled() (bool, error)
|
2024-12-05 17:48:51 +04:00
|
|
|
|
|
|
|
SetUserRpcProviders(chainID uint64, providers []params.RpcProvider) error
|
2024-06-27 23:27:09 +02:00
|
|
|
}
|
|
|
|
|
2021-09-09 16:28:54 +02:00
|
|
|
type Manager struct {
|
2023-08-08 11:05:17 +02:00
|
|
|
db *sql.DB
|
2023-10-03 15:27:42 +02:00
|
|
|
accountsDB *accounts.Database
|
2024-12-05 17:48:51 +04:00
|
|
|
networkPersistence persistence.NetworksPersistenceInterface
|
|
|
|
configuredNetworks []params.Network
|
2021-09-09 16:28:54 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// NewManager creates a new instance of Manager.
|
2021-09-22 19:49:20 +02:00
|
|
|
func NewManager(db *sql.DB) *Manager {
|
2023-10-03 15:27:42 +02:00
|
|
|
accountsDB, err := accounts.NewDB(db)
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
2021-09-09 16:28:54 +02:00
|
|
|
return &Manager{
|
2024-12-05 17:48:51 +04:00
|
|
|
db: db,
|
|
|
|
accountsDB: accountsDB,
|
|
|
|
networkPersistence: persistence.NewNetworksPersistence(db),
|
2022-05-16 09:58:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Init initializes the networks, merging with existing ones and wrapping the operation in a transaction.
|
|
|
|
func (nm *Manager) InitEmbeddedNetworks(networks []params.Network) error {
|
2021-09-22 19:49:20 +02:00
|
|
|
if networks == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Begin a transaction
|
|
|
|
return persistence.ExecuteWithinTransaction(nm.db, func(tx *sql.Tx) error {
|
|
|
|
// Create temporary persistence instances with the transaction
|
|
|
|
txNetworksPersistence := persistence.NewNetworksPersistence(tx)
|
2022-05-16 09:58:36 +02:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
currentNetworks, err := txNetworksPersistence.GetAllNetworks()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error fetching current networks: %w", err)
|
2022-05-16 09:58:36 +02:00
|
|
|
}
|
2021-09-09 16:28:54 +02:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Create a map for quick access to current networks
|
|
|
|
currentNetworkMap := make(map[uint64]params.Network)
|
|
|
|
for _, currentNetwork := range currentNetworks {
|
|
|
|
currentNetworkMap[currentNetwork.ChainID] = *currentNetwork
|
2022-05-16 09:58:36 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Process new networks
|
|
|
|
var updatedNetworks []params.Network
|
|
|
|
for _, newNetwork := range networks {
|
|
|
|
if existingNetwork, exists := currentNetworkMap[newNetwork.ChainID]; exists {
|
|
|
|
// If network already exists, merge providers
|
|
|
|
newNetwork.RpcProviders = networkhelper.ReplaceEmbeddedProviders(existingNetwork.RpcProviders, newNetwork.RpcProviders)
|
2022-05-16 09:58:36 +02:00
|
|
|
}
|
2024-12-05 17:48:51 +04:00
|
|
|
updatedNetworks = append(updatedNetworks, newNetwork)
|
2021-09-09 16:28:54 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Use SetNetworks to replace all networks in the database
|
|
|
|
err = txNetworksPersistence.SetNetworks(updatedNetworks)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error setting networks: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update configured networks
|
|
|
|
nm.configuredNetworks = networks
|
2022-05-16 09:58:36 +02:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
return nil
|
|
|
|
})
|
2021-09-09 16:28:54 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Upsert adds or updates a network, synchronizing RPC providers, wrapped in a transaction.
|
2022-01-12 20:04:43 +00:00
|
|
|
func (nm *Manager) Upsert(network *params.Network) error {
|
2024-12-05 17:48:51 +04:00
|
|
|
return persistence.ExecuteWithinTransaction(nm.db, func(tx *sql.Tx) error {
|
|
|
|
txNetworksPersistence := persistence.NewNetworksPersistence(tx)
|
|
|
|
err := txNetworksPersistence.UpsertNetwork(network)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to upsert network: %w", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
2021-09-09 16:28:54 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Delete removes a network by ChainID, wrapped in a transaction.
|
2021-09-09 16:28:54 +02:00
|
|
|
func (nm *Manager) Delete(chainID uint64) error {
|
2024-12-05 17:48:51 +04:00
|
|
|
return persistence.ExecuteWithinTransaction(nm.db, func(tx *sql.Tx) error {
|
|
|
|
txNetworksPersistence := persistence.NewNetworksPersistence(tx)
|
|
|
|
err := txNetworksPersistence.DeleteNetwork(chainID)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to delete network: %w", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
2021-09-09 16:28:54 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// SetUserRpcProviders updates user RPC providers, wrapped in a transaction.
|
|
|
|
func (nm *Manager) SetUserRpcProviders(chainID uint64, userProviders []params.RpcProvider) error {
|
|
|
|
return persistence.ExecuteWithinTransaction(nm.db, func(tx *sql.Tx) error {
|
|
|
|
// Create temporary persistence instances with the transaction
|
|
|
|
txRpcPersistence := persistence.NewRpcProvidersPersistence(tx)
|
2023-07-13 16:03:49 +02:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Get all providers using the transactional RPC persistence
|
|
|
|
allProviders, err := txRpcPersistence.GetRpcProviders(chainID)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to get all providers: %w", err)
|
|
|
|
}
|
2024-01-16 14:47:57 +01:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Replace user providers
|
|
|
|
providers := networkhelper.ReplaceUserProviders(allProviders, userProviders)
|
|
|
|
|
|
|
|
// Set RPC providers using the transactional RPC persistence
|
|
|
|
err = txRpcPersistence.SetRpcProviders(chainID, providers)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to set RPC providers: %w", err)
|
|
|
|
}
|
2024-01-16 14:47:57 +01:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
return nil
|
|
|
|
})
|
2023-09-15 10:06:44 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Find locates a network by ChainID.
|
2022-01-12 20:04:43 +00:00
|
|
|
func (nm *Manager) Find(chainID uint64) *params.Network {
|
2024-12-05 17:48:51 +04:00
|
|
|
networks, err := nm.networkPersistence.GetNetworkByChainID(chainID)
|
2021-09-09 16:28:54 +02:00
|
|
|
if len(networks) != 1 || err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return networks[0]
|
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// GetAll returns all networks.
|
2023-10-03 15:27:42 +02:00
|
|
|
func (nm *Manager) GetAll() ([]*params.Network, error) {
|
2024-12-05 17:48:51 +04:00
|
|
|
return nm.networkPersistence.GetAllNetworks()
|
2023-10-03 15:27:42 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// Get returns networks filtered by the enabled status.
|
2022-01-12 20:04:43 +00:00
|
|
|
func (nm *Manager) Get(onlyEnabled bool) ([]*params.Network, error) {
|
2024-12-05 17:48:51 +04:00
|
|
|
return nm.networkPersistence.GetNetworks(onlyEnabled, nil)
|
2023-07-13 16:03:49 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// GetConfiguredNetworks returns the configured networks.
|
2022-09-13 11:30:52 +02:00
|
|
|
func (nm *Manager) GetConfiguredNetworks() []params.Network {
|
2023-08-08 11:05:17 +02:00
|
|
|
return nm.configuredNetworks
|
2022-09-13 11:30:52 +02:00
|
|
|
}
|
2024-02-22 16:17:35 +01:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// GetTestNetworksEnabled checks if test networks are enabled.
|
2024-02-22 16:17:35 +01:00
|
|
|
func (nm *Manager) GetTestNetworksEnabled() (result bool, err error) {
|
|
|
|
return nm.accountsDB.GetTestNetworksEnabled()
|
|
|
|
}
|
2024-06-06 20:57:29 +01:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
// GetActiveNetworks returns active networks based on the current mode (test/prod).
|
2024-06-06 20:57:29 +01:00
|
|
|
func (nm *Manager) GetActiveNetworks() ([]*params.Network, error) {
|
|
|
|
areTestNetworksEnabled, err := nm.GetTestNetworksEnabled()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2025-01-20 12:12:11 -03:00
|
|
|
networks, err := nm.GetAll()
|
2024-06-06 20:57:29 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-12-05 17:48:51 +04:00
|
|
|
|
|
|
|
var availableNetworks []*params.Network
|
2024-06-06 20:57:29 +01:00
|
|
|
for _, network := range networks {
|
2024-12-05 17:48:51 +04:00
|
|
|
if network.IsTest == areTestNetworksEnabled {
|
|
|
|
availableNetworks = append(availableNetworks, network)
|
2024-06-06 20:57:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return availableNetworks, nil
|
|
|
|
}
|
2024-07-31 08:21:11 +02:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
func (nm *Manager) GetCombinedNetworks() ([]*CombinedNetwork, error) {
|
|
|
|
networks, err := nm.Get(false)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2024-07-31 08:21:11 +02:00
|
|
|
}
|
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
combinedNetworksMap := make(map[uint64]*CombinedNetwork)
|
|
|
|
combinedNetworksSlice := make([]*CombinedNetwork, 0)
|
2024-07-31 08:21:11 +02:00
|
|
|
|
2024-12-05 17:48:51 +04:00
|
|
|
for _, network := range networks {
|
|
|
|
combinedNetwork, exists := combinedNetworksMap[network.RelatedChainID]
|
|
|
|
|
|
|
|
if !exists {
|
|
|
|
combinedNetwork = &CombinedNetwork{}
|
|
|
|
combinedNetworksMap[network.ChainID] = combinedNetwork
|
|
|
|
combinedNetworksSlice = append(combinedNetworksSlice, combinedNetwork)
|
|
|
|
}
|
|
|
|
|
|
|
|
if network.IsTest {
|
|
|
|
combinedNetwork.Test = network
|
|
|
|
} else {
|
|
|
|
combinedNetwork.Prod = network
|
2024-07-31 08:21:11 +02:00
|
|
|
}
|
|
|
|
}
|
2024-12-05 17:48:51 +04:00
|
|
|
|
|
|
|
return combinedNetworksSlice, nil
|
2024-07-31 08:21:11 +02:00
|
|
|
}
|