-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(evm): app config and json-rpc (#1871)
- Loading branch information
1 parent
fac6492
commit aeff126
Showing
10 changed files
with
998 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package server | ||
|
||
import ( | ||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
"github.com/cosmos/cosmos-sdk/crypto/keyring" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
// Tendermint/cosmos-sdk full-node start flags | ||
const ( | ||
WithTendermint = "with-tendermint" | ||
Address = "address" | ||
Transport = "transport" | ||
TraceStore = "trace-store" | ||
CPUProfile = "cpu-profile" | ||
// The type of database for application and snapshots databases | ||
AppDBBackend = "app-db-backend" | ||
) | ||
|
||
// GRPC-related flags. | ||
const ( | ||
GRPCOnly = "grpc-only" | ||
GRPCEnable = "grpc.enable" | ||
GRPCAddress = "grpc.address" | ||
GRPCWebEnable = "grpc-web.enable" | ||
GRPCWebAddress = "grpc-web.address" | ||
) | ||
|
||
// Cosmos API flags | ||
const ( | ||
RPCEnable = "api.enable" | ||
EnabledUnsafeCors = "api.enabled-unsafe-cors" | ||
) | ||
|
||
// JSON-RPC flags | ||
const ( | ||
JSONRPCEnable = "json-rpc.enable" | ||
JSONRPCAPI = "json-rpc.api" | ||
JSONRPCAddress = "json-rpc.address" | ||
JSONWsAddress = "json-rpc.ws-address" | ||
JSONRPCGasCap = "json-rpc.gas-cap" | ||
JSONRPCEVMTimeout = "json-rpc.evm-timeout" | ||
JSONRPCTxFeeCap = "json-rpc.txfee-cap" | ||
JSONRPCFilterCap = "json-rpc.filter-cap" | ||
JSONRPCLogsCap = "json-rpc.logs-cap" | ||
JSONRPCBlockRangeCap = "json-rpc.block-range-cap" | ||
JSONRPCHTTPTimeout = "json-rpc.http-timeout" | ||
JSONRPCHTTPIdleTimeout = "json-rpc.http-idle-timeout" | ||
JSONRPCAllowUnprotectedTxs = "json-rpc.allow-unprotected-txs" | ||
JSONRPCMaxOpenConnections = "json-rpc.max-open-connections" | ||
JSONRPCEnableIndexer = "json-rpc.enable-indexer" | ||
JSONRPCEnableMetrics = "metrics" | ||
) | ||
|
||
// EVM flags | ||
const ( | ||
EVMTracer = "evm.tracer" | ||
EVMMaxTxGasWanted = "evm.max-tx-gas-wanted" | ||
) | ||
|
||
// TLS flags | ||
const ( | ||
TLSCertPath = "tls.certificate-path" | ||
TLSKeyPath = "tls.key-path" | ||
) | ||
|
||
// AddTxFlags adds common flags for commands to post tx | ||
func AddTxFlags(cmd *cobra.Command) (*cobra.Command, error) { | ||
cmd.PersistentFlags().String(flags.FlagChainID, "", "Specify Chain ID for sending Tx") | ||
cmd.PersistentFlags().String(flags.FlagFrom, "", "Name or address of private key with which to sign") | ||
cmd.PersistentFlags().String(flags.FlagFees, "", "Fees to pay along with transaction; eg: 5000unibi") | ||
cmd.PersistentFlags().String(flags.FlagGasPrices, "", "Gas prices to determine the transaction fee (e.g. 5000unibi)") | ||
cmd.PersistentFlags().String(flags.FlagNode, "tcp://localhost:26657", "<host>:<port> to tendermint rpc interface for this chain") //nolint:lll | ||
cmd.PersistentFlags().Float64(flags.FlagGasAdjustment, flags.DefaultGasAdjustment, "adjustment factor to be multiplied against the estimate returned by the tx simulation; if the gas limit is set manually this flag is ignored ") //nolint:lll | ||
cmd.PersistentFlags().StringP(flags.FlagBroadcastMode, "b", flags.BroadcastSync, "Transaction broadcasting mode (sync|async)") | ||
cmd.PersistentFlags().String(flags.FlagKeyringBackend, keyring.BackendOS, "Select keyring's backend") | ||
|
||
// --gas can accept integers and "simulate" | ||
// cmd.PersistentFlags().Var(&flags.GasFlagVar, "gas", fmt.Sprintf( | ||
// "gas limit to set per-transaction; set to %q to calculate required gas automatically (default %d)", | ||
// flags.GasFlagAuto, flags.DefaultGasLimit, | ||
// )) | ||
|
||
// viper.BindPFlag(flags.FlagTrustNode, cmd.Flags().Lookup(flags.FlagTrustNode)) | ||
if err := viper.BindPFlag(flags.FlagNode, cmd.PersistentFlags().Lookup(flags.FlagNode)); err != nil { | ||
return nil, err | ||
} | ||
if err := viper.BindPFlag(flags.FlagKeyringBackend, cmd.PersistentFlags().Lookup(flags.FlagKeyringBackend)); err != nil { | ||
return nil, err | ||
} | ||
return cmd, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package server | ||
|
||
import ( | ||
"net/http" | ||
"time" | ||
|
||
"github.com/NibiruChain/nibiru/eth" | ||
"github.com/NibiruChain/nibiru/eth/rpc/rpcapi" | ||
|
||
"github.com/gorilla/mux" | ||
"github.com/rs/cors" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/server" | ||
"github.com/cosmos/cosmos-sdk/server/types" | ||
ethlog "github.com/ethereum/go-ethereum/log" | ||
ethrpc "github.com/ethereum/go-ethereum/rpc" | ||
|
||
srvconfig "github.com/NibiruChain/nibiru/app/server/config" | ||
) | ||
|
||
// StartJSONRPC starts the JSON-RPC server | ||
func StartJSONRPC(ctx *server.Context, | ||
clientCtx client.Context, | ||
tmRPCAddr, | ||
tmEndpoint string, | ||
config *srvconfig.Config, | ||
indexer eth.EVMTxIndexer, | ||
) (*http.Server, chan struct{}, error) { | ||
tmWsClient := ConnectTmWS(tmRPCAddr, tmEndpoint, ctx.Logger) | ||
|
||
logger := ctx.Logger.With("module", "geth") | ||
ethlog.Root().SetHandler(ethlog.FuncHandler(func(r *ethlog.Record) error { | ||
switch r.Lvl { | ||
case ethlog.LvlTrace, ethlog.LvlDebug: | ||
logger.Debug(r.Msg, r.Ctx...) | ||
case ethlog.LvlInfo, ethlog.LvlWarn: | ||
logger.Info(r.Msg, r.Ctx...) | ||
case ethlog.LvlError, ethlog.LvlCrit: | ||
logger.Error(r.Msg, r.Ctx...) | ||
} | ||
return nil | ||
})) | ||
|
||
rpcServer := ethrpc.NewServer() | ||
|
||
allowUnprotectedTxs := config.JSONRPC.AllowUnprotectedTxs | ||
rpcAPIArr := config.JSONRPC.API | ||
|
||
apis := rpcapi.GetRPCAPIs(ctx, clientCtx, tmWsClient, allowUnprotectedTxs, indexer, rpcAPIArr) | ||
|
||
for _, api := range apis { | ||
if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil { | ||
ctx.Logger.Error( | ||
"failed to register service in JSON RPC namespace", | ||
"namespace", api.Namespace, | ||
"service", api.Service, | ||
) | ||
return nil, nil, err | ||
} | ||
} | ||
|
||
r := mux.NewRouter() | ||
r.HandleFunc("/", rpcServer.ServeHTTP).Methods("POST") | ||
|
||
handlerWithCors := cors.Default() | ||
if config.API.EnableUnsafeCORS { | ||
handlerWithCors = cors.AllowAll() | ||
} | ||
|
||
httpSrv := &http.Server{ | ||
Addr: config.JSONRPC.Address, | ||
Handler: handlerWithCors.Handler(r), | ||
ReadHeaderTimeout: config.JSONRPC.HTTPTimeout, | ||
ReadTimeout: config.JSONRPC.HTTPTimeout, | ||
WriteTimeout: config.JSONRPC.HTTPTimeout, | ||
IdleTimeout: config.JSONRPC.HTTPIdleTimeout, | ||
} | ||
httpSrvDone := make(chan struct{}, 1) | ||
|
||
ln, err := Listen(httpSrv.Addr, config) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
errCh := make(chan error) | ||
go func() { | ||
ctx.Logger.Info("Starting JSON-RPC server", "address", config.JSONRPC.Address) | ||
if err := httpSrv.Serve(ln); err != nil { | ||
if err == http.ErrServerClosed { | ||
close(httpSrvDone) | ||
return | ||
} | ||
|
||
ctx.Logger.Error("failed to start JSON-RPC server", "error", err.Error()) | ||
errCh <- err | ||
} | ||
}() | ||
|
||
select { | ||
case err := <-errCh: | ||
ctx.Logger.Error("failed to boot JSON-RPC server", "error", err.Error()) | ||
return nil, nil, err | ||
case <-time.After(types.ServerStartTime): // assume JSON RPC server started successfully | ||
} | ||
|
||
ctx.Logger.Info("Starting JSON WebSocket server", "address", config.JSONRPC.WsAddress) | ||
|
||
// allocate separate WS connection to Tendermint | ||
tmWsClient = ConnectTmWS(tmRPCAddr, tmEndpoint, ctx.Logger) | ||
wsSrv := rpcapi.NewWebsocketsServer(clientCtx, ctx.Logger, tmWsClient, config) | ||
wsSrv.Start() | ||
return httpSrv, httpSrvDone, nil | ||
} |
Oops, something went wrong.