Skip to content

Commit

Permalink
chore(config)_: Integration of new RPC Provider configurations
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
friofry committed Jan 7, 2025
1 parent e04001a commit 526f19c
Show file tree
Hide file tree
Showing 26 changed files with 586 additions and 778 deletions.
189 changes: 104 additions & 85 deletions api/default_networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ package api

import (
"fmt"
"strings"

"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/params/networkhelper"
"github.com/status-im/status-go/protocol/requests"
)

Expand All @@ -20,17 +19,29 @@ const (
sttSymbol = "STT"
)

var ganacheTokenAddress = common.HexToAddress("0x8571Ddc46b10d31EF963aF49b6C7799Ea7eff818")
func proxyUrl(stageName, provider, chainName, networkName string) string {
return fmt.Sprintf("https://%s.api.status.im/%s/%s/%s/", stageName, provider, chainName, networkName)
}

func mainnet(stageName string) params.Network {
chainID := MainnetChainID
chainName := "ethereum"
networkName := "mainnet"

rpcProviders := []params.RpcProvider{
// Proxy providers
*params.NewProxyProvider(chainID, "proxy-nodefleet", proxyUrl(stageName, "nodefleet", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-infura", proxyUrl(stageName, "infura", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-grove", proxyUrl(stageName, "grove", chainName, networkName), false),
// Direct providers
*params.NewDirectProvider(chainID, "direct-infura", "https://mainnet.infura.io/v3/", true),
*params.NewDirectProvider(chainID, "direct-grove", "https://eth-archival.rpc.grove.city/v1/", false),
}

return params.Network{
ChainID: MainnetChainID,
ChainID: chainID,
ChainName: "Mainnet",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/ethereum/mainnet/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/ethereum/mainnet/", stageName),
DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/ethereum/mainnet/", stageName),
RPCURL: "https://mainnet.infura.io/v3/",
FallbackURL: "https://eth-archival.rpc.grove.city/v1/",
RpcProviders: rpcProviders,
BlockExplorerURL: "https://etherscan.io/",
IconURL: "network/Network=Ethereum",
ChainColor: "#627EEA",
Expand All @@ -46,14 +57,24 @@ func mainnet(stageName string) params.Network {
}

func sepolia(stageName string) params.Network {
chainID := SepoliaChainID
chainName := "ethereum"
networkName := "sepolia"

rpcProviders := []params.RpcProvider{
// Proxy providers
*params.NewProxyProvider(chainID, "proxy-nodefleet", proxyUrl(stageName, "nodefleet", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-infura", proxyUrl(stageName, "infura", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-grove", proxyUrl(stageName, "grove", chainName, networkName), true),
// Direct providers
*params.NewDirectProvider(chainID, "direct-infura", "https://sepolia.infura.io/v3/", true),
*params.NewDirectProvider(chainID, "direct-grove", "https://sepolia-archival.rpc.grove.city/v1/", false),
}

return params.Network{
ChainID: SepoliaChainID,
ChainID: chainID,
ChainName: "Mainnet",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/ethereum/sepolia/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/ethereum/sepolia/", stageName),
DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/ethereum/sepolia/", stageName),
RPCURL: "https://sepolia.infura.io/v3/",
FallbackURL: "https://sepolia-archival.rpc.grove.city/v1/",
RpcProviders: rpcProviders,
BlockExplorerURL: "https://sepolia.etherscan.io/",
IconURL: "network/Network=Ethereum",
ChainColor: "#627EEA",
Expand All @@ -67,16 +88,25 @@ func sepolia(stageName string) params.Network {
RelatedChainID: MainnetChainID,
}
}

func optimism(stageName string) params.Network {
chainID := OptimismChainID
chainName := "optimism"
networkName := "mainnet"

rpcProviders := []params.RpcProvider{
// Proxy providers
*params.NewProxyProvider(chainID, "proxy-nodefleet", proxyUrl(stageName, "nodefleet", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-infura", proxyUrl(stageName, "infura", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-grove", proxyUrl(stageName, "grove", chainName, networkName), true),
// Direct providers
*params.NewDirectProvider(chainID, "direct-infura", "https://optimism-mainnet.infura.io/v3/", true),
*params.NewDirectProvider(chainID, "direct-grove", "https://optimism-archival.rpc.grove.city/v1/", false),
}

return params.Network{
ChainID: OptimismChainID,
ChainID: chainID,
ChainName: "Optimism",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/optimism/mainnet/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/optimism/mainnet/", stageName),
DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/optimism/mainnet/", stageName),
RPCURL: "https://optimism-mainnet.infura.io/v3/",
FallbackURL: "https://optimism-archival.rpc.grove.city/v1/",
RpcProviders: rpcProviders,
BlockExplorerURL: "https://optimistic.etherscan.io",
IconURL: "network/Network=Optimism",
ChainColor: "#E90101",
Expand All @@ -90,16 +120,25 @@ func optimism(stageName string) params.Network {
RelatedChainID: OptimismSepoliaChainID,
}
}

func optimismSepolia(stageName string) params.Network {
chainID := OptimismSepoliaChainID
chainName := "optimism"
networkName := "sepolia"

rpcProviders := []params.RpcProvider{
// Proxy providers
*params.NewProxyProvider(chainID, "proxy-nodefleet", proxyUrl(stageName, "nodefleet", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-infura", proxyUrl(stageName, "infura", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-grove", proxyUrl(stageName, "grove", chainName, networkName), true),
// Direct providers
*params.NewDirectProvider(chainID, "direct-infura", "https://optimism-sepolia.infura.io/v3/", true),
*params.NewDirectProvider(chainID, "direct-grove", "https://optimism-sepolia-archival.rpc.grove.city/v1/", false),
}

return params.Network{
ChainID: OptimismSepoliaChainID,
ChainID: chainID,
ChainName: "Optimism",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/optimism/sepolia/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/optimism/sepolia/", stageName),
DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/optimism/sepolia/", stageName),
RPCURL: "https://optimism-sepolia.infura.io/v3/",
FallbackURL: "https://optimism-sepolia-archival.rpc.grove.city/v1/",
RpcProviders: rpcProviders,
BlockExplorerURL: "https://sepolia-optimism.etherscan.io/",
IconURL: "network/Network=Optimism",
ChainColor: "#E90101",
Expand All @@ -113,16 +152,25 @@ func optimismSepolia(stageName string) params.Network {
RelatedChainID: OptimismChainID,
}
}

func arbitrum(stageName string) params.Network {
chainID := ArbitrumChainID
chainName := "arbitrum"
networkName := "mainnet"

rpcProviders := []params.RpcProvider{
// Proxy providers
*params.NewProxyProvider(chainID, "proxy-nodefleet", proxyUrl(stageName, "nodefleet", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-infura", proxyUrl(stageName, "infura", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-grove", proxyUrl(stageName, "grove", chainName, networkName), true),
// Direct providers
*params.NewDirectProvider(chainID, "direct-infura", "https://arbitrum-mainnet.infura.io/v3/", true),
*params.NewDirectProvider(chainID, "direct-grove", "https://arbitrum-one.rpc.grove.city/v1/", false),
}

return params.Network{
ChainID: ArbitrumChainID,
ChainID: chainID,
ChainName: "Arbitrum",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/arbitrum/mainnet/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/arbitrum/mainnet/", stageName),
DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/arbitrum/mainnet/", stageName),
RPCURL: "https://arbitrum-mainnet.infura.io/v3/",
FallbackURL: "https://arbitrum-one.rpc.grove.city/v1/",
RpcProviders: rpcProviders,
BlockExplorerURL: "https://arbiscan.io/",
IconURL: "network/Network=Arbitrum",
ChainColor: "#51D0F0",
Expand All @@ -136,16 +184,25 @@ func arbitrum(stageName string) params.Network {
RelatedChainID: ArbitrumSepoliaChainID,
}
}

func arbitrumSepolia(stageName string) params.Network {
chainID := ArbitrumSepoliaChainID
chainName := "arbitrum"
networkName := "sepolia"

rpcProviders := []params.RpcProvider{
// Proxy providers
*params.NewProxyProvider(chainID, "proxy-nodefleet", proxyUrl(stageName, "nodefleet", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-infura", proxyUrl(stageName, "infura", chainName, networkName), false),
*params.NewProxyProvider(chainID, "proxy-grove", proxyUrl(stageName, "grove", chainName, networkName), true),
// Direct providers
*params.NewDirectProvider(chainID, "direct-infura", "https://arbitrum-sepolia.infura.io/v3/", true),
*params.NewDirectProvider(chainID, "direct-grove", "https://arbitrum-sepolia-archival.rpc.grove.city/v1/", false),
}

return params.Network{
ChainID: ArbitrumSepoliaChainID,
ChainID: chainID,
ChainName: "Arbitrum",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/arbitrum/sepolia/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/arbitrum/sepolia/", stageName),
DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/arbitrum/sepolia/", stageName),
RPCURL: "https://arbitrum-sepolia.infura.io/v3/",
FallbackURL: "https://arbitrum-sepolia-archival.rpc.grove.city/v1/",
RpcProviders: rpcProviders,
BlockExplorerURL: "https://sepolia-explorer.arbitrum.io/",
IconURL: "network/Network=Arbitrum",
ChainColor: "#51D0F0",
Expand All @@ -171,50 +228,12 @@ func defaultNetworks(stageName string) []params.Network {
}
}

var mainnetGanacheTokenOverrides = params.TokenOverride{
Symbol: sntSymbol,
Address: ganacheTokenAddress,
}

func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) []params.Network {

var networksWithRPC []params.Network

const (
infura = "infura.io/"
grove = "grove.city/"
)

appendToken := func(url string) string {
if strings.Contains(url, infura) && request.InfuraToken != "" {
return url + request.InfuraToken
} else if strings.Contains(url, grove) && request.PoktToken != "" {
return url + request.PoktToken
}
return url
authTokens := map[string]string{
"infura.io": request.InfuraToken,
"grove.city": request.PoktToken,
}

for _, n := range networks {
n.DefaultRPCURL = appendToken(n.DefaultRPCURL)
n.DefaultFallbackURL = appendToken(n.DefaultFallbackURL)
n.DefaultFallbackURL2 = appendToken(n.DefaultFallbackURL2)
n.RPCURL = appendToken(n.RPCURL)
n.FallbackURL = appendToken(n.FallbackURL)

if request.GanacheURL != "" {
n.RPCURL = request.GanacheURL
n.FallbackURL = request.GanacheURL
if n.ChainID == MainnetChainID {
n.TokenOverrides = []params.TokenOverride{
mainnetGanacheTokenOverrides,
}
}
}

networksWithRPC = append(networksWithRPC, n)
}

return networksWithRPC
return networkhelper.OverrideDirectProvidersAuth(networks, authTokens)
}

func BuildDefaultNetworks(walletSecretsConfig *requests.WalletSecretsConfig) []params.Network {
Expand Down
48 changes: 22 additions & 26 deletions api/default_networks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@ 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,
},
}
Expand Down Expand Up @@ -50,30 +53,23 @@ 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,
},
}

actualNetworks := BuildDefaultNetworks(&request.WalletSecretsConfig)

require.Len(t, actualNetworks, 6)
// 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 {
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)
}
21 changes: 10 additions & 11 deletions node/get_status_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"reflect"
"sync"

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

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

Expand Down Expand Up @@ -336,25 +338,22 @@ 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)
n.rpcClient.Start(context.Background())
Expand Down
Loading

0 comments on commit 526f19c

Please sign in to comment.