diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go index eb4ce32acc90d8436d17835f76cc78989ad6b92a..c6c85e3370245e22d618c674e4720097c81f7ce9 100644 --- a/cmd/rpcdaemon/cli/config.go +++ b/cmd/rpcdaemon/cli/config.go @@ -22,6 +22,7 @@ import ( kv2 "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/erigon-lib/kv/remotedb" "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli/httpcfg" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/filters" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/health" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/interfaces" @@ -44,49 +45,15 @@ import ( "google.golang.org/grpc/status" ) -type Flags struct { - PrivateApiAddr string - SingleNodeMode bool // Erigon's database can be read by separated processes on same machine - in read-only mode - with full support of transactions. It will share same "OS PageCache" with Erigon process. - Datadir string - Chaindata string - HttpListenAddress string - EngineHTTPListenAddress string - TLSCertfile string - TLSCACert string - TLSKeyFile string - HttpPort int - EnginePort int - HttpCORSDomain []string - HttpVirtualHost []string - HttpCompression bool - API []string - Gascap uint64 - MaxTraces uint64 - WebsocketEnabled bool - WebsocketCompression bool - RpcAllowListFilePath string - RpcBatchConcurrency uint - TraceCompatibility bool // Bug for bug compatibility for trace_ routines with OpenEthereum - TxPoolApiAddr string - TevmEnabled bool - StateCache kvcache.CoherentConfig - Snapshot ethconfig.Snapshot - GRPCServerEnabled bool - GRPCListenAddress string - GRPCPort int - GRPCHealthCheckEnabled bool - StarknetGRPCAddress string -} - var rootCmd = &cobra.Command{ Use: "rpcdaemon", Short: "rpcdaemon is JSON RPC server that connects to Erigon node for remote DB access", } -func RootCommand() (*cobra.Command, *Flags) { +func RootCommand() (*cobra.Command, *httpcfg.HttpCfg) { utils.CobraFlags(rootCmd, append(debug.Flags, utils.MetricFlags...)) - cfg := &Flags{StateCache: kvcache.DefaultCoherentConfig} + cfg := &httpcfg.HttpCfg{StateCache: kvcache.DefaultCoherentConfig} rootCmd.PersistentFlags().StringVar(&cfg.PrivateApiAddr, "private.api.addr", "127.0.0.1:9090", "private api network address, for example: 127.0.0.1:9090") rootCmd.PersistentFlags().StringVar(&cfg.Datadir, "datadir", "", "path to Erigon working directory") rootCmd.PersistentFlags().StringVar(&cfg.Chaindata, "chaindata", "", "path to the database") @@ -263,7 +230,7 @@ func EmbeddedServices(ctx context.Context, erigonDB kv.RoDB, stateCacheCfg kvcac // RemoteServices - use when RPCDaemon run as independent process. Still it can use --datadir flag to enable // `cfg.SingleNodeMode` (mode when it on 1 machine with Erigon) -func RemoteServices(ctx context.Context, cfg Flags, logger log.Logger, rootCancel context.CancelFunc) ( +func RemoteServices(ctx context.Context, cfg httpcfg.HttpCfg, logger log.Logger, rootCancel context.CancelFunc) ( db kv.RoDB, borDb kv.RoDB, eth services.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, starknet *services.StarknetService, @@ -411,7 +378,7 @@ func RemoteServices(ctx context.Context, cfg Flags, logger log.Logger, rootCance return db, borDb, eth, txPool, mining, starknet, stateCache, blockReader, ff, err } -func StartRpcServer(ctx context.Context, cfg Flags, rpcAPI []rpc.API) error { +func StartRpcServer(ctx context.Context, cfg httpcfg.HttpCfg, rpcAPI []rpc.API) error { var engineListener *http.Server var enginesrv *rpc.Server var engineHttpEndpoint string @@ -532,7 +499,7 @@ func isWebsocket(r *http.Request) bool { strings.Contains(strings.ToLower(r.Header.Get("Connection")), "upgrade") } -func createHandler(cfg Flags, apiList []rpc.API, httpHandler http.Handler, wsHandler http.Handler) http.Handler { +func createHandler(cfg httpcfg.HttpCfg, apiList []rpc.API, httpHandler http.Handler, wsHandler http.Handler) http.Handler { var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // adding a healthcheck here if health.ProcessHealthcheckIfNeeded(w, r, apiList) { @@ -548,7 +515,7 @@ func createHandler(cfg Flags, apiList []rpc.API, httpHandler http.Handler, wsHan return handler } -func createEngineListener(cfg Flags, engineApi []rpc.API, engineFlag []string) (*http.Server, *rpc.Server, string, error) { +func createEngineListener(cfg httpcfg.HttpCfg, engineApi []rpc.API, engineFlag []string) (*http.Server, *rpc.Server, string, error) { engineHttpEndpoint := fmt.Sprintf("%s:%d", cfg.EngineHTTPListenAddress, cfg.EnginePort) enginesrv := rpc.NewServer(cfg.RpcBatchConcurrency) diff --git a/cmd/rpcdaemon/cli/httpcfg/http_cfg.go b/cmd/rpcdaemon/cli/httpcfg/http_cfg.go new file mode 100644 index 0000000000000000000000000000000000000000..32d9dec7e7c65505dae50cd1fc0f8dbbba9497db --- /dev/null +++ b/cmd/rpcdaemon/cli/httpcfg/http_cfg.go @@ -0,0 +1,40 @@ +package httpcfg + +import ( + "github.com/ledgerwatch/erigon-lib/kv/kvcache" + "github.com/ledgerwatch/erigon/eth/ethconfig" +) + +type HttpCfg struct { + PrivateApiAddr string + SingleNodeMode bool // Erigon's database can be read by separated processes on same machine - in read-only mode - with full support of transactions. It will share same "OS PageCache" with Erigon process. + Datadir string + Chaindata string + HttpListenAddress string + EngineHTTPListenAddress string + TLSCertfile string + TLSCACert string + TLSKeyFile string + HttpPort int + EnginePort int + HttpCORSDomain []string + HttpVirtualHost []string + HttpCompression bool + API []string + Gascap uint64 + MaxTraces uint64 + WebsocketEnabled bool + WebsocketCompression bool + RpcAllowListFilePath string + RpcBatchConcurrency uint + TraceCompatibility bool // Bug for bug compatibility for trace_ routines with OpenEthereum + TxPoolApiAddr string + TevmEnabled bool + StateCache kvcache.CoherentConfig + Snapshot ethconfig.Snapshot + GRPCServerEnabled bool + GRPCListenAddress string + GRPCPort int + GRPCHealthCheckEnabled bool + StarknetGRPCAddress string +} diff --git a/cmd/rpcdaemon/commands/call_traces_test.go b/cmd/rpcdaemon/commands/call_traces_test.go index 40fbdc1e7a25d16755a22e184ac180df50de2d7d..ec3b65cba6a6960355631beb1c04da6254741c9e 100644 --- a/cmd/rpcdaemon/commands/call_traces_test.go +++ b/cmd/rpcdaemon/commands/call_traces_test.go @@ -9,11 +9,11 @@ import ( "github.com/holiman/uint256" jsoniter "github.com/json-iterator/go" "github.com/ledgerwatch/erigon-lib/kv/kvcache" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli/httpcfg" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/fastjson" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core" @@ -53,7 +53,7 @@ func TestCallTraceOneByOne(t *testing.T) { } api := NewTraceAPI( NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), false), - m.DB, &cli.Flags{}) + m.DB, &httpcfg.HttpCfg{}) // Insert blocks 1 by 1, to tirgget possible "off by one" errors for i := 0; i < chain.Length; i++ { if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { @@ -98,7 +98,7 @@ func TestCallTraceUnwind(t *testing.T) { if err != nil { t.Fatalf("generate chainB: %v", err) } - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), false), m.DB, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), false), m.DB, &httpcfg.HttpCfg{}) if err = m.InsertChain(chainA); err != nil { t.Fatalf("inserting chainA: %v", err) } @@ -158,7 +158,7 @@ func TestFilterNoAddresses(t *testing.T) { if err != nil { t.Fatalf("generate chain: %v", err) } - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), false), m.DB, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), false), m.DB, &httpcfg.HttpCfg{}) // Insert blocks 1 by 1, to tirgget possible "off by one" errors for i := 0; i < chain.Length; i++ { if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { @@ -184,7 +184,7 @@ func TestFilterAddressIntersection(t *testing.T) { m := stages.Mock(t) defer m.DB.Close() - api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), false), m.DB, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), snapshotsync.NewBlockReader(), false), m.DB, &httpcfg.HttpCfg{}) toAddress1, toAddress2, other := common.Address{1}, common.Address{2}, common.Address{3} diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index af3f6a863b7d99c5a468e1afb5814eb4e194fcbc..a84b6094a8efe26c12be47e6134ccdfbcdda14a3 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -5,7 +5,7 @@ import ( "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli/httpcfg" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/filters" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/interfaces" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/services" @@ -13,12 +13,9 @@ import ( ) // APIList describes the list of available RPC apis -func APIList(db kv.RoDB, borDb kv.RoDB, eth services.ApiBackend, - txPool txpool.TxpoolClient, mining txpool.MiningClient, - starknet starknet.CAIROVMClient, - filters *filters.Filters, stateCache kvcache.Cache, blockReader interfaces.BlockAndTxnReader, - cfg cli.Flags, customAPIList []rpc.API) []rpc.API { - var defaultAPIList []rpc.API +func APIList(db kv.RoDB, borDb kv.RoDB, eth services.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, + starknet starknet.CAIROVMClient, filters *filters.Filters, stateCache kvcache.Cache, + blockReader interfaces.BlockAndTxnReader, cfg httpcfg.HttpCfg) (list []rpc.API) { base := NewBaseApi(filters, stateCache, blockReader, cfg.SingleNodeMode) if cfg.TevmEnabled { @@ -41,91 +38,91 @@ func APIList(db kv.RoDB, borDb kv.RoDB, eth services.ApiBackend, for _, enabledAPI := range cfg.API { switch enabledAPI { case "eth": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "eth", Public: true, Service: EthAPI(ethImpl), Version: "1.0", }) case "debug": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "debug", Public: true, Service: PrivateDebugAPI(debugImpl), Version: "1.0", }) case "net": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "net", Public: true, Service: NetAPI(netImpl), Version: "1.0", }) case "txpool": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "txpool", Public: true, Service: TxPoolAPI(txpoolImpl), Version: "1.0", }) case "web3": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "web3", Public: true, Service: Web3API(web3Impl), Version: "1.0", }) case "trace": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "trace", Public: true, Service: TraceAPI(traceImpl), Version: "1.0", }) case "db": /* Deprecated */ - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "db", Public: true, Service: DBAPI(dbImpl), Version: "1.0", }) case "erigon": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "erigon", Public: true, Service: ErigonAPI(erigonImpl), Version: "1.0", }) case "starknet": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "starknet", Public: true, Service: StarknetAPI(starknetImpl), Version: "1.0", }) case "engine": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "engine", Public: true, Service: EngineAPI(engineImpl), Version: "1.0", }) case "bor": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "bor", Public: true, Service: BorAPI(borImpl), Version: "1.0", }) case "admin": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "admin", Public: false, Service: AdminAPI(adminImpl), Version: "1.0", }) case "parity": - defaultAPIList = append(defaultAPIList, rpc.API{ + list = append(list, rpc.API{ Namespace: "parity", Public: false, Service: ParityAPI(parityImpl), @@ -134,5 +131,5 @@ func APIList(db kv.RoDB, borDb kv.RoDB, eth services.ApiBackend, } } - return append(defaultAPIList, customAPIList...) + return list } diff --git a/cmd/rpcdaemon/commands/trace_adhoc_test.go b/cmd/rpcdaemon/commands/trace_adhoc_test.go index efa5c53a1b186ba4efc69844a41345f1070f03fe..b3b2ea5f843d342fd44f714f5a74970cffc81873 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc_test.go +++ b/cmd/rpcdaemon/commands/trace_adhoc_test.go @@ -7,7 +7,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli/httpcfg" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" @@ -20,7 +20,7 @@ import ( func TestEmptyQuery(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, &httpcfg.HttpCfg{}) // Call GetTransactionReceipt for transaction which is not in the database var latest = rpc.LatestBlockNumber results, err := api.CallMany(context.Background(), json.RawMessage("[]"), &rpc.BlockNumberOrHash{BlockNumber: &latest}) @@ -37,7 +37,7 @@ func TestEmptyQuery(t *testing.T) { func TestCoinbaseBalance(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, &httpcfg.HttpCfg{}) // Call GetTransactionReceipt for transaction which is not in the database var latest = rpc.LatestBlockNumber results, err := api.CallMany(context.Background(), json.RawMessage(` @@ -64,7 +64,7 @@ func TestCoinbaseBalance(t *testing.T) { func TestReplayTransaction(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, &httpcfg.HttpCfg{}) var txnHash common.Hash if err := db.View(context.Background(), func(tx kv.Tx) error { b, err := rawdb.ReadBlockByNumber(tx, 6) @@ -92,7 +92,7 @@ func TestReplayTransaction(t *testing.T) { func TestReplayBlockTransactions(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, &cli.Flags{}) + api := NewTraceAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, &httpcfg.HttpCfg{}) // Call GetTransactionReceipt for transaction which is not in the database n := rpc.BlockNumber(6) diff --git a/cmd/rpcdaemon/commands/trace_api.go b/cmd/rpcdaemon/commands/trace_api.go index df58c8c747bcd6d66f191b0147489246b2c5f042..d71dc1d4b84a24d7e1139017b9ff7b3e0637f8df 100644 --- a/cmd/rpcdaemon/commands/trace_api.go +++ b/cmd/rpcdaemon/commands/trace_api.go @@ -6,7 +6,7 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli/httpcfg" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/rpc" @@ -38,7 +38,7 @@ type TraceAPIImpl struct { } // NewTraceAPI returns NewTraceAPI instance -func NewTraceAPI(base *BaseAPI, kv kv.RoDB, cfg *cli.Flags) *TraceAPIImpl { +func NewTraceAPI(base *BaseAPI, kv kv.RoDB, cfg *httpcfg.HttpCfg) *TraceAPIImpl { return &TraceAPIImpl{ BaseAPI: base, kv: kv, diff --git a/cmd/rpcdaemon/main.go b/cmd/rpcdaemon/main.go index a3a64814f4c515fe3dca5fc777ff42534a5a0351..708e8603be38a1448f9c1ad2c02f5132d225853f 100644 --- a/cmd/rpcdaemon/main.go +++ b/cmd/rpcdaemon/main.go @@ -26,7 +26,7 @@ func main() { defer borDb.Close() } - apiList := commands.APIList(db, borDb, backend, txPool, mining, starknet, ff, stateCache, blockReader, *cfg, nil) + apiList := commands.APIList(db, borDb, backend, txPool, mining, starknet, ff, stateCache, blockReader, *cfg) if err := cli.StartRpcServer(ctx, *cfg, apiList); err != nil { log.Error(err.Error()) return nil diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 66508eb2b5de87479d8b910093c0af332e6ddce5..87606eb19058d35e3ffda1cd35741318630d4c15 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -34,6 +34,7 @@ import ( "github.com/c2h5oh/datasize" common2 "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon-lib/kv/kvcache" "github.com/ledgerwatch/erigon-lib/txpool" "github.com/ledgerwatch/erigon/cmd/downloader/downloader/torrentcfg" "github.com/spf13/cobra" @@ -319,6 +320,25 @@ var ( Usage: "HTTP-RPC server listening port", Value: node.DefaultHTTPPort, } + EngineAddr = cli.StringFlag{ + Name: "engine.addr", + Usage: "HTTP-RPC server listening interface for engineAPI", + Value: node.DefaultHTTPHost, + } + EnginePort = cli.UintFlag{ + Name: "engine.port", + Usage: "HTTP-RPC server listening port for the engineAPI", + Value: node.DefaultEngineHTTPPort, + } + + HttpCompressionFlag = cli.BoolFlag{ + Name: "http.compression", + Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", + } + WsCompressionFlag = cli.BoolFlag{ + Name: "ws.compression", + Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", + } HTTPCORSDomainFlag = cli.StringFlag{ Name: "http.corsdomain", Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", @@ -332,8 +352,26 @@ var ( HTTPApiFlag = cli.StringFlag{ Name: "http.api", Usage: "API's offered over the HTTP-RPC interface", - Value: "", + Value: "eth,erigon", } + RpcBatchConcurrencyFlag = cli.UintFlag{ + Name: "rpc.batch.concurrency", + Usage: "Does limit amount of goroutines to process 1 batch request. Means 1 bach request can't overload server. 1 batch still can have unlimited amount of request", + Value: 2, + } + + RpcGasCapFlag = cli.UintFlag{ + Name: "rpc.gascap", + Usage: "Sets a cap on gas that can be used in eth_call/estimateGas", + Value: 50000000, + } + + TraceMaxtracesFlag = cli.UintFlag{ + Name: "trace.maxtraces", + Usage: "Sets a limit on traces that can be returned in trace_filter", + Value: 200, + } + HTTPPathPrefixFlag = cli.StringFlag{ Name: "http.rpcprefix", Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", @@ -399,6 +437,11 @@ var ( Name: "rpc.allow-unprotected-txs", Usage: "Allow for unprotected (non EIP155 signed) transactions to be submitted via RPC", } + StateCacheFlag = cli.IntFlag{ + Name: "state.cache", + Value: kvcache.DefaultCoherentConfig.KeysLimit, + Usage: "Amount of keys to store in StateCache (enabled if no --datadir set). Set 0 to disable StateCache. 1_000_000 keys ~ equal to 2Gb RAM (maybe we will add RAM accounting in future versions).", + } // Network Settings MaxPeersFlag = cli.IntFlag{ @@ -1384,6 +1427,8 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *node.Config, cfg *ethconfig.Conf cfg.TorrentPieceCompletionStorage = pieceCompletion } + nodeConfig.Http.Snapshot = cfg.Snapshot + if ctx.Command.Name == "import" { cfg.ImportMode = true } diff --git a/eth/backend.go b/eth/backend.go index a087c36f70d3b365be1aac204f35c9a9b3744715..3cf3e6d0f04bb1ae8d2afe46d615fed25f7314dc 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -48,11 +48,14 @@ import ( "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" "github.com/ledgerwatch/erigon/cmd/downloader/downloader" "github.com/ledgerwatch/erigon/cmd/downloader/downloadergrpc" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/commands" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/interfaces" "github.com/ledgerwatch/erigon/cmd/sentry/sentry" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/debug" "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/bor" "github.com/ledgerwatch/erigon/consensus/clique" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/consensus/parlia" @@ -526,35 +529,30 @@ func New(stack *node.Node, config *ethconfig.Config, txpoolCfg txpool2.Config, l gpoParams.Default = config.Miner.GasPrice } //eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams) - /* - // start HTTP API - httpRpcCfg := cli.Flags{ - HttpListenAddress: "0.0.0.0", - HttpPort: 8545, - API: []string{"eth", "net", "web3", "txpool", "debug"}, - } // TODO: add rpcdaemon cli flags to Erigon and fill this struct (or break it to smaller config objects) - ethRpcClient, txPoolRpcClient, miningRpcClient, starkNetRpcClient, stateCache, ff, err := cli.EmbeddedServices( - ctx, chainKv, httpRpcCfg.StateCache, blockReader, - ethBackendRPC, - backend.txPool2GrpcServer, - miningRPC, - ) - if err != nil { - return nil, err - } - var borDb kv.RoDB - if casted, ok := backend.engine.(*bor.Bor); ok { - borDb = casted.DB + // start HTTP API + httpRpcCfg := stack.Config().Http + ethRpcClient, txPoolRpcClient, miningRpcClient, starkNetRpcClient, stateCache, ff, err := cli.EmbeddedServices( + ctx, chainKv, httpRpcCfg.StateCache, blockReader, + ethBackendRPC, + backend.txPool2GrpcServer, + miningRPC, + ) + if err != nil { + return nil, err + } + + var borDb kv.RoDB + if casted, ok := backend.engine.(*bor.Bor); ok { + borDb = casted.DB + } + apiList := commands.APIList(chainKv, borDb, ethRpcClient, txPoolRpcClient, miningRpcClient, starkNetRpcClient, ff, stateCache, blockReader, httpRpcCfg) + go func() { + if err := cli.StartRpcServer(ctx, httpRpcCfg, apiList); err != nil { + log.Error(err.Error()) + return } - apiList := commands.APIList(chainKv, borDb, ethRpcClient, txPoolRpcClient, miningRpcClient, starkNetRpcClient, ff, stateCache, blockReader, httpRpcCfg, nil) - go func() { - if err := cli.StartRpcServer(ctx, httpRpcCfg, apiList); err != nil { - log.Error(err.Error()) - return - } - }() - */ + }() // Register the backend on the node stack.RegisterAPIs(backend.APIs()) diff --git a/node/config.go b/node/config.go index 49b63c980e41132b12029d46c0ff8fdb4712c37f..f4decfc79d66756b5df6fccbda85f993d3b49e07 100644 --- a/node/config.go +++ b/node/config.go @@ -27,6 +27,7 @@ import ( "github.com/c2h5oh/datasize" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli/httpcfg" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/paths" @@ -166,6 +167,8 @@ type Config struct { // HealthCheck enables standard grpc health check HealthCheck bool + + Http httpcfg.HttpCfg } // IPCEndpoint resolves an IPC endpoint based on a configured value, taking into diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index e11d30733cd7958ebe42850d1a2ad2d241a4fb8d..da8a670ef25e4594bbc85d04022f7a69276d1df3 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -46,6 +46,23 @@ var DefaultFlags = []cli.Flag{ StateStreamDisableFlag, SyncLoopThrottleFlag, BadBlockFlag, + + utils.HTTPEnabledFlag, + utils.HTTPListenAddrFlag, + utils.HTTPPortFlag, + utils.EngineAddr, + utils.EnginePort, + utils.HttpCompressionFlag, + utils.HTTPCORSDomainFlag, + utils.HTTPVirtualHostsFlag, + utils.HTTPApiFlag, + utils.WSEnabledFlag, + utils.WsCompressionFlag, + utils.StateCacheFlag, + utils.RpcBatchConcurrencyFlag, + utils.RpcGasCapFlag, + utils.TraceMaxtracesFlag, + utils.SnapshotSyncFlag, utils.SnapshotRetireFlag, utils.DbPageSizeFlag, diff --git a/turbo/cli/flags.go b/turbo/cli/flags.go index 78a3eeb66c15611e269d0675f4aef8870a908280..8156ce0e7aee18a95da5168eb9811a1fb81ea3c9 100644 --- a/turbo/cli/flags.go +++ b/turbo/cli/flags.go @@ -2,12 +2,15 @@ package cli import ( "fmt" + "path/filepath" "strings" "time" "github.com/c2h5oh/datasize" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon-lib/kv/kvcache" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli/httpcfg" "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" @@ -61,7 +64,7 @@ var ( PruneFlag = cli.StringFlag{ Name: "prune", - Usage: `Choose which ancient data delete from DB: + Usage: `Choose which ancient data delete from DB: h - prune history (ChangeSets, HistoryIndices - used by historical state access) r - prune receipts (Receipts, Logs, LogTopicIndex, LogAddressIndex - used by eth_getLogs and similar RPC methods) t - prune transaction by it's hash index @@ -277,9 +280,61 @@ func ApplyFlagsForEthConfigCobra(f *pflag.FlagSet, cfg *ethconfig.Config) { func ApplyFlagsForNodeConfig(ctx *cli.Context, cfg *node.Config) { setPrivateApi(ctx, cfg) + setEmbeddedRpcDaemon(ctx, cfg) cfg.DatabaseVerbosity = kv.DBVerbosityLvl(ctx.GlobalInt(DatabaseVerbosityFlag.Name)) } +func setEmbeddedRpcDaemon(ctx *cli.Context, cfg *node.Config) { + c := &httpcfg.HttpCfg{ + Datadir: cfg.DataDir, + Chaindata: filepath.Join(cfg.DataDir, "chaindata"), + + TLSKeyFile: cfg.TLSKeyFile, + TLSCACert: cfg.TLSCACert, + TLSCertfile: cfg.TLSCertFile, + + HttpListenAddress: ctx.GlobalString(utils.HTTPListenAddrFlag.Name), + HttpPort: ctx.GlobalInt(utils.HTTPPortFlag.Name), + EngineHTTPListenAddress: ctx.GlobalString(utils.EngineAddr.Name), + EnginePort: ctx.GlobalInt(utils.EnginePort.Name), + HttpCORSDomain: strings.Split(ctx.GlobalString(utils.HTTPCORSDomainFlag.Name), ","), + HttpVirtualHost: strings.Split(ctx.GlobalString(utils.HTTPVirtualHostsFlag.Name), ","), + API: strings.Split(ctx.GlobalString(utils.HTTPApiFlag.Name), ","), + + WebsocketEnabled: ctx.GlobalIsSet(utils.WSEnabledFlag.Name), + RpcBatchConcurrency: ctx.GlobalUint(utils.RpcBatchConcurrencyFlag.Name), + Gascap: ctx.GlobalUint64(utils.RpcGasCapFlag.Name), + MaxTraces: ctx.GlobalUint64(utils.TraceMaxtracesFlag.Name), + + StateCache: kvcache.DefaultCoherentConfig, + } + if ctx.GlobalIsSet(utils.HttpCompressionFlag.Name) { + c.HttpCompression = ctx.GlobalBool(utils.HttpCompressionFlag.Name) + } else { + c.HttpCompression = true + } + if ctx.GlobalIsSet(utils.WsCompressionFlag.Name) { + c.WebsocketCompression = ctx.GlobalBool(utils.WsCompressionFlag.Name) + } else { + c.WebsocketCompression = true + } + + c.StateCache.CodeKeysLimit = ctx.GlobalInt(utils.StateCacheFlag.Name) + + /* + rootCmd.PersistentFlags().StringVar(&cfg.RpcAllowListFilePath, "rpc.accessList", "", "Specify granular (method-by-method) API allowlist") + rootCmd.PersistentFlags().BoolVar(&cfg.TraceCompatibility, "trace.compat", false, "Bug for bug compatibility with OE for trace_ routines") + rootCmd.PersistentFlags().StringVar(&cfg.TxPoolApiAddr, "txpool.api.addr", "127.0.0.1:9090", "txpool api network address, for example: 127.0.0.1:9090") + rootCmd.PersistentFlags().BoolVar(&cfg.TevmEnabled, "tevm", false, "Enables Transpiled EVM experiment") + rootCmd.PersistentFlags().BoolVar(&cfg.GRPCServerEnabled, "grpc", false, "Enable GRPC server") + rootCmd.PersistentFlags().StringVar(&cfg.GRPCListenAddress, "grpc.addr", node.DefaultGRPCHost, "GRPC server listening interface") + rootCmd.PersistentFlags().IntVar(&cfg.GRPCPort, "grpc.port", node.DefaultGRPCPort, "GRPC server listening port") + rootCmd.PersistentFlags().BoolVar(&cfg.GRPCHealthCheckEnabled, "grpc.healthcheck", false, "Enable GRPC health check") + rootCmd.PersistentFlags().StringVar(&cfg.StarknetGRPCAddress, "starknet.grpc.address", "127.0.0.1:6066", "Starknet GRPC address") + */ + cfg.Http = *c +} + // setPrivateApi populates configuration fields related to the remote // read-only interface to the database func setPrivateApi(ctx *cli.Context, cfg *node.Config) {