feat_: implement connector service (#5375)

This commit is contained in:
Godfrain Jacques 2024-06-20 14:11:55 -07:00 committed by GitHub
parent a049f0b688
commit b25ff41e51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 235 additions and 1 deletions

View File

@ -146,6 +146,7 @@ func randomNodeConfig() *params.NodeConfig {
PermissionsConfig: params.PermissionsConfig{Enabled: randomBool()},
MailserversConfig: params.MailserversConfig{Enabled: randomBool()},
Web3ProviderConfig: params.Web3ProviderConfig{Enabled: randomBool()},
ConnectorConfig: params.ConnectorConfig{Enabled: randomBool()},
SwarmConfig: params.SwarmConfig{Enabled: randomBool()},
MailServerRegistryAddress: randomString(),
HTTPEnabled: randomBool(),

View File

@ -37,6 +37,7 @@ import (
"github.com/status-im/status-go/services/browsers"
"github.com/status-im/status-go/services/chat"
"github.com/status-im/status-go/services/communitytokens"
"github.com/status-im/status-go/services/connector"
"github.com/status-im/status-go/services/ens"
"github.com/status-im/status-go/services/gif"
localnotifications "github.com/status-im/status-go/services/local-notifications"
@ -129,6 +130,7 @@ type StatusNode struct {
chatSrvc *chat.Service
updatesSrvc *updates.Service
pendingTracker *transactions.PendingTxTracker
connectorSrvc *connector.Service
walletFeed event.Feed
}
@ -505,6 +507,7 @@ func (n *StatusNode) stop() error {
n.ensSrvc = nil
n.communityTokensSrvc = nil
n.stickersSrvc = nil
n.connectorSrvc = nil
n.publicMethods = make(map[string]bool)
n.pendingTracker = nil
n.log.Debug("status node stopped")

View File

@ -37,6 +37,7 @@ import (
"github.com/status-im/status-go/services/browsers"
"github.com/status-im/status-go/services/chat"
"github.com/status-im/status-go/services/communitytokens"
"github.com/status-im/status-go/services/connector"
"github.com/status-im/status-go/services/ens"
"github.com/status-im/status-go/services/ext"
"github.com/status-im/status-go/services/gif"
@ -99,6 +100,7 @@ func (b *StatusNode) initServices(config *params.NodeConfig, mediaServer *server
services = appendIf(config.PermissionsConfig.Enabled, services, b.permissionsService())
services = appendIf(config.MailserversConfig.Enabled, services, b.mailserversService())
services = appendIf(config.Web3ProviderConfig.Enabled, services, b.providerService(accDB))
services = appendIf(config.ConnectorConfig.Enabled, services, b.connectorService())
services = append(services, b.gifService(accDB))
services = append(services, b.ChatService(accDB))
@ -425,6 +427,13 @@ func wakuRateLimiter(wakuCfg *params.WakuConfig, clusterCfg *params.ClusterConfi
)
}
func (b *StatusNode) connectorService() *connector.Service {
if b.connectorSrvc == nil {
b.connectorSrvc = connector.NewService(b.rpcClient, b.connectorSrvc)
}
return b.connectorSrvc
}
func (b *StatusNode) rpcFiltersService() *rpcfilters.Service {
if b.rpcFiltersSrvc == nil {
b.rpcFiltersSrvc = rpcfilters.New(b)

View File

@ -52,6 +52,7 @@ func insertNodeConfig(tx *sql.Tx, c *params.NodeConfig) error {
c.BridgeConfig.Enabled, c.WalletConfig.Enabled, c.LocalNotificationsConfig.Enabled,
c.BrowsersConfig.Enabled, c.PermissionsConfig.Enabled, c.MailserversConfig.Enabled,
c.SwarmConfig.Enabled, c.MailServerRegistryAddress, c.Web3ProviderConfig.Enabled,
c.ConnectorConfig.Enabled,
)
return err
}
@ -456,7 +457,7 @@ func loadNodeConfig(tx *sql.Tx) (*params.NodeConfig, error) {
&nodecfg.ListenAddr, &nodecfg.AdvertiseAddr, &nodecfg.Name, &nodecfg.Version, &nodecfg.APIModules, &nodecfg.TLSEnabled, &nodecfg.MaxPeers, &nodecfg.MaxPendingPeers,
&nodecfg.EnableStatusService, &nodecfg.BridgeConfig.Enabled, &nodecfg.WalletConfig.Enabled, &nodecfg.LocalNotificationsConfig.Enabled,
&nodecfg.BrowsersConfig.Enabled, &nodecfg.PermissionsConfig.Enabled, &nodecfg.MailserversConfig.Enabled, &nodecfg.SwarmConfig.Enabled,
&nodecfg.MailServerRegistryAddress, &nodecfg.Web3ProviderConfig.Enabled,
&nodecfg.MailServerRegistryAddress, &nodecfg.Web3ProviderConfig.Enabled, &nodecfg.ConnectorConfig.Enabled,
)
if err != nil && err != sql.ErrNoRows {
return nil, err

View File

@ -483,6 +483,9 @@ type NodeConfig struct {
// (desktop provider API)
Web3ProviderConfig Web3ProviderConfig
// ConnectorConfig extra configuration for connector.Service
ConnectorConfig ConnectorConfig
// SwarmConfig extra configuration for Swarm and ENS
SwarmConfig SwarmConfig `json:"SwarmConfig," validate:"structonly"`
@ -571,6 +574,11 @@ type Web3ProviderConfig struct {
Enabled bool
}
// ConnectorConfig extra configuration for provider.Service
type ConnectorConfig struct {
Enabled bool
}
// BridgeConfig provides configuration for Whisper-Waku bridge.
type BridgeConfig struct {
Enabled bool

15
services/connector/api.go Normal file
View File

@ -0,0 +1,15 @@
package connector
func NewAPI(s *Service) *API {
return &API{
s: s,
}
}
type API struct {
s *Service
}
func (api *API) CallRPC(inputJSON string) (string, error) {
return api.s.rpcClient.CallRaw(inputJSON), nil
}

View File

@ -0,0 +1,86 @@
package connector
import (
"database/sql"
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
gethrpc "github.com/ethereum/go-ethereum/rpc"
"github.com/status-im/status-go/appdatabase"
"github.com/status-im/status-go/params"
statusRPC "github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/t/helpers"
"github.com/status-im/status-go/transactions/fake"
)
func createDB(t *testing.T) (*sql.DB, func()) {
db, cleanup, err := helpers.SetupTestSQLDB(appdatabase.DbInitializer{}, "provider-tests-")
require.NoError(t, err)
return db, func() { require.NoError(t, cleanup()) }
}
func setupTestAPI(t *testing.T) (*API, func()) {
db, cancel := createDB(t)
txServiceMockCtrl := gomock.NewController(t)
server, _ := fake.NewTestServer(txServiceMockCtrl)
// Creating a dummy status node to simulate what it's done in get_status_node.go
upstreamConfig := params.UpstreamRPCConfig{
URL: "https://mainnet.infura.io/v3/fake",
Enabled: true,
}
client := gethrpc.DialInProc(server)
rpcClient, err := statusRPC.NewClient(client, 1, upstreamConfig, nil, db)
require.NoError(t, err)
service := NewService(rpcClient, nil)
return &API{
s: service,
}, cancel
}
func TestCallRPC(t *testing.T) {
api, cancel := setupTestAPI(t)
defer cancel()
tests := []struct {
request string
expectedContains string
notContains bool
}{
{
request: "{\"method\": \"eth_blockNumber\", \"params\": []}",
expectedContains: "does not exist/is not available",
notContains: true,
},
{
request: "{\"method\": \"eth_blockNumbers\", \"params\": []}",
expectedContains: "does not exist/is not available",
notContains: false,
},
{
request: "",
expectedContains: "does not exist/is not available",
notContains: true,
},
}
for _, tt := range tests {
t.Run(tt.request, func(t *testing.T) {
response, err := api.CallRPC(tt.request)
require.NoError(t, err)
require.NotEmpty(t, response)
if tt.notContains {
require.NotContains(t, response, tt.expectedContains)
} else {
require.Contains(t, response, tt.expectedContains)
}
})
}
}

View File

@ -0,0 +1,42 @@
package connector
import (
"github.com/ethereum/go-ethereum/p2p"
gethrpc "github.com/ethereum/go-ethereum/rpc"
"github.com/status-im/status-go/rpc"
)
func NewService(rpcClient *rpc.Client, connectorSrvc *Service) *Service {
return &Service{
rpcClient: rpcClient,
connectorSrvc: connectorSrvc,
}
}
type Service struct {
rpcClient *rpc.Client
connectorSrvc *Service
}
func (s *Service) Start() error {
return nil
}
func (s *Service) Stop() error {
return nil
}
func (s *Service) APIs() []gethrpc.API {
return []gethrpc.API{
{
Namespace: "connector",
Version: "0.1.0",
Service: NewAPI(s),
},
}
}
func (s *Service) Protocols() []p2p.Protocol {
return nil
}

View File

@ -0,0 +1,69 @@
package connector
import (
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
gethrpc "github.com/ethereum/go-ethereum/rpc"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/rpc"
statusRPC "github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/transactions/fake"
)
func TestNewService(t *testing.T) {
db, _ := createDB(t)
txServiceMockCtrl := gomock.NewController(t)
server, _ := fake.NewTestServer(txServiceMockCtrl)
// Creating a dummy status node to simulate what it's done in get_status_node.go
upstreamConfig := params.UpstreamRPCConfig{
URL: "https://mainnet.infura.io/v3/fake",
Enabled: true,
}
client := gethrpc.DialInProc(server)
rpcClient, err := statusRPC.NewClient(client, 1, upstreamConfig, nil, db)
require.NoError(t, err)
mockConnectorService := &Service{}
service := NewService(rpcClient, mockConnectorService)
assert.NotNil(t, service)
assert.Equal(t, rpcClient, service.rpcClient)
assert.Equal(t, mockConnectorService, service.connectorSrvc)
}
func TestService_Start(t *testing.T) {
service := NewService(&rpc.Client{}, &Service{})
err := service.Start()
assert.NoError(t, err)
}
func TestService_Stop(t *testing.T) {
service := NewService(&rpc.Client{}, &Service{})
err := service.Stop()
assert.NoError(t, err)
}
func TestService_APIs(t *testing.T) {
api, cancel := setupTestAPI(t)
defer cancel()
apis := api.s.APIs()
assert.Len(t, apis, 1)
assert.Equal(t, "connector", apis[0].Namespace)
assert.Equal(t, "0.1.0", apis[0].Version)
assert.NotNil(t, apis[0].Service)
}
func TestService_Protocols(t *testing.T) {
service := NewService(&rpc.Client{}, &Service{})
protocols := service.Protocols()
assert.Nil(t, protocols)
}