mirror of
https://github.com/status-im/status-go.git
synced 2025-01-15 01:05:06 +00:00
9d01f7aa26
An issue arose that shh_newMessageFilter was routed to the upstream instead of local node. This PR fixes that. It also revisits routing logic and makes all requests go to the local node by default.
80 lines
2.2 KiB
Go
80 lines
2.2 KiB
Go
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/ethereum/go-ethereum/node"
|
|
"github.com/status-im/status-go/geth/params"
|
|
|
|
gethrpc "github.com/ethereum/go-ethereum/rpc"
|
|
)
|
|
|
|
// Client represents RPC client with custom routing
|
|
// scheme. It automatically decides where RPC call
|
|
// goes - Upstream or Local node.
|
|
type Client struct {
|
|
upstreamEnabled bool
|
|
upstreamURL string
|
|
|
|
local *gethrpc.Client
|
|
upstream *gethrpc.Client
|
|
|
|
router *router
|
|
}
|
|
|
|
// NewClient initializes Client and tries to connect to both,
|
|
// upstream and local node.
|
|
//
|
|
// Client is safe for concurrent use and will automatically
|
|
// reconnect to the server if connection is lost.
|
|
func NewClient(node *node.Node, upstream params.UpstreamRPCConfig) (*Client, error) {
|
|
c := &Client{}
|
|
|
|
var err error
|
|
c.local, err = node.Attach()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("attach to local node: %s", err)
|
|
}
|
|
|
|
if upstream.Enabled {
|
|
c.upstreamEnabled = upstream.Enabled
|
|
c.upstreamURL = upstream.URL
|
|
|
|
c.upstream, err = gethrpc.Dial(c.upstreamURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("dial upstream server: %s", err)
|
|
}
|
|
}
|
|
|
|
c.router = newRouter(c.upstreamEnabled)
|
|
|
|
return c, nil
|
|
}
|
|
|
|
// Call performs a JSON-RPC call with the given arguments and unmarshals into
|
|
// result if no error occurred.
|
|
//
|
|
// The result must be a pointer so that package json can unmarshal into it. You
|
|
// can also pass nil, in which case the result is ignored.
|
|
//
|
|
// It uses custom routing scheme for calls.
|
|
func (c *Client) Call(result interface{}, method string, args ...interface{}) error {
|
|
ctx := context.Background()
|
|
return c.CallContext(ctx, result, method, args...)
|
|
}
|
|
|
|
// CallContext performs a JSON-RPC call with the given arguments. If the context is
|
|
// canceled before the call has successfully returned, CallContext returns immediately.
|
|
//
|
|
// The result must be a pointer so that package json can unmarshal into it. You
|
|
// can also pass nil, in which case the result is ignored.
|
|
//
|
|
// It uses custom routing scheme for calls.
|
|
func (c *Client) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
|
|
if c.router.routeRemote(method) {
|
|
return c.upstream.CallContext(ctx, result, method, args...)
|
|
}
|
|
return c.local.CallContext(ctx, result, method, args...)
|
|
}
|