From 17eeb2b8b911fa4527600049373cc9d9a669a545 Mon Sep 17 00:00:00 2001 From: VictorTrustyDev Date: Thu, 5 Sep 2024 05:06:01 +0700 Subject: [PATCH 1/5] add support allow insecure unlock by using flag `json-rpc.allow-insecure-unlock` --- local_node.sh | 1 + rpc/backend/node_info.go | 16 ++++++++++++++++ rpc/backend/sign_tx.go | 5 +++++ server/config/config.go | 41 ++++++++++++++++++++++++---------------- server/config/toml.go | 5 ++++- server/flags/flags.go | 1 + server/start.go | 1 + 7 files changed, 53 insertions(+), 17 deletions(-) diff --git a/local_node.sh b/local_node.sh index e3ecd9b9b0..f73b838d01 100755 --- a/local_node.sh +++ b/local_node.sh @@ -165,6 +165,7 @@ fi --metrics "$TRACE" --log_level "$LOGLEVEL" \ --minimum-gas-prices="0.0001$MIN_DENOM" \ --json-rpc.api eth,txpool,personal,net,debug,web3 \ + --json-rpc.allow-insecure-unlock true \ --api.enable \ --grpc.enable true \ --home "$HOMEDIR" \ diff --git a/rpc/backend/node_info.go b/rpc/backend/node_info.go index 3bf1f8da80..77bd91f68b 100644 --- a/rpc/backend/node_info.go +++ b/rpc/backend/node_info.go @@ -1,6 +1,7 @@ package backend import ( + "errors" "fmt" "math/big" "time" @@ -28,6 +29,11 @@ import ( // Accounts returns the list of accounts available to this node. func (b *Backend) Accounts() ([]common.Address, error) { + if !b.cfg.JSONRPC.AllowInsecureUnlock { + b.logger.Debug("account unlock with HTTP access is forbidden") + return []common.Address{}, errors.New("account unlock with HTTP access is forbidden") + } + addresses := make([]common.Address, 0) // return [] instead of nil if empty infos, err := b.clientCtx.Keyring.List() @@ -75,6 +81,11 @@ func (b *Backend) Syncing() (interface{}, error) { // SetEtherbase sets the etherbase of the miner func (b *Backend) SetEtherbase(etherbase common.Address) bool { + if !b.cfg.JSONRPC.AllowInsecureUnlock { + b.logger.Debug("account unlock with HTTP access is forbidden") + return false + } + delAddr, err := b.GetCoinbase() if err != nil { b.logger.Debug("failed to get coinbase address", "error", err.Error()) @@ -214,6 +225,11 @@ func (b *Backend) ImportRawKey(privkey, password string) (common.Address, error) // ListAccounts will return a list of addresses for accounts this node manages. func (b *Backend) ListAccounts() ([]common.Address, error) { + if !b.cfg.JSONRPC.AllowInsecureUnlock { + b.logger.Debug("account unlock with HTTP access is forbidden") + return []common.Address{}, fmt.Errorf("account unlock with HTTP access is forbidden") + } + addrs := []common.Address{} list, err := b.clientCtx.Keyring.List() diff --git a/rpc/backend/sign_tx.go b/rpc/backend/sign_tx.go index 493a661c69..886f269d7f 100644 --- a/rpc/backend/sign_tx.go +++ b/rpc/backend/sign_tx.go @@ -20,6 +20,11 @@ import ( // SendTransaction sends transaction based on received args using Node's key to sign it func (b *Backend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) { + if !b.cfg.JSONRPC.AllowInsecureUnlock { + b.logger.Debug("account unlock with HTTP access is forbidden") + return common.Hash{}, fmt.Errorf("account unlock with HTTP access is forbidden") + } + // Look up the wallet containing the requested signer _, err := b.clientCtx.Keyring.KeyByAddress(sdk.AccAddress(args.GetFrom().Bytes())) if err != nil { diff --git a/server/config/config.go b/server/config/config.go index 017315dabc..b8bf28f246 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -3,6 +3,7 @@ package config import ( "errors" "fmt" + "github.com/EscanBE/evermint/v12/server/flags" "path" "time" @@ -25,7 +26,7 @@ const ( // DefaultJSONRPCWsAddress is the default address the JSON-RPC WebSocket server binds to. DefaultJSONRPCWsAddress = "127.0.0.1:8546" - // DefaultJsonRPCMetricsAddress is the default address the JSON-RPC Metrics server binds to. + // DefaultJSONRPCMetricsAddress is the default address the JSON-RPC Metrics server binds to. DefaultJSONRPCMetricsAddress = "127.0.0.1:6065" // DefaultEVMTracer is the default vm.Tracer type @@ -64,6 +65,9 @@ const ( // DefaultAllowUnprotectedTxs value is false DefaultAllowUnprotectedTxs = false + // DefaultAllowInsecureUnlock is the default value of allow insecure unlock configuration + DefaultAllowInsecureUnlock = false + // DefaultMaxOpenConnections represents the amount of open connections (unlimited = 0) DefaultMaxOpenConnections = 0 ) @@ -120,6 +124,8 @@ type JSONRPCConfig struct { // AllowUnprotectedTxs restricts unprotected (non EIP155 signed) transactions to be submitted via // the node's RPC when global parameter is disabled. AllowUnprotectedTxs bool `mapstructure:"allow-unprotected-txs"` + // AllowInsecureUnlock allow insecure account unlocking when account-related RPCs are exposed by http + AllowInsecureUnlock bool `mapstructure:"allow-insecure-unlock"` // MaxOpenConnections sets the maximum number of simultaneous connections // for the server listener. MaxOpenConnections int `mapstructure:"max-open-connections"` @@ -224,6 +230,7 @@ func DefaultJSONRPCConfig() *JSONRPCConfig { HTTPTimeout: DefaultHTTPTimeout, HTTPIdleTimeout: DefaultHTTPIdleTimeout, AllowUnprotectedTxs: DefaultAllowUnprotectedTxs, + AllowInsecureUnlock: DefaultAllowInsecureUnlock, MaxOpenConnections: DefaultMaxOpenConnections, MetricsAddress: DefaultJSONRPCMetricsAddress, } @@ -319,21 +326,23 @@ func GetConfig(v *viper.Viper) (Config, error) { MaxTxGasWanted: v.GetUint64("evm.max-tx-gas-wanted"), }, JSONRPC: JSONRPCConfig{ - Enable: v.GetBool("json-rpc.enable"), - API: v.GetStringSlice("json-rpc.api"), - Address: v.GetString("json-rpc.address"), - WsAddress: v.GetString("json-rpc.ws-address"), - GasCap: v.GetUint64("json-rpc.gas-cap"), - FilterCap: v.GetInt32("json-rpc.filter-cap"), - FeeHistoryCap: v.GetInt32("json-rpc.feehistory-cap"), - TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"), - EVMTimeout: v.GetDuration("json-rpc.evm-timeout"), - LogsCap: v.GetInt32("json-rpc.logs-cap"), - BlockRangeCap: v.GetInt32("json-rpc.block-range-cap"), - HTTPTimeout: v.GetDuration("json-rpc.http-timeout"), - HTTPIdleTimeout: v.GetDuration("json-rpc.http-idle-timeout"), - MaxOpenConnections: v.GetInt("json-rpc.max-open-connections"), - MetricsAddress: v.GetString("json-rpc.metrics-address"), + Enable: v.GetBool("json-rpc.enable"), + API: v.GetStringSlice("json-rpc.api"), + Address: v.GetString("json-rpc.address"), + WsAddress: v.GetString("json-rpc.ws-address"), + GasCap: v.GetUint64("json-rpc.gas-cap"), + FilterCap: v.GetInt32("json-rpc.filter-cap"), + FeeHistoryCap: v.GetInt32("json-rpc.feehistory-cap"), + TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"), + EVMTimeout: v.GetDuration("json-rpc.evm-timeout"), + LogsCap: v.GetInt32("json-rpc.logs-cap"), + BlockRangeCap: v.GetInt32("json-rpc.block-range-cap"), + HTTPTimeout: v.GetDuration("json-rpc.http-timeout"), + HTTPIdleTimeout: v.GetDuration("json-rpc.http-idle-timeout"), + AllowUnprotectedTxs: v.GetBool(flags.JSONRPCAllowUnprotectedTxs), + AllowInsecureUnlock: v.GetBool(flags.JSONRPCAllowInsecureUnlock), + MaxOpenConnections: v.GetInt("json-rpc.max-open-connections"), + MetricsAddress: v.GetString("json-rpc.metrics-address"), }, TLS: TLSConfig{ CertificatePath: v.GetString("tls.certificate-path"), diff --git a/server/config/toml.go b/server/config/toml.go index 6486e6e75e..838a1c7080 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -22,7 +22,7 @@ max-tx-gas-wanted = {{ .EVM.MaxTxGasWanted }} [json-rpc] -# Enable defines if the gRPC server should be enabled. +# Enable defines if the EVM Json-RPC server should be enabled. enable = {{ .JSONRPC.Enable }} # Address defines the EVM RPC HTTP server address to bind to. @@ -66,6 +66,9 @@ http-idle-timeout = "{{ .JSONRPC.HTTPIdleTimeout }}" # the node's RPC when the global parameter is disabled. allow-unprotected-txs = {{ .JSONRPC.AllowUnprotectedTxs }} +# Allow insecure account unlocking when account-related RPCs are exposed by http +allow-insecure-unlock = {{ .JSONRPC.AllowInsecureUnlock }} + # MaxOpenConnections sets the maximum number of simultaneous connections # for the server listener. max-open-connections = {{ .JSONRPC.MaxOpenConnections }} diff --git a/server/flags/flags.go b/server/flags/flags.go index ccdc29b722..689cade88a 100644 --- a/server/flags/flags.go +++ b/server/flags/flags.go @@ -50,6 +50,7 @@ const ( JSONRPCHTTPTimeout = "json-rpc.http-timeout" JSONRPCHTTPIdleTimeout = "json-rpc.http-idle-timeout" JSONRPCAllowUnprotectedTxs = "json-rpc.allow-unprotected-txs" + JSONRPCAllowInsecureUnlock = "json-rpc.allow-insecure-unlock" JSONRPCMaxOpenConnections = "json-rpc.max-open-connections" // JSONRPCEnableMetrics enables EVM RPC metrics server. // Set to `metrics` which is hardcoded flag from go-ethereum. diff --git a/server/start.go b/server/start.go index 3e11d4f4d8..eee522d4fa 100644 --- a/server/start.go +++ b/server/start.go @@ -191,6 +191,7 @@ which accepts a path for the resulting pprof file. cmd.Flags().Duration(srvflags.JSONRPCHTTPTimeout, config.DefaultHTTPTimeout, "Sets a read/write timeout for json-rpc http server (0=infinite)") cmd.Flags().Duration(srvflags.JSONRPCHTTPIdleTimeout, config.DefaultHTTPIdleTimeout, "Sets a idle timeout for json-rpc http server (0=infinite)") cmd.Flags().Bool(srvflags.JSONRPCAllowUnprotectedTxs, config.DefaultAllowUnprotectedTxs, "Allow for unprotected (non EIP155 signed) transactions to be submitted via the node's RPC when the global parameter is disabled") //nolint:lll + cmd.Flags().Bool(srvflags.JSONRPCAllowInsecureUnlock, config.DefaultAllowInsecureUnlock, "Allow insecure account unlocking when account-related RPCs are exposed by http") cmd.Flags().Int32(srvflags.JSONRPCLogsCap, config.DefaultLogsCap, "Sets the max number of results can be returned from single `eth_getLogs` query") cmd.Flags().Int32(srvflags.JSONRPCBlockRangeCap, config.DefaultBlockRangeCap, "Sets the max block range allowed for `eth_getLogs` query") cmd.Flags().Int(srvflags.JSONRPCMaxOpenConnections, config.DefaultMaxOpenConnections, "Sets the maximum number of simultaneous connections for the server listener") //nolint:lll From 0cc8e736f5f938430fefcb69704fb136cdee29a7 Mon Sep 17 00:00:00 2001 From: VictorTrustyDev Date: Thu, 5 Sep 2024 05:18:00 +0700 Subject: [PATCH 2/5] add flag alias to consistency with go-ethereum naming --- server/config/config.go | 4 ++-- server/flags/flags.go | 6 ++++++ server/start.go | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/server/config/config.go b/server/config/config.go index b8bf28f246..28b2da4992 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -339,8 +339,8 @@ func GetConfig(v *viper.Viper) (Config, error) { BlockRangeCap: v.GetInt32("json-rpc.block-range-cap"), HTTPTimeout: v.GetDuration("json-rpc.http-timeout"), HTTPIdleTimeout: v.GetDuration("json-rpc.http-idle-timeout"), - AllowUnprotectedTxs: v.GetBool(flags.JSONRPCAllowUnprotectedTxs), - AllowInsecureUnlock: v.GetBool(flags.JSONRPCAllowInsecureUnlock), + AllowUnprotectedTxs: v.GetBool(flags.JSONRPCAllowUnprotectedTxs) || v.GetBool(flags.LegacyRpcAllowUnprotectedTxs), + AllowInsecureUnlock: v.GetBool(flags.JSONRPCAllowInsecureUnlock) || v.GetBool(flags.LegacyAllowInsecureUnlock), MaxOpenConnections: v.GetInt("json-rpc.max-open-connections"), MetricsAddress: v.GetString("json-rpc.metrics-address"), }, diff --git a/server/flags/flags.go b/server/flags/flags.go index 689cade88a..8adde11af6 100644 --- a/server/flags/flags.go +++ b/server/flags/flags.go @@ -58,6 +58,12 @@ const ( JSONRPCEnableMetrics = "metrics" ) +// Flags follow go-ethereum naming +const ( + LegacyRpcAllowUnprotectedTxs = "rpc.allow-unprotected-txs" + LegacyAllowInsecureUnlock = "allow-insecure-unlock" +) + // EVM flags const ( EVMTracer = "evm.tracer" diff --git a/server/start.go b/server/start.go index eee522d4fa..00cc7bba62 100644 --- a/server/start.go +++ b/server/start.go @@ -191,7 +191,9 @@ which accepts a path for the resulting pprof file. cmd.Flags().Duration(srvflags.JSONRPCHTTPTimeout, config.DefaultHTTPTimeout, "Sets a read/write timeout for json-rpc http server (0=infinite)") cmd.Flags().Duration(srvflags.JSONRPCHTTPIdleTimeout, config.DefaultHTTPIdleTimeout, "Sets a idle timeout for json-rpc http server (0=infinite)") cmd.Flags().Bool(srvflags.JSONRPCAllowUnprotectedTxs, config.DefaultAllowUnprotectedTxs, "Allow for unprotected (non EIP155 signed) transactions to be submitted via the node's RPC when the global parameter is disabled") //nolint:lll + cmd.Flags().Bool(srvflags.LegacyRpcAllowUnprotectedTxs, config.DefaultAllowUnprotectedTxs, fmt.Sprintf("alias of flag --%s to consistency with go-ethereum naming", srvflags.JSONRPCAllowUnprotectedTxs)) //nolint:lll cmd.Flags().Bool(srvflags.JSONRPCAllowInsecureUnlock, config.DefaultAllowInsecureUnlock, "Allow insecure account unlocking when account-related RPCs are exposed by http") + cmd.Flags().Bool(srvflags.LegacyAllowInsecureUnlock, config.DefaultAllowInsecureUnlock, fmt.Sprintf("alias of flag --%s to consistency with go-ethereum naming", srvflags.JSONRPCAllowInsecureUnlock)) cmd.Flags().Int32(srvflags.JSONRPCLogsCap, config.DefaultLogsCap, "Sets the max number of results can be returned from single `eth_getLogs` query") cmd.Flags().Int32(srvflags.JSONRPCBlockRangeCap, config.DefaultBlockRangeCap, "Sets the max block range allowed for `eth_getLogs` query") cmd.Flags().Int(srvflags.JSONRPCMaxOpenConnections, config.DefaultMaxOpenConnections, "Sets the maximum number of simultaneous connections for the server listener") //nolint:lll From 42082ff9f90000d2585400de4853a85fa42c2a78 Mon Sep 17 00:00:00 2001 From: VictorTrustyDev Date: Thu, 5 Sep 2024 05:19:42 +0700 Subject: [PATCH 3/5] update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7c226d957..45145b9e9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ - (evm) [#130](https://github.com/EscanBE/evermint/pull/130) Allow one and only one Ethereum Tx per tx execution - (misc) [#131](https://github.com/EscanBE/evermint/pull/131) Miscellaneous refactor and improve code logic - (rpc+indexer) [#138](https://github.com/EscanBE/evermint/pull/138) Improve check txs dropped pre-AnteHandle +- (rpc) [#142](https://github.com/EscanBE/evermint/pull/142) Support flag `--allow-insecure-unlock` to protect local accounts on node ### Bug Fixes From d95ed7d4550a75c45b7951803b8b5be08d59640e Mon Sep 17 00:00:00 2001 From: VictorTrustyDev Date: Thu, 5 Sep 2024 05:23:25 +0700 Subject: [PATCH 4/5] update script --- local_node.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local_node.sh b/local_node.sh index f73b838d01..bcc438566b 100755 --- a/local_node.sh +++ b/local_node.sh @@ -165,7 +165,7 @@ fi --metrics "$TRACE" --log_level "$LOGLEVEL" \ --minimum-gas-prices="0.0001$MIN_DENOM" \ --json-rpc.api eth,txpool,personal,net,debug,web3 \ - --json-rpc.allow-insecure-unlock true \ + --allow-insecure-unlock true \ --api.enable \ --grpc.enable true \ --home "$HOMEDIR" \ From e06d0d3b0f606bdce3ec4c209d4ae5f4a6d71562 Mon Sep 17 00:00:00 2001 From: VictorTrustyDev Date: Thu, 5 Sep 2024 05:25:46 +0700 Subject: [PATCH 5/5] update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a901da4408..3cba3c9253 100644 --- a/README.md +++ b/README.md @@ -63,4 +63,5 @@ evmd convert-address evm1sv9m0g7ycejwr3s369km58h5qe7xj77hxrsmsz evmos 2. [Rename chain](https://github.com/EscanBE/evermint/blob/main/RENAME_CHAIN.md) 3. [`snapshots` command](https://github.com/EscanBE/evermint/pull/12) 4. [`inspect` command](https://github.com/EscanBE/evermint/pull/14) -5. Dependencies updated: `Cosmos-SDK v0.47.13`, `CometBFT v0.37.5`, `ibc-go v7.8.0`, `go-ethereum v1.10.26` \ No newline at end of file +5. [Flag `--allow-insecure-unlock`](https://github.com/EscanBE/evermint/pull/142) +6. Dependencies updated: `Cosmos-SDK v0.47.13`, `CometBFT v0.37.5`, `ibc-go v7.8.0`, `go-ethereum v1.10.26` \ No newline at end of file