Skip to content

Commit

Permalink
chore(config)_: integrate new rpc providers configs (#6178)
Browse files Browse the repository at this point in the history
* chore(config)_: Integration of new RPC Provider configurations

* default_networks.go
  * explicit provider initialization with more granular config (rps limiter, order)
  * token overrides made more flexible, support not only infura and grove
* get_status_node.go
  * override status-proxy auth instead of passing override config to rpc/client.go
* config.go
  * ProviderConfig removed
* client.go
  * Now any provider can be enabled/disabled (if user wants to use only his custom RPC urls)
  * Use bearer auth instead of URL auth
  * Provider order is defined by default_networks.go

* Do not store embedded RPC provider credentials in the DB

* FIXME:  TestLoginAndMigrationsStillWorkWithExistingDesktopUser uses deprecated test data (with non-existing related_chain_id in networks table)
  • Loading branch information
friofry authored Jan 31, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 214cac9 commit 17adba6
Showing 36 changed files with 1,064 additions and 903 deletions.
299 changes: 178 additions & 121 deletions api/default_networks.go

Large diffs are not rendered by default.

54 changes: 25 additions & 29 deletions api/default_networks_test.go
Original file line number Diff line number Diff line change
@@ -4,27 +4,29 @@ import (
"strings"
"testing"

"github.com/status-im/status-go/params"

"github.com/pkg/errors"
"github.com/stretchr/testify/require"

"github.com/status-im/status-go/protocol/requests"
)

func TestBuildDefaultNetworks(t *testing.T) {
rpcToken := "infura-token"
fallbackToken := ""
infuraToken := "infura-token"
poktToken := "pokt-token"
stageName := "fast-n-bulbous"
request := &requests.CreateAccount{
WalletSecretsConfig: requests.WalletSecretsConfig{
InfuraToken: rpcToken,
InfuraToken: infuraToken,
PoktToken: poktToken,
StatusProxyStageName: stageName,
},
}

actualNetworks := BuildDefaultNetworks(&request.WalletSecretsConfig)

require.Len(t, actualNetworks, 8)

for _, n := range actualNetworks {
var err error
switch n.ChainID {
@@ -50,32 +52,26 @@ func TestBuildDefaultNetworks(t *testing.T) {
}

// check fallback options
require.True(t, strings.Contains(n.RPCURL, rpcToken))
require.True(t, strings.Contains(n.FallbackURL, fallbackToken))
}
}

func TestBuildDefaultNetworksGanache(t *testing.T) {
ganacheURL := "ganacheurl"
request := &requests.CreateAccount{
WalletSecretsConfig: requests.WalletSecretsConfig{
GanacheURL: ganacheURL,
},
}
require.True(t, strings.Contains(n.RPCURL, infuraToken))
require.True(t, strings.Contains(n.FallbackURL, poktToken))

actualNetworks := BuildDefaultNetworks(&request.WalletSecretsConfig)

require.Len(t, actualNetworks, 8)
// Check proxy providers for stageName
for _, provider := range n.RpcProviders {
if provider.Type == params.EmbeddedProxyProviderType {
require.Contains(t, provider.URL, stageName, "Proxy provider URL should contain stageName")
}
}

for _, n := range actualNetworks {
require.True(t, strings.Contains(n.RPCURL, ganacheURL))
require.True(t, strings.Contains(n.FallbackURL, ganacheURL))
// Check direct providers for tokens
for _, provider := range n.RpcProviders {
if provider.Type != params.EmbeddedDirectProviderType {
continue
}
if strings.Contains(provider.URL, "infura.io") {
require.Equal(t, provider.AuthToken, infuraToken, "Direct provider URL should have infuraToken")
} else if strings.Contains(provider.URL, "grove.city") {
require.Equal(t, provider.AuthToken, poktToken, "Direct provider URL should have poktToken")
}
}
}

require.Equal(t, MainnetChainID, actualNetworks[0].ChainID)

require.NotNil(t, actualNetworks[0].TokenOverrides)
require.Len(t, actualNetworks[0].TokenOverrides, 1)
require.Equal(t, sntSymbol, actualNetworks[0].TokenOverrides[0].Symbol)
require.Equal(t, ganacheTokenAddress, actualNetworks[0].TokenOverrides[0].Address)
}
2 changes: 1 addition & 1 deletion api/geth_backend.go
Original file line number Diff line number Diff line change
@@ -806,7 +806,7 @@ func (b *GethStatusBackend) startNodeWithAccount(acc multiaccounts.Account, pass

err = b.StartNode(b.config)
if err != nil {
b.logger.Info("failed to start node")
b.logger.Info("failed to start node", zap.Error(err))
return err
}

24 changes: 13 additions & 11 deletions node/get_status_node.go
Original file line number Diff line number Diff line change
@@ -11,6 +11,8 @@ import (
"reflect"
"sync"

"github.com/status-im/status-go/params/networkhelper"

"github.com/syndtr/goleveldb/leveldb"
"go.uber.org/zap"

@@ -336,27 +338,27 @@ func (n *StatusNode) setupRPCClient() (err error) {
return
}

// ProviderConfigs should be passed not in wallet secrets config on login
// Proxy AuthConfigs should be passed not in wallet secrets config on login
// but some other way, as it's not wallet specific and should not be passed with login request
// but currently there is no other way to pass it
providerConfigs := []params.ProviderConfig{
{
Enabled: n.config.WalletConfig.StatusProxyEnabled,
Name: rpc.ProviderStatusProxy,
User: n.config.WalletConfig.StatusProxyBlockchainUser,
Password: n.config.WalletConfig.StatusProxyBlockchainPassword,
},
}
// (maybe move to default_networks.go)
networks := networkhelper.OverrideEmbeddedProxyProviders(
n.config.Networks,
n.config.WalletConfig.StatusProxyEnabled,
n.config.WalletConfig.StatusProxyBlockchainUser,
n.config.WalletConfig.StatusProxyBlockchainPassword)

config := rpc.ClientConfig{
Client: gethNodeClient,
UpstreamChainID: n.config.NetworkID,
Networks: n.config.Networks,
Networks: networks,
DB: n.appDB,
WalletFeed: &n.walletFeed,
ProviderConfigs: providerConfigs,
}
n.rpcClient, err = rpc.NewClient(config)
if err != nil {
return
}
n.rpcClient.Start(context.Background())
if err != nil {
return
15 changes: 0 additions & 15 deletions params/config.go
Original file line number Diff line number Diff line change
@@ -293,21 +293,6 @@ func NewLimits(min, max int) Limits {
}
}

type ProviderConfig struct {
// Enabled flag specifies whether feature is enabled
Enabled bool `validate:"required"`

// To identify provider
Name string `validate:"required"`

// URL sets the rpc upstream host address for communication with
// a non-local infura endpoint.
User string `json:",omitempty"`
Password string `json:",omitempty"`
APIKey string `json:"APIKey,omitempty"`
APIKeySecret string `json:"APIKeySecret,omitempty"`
}

// ----------
// NodeConfig
// ----------
17 changes: 17 additions & 0 deletions params/network_config.go
Original file line number Diff line number Diff line change
@@ -36,6 +36,14 @@ type RpcProvider struct {
AuthToken string `json:"authToken" validate:"omitempty,min=1"` // Token for TokenAuth (empty string if not used)
}

// GetFullURL returns the URL with auth token if TokenAuth is used
func (p RpcProvider) GetFullURL() string {
if p.AuthType == TokenAuth && p.AuthToken != "" {
return p.URL + "/" + p.AuthToken
}
return p.URL
}

type TokenOverride struct {
Symbol string `json:"symbol"`
Address common.Address `json:"address"`
@@ -70,6 +78,15 @@ type Network struct {
RelatedChainID uint64 `json:"relatedChainId" validate:"omitempty"`
}

func (n *Network) DeepCopy() Network {
updatedNetwork := *n
updatedNetwork.RpcProviders = make([]RpcProvider, len(n.RpcProviders))
copy(updatedNetwork.RpcProviders, n.RpcProviders)
updatedNetwork.TokenOverrides = make([]TokenOverride, len(n.TokenOverrides))
copy(updatedNetwork.TokenOverrides, n.TokenOverrides)
return updatedNetwork
}

func newRpcProvider(chainID uint64, name, url string, enableRpsLimiter bool, providerType RpcProviderType) *RpcProvider {
return &RpcProvider{
ChainID: chainID,
36 changes: 9 additions & 27 deletions params/networkhelper/provider_utils.go
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@ import (
"net/url"
"strings"

"github.com/status-im/status-go/rpc/network/db"

"github.com/status-im/status-go/params"
)

@@ -51,7 +53,7 @@ func ToggleUserProviders(providers []params.RpcProvider, enabled bool) []params.

// GetEmbeddedProviders returns the embedded providers from the list.
func GetEmbeddedProviders(providers []params.RpcProvider) []params.RpcProvider {
var embeddedProviders []params.RpcProvider
embeddedProviders := make([]params.RpcProvider, 0, len(providers))
for _, provider := range providers {
if provider.Type != params.UserProviderType {
embeddedProviders = append(embeddedProviders, provider)
@@ -62,7 +64,7 @@ func GetEmbeddedProviders(providers []params.RpcProvider) []params.RpcProvider {

// GetUserProviders returns the user-defined providers from the list.
func GetUserProviders(providers []params.RpcProvider) []params.RpcProvider {
var userProviders []params.RpcProvider
userProviders := make([]params.RpcProvider, 0, len(providers))
for _, provider := range providers {
if provider.Type == params.UserProviderType {
userProviders = append(userProviders, provider)
@@ -104,6 +106,7 @@ func OverrideEmbeddedProxyProviders(networks []params.Network, enabled bool, use
for j, provider := range network.RpcProviders {
if provider.Type == params.EmbeddedProxyProviderType {
provider.Enabled = enabled
provider.AuthType = params.BasicAuth
provider.AuthLogin = user
provider.AuthPassword = password
}
@@ -117,19 +120,16 @@ func OverrideEmbeddedProxyProviders(networks []params.Network, enabled bool, use
return updatedNetworks
}

func deepCopyNetworks(networks []params.Network) []params.Network {
func DeepCopyNetworks(networks []params.Network) []params.Network {
updatedNetworks := make([]params.Network, len(networks))
for i, network := range networks {
updatedNetwork := network
updatedNetwork.RpcProviders = make([]params.RpcProvider, len(network.RpcProviders))
copy(updatedNetwork.RpcProviders, network.RpcProviders)
updatedNetworks[i] = updatedNetwork
updatedNetworks[i] = network.DeepCopy()
}
return updatedNetworks
}

func OverrideDirectProvidersAuth(networks []params.Network, authTokens map[string]string) []params.Network {
updatedNetworks := deepCopyNetworks(networks)
updatedNetworks := DeepCopyNetworks(networks)

for i := range updatedNetworks {
network := &updatedNetworks[i]
@@ -154,25 +154,7 @@ func OverrideDirectProvidersAuth(networks []params.Network, authTokens map[strin
}
}
}
}
return updatedNetworks
}

func OverrideGanacheToken(networks []params.Network, ganacheURL string, chainID uint64, tokenOverride params.TokenOverride) []params.Network {
updatedNetworks := deepCopyNetworks(networks)

for i := range updatedNetworks {
network := &updatedNetworks[i]

if network.ChainID != chainID {
continue
}
for j := range network.RpcProviders {
if ganacheURL != "" {
network.RpcProviders[j].URL = ganacheURL
}
}
network.TokenOverrides = []params.TokenOverride{tokenOverride}
db.FillDeprecatedURLs(network, network.RpcProviders)
}
return updatedNetworks
}
37 changes: 16 additions & 21 deletions params/networkhelper/provider_utils_test.go
Original file line number Diff line number Diff line change
@@ -87,6 +87,7 @@ func TestUpdateEmbeddedProxyProviders(t *testing.T) {
assert.True(t, provider.Enabled, "Provider Enabled state should be overridden")
assert.Equal(t, user, provider.AuthLogin, "Provider AuthLogin should be overridden")
assert.Equal(t, password, provider.AuthPassword, "Provider AuthPassword should be overridden")
assert.Equal(t, params.BasicAuth, provider.AuthType, "Provider AuthType should be set to BasicAuth")
} else {
assert.Equal(t, expectedProvider.Enabled, provider.Enabled, "Provider Enabled state should remain unchanged")
assert.Equal(t, expectedProvider.AuthLogin, provider.AuthLogin, "Provider AuthLogin should remain unchanged")
@@ -143,29 +144,23 @@ func TestOverrideDirectProvidersAuth(t *testing.T) {
}
}

func TestOverrideGanacheTokenOverrides(t *testing.T) {
// Create a sample list of networks with various ChainIDs
networks := []params.Network{
*testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", nil),
*testutil.CreateNetwork(api.OptimismChainID, "Optimism", nil),
*testutil.CreateNetwork(api.MainnetChainID, "Mainnet Duplicate", nil),
}
func TestDeepCopyNetwork(t *testing.T) {
originalNetwork := testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
*params.NewUserProvider(api.MainnetChainID, "Provider1", "https://userprovider.example.com", true),
*params.NewDirectProvider(api.MainnetChainID, "Provider2", "https://mainnet.infura.io/v3/", true),
})

ganacheTokenOverride := params.TokenOverride{
Symbol: "SNT",
Address: common.HexToAddress("0x8571Ddc46b10d31EF963aF49b6C7799Ea7eff818"),
originalNetwork.TokenOverrides = []params.TokenOverride{
{Symbol: "token1", Address: common.HexToAddress("0x123")},
}

// Call OverrideGanacheTokenOverrides
updatedNetworks := networkhelper.OverrideGanacheToken(networks, "url", api.MainnetChainID, ganacheTokenOverride)
copiedNetwork := originalNetwork.DeepCopy()

// Verify that only networks with the specified ChainID have the token override applied
for _, network := range updatedNetworks {
if network.ChainID == api.MainnetChainID {
require.NotNil(t, network.TokenOverrides, "TokenOverrides should not be nil for ChainID %d", network.ChainID)
assert.Contains(t, network.TokenOverrides, ganacheTokenOverride, "TokenOverrides should contain the ganache token")
} else {
assert.Nil(t, network.TokenOverrides, "TokenOverrides should be nil for ChainID %d", network.ChainID)
}
}
assert.True(t, reflect.DeepEqual(originalNetwork, &copiedNetwork), "Copied network should be deeply equal to the original")

// Modify the copied network and verify that the original network remains unchanged
copiedNetwork.RpcProviders[0].Enabled = false
copiedNetwork.TokenOverrides[0].Symbol = "modifiedSymbol"
assert.NotEqual(t, originalNetwork.RpcProviders[0].Enabled, copiedNetwork.RpcProviders[0].Enabled, "Original network should remain unchanged")
assert.NotEqual(t, originalNetwork.TokenOverrides[0].Symbol, copiedNetwork.TokenOverrides[0].Symbol, "Original network should remain unchanged")
}
6 changes: 4 additions & 2 deletions params/networkhelper/validate_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package networkhelper
package networkhelper_test

import (
"testing"

"github.com/status-im/status-go/params/networkhelper"

"github.com/stretchr/testify/require"

"gopkg.in/go-playground/validator.v9"
@@ -11,7 +13,7 @@ import (
)

func TestValidation(t *testing.T) {
validate := GetValidator()
validate := networkhelper.GetValidator()

// Test cases for RpcProvider
providerTests := []struct {
3 changes: 0 additions & 3 deletions protocol/requests/create_account.go
Original file line number Diff line number Diff line change
@@ -110,9 +110,6 @@ type WalletSecretsConfig struct {
StatusProxyMarketPassword string `json:"statusProxyMarketPassword"`
StatusProxyBlockchainUser string `json:"statusProxyBlockchainUser"`
StatusProxyBlockchainPassword string `json:"statusProxyBlockchainPassword"`

// Testing
GanacheURL string `json:"ganacheURL"`
}

func (c *CreateAccount) Validate(validation *CreateAccountValidation) error {
Loading

0 comments on commit 17adba6

Please sign in to comment.