Skip to content

Commit 8582775

Browse files
committed
feat(config)_: Do not store embedded RPC provider credentials in the DB
* +tests
1 parent 4a1e465 commit 8582775

File tree

3 files changed

+181
-72
lines changed

3 files changed

+181
-72
lines changed

rpc/network/network.go

+83-44
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ package network
33
import (
44
"database/sql"
55
"fmt"
6-
"github.com/status-im/status-go/multiaccounts/accounts"
76

7+
"go.uber.org/zap"
8+
9+
"github.com/status-im/status-go/logutils"
10+
"github.com/status-im/status-go/multiaccounts/accounts"
811
"github.com/status-im/status-go/params"
912
"github.com/status-im/status-go/params/networkhelper"
13+
1014
persistence "github.com/status-im/status-go/rpc/network/db"
1115
)
1216

@@ -26,7 +30,7 @@ type ManagerInterface interface {
2630
GetAll() ([]*params.Network, error)
2731
GetActiveNetworks() ([]*params.Network, error)
2832
GetCombinedNetworks() ([]*CombinedNetwork, error)
29-
GetConfiguredNetworks() []params.Network
33+
GetEmbeddedNetworks() []params.Network // Networks that are embedded in the app binary code
3034
GetTestNetworksEnabled() (bool, error)
3135

3236
SetUserRpcProviders(chainID uint64, providers []params.RpcProvider) error
@@ -36,7 +40,9 @@ type Manager struct {
3640
db *sql.DB
3741
accountsDB *accounts.Database
3842
networkPersistence persistence.NetworksPersistenceInterface
39-
configuredNetworks []params.Network
43+
embeddedNetworks []params.Network
44+
45+
logger *zap.Logger
4046
}
4147

4248
// NewManager creates a new instance of Manager.
@@ -45,19 +51,30 @@ func NewManager(db *sql.DB) *Manager {
4551
if err != nil {
4652
return nil
4753
}
54+
55+
logger := logutils.ZapLogger().Named("NetworkManager")
56+
4857
return &Manager{
4958
db: db,
5059
accountsDB: accountsDB,
5160
networkPersistence: persistence.NewNetworksPersistence(db),
61+
logger: logger,
5262
}
5363
}
5464

55-
// Init initializes the networks, merging with existing ones and wrapping the operation in a transaction.
56-
func (nm *Manager) InitEmbeddedNetworks(networks []params.Network) error {
57-
if networks == nil {
65+
// Init initializes the nets, merges them with existing ones, and wraps the operation in a transaction.
66+
// We should store the following information in the DB:
67+
// - User's RPC providers
68+
// - Enabled state of the network
69+
// Embedded RPC providers should only be stored in memory
70+
func (nm *Manager) InitEmbeddedNetworks(embeddedNetworks []params.Network) error {
71+
if embeddedNetworks == nil {
5872
return nil
5973
}
6074

75+
// Update embedded networks
76+
nm.embeddedNetworks = embeddedNetworks
77+
6178
// Begin a transaction
6279
return persistence.ExecuteWithinTransaction(nm.db, func(tx *sql.Tx) error {
6380
// Create temporary persistence instances with the transaction
@@ -69,39 +86,67 @@ func (nm *Manager) InitEmbeddedNetworks(networks []params.Network) error {
6986
}
7087

7188
// Create a map for quick access to current networks
72-
currentNetworkMap := make(map[uint64]params.Network)
89+
currentNetworskMap := make(map[uint64]params.Network)
7390
for _, currentNetwork := range currentNetworks {
74-
currentNetworkMap[currentNetwork.ChainID] = *currentNetwork
91+
currentNetworskMap[currentNetwork.ChainID] = *currentNetwork
7592
}
7693

77-
// Process new networks
94+
// Keep user's rpc providers and enabled state
7895
var updatedNetworks []params.Network
79-
for _, newNetwork := range networks {
80-
if existingNetwork, exists := currentNetworkMap[newNetwork.ChainID]; exists {
81-
// If network already exists, merge providers
82-
newNetwork.RpcProviders = networkhelper.ReplaceEmbeddedProviders(existingNetwork.RpcProviders, newNetwork.RpcProviders)
96+
for _, newNetwork := range embeddedNetworks {
97+
if existingNetwork, exists := currentNetworskMap[newNetwork.ChainID]; exists {
98+
newNetwork.RpcProviders = networkhelper.GetUserProviders(existingNetwork.RpcProviders)
99+
newNetwork.Enabled = existingNetwork.Enabled
100+
} else {
101+
newNetwork.RpcProviders = networkhelper.GetUserProviders(newNetwork.RpcProviders)
83102
}
84103
updatedNetworks = append(updatedNetworks, newNetwork)
85104
}
86105

87-
// Use SetNetworks to replace all networks in the database
106+
// Use SetNetworks to replace all networks in the database without embedded RPC providers
88107
err = txNetworksPersistence.SetNetworks(updatedNetworks)
89108
if err != nil {
90109
return fmt.Errorf("error setting networks: %w", err)
91110
}
92111

93-
// Update configured networks
94-
nm.configuredNetworks = networks
95-
96112
return nil
97113
})
98114
}
99115

116+
// GetEmbeddedProviders returns embedded providers for a given chainID.
117+
func (nm *Manager) getEmbeddedProviders(chainID uint64) []params.RpcProvider {
118+
for _, network := range nm.embeddedNetworks {
119+
if network.ChainID == chainID {
120+
return networkhelper.GetEmbeddedProviders(network.RpcProviders)
121+
}
122+
}
123+
return nil
124+
}
125+
126+
// setEmbeddedProviders adds embedded providers to a network.
127+
func (nm *Manager) setNetworkEmbeddedProviders(network *params.Network) {
128+
network.RpcProviders = networkhelper.ReplaceEmbeddedProviders(
129+
network.RpcProviders, nm.getEmbeddedProviders(network.ChainID))
130+
}
131+
132+
func (nm *Manager) setEmbeddedProviders(networks []*params.Network) {
133+
for _, network := range networks {
134+
nm.setNetworkEmbeddedProviders(network)
135+
}
136+
}
137+
138+
// networkWithoutEmbeddedProviders returns a copy of the given network without embedded RPC providers.
139+
func (nm *Manager) networkWithoutEmbeddedProviders(network *params.Network) *params.Network {
140+
networkCopy := networkhelper.DeepCopyNetwork(*network)
141+
networkCopy.RpcProviders = networkhelper.GetUserProviders(network.RpcProviders)
142+
return &networkCopy
143+
}
144+
100145
// Upsert adds or updates a network, synchronizing RPC providers, wrapped in a transaction.
101146
func (nm *Manager) Upsert(network *params.Network) error {
102147
return persistence.ExecuteWithinTransaction(nm.db, func(tx *sql.Tx) error {
103148
txNetworksPersistence := persistence.NewNetworksPersistence(tx)
104-
err := txNetworksPersistence.UpsertNetwork(network)
149+
err := txNetworksPersistence.UpsertNetwork(nm.networkWithoutEmbeddedProviders(network))
105150
if err != nil {
106151
return fmt.Errorf("failed to upsert network: %w", err)
107152
}
@@ -123,51 +168,45 @@ func (nm *Manager) Delete(chainID uint64) error {
123168

124169
// SetUserRpcProviders updates user RPC providers, wrapped in a transaction.
125170
func (nm *Manager) SetUserRpcProviders(chainID uint64, userProviders []params.RpcProvider) error {
126-
return persistence.ExecuteWithinTransaction(nm.db, func(tx *sql.Tx) error {
127-
// Create temporary persistence instances with the transaction
128-
txRpcPersistence := persistence.NewRpcProvidersPersistence(tx)
129-
130-
// Get all providers using the transactional RPC persistence
131-
allProviders, err := txRpcPersistence.GetRpcProviders(chainID)
132-
if err != nil {
133-
return fmt.Errorf("failed to get all providers: %w", err)
134-
}
135-
136-
// Replace user providers
137-
providers := networkhelper.ReplaceUserProviders(allProviders, userProviders)
138-
139-
// Set RPC providers using the transactional RPC persistence
140-
err = txRpcPersistence.SetRpcProviders(chainID, providers)
141-
if err != nil {
142-
return fmt.Errorf("failed to set RPC providers: %w", err)
143-
}
144-
145-
return nil
146-
})
171+
rpcPersistence := nm.networkPersistence.GetRpcPersistence()
172+
return rpcPersistence.SetRpcProviders(chainID, networkhelper.GetUserProviders(userProviders))
147173
}
148174

149175
// Find locates a network by ChainID.
150176
func (nm *Manager) Find(chainID uint64) *params.Network {
151177
networks, err := nm.networkPersistence.GetNetworkByChainID(chainID)
152178
if len(networks) != 1 || err != nil {
179+
nm.logger.Warn("Failed to find network", zap.Uint64("chainID", chainID), zap.Error(err))
153180
return nil
154181
}
155-
return networks[0]
182+
result := networks[0]
183+
nm.setNetworkEmbeddedProviders(result)
184+
return result
156185
}
157186

158187
// GetAll returns all networks.
159188
func (nm *Manager) GetAll() ([]*params.Network, error) {
160-
return nm.networkPersistence.GetAllNetworks()
189+
networks, err := nm.networkPersistence.GetAllNetworks()
190+
if err != nil {
191+
return nil, err
192+
}
193+
nm.setEmbeddedProviders(networks)
194+
return networks, nil
161195
}
162196

163197
// Get returns networks filtered by the enabled status.
164198
func (nm *Manager) Get(onlyEnabled bool) ([]*params.Network, error) {
165-
return nm.networkPersistence.GetNetworks(onlyEnabled, nil)
199+
networks, err := nm.networkPersistence.GetNetworks(onlyEnabled, nil)
200+
if err != nil {
201+
return nil, err
202+
}
203+
nm.setEmbeddedProviders(networks)
204+
return networks, nil
166205
}
167206

168207
// GetConfiguredNetworks returns the configured networks.
169-
func (nm *Manager) GetConfiguredNetworks() []params.Network {
170-
return nm.configuredNetworks
208+
func (nm *Manager) GetEmbeddedNetworks() []params.Network {
209+
return nm.embeddedNetworks
171210
}
172211

173212
// GetTestNetworksEnabled checks if test networks are enabled.

rpc/network/network_test.go

+97-27
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package network_test
22

33
import (
44
"database/sql"
5-
"github.com/status-im/status-go/api"
65
"testing"
76

7+
"github.com/status-im/status-go/api"
8+
89
"github.com/status-im/status-go/appdatabase"
910
"github.com/status-im/status-go/params"
1011
"github.com/status-im/status-go/params/networkhelper"
@@ -36,14 +37,12 @@ func (s *NetworkManagerTestSuite) SetupTest() {
3637
initNetworks := []params.Network{
3738
*testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
3839
testutil.CreateProvider(api.MainnetChainID, "Infura Mainnet", params.UserProviderType, true, "https://mainnet.infura.io"),
39-
testutil.CreateProvider(api.MainnetChainID, "Backup Mainnet", params.EmbeddedProxyProviderType, false, "https://backup.mainnet.provider.com"),
4040
}),
4141
*testutil.CreateNetwork(api.SepoliaChainID, "Sepolia Testnet", []params.RpcProvider{
4242
testutil.CreateProvider(api.SepoliaChainID, "Infura Sepolia", params.UserProviderType, true, "https://sepolia.infura.io"),
4343
}),
4444
*testutil.CreateNetwork(api.OptimismChainID, "Optimistic Ethereum", []params.RpcProvider{
4545
testutil.CreateProvider(api.OptimismChainID, "Infura Optimism", params.UserProviderType, true, "https://optimism.infura.io"),
46-
testutil.CreateProvider(api.OptimismChainID, "Backup Optimism", params.EmbeddedDirectProviderType, false, "https://backup.optimism.provider.com"),
4746
}),
4847
}
4948
err = persistence.SetNetworks(initNetworks)
@@ -75,29 +74,6 @@ func (s *NetworkManagerTestSuite) assertDbNetworks(expectedNetworks []params.Net
7574
testutil.CompareNetworksList(s.T(), expectedNetworksPtr, savedNetworks)
7675
}
7776

78-
func (s *NetworkManagerTestSuite) TestInitNetworksWithChangedAuth() {
79-
// Change auth token for a provider
80-
updatedNetworks := []params.Network{
81-
*testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
82-
testutil.CreateProvider(api.MainnetChainID, "Infura Mainnet", params.UserProviderType, true, "https://mainnet.infura.io"),
83-
{
84-
Name: "Backup Mainnet",
85-
ChainID: api.MainnetChainID,
86-
Type: params.EmbeddedProxyProviderType,
87-
Enabled: false,
88-
URL: "https://backup.mainnet.provider.com",
89-
AuthType: params.TokenAuth,
90-
AuthToken: "new-token",
91-
},
92-
}),
93-
}
94-
95-
// Re-initialize and assert
96-
err := s.manager.InitEmbeddedNetworks(updatedNetworks)
97-
s.Require().NoError(err)
98-
s.assertDbNetworks(updatedNetworks)
99-
}
100-
10177
func (s *NetworkManagerTestSuite) TestUserAddsCustomProviders() {
10278
// Adding custom providers
10379
customProviders := []params.RpcProvider{
@@ -126,7 +102,7 @@ func (s *NetworkManagerTestSuite) TestInitNetworksKeepsUserProviders() {
126102
// Re-initialize networks
127103
initNetworks := []params.Network{
128104
*testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
129-
testutil.CreateProvider(api.MainnetChainID, "Infura Mainnet", params.UserProviderType, true, "https://mainnet.infura.io"),
105+
testutil.CreateProvider(api.MainnetChainID, "Infura Mainnet", params.EmbeddedProxyProviderType, true, "https://mainnet.infura.io"),
130106
}),
131107
}
132108
err = s.manager.InitEmbeddedNetworks(initNetworks)
@@ -139,6 +115,81 @@ func (s *NetworkManagerTestSuite) TestInitNetworksKeepsUserProviders() {
139115
testutil.CompareProvidersList(s.T(), expectedProviders, foundNetwork.RpcProviders)
140116
}
141117

118+
func (s *NetworkManagerTestSuite) TestInitNetworksDoesNotSaveEmbeddedProviders() {
119+
persistence := db.NewNetworksPersistence(s.db)
120+
s.Require().NoError(persistence.DeleteAllNetworks())
121+
122+
// Re-initialize networks
123+
initNetworks := []params.Network{
124+
*testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
125+
testutil.CreateProvider(api.MainnetChainID, "Infura Mainnet", params.EmbeddedProxyProviderType, true, "https://mainnet.infura.io"),
126+
}),
127+
}
128+
err := s.manager.InitEmbeddedNetworks(initNetworks)
129+
s.Require().NoError(err)
130+
131+
// Check that embedded providers are not saved using persistence
132+
networks, err := persistence.GetNetworks(false, nil)
133+
s.Require().NoError(err)
134+
s.Require().Len(networks, 1)
135+
s.Require().Len(networks[0].RpcProviders, 0)
136+
}
137+
138+
func (s *NetworkManagerTestSuite) TestInitEmbeddedNetworks() {
139+
// Re-initialize networks
140+
initNetworks := []params.Network{
141+
*testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
142+
testutil.CreateProvider(api.MainnetChainID, "Infura Mainnet", params.EmbeddedProxyProviderType, true, "https://mainnet.infura.io"),
143+
}),
144+
}
145+
expectedProviders := networkhelper.GetEmbeddedProviders(initNetworks[0].RpcProviders)
146+
err := s.manager.InitEmbeddedNetworks(initNetworks)
147+
s.Require().NoError(err)
148+
149+
// functor tests if embedded providers are present in the networks
150+
expectEmbeddedProviders := func(networks []*params.Network) {
151+
for _, network := range networks {
152+
if network.ChainID == api.MainnetChainID {
153+
storedEmbeddedProviders := networkhelper.GetEmbeddedProviders(network.RpcProviders)
154+
testutil.CompareProvidersList(s.T(), expectedProviders, storedEmbeddedProviders)
155+
}
156+
}
157+
}
158+
159+
// GetAll
160+
networks, err := s.manager.GetAll()
161+
s.Require().NoError(err)
162+
expectEmbeddedProviders(networks)
163+
164+
// Get
165+
networks, err = s.manager.Get(false)
166+
s.Require().NoError(err)
167+
expectEmbeddedProviders(networks)
168+
169+
// GetActiveNetworks
170+
networks, err = s.manager.GetActiveNetworks()
171+
s.Require().NoError(err)
172+
expectEmbeddedProviders(networks)
173+
174+
// GetCombinedNetworks
175+
combinedNetworks, err := s.manager.GetCombinedNetworks()
176+
s.Require().NoError(err)
177+
for _, combinedNetwork := range combinedNetworks {
178+
if combinedNetwork.Test != nil && combinedNetwork.Test.ChainID == api.MainnetChainID {
179+
storedEmbeddedProviders := networkhelper.GetEmbeddedProviders(combinedNetwork.Test.RpcProviders)
180+
testutil.CompareProvidersList(s.T(), expectedProviders, storedEmbeddedProviders)
181+
}
182+
if combinedNetwork.Prod != nil && combinedNetwork.Prod.ChainID == api.MainnetChainID {
183+
storedEmbeddedProviders := networkhelper.GetEmbeddedProviders(combinedNetwork.Prod.RpcProviders)
184+
testutil.CompareProvidersList(s.T(), expectedProviders, storedEmbeddedProviders)
185+
}
186+
}
187+
188+
// GetEmbeddedNetworks
189+
embeddedNetworks := s.manager.GetEmbeddedNetworks()
190+
expectEmbeddedProviders(testutil.ConvertNetworksToPointers(embeddedNetworks))
191+
}
192+
142193
func (s *NetworkManagerTestSuite) TestLegacyFieldPopulation() {
143194
// Create initial test networks with various providers
144195
initNetworks := []params.Network{
@@ -206,3 +257,22 @@ func (s *NetworkManagerTestSuite) TestLegacyFieldPopulationWithoutUserProviders(
206257
s.Equal("https://proxy2.sepolia.io", network.DefaultFallbackURL)
207258
s.Empty(network.DefaultFallbackURL2) // No third Proxy provider
208259
}
260+
261+
func (s *NetworkManagerTestSuite) TestUpsertNetwork() {
262+
// Create a new network
263+
newNetwork := testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
264+
testutil.CreateProvider(api.MainnetChainID, "Infura Mainnet", params.EmbeddedProxyProviderType, true, "https://mainnet.infura.io"),
265+
})
266+
267+
// Upsert the network
268+
err := s.manager.Upsert(newNetwork)
269+
s.Require().NoError(err)
270+
271+
// Verify the network was upserted without embedded providers
272+
persistence := db.NewNetworksPersistence(s.db)
273+
chainID := api.MainnetChainID
274+
networks, err := persistence.GetNetworks(false, &chainID)
275+
s.Require().NoError(err)
276+
s.Require().Len(networks, 1)
277+
s.Require().Len(networkhelper.GetEmbeddedProviders(networks[0].RpcProviders), 0)
278+
}

0 commit comments

Comments
 (0)