option to immediately forward eth_calls to proxy node

This commit is contained in:
i-norden 2021-12-27 12:25:54 -06:00
parent 68152b0d77
commit 140989cbf7
6 changed files with 81 additions and 58 deletions

View File

@ -57,13 +57,17 @@ type PublicEthAPI struct {
B *Backend
// Proxy node for forwarding cache misses
supportsStateDiff bool // Whether or not the remote node supports the statediff_writeStateDiffAt endpoint, if it does we can fill the local cache when we hit a miss
supportsStateDiff bool // Whether the remote node supports the statediff_writeStateDiffAt endpoint, if it does we can fill the local cache when we hit a miss
rpc *rpc.Client
ethClient *ethclient.Client
forwardEthCalls bool // if true, forward eth_call calls directly to the configured proxy node
}
// NewPublicEthAPI creates a new PublicEthAPI with the provided underlying Backend
func NewPublicEthAPI(b *Backend, client *rpc.Client, supportsStateDiff bool) *PublicEthAPI {
func NewPublicEthAPI(b *Backend, client *rpc.Client, supportsStateDiff, forwardEthCalls bool) (*PublicEthAPI, error) {
if forwardEthCalls && client == nil {
return nil, errors.New("ipld-eth-server is configured to forward eth_calls to proxy node but no proxy node is configured")
}
var ethClient *ethclient.Client
if client != nil {
ethClient = ethclient.NewClient(client)
@ -73,7 +77,8 @@ func NewPublicEthAPI(b *Backend, client *rpc.Client, supportsStateDiff bool) *Pu
supportsStateDiff: supportsStateDiff,
rpc: client,
ethClient: ethClient,
}
forwardEthCalls: forwardEthCalls,
}, nil
}
/*
@ -910,6 +915,12 @@ func (diff *StateOverride) Apply(state *state.StateDB) error {
// Note, this function doesn't make and changes in the state/blockchain and is
// useful to execute and retrieve values.
func (pea *PublicEthAPI) Call(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) {
if pea.forwardEthCalls {
var hex hexutil.Bytes
err := pea.rpc.CallContext(ctx, &hex, "eth_call", args, blockNrOrHash, overrides)
return hex, err
}
result, err := DoCall(ctx, pea.B, args, blockNrOrHash, overrides, 5*time.Second, pea.B.Config.RPCGasCap.Uint64())
// If the result contains a revert reason, try to unpack and return it.

View File

@ -19,9 +19,10 @@ package eth
import (
"encoding/json"
"fmt"
"os"
"github.com/ethereum/go-ethereum/cmd/utils"
log "github.com/sirupsen/logrus"
"os"
sdtypes "github.com/ethereum/go-ethereum/statediff/types"

View File

@ -36,21 +36,22 @@ import (
// Env variables
const (
serverWsPath = "SERVER_WS_PATH"
serverIpcPath = "SERVER_IPC_PATH"
serverHTTPPath = "SERVER_HTTP_PATH"
SERVER_WS_PATH = "SERVER_WS_PATH"
SERVER_IPC_PATH = "SERVER_IPC_PATH"
SERVER_HTTP_PATH = "SERVER_HTTP_PATH"
serverMaxIdleConnections = "SERVER_MAX_IDLE_CONNECTIONS"
serverMaxOpenConnections = "SERVER_MAX_OPEN_CONNECTIONS"
serverMaxConnLifetime = "SERVER_MAX_CONN_LIFETIME"
SERVER_MAX_IDLE_CONNECTIONS = "SERVER_MAX_IDLE_CONNECTIONS"
SERVER_MAX_OPEN_CONNECTIONS = "SERVER_MAX_OPEN_CONNECTIONS"
SERVER_MAX_CONN_LIFETIME = "SERVER_MAX_CONN_LIFETIME"
ethDefaultSenderAddr = "ETH_DEFAULT_SENDER_ADDR"
ethRPCGasCap = "ETH_RPC_GAS_CAP"
ethChainConfig = "ETH_CHAIN_CONFIG"
ethSupportsStatediff = "ETH_SUPPORTS_STATEDIFF"
ETH_DEFAULT_SENDER_ADDR = "ETH_DEFAULT_SENDER_ADDR"
ETH_RPC_GAS_CAP = "ETH_RPC_GAS_CAP"
ETH_CHAIN_CONFIG = "ETH_CHAIN_CONFIG"
ETH_SUPPORTS_STATEDIFF = "ETH_SUPPORTS_STATEDIFF"
ETH_FORWARD_ETH_CALLS = "ETH_FORWARD_ETH_CALLS"
ValidatorEnabled = "VALIDATOR_ENABLED"
ValidatorEveryNthBlock = "VALIDATOR_EVERY_NTH_BLOCK"
VALIDATOR_ENABLED = "VALIDATOR_ENABLED"
VALIDATOR_EVERY_NTH_BLOCK = "VALIDATOR_EVERY_NTH_BLOCK"
)
// Config struct
@ -83,6 +84,7 @@ type Config struct {
EthHttpEndpoint string
Client *rpc.Client
SupportStateDiff bool
ForwardEthCalls bool
// Cache configuration.
GroupCache *ethServerShared.GroupCacheConfig
@ -96,11 +98,12 @@ type Config struct {
func NewConfig() (*Config, error) {
c := new(Config)
viper.BindEnv("ethereum.httpPath", ethHTTPPath)
viper.BindEnv("ethereum.defaultSender", ethDefaultSenderAddr)
viper.BindEnv("ethereum.rpcGasCap", ethRPCGasCap)
viper.BindEnv("ethereum.chainConfig", ethChainConfig)
viper.BindEnv("ethereum.supportsStateDiff", ethSupportsStatediff)
viper.BindEnv("ethereum.httpPath", ETH_HTTP_PATH)
viper.BindEnv("ethereum.defaultSender", ETH_DEFAULT_SENDER_ADDR)
viper.BindEnv("ethereum.rpcGasCap", ETH_RPC_GAS_CAP)
viper.BindEnv("ethereum.chainConfig", ETH_CHAIN_CONFIG)
viper.BindEnv("ethereum.supportsStateDiff", ETH_SUPPORTS_STATEDIFF)
viper.BindEnv("ethereum.forwardEthCalls", ETH_FORWARD_ETH_CALLS)
c.dbInit()
ethHTTP := viper.GetString("ethereum.httpPath")
@ -111,6 +114,7 @@ func NewConfig() (*Config, error) {
}
c.Client = cli
c.SupportStateDiff = viper.GetBool("ethereum.supportsStateDiff")
c.ForwardEthCalls = viper.GetBool("ethereum.forwardEthCalls")
c.EthHttpEndpoint = ethHTTPEndpoint
// websocket server
@ -224,23 +228,23 @@ func NewConfig() (*Config, error) {
}
func overrideDBConnConfig(con *postgres.ConnectionConfig) {
viper.BindEnv("database.server.maxIdle", serverMaxIdleConnections)
viper.BindEnv("database.server.maxOpen", serverMaxOpenConnections)
viper.BindEnv("database.server.maxLifetime", serverMaxConnLifetime)
viper.BindEnv("database.server.maxIdle", SERVER_MAX_IDLE_CONNECTIONS)
viper.BindEnv("database.server.maxOpen", SERVER_MAX_OPEN_CONNECTIONS)
viper.BindEnv("database.server.maxLifetime", SERVER_MAX_CONN_LIFETIME)
con.MaxIdle = viper.GetInt("database.server.maxIdle")
con.MaxOpen = viper.GetInt("database.server.maxOpen")
con.MaxLifetime = viper.GetInt("database.server.maxLifetime")
}
func (c *Config) dbInit() {
viper.BindEnv("database.name", databaseName)
viper.BindEnv("database.hostname", databaseHostname)
viper.BindEnv("database.port", databasePort)
viper.BindEnv("database.user", databaseUser)
viper.BindEnv("database.password", databasePassword)
viper.BindEnv("database.maxIdle", databaseMaxIdleConnections)
viper.BindEnv("database.maxOpen", databaseMaxOpenConnections)
viper.BindEnv("database.maxLifetime", databaseMaxOpenConnLifetime)
viper.BindEnv("database.name", DATABASE_NAME)
viper.BindEnv("database.hostname", DATABASE_HOSTNAME)
viper.BindEnv("database.port", DATABASE_PORT)
viper.BindEnv("database.user", DATABASE_USER)
viper.BindEnv("database.password", DATABASE_PASSWORD)
viper.BindEnv("database.maxIdle", DATABASE_MAX_IDLE_CONNECTIONS)
viper.BindEnv("database.maxOpen", DATABASE_MAX_OPEN_CONNECTIONS)
viper.BindEnv("database.maxLifetime", DATABASE_MAX_CONN_LIFETIME)
c.DBParams.Name = viper.GetString("database.name")
c.DBParams.Hostname = viper.GetString("database.hostname")
@ -276,8 +280,8 @@ func (c *Config) loadGroupCacheConfig() {
}
func (c *Config) loadValidatorConfig() {
viper.BindEnv("validator.enabled", ValidatorEnabled)
viper.BindEnv("validator.everyNthBlock", ValidatorEveryNthBlock)
viper.BindEnv("validator.enabled", VALIDATOR_ENABLED)
viper.BindEnv("validator.everyNthBlock", VALIDATOR_EVERY_NTH_BLOCK)
c.StateValidationEnabled = viper.GetBool("validator.enabled")
c.StateValidationEveryNthBlock = viper.GetUint64("validator.everyNthBlock")

View File

@ -8,33 +8,33 @@ import (
// Env variables
const (
HTTPTimeout = "HTTP_TIMEOUT"
HTTP_TIMEOUT = "HTTP_TIMEOUT"
EthWsPath = "ETH_WS_PATH"
ethHTTPPath = "ETH_HTTP_PATH"
ethNodeID = "ETH_NODE_ID"
ethClientName = "ETH_CLIENT_NAME"
ethGenesisBlock = "ETH_GENESIS_BLOCK"
ethNetworkID = "ETH_NETWORK_ID"
ethChainID = "ETH_CHAIN_ID"
ETH_WS_PATH = "ETH_WS_PATH"
ETH_HTTP_PATH = "ETH_HTTP_PATH"
ETH_NODE_ID = "ETH_NODE_ID"
ETH_CLIENT_NAME = "ETH_CLIENT_NAME"
ETH_GENESIS_BLOCK = "ETH_GENESIS_BLOCK"
ETH_NETWORK_ID = "ETH_NETWORK_ID"
ETH_CHAIN_ID = "ETH_CHAIN_ID"
databaseName = "DATABASE_NAME"
databaseHostname = "DATABASE_HOSTNAME"
databasePort = "DATABASE_PORT"
databaseUser = "DATABASE_USER"
databasePassword = "DATABASE_PASSWORD"
databaseMaxIdleConnections = "DATABASE_MAX_IDLE_CONNECTIONS"
databaseMaxOpenConnections = "DATABASE_MAX_OPEN_CONNECTIONS"
databaseMaxOpenConnLifetime = "DATABASE_MAX_CONN_LIFETIME"
DATABASE_NAME = "DATABASE_NAME"
DATABASE_HOSTNAME = "DATABASE_HOSTNAME"
DATABASE_PORT = "DATABASE_PORT"
DATABASE_USER = "DATABASE_USER"
DATABASE_PASSWORD = "DATABASE_PASSWORD"
DATABASE_MAX_IDLE_CONNECTIONS = "DATABASE_MAX_IDLE_CONNECTIONS"
DATABASE_MAX_OPEN_CONNECTIONS = "DATABASE_MAX_OPEN_CONNECTIONS"
DATABASE_MAX_CONN_LIFETIME = "DATABASE_MAX_CONN_LIFETIME"
)
// GetEthNodeAndClient returns eth node info and client from path url
func getEthNodeAndClient(path string) (node.Info, *rpc.Client, error) {
viper.BindEnv("ethereum.nodeID", ethNodeID)
viper.BindEnv("ethereum.clientName", ethClientName)
viper.BindEnv("ethereum.genesisBlock", ethGenesisBlock)
viper.BindEnv("ethereum.networkID", ethNetworkID)
viper.BindEnv("ethereum.chainID", ethChainID)
viper.BindEnv("ethereum.nodeID", ETH_NODE_ID)
viper.BindEnv("ethereum.clientName", ETH_CLIENT_NAME)
viper.BindEnv("ethereum.genesisBlock", ETH_GENESIS_BLOCK)
viper.BindEnv("ethereum.networkID", ETH_NETWORK_ID)
viper.BindEnv("ethereum.chainID", ETH_CHAIN_ID)
rpcClient, err := rpc.Dial(path)
if err != nil {

View File

@ -83,6 +83,8 @@ type Service struct {
supportsStateDiffing bool
// backend for the server
backend *eth.Backend
// whether to forward eth_calls directly to proxy node
forwardEthCalls bool
}
// NewServer creates a new Server using an underlying Service struct
@ -97,6 +99,7 @@ func NewServer(settings *Config) (Server, error) {
sap.SubscriptionTypes = make(map[common.Hash]eth.SubscriptionSettings)
sap.client = settings.Client
sap.supportsStateDiffing = settings.SupportStateDiff
sap.forwardEthCalls = settings.ForwardEthCalls
var err error
sap.backend, err = eth.NewEthBackend(sap.db, &eth.Config{
ChainConfig: settings.ChainConfig,
@ -130,10 +133,14 @@ func (sap *Service) APIs() []rpc.API {
Public: true,
},
}
ethAPI, err := eth.NewPublicEthAPI(sap.backend, sap.client, sap.supportsStateDiffing, sap.forwardEthCalls)
if err != nil {
log.Fatalf("unable to create public eth api: %v", err)
}
return append(apis, rpc.API{
Namespace: eth.APIName,
Version: eth.APIVersion,
Service: eth.NewPublicEthAPI(sap.backend, sap.client, sap.supportsStateDiffing),
Service: ethAPI,
Public: true,
})
}

View File

@ -20,8 +20,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/statediff/indexer/ipfs/ipld"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-ipfs-blockstore"
"github.com/ipfs/go-ipfs-ds-help"
blockstore "github.com/ipfs/go-ipfs-blockstore"
dshelp "github.com/ipfs/go-ipfs-ds-help"
node "github.com/ipfs/go-ipld-format"
"github.com/jmoiron/sqlx"
"github.com/sirupsen/logrus"