From 59361c345e837ebbf3f4d58653e21903ade563ef Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 17 Jan 2023 07:36:10 +0800 Subject: [PATCH 01/29] update nix --- go.mod | 1 - gomod2nix.toml | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index f45db540ee..f03d6b5dc8 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,6 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 golang.org/x/net v0.5.0 golang.org/x/text v0.6.0 - golang.org/x/text v0.6.0 google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 google.golang.org/grpc v1.52.0 sigs.k8s.io/yaml v1.3.0 diff --git a/gomod2nix.toml b/gomod2nix.toml index d54d7f90a2..21e2192e8d 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -358,8 +358,8 @@ schema = 3 version = "v0.0.5" hash = "sha256-/5i70IkH/qSW5KjGzv8aQNKh9tHoz98tqtL0K2DMFn4=" [mod."github.com/onsi/ginkgo/v2"] - version = "v2.6.1" - hash = "sha256-OEiWYKCGPCaqL3vzSrHquHGm+Q8URT2anpanAVK5hRo=" + version = "v2.7.0" + hash = "sha256-BKqQKCsPA73FaQwYpAY+QsWFHIncrG5jgRhC2IiNmCk=" [mod."github.com/onsi/gomega"] version = "v1.24.2" hash = "sha256-iascSzzBT1Uv/XybezSblIwwrq78BU4a9BVB5MvK6MM=" @@ -496,8 +496,8 @@ schema = 3 version = "v0.0.0-20220722155223-a9213eeb770e" hash = "sha256-kNgzydWRpjm0sZl4uXEs3LX5L0xjJtJRAFf/CTlYUN4=" [mod."golang.org/x/net"] - version = "v0.4.0" - hash = "sha256-7IwGZh/xg4mQz88cJio2Ov5d3jGRXKj1itlAja/EAbQ=" + version = "v0.5.0" + hash = "sha256-HpbIAiLs7S1+tVsaSSdbCPw1IK43A0bFFuSzPSyjLbo=" [mod."golang.org/x/oauth2"] version = "v0.0.0-20221014153046-6fdb5e3db783" hash = "sha256-IoygidVNqyAZmN+3macDeIefK8hhJToygpcqlwehdYQ=" @@ -505,14 +505,14 @@ schema = 3 version = "v0.1.0" hash = "sha256-Hygjq9euZ0qz6TvHYQwOZEjNiTbTh1nSLRAWZ6KFGR8=" [mod."golang.org/x/sys"] - version = "v0.3.0" - hash = "sha256-TIHhfYbZ99sCU1ZMikxwomXH5AEtD/lA1VMMW+UAhbU=" + version = "v0.4.0" + hash = "sha256-jchMzHCH5dg+IL/F+LqaX/fyAcB/nvHQpfBjqwaRJH0=" [mod."golang.org/x/term"] - version = "v0.3.0" - hash = "sha256-NKv2o8wz8DB/2W2h/muGEIHb+S06mBXZxhG254RpQ5s=" + version = "v0.4.0" + hash = "sha256-wQKxHV10TU4vCU8Re2/hFmAbur/jRWEOB8QXBzgTFNY=" [mod."golang.org/x/text"] - version = "v0.5.0" - hash = "sha256-ztH+xQyM/clOcQl+y/UEPcfNKbc3xApMbEPDDZ9up0o=" + version = "v0.6.0" + hash = "sha256-+bpeRWR3relKACdal6NPj+eP5dnWCplTViArSN7/qA4=" [mod."golang.org/x/xerrors"] version = "v0.0.0-20220907171357-04be3eba64a2" hash = "sha256-6+zueutgefIYmgXinOflz8qGDDDj0Zhv+2OkGhBTKno=" From cd7612211ad1d381ebb271e9b97bbf0e2c11181c Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 12 Jan 2023 12:04:00 +0800 Subject: [PATCH 02/29] support backup grpc client --- rpc/apis.go | 23 ++-- rpc/backend/backend.go | 15 ++- server/json_rpc.go | 4 +- server/start.go | 36 +++++- .../integration_tests/configs/backup.jsonnet | 9 ++ tests/integration_tests/configs/main.jsonnet | 9 ++ tests/integration_tests/test_backup_grpc.py | 112 ++++++++++++++++++ tests/integration_tests/utils.py | 11 ++ testutil/network/util.go | 2 +- 9 files changed, 205 insertions(+), 16 deletions(-) create mode 100644 tests/integration_tests/configs/backup.jsonnet create mode 100644 tests/integration_tests/configs/main.jsonnet create mode 100644 tests/integration_tests/test_backup_grpc.py diff --git a/rpc/apis.go b/rpc/apis.go index e297721cf8..3ffcfec6f4 100644 --- a/rpc/apis.go +++ b/rpc/apis.go @@ -35,6 +35,7 @@ import ( ethermint "github.com/evmos/ethermint/types" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" + "google.golang.org/grpc" ) // RPC namespaces and API version @@ -60,6 +61,7 @@ const ( type APICreator = func( ctx *server.Context, clientCtx client.Context, + backupGRPCClient *grpc.ClientConn, tendermintWebsocketClient *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, @@ -72,11 +74,12 @@ func init() { apiCreators = map[string]APICreator{ EthNamespace: func(ctx *server.Context, clientCtx client.Context, + backupGRPCClient *grpc.ClientConn, tmWSClient *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClient, allowUnprotectedTxs, indexer) return []rpc.API{ { Namespace: EthNamespace, @@ -92,7 +95,7 @@ func init() { }, } }, - Web3Namespace: func(*server.Context, client.Context, *rpcclient.WSClient, bool, ethermint.EVMTxIndexer) []rpc.API { + Web3Namespace: func(*server.Context, client.Context, *grpc.ClientConn, *rpcclient.WSClient, bool, ethermint.EVMTxIndexer) []rpc.API { return []rpc.API{ { Namespace: Web3Namespace, @@ -102,7 +105,7 @@ func init() { }, } }, - NetNamespace: func(_ *server.Context, clientCtx client.Context, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { + NetNamespace: func(_ *server.Context, clientCtx client.Context, _ *grpc.ClientConn, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { return []rpc.API{ { Namespace: NetNamespace, @@ -114,11 +117,12 @@ func init() { }, PersonalNamespace: func(ctx *server.Context, clientCtx client.Context, + backupGRPCClient *grpc.ClientConn, _ *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClient, allowUnprotectedTxs, indexer) return []rpc.API{ { Namespace: PersonalNamespace, @@ -128,7 +132,7 @@ func init() { }, } }, - TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { + TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *grpc.ClientConn, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { return []rpc.API{ { Namespace: TxPoolNamespace, @@ -140,11 +144,12 @@ func init() { }, DebugNamespace: func(ctx *server.Context, clientCtx client.Context, + backupGRPCClient *grpc.ClientConn, _ *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClient, allowUnprotectedTxs, indexer) return []rpc.API{ { Namespace: DebugNamespace, @@ -156,11 +161,12 @@ func init() { }, MinerNamespace: func(ctx *server.Context, clientCtx client.Context, + backupGRPCClient *grpc.ClientConn, _ *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer) + evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClient, allowUnprotectedTxs, indexer) return []rpc.API{ { Namespace: MinerNamespace, @@ -176,6 +182,7 @@ func init() { // GetRPCAPIs returns the list of all APIs func GetRPCAPIs(ctx *server.Context, clientCtx client.Context, + backupGRPCClient *grpc.ClientConn, tmWSClient *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, @@ -185,7 +192,7 @@ func GetRPCAPIs(ctx *server.Context, for _, ns := range selectedAPIs { if creator, ok := apiCreators[ns]; ok { - apis = append(apis, creator(ctx, clientCtx, tmWSClient, allowUnprotectedTxs, indexer)...) + apis = append(apis, creator(ctx, clientCtx, backupGRPCClient, tmWSClient, allowUnprotectedTxs, indexer)...) } else { ctx.Logger.Error("invalid namespace value", "namespace", ns) } diff --git a/rpc/backend/backend.go b/rpc/backend/backend.go index 09709e7bce..186df8188f 100644 --- a/rpc/backend/backend.go +++ b/rpc/backend/backend.go @@ -24,6 +24,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -34,8 +35,10 @@ import ( "github.com/evmos/ethermint/server/config" ethermint "github.com/evmos/ethermint/types" evmtypes "github.com/evmos/ethermint/x/evm/types" + feemarkettypes "github.com/evmos/ethermint/x/feemarket/types" "github.com/tendermint/tendermint/libs/log" tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" + "google.golang.org/grpc" ) // BackendI implements the Cosmos and EVM backend. @@ -149,6 +152,7 @@ type Backend struct { ctx context.Context clientCtx client.Context queryClient *rpctypes.QueryClient // gRPC query client + backupQueryClient *rpctypes.QueryClient logger log.Logger chainID *big.Int cfg config.Config @@ -161,6 +165,7 @@ func NewBackend( ctx *server.Context, logger log.Logger, clientCtx client.Context, + backupGRPCClient *grpc.ClientConn, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) *Backend { @@ -174,7 +179,7 @@ func NewBackend( panic(err) } - return &Backend{ + backend := &Backend{ ctx: context.Background(), clientCtx: clientCtx, queryClient: rpctypes.NewQueryClient(clientCtx), @@ -184,4 +189,12 @@ func NewBackend( allowUnprotectedTxs: allowUnprotectedTxs, indexer: indexer, } + if backupGRPCClient != nil { + backend.backupQueryClient = &rpctypes.QueryClient{ + ServiceClient: tx.NewServiceClient(backupGRPCClient), + QueryClient: evmtypes.NewQueryClient(backupGRPCClient), + FeeMarket: feemarkettypes.NewQueryClient(backupGRPCClient), + } + } + return backend } diff --git a/server/json_rpc.go b/server/json_rpc.go index 7934a30c77..7084886be4 100644 --- a/server/json_rpc.go +++ b/server/json_rpc.go @@ -31,11 +31,13 @@ import ( "github.com/evmos/ethermint/server/config" ethermint "github.com/evmos/ethermint/types" + "google.golang.org/grpc" ) // StartJSONRPC starts the JSON-RPC server func StartJSONRPC(ctx *server.Context, clientCtx client.Context, + backupGRPCClient *grpc.ClientConn, tmRPCAddr, tmEndpoint string, config *config.Config, @@ -61,7 +63,7 @@ func StartJSONRPC(ctx *server.Context, allowUnprotectedTxs := config.JSONRPC.AllowUnprotectedTxs rpcAPIArr := config.JSONRPC.API - apis := rpc.GetRPCAPIs(ctx, clientCtx, tmWsClient, allowUnprotectedTxs, indexer, rpcAPIArr) + apis := rpc.GetRPCAPIs(ctx, clientCtx, backupGRPCClient, tmWsClient, allowUnprotectedTxs, indexer, rpcAPIArr) for _, api := range apis { if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil { diff --git a/server/start.go b/server/start.go index 96c03d9632..ab22d0862a 100644 --- a/server/start.go +++ b/server/start.go @@ -268,6 +268,14 @@ func startStandAlone(ctx *server.Context, appCreator types.AppCreator) error { return server.WaitForQuitSignals() } +func parseGrpcAddress(address string) (string, error) { + _, port, err := net.SplitHostPort(address) + if err != nil { + return "", errorsmod.Wrapf(err, "invalid grpc address %s", address) + } + return fmt.Sprintf("127.0.0.1:%s", port), nil +} + // legacyAminoCdc is used for the legacy REST API func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator types.AppCreator) (err error) { cfg := ctx.Config @@ -431,6 +439,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty } } + var backupGrpcClient *grpc.ClientConn if config.API.Enable || config.JSONRPC.Enable { genDoc, err := genDocProvider() if err != nil { @@ -444,9 +453,9 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty // Set `GRPCClient` to `clientCtx` to enjoy concurrent grpc query. // only use it if gRPC server is enabled. if config.GRPC.Enable { - _, port, err := net.SplitHostPort(config.GRPC.Address) + grpcAddress, err := parseGrpcAddress(config.GRPC.Address) if err != nil { - return errorsmod.Wrapf(err, "invalid grpc address %s", config.GRPC.Address) + return err } maxSendMsgSize := config.GRPC.MaxSendMsgSize @@ -459,8 +468,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty maxRecvMsgSize = serverconfig.DefaultGRPCMaxRecvMsgSize } - grpcAddress := fmt.Sprintf("127.0.0.1:%s", port) - // If grpc is enabled, configure grpc client for grpc gateway and json-rpc. grpcClient, err := grpc.Dial( grpcAddress, @@ -477,6 +484,24 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty clientCtx = clientCtx.WithGRPCClient(grpcClient) ctx.Logger.Debug("gRPC client assigned to client context", "address", grpcAddress) + + // Config backup GRPCClient + backupGrpcAddress, err := parseGrpcAddress("0.0.0.0:26754") + if err != nil { + return err + } + backupGrpcClient, err = grpc.Dial( + backupGrpcAddress, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithDefaultCallOptions( + grpc.ForceCodec(codec.NewProtoCodec(clientCtx.InterfaceRegistry).GRPCCodec()), + grpc.MaxCallRecvMsgSize(maxRecvMsgSize), + grpc.MaxCallSendMsgSize(maxSendMsgSize), + ), + ) + if err != nil { + return err + } } } @@ -546,7 +571,8 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty tmEndpoint := "/websocket" tmRPCAddr := cfg.RPC.ListenAddress - httpSrv, httpSrvDone, err = StartJSONRPC(ctx, clientCtx, tmRPCAddr, tmEndpoint, &config, idxer) + + httpSrv, httpSrvDone, err = StartJSONRPC(ctx, clientCtx, backupGrpcClient, tmRPCAddr, tmEndpoint, &config, idxer) if err != nil { return err } diff --git a/tests/integration_tests/configs/backup.jsonnet b/tests/integration_tests/configs/backup.jsonnet new file mode 100644 index 0000000000..6e1558112e --- /dev/null +++ b/tests/integration_tests/configs/backup.jsonnet @@ -0,0 +1,9 @@ +local config = import 'main.jsonnet'; + +config { + 'ethermint_9000-1'+: { + 'app-config'+: { + 'backup-grpc-address': '0.0.0.0:26754', + }, + }, +} diff --git a/tests/integration_tests/configs/main.jsonnet b/tests/integration_tests/configs/main.jsonnet new file mode 100644 index 0000000000..bf3a1b3bd7 --- /dev/null +++ b/tests/integration_tests/configs/main.jsonnet @@ -0,0 +1,9 @@ +local config = import 'default.jsonnet'; + +config { + 'ethermint_9000-1'+: { + 'app-config'+: { + 'minimum-gas-prices': '100000000000aphoton', + }, + }, +} diff --git a/tests/integration_tests/test_backup_grpc.py b/tests/integration_tests/test_backup_grpc.py new file mode 100644 index 0000000000..3da0453dc9 --- /dev/null +++ b/tests/integration_tests/test_backup_grpc.py @@ -0,0 +1,112 @@ +import os +import signal +import subprocess +from pathlib import Path +from typing import NamedTuple + +import pytest +import requests +from pystarport import ports + +from .network import Ethermint +from .utils import ADDRS, wait_for_fn, wait_for_port + + +class Network(NamedTuple): + main: Ethermint + backup: Ethermint + + +def exec(config, path, base_port): + cmd = [ + "pystarport", + "init", + "--config", + config, + "--data", + path, + "--base_port", + str(base_port), + "--no_remove", + ] + print(*cmd) + subprocess.run(cmd, check=True) + return subprocess.Popen( + ["pystarport", "start", "--data", path, "--quiet"], + preexec_fn=os.setsid, + ) + + +@pytest.fixture(scope="module") +def network(tmp_path_factory): + chain_id = "ethermint_9000-1" + base = Path(__file__).parent / "configs" + + # backup + path0 = tmp_path_factory.mktemp("ethermint-backup") + base_port0 = 26770 + procs = [exec(base / "backup.jsonnet", path0, base_port0)] + + wait_for_port(base_port0) + + # main + path1 = tmp_path_factory.mktemp("ethermint-main") + base_port1 = 26750 + procs.append(exec(base / "main.jsonnet", path1, base_port1)) + + try: + wait_for_port(ports.evmrpc_port(base_port0)) + wait_for_port(ports.evmrpc_ws_port(base_port0)) + wait_for_port(ports.grpc_port(base_port1)) + yield Network(Ethermint(path0 / chain_id), Ethermint(path1 / chain_id)) + finally: + for proc in procs: + os.killpg(os.getpgid(proc.pid), signal.SIGTERM) + proc.wait() + print("killed:", proc.pid) + + +def grpc_call(p, address): + url = f"http://127.0.0.1:{p}/cosmos/bank/v1beta1/balances/{address}" + response = requests.get(url) + if not response.ok: + # retry until file get synced + return -1 + # raise Exception( + # f"response code: {response.status_code}, " + # f"{response.reason}, {response.json()}" + # ) + result = response.json() + if result.get("code"): + raise Exception(result["raw_log"]) + return result["balances"] + + +def test_basic(network): + pw3 = network.main.w3 + pcli = network.main.cosmos_cli() + validator = pcli.address("validator") + community = pcli.address("community") + print("address: ", validator, community) + backup_grpc_port = ports.api_port(network.backup.base_port(0)) + + def check_balances(): + mbalances = [pcli.balances(community), pcli.balances(validator)] + bbalances = [ + grpc_call(backup_grpc_port, community), + grpc_call(backup_grpc_port, validator), + ] + print("main", mbalances) + print("backup", bbalances) + return mbalances == bbalances + + txhash = pw3.eth.send_transaction( + { + "from": ADDRS["validator"], + "to": ADDRS["community"], + "value": 1000, + } + ) + receipt = pw3.eth.wait_for_transaction_receipt(txhash) + assert receipt.status == 1 + wait_for_fn("cross-check-balances", check_balances) diff --git a/tests/integration_tests/utils.py b/tests/integration_tests/utils.py index ce28e9c4c9..4ae900e267 100644 --- a/tests/integration_tests/utils.py +++ b/tests/integration_tests/utils.py @@ -123,6 +123,17 @@ def wait_for_block_time(cli, t): time.sleep(0.5) +def wait_for_fn(name, fn, *, timeout=240, interval=1): + for i in range(int(timeout / interval)): + result = fn() + print("check", name, result) + if result: + break + time.sleep(interval) + else: + raise TimeoutError(f"wait for {name} timeout") + + def deploy_contract(w3, jsonfile, args=(), key=KEYS["validator"]): """ deploy contract and return the deployed contract instance diff --git a/testutil/network/util.go b/testutil/network/util.go index 03123cfbeb..381b9999d0 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -146,7 +146,7 @@ func startInProcess(cfg Config, val *Validator) error { tmEndpoint := "/websocket" tmRPCAddr := val.RPCAddress - val.jsonrpc, val.jsonrpcDone, err = server.StartJSONRPC(val.Ctx, val.ClientCtx, tmRPCAddr, tmEndpoint, val.AppConfig, nil) + val.jsonrpc, val.jsonrpcDone, err = server.StartJSONRPC(val.Ctx, val.ClientCtx, val.ClientCtx.GRPCClient, tmRPCAddr, tmEndpoint, val.AppConfig, nil) if err != nil { return err } From cca8b87149ef80103cbf103c94b44beaaee89282 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 13 Jan 2023 09:42:27 +0800 Subject: [PATCH 03/29] support grpc client map --- rpc/apis.go | 28 ++++++++++++++-------------- rpc/backend/backend.go | 15 ++++++++------- rpc/backend/tracing.go | 11 +++++++++++ server/json_rpc.go | 4 ++-- server/start.go | 40 ++++++++++++++++++++++------------------ testutil/network/util.go | 7 +++++-- 6 files changed, 62 insertions(+), 43 deletions(-) diff --git a/rpc/apis.go b/rpc/apis.go index 3ffcfec6f4..dae7114a75 100644 --- a/rpc/apis.go +++ b/rpc/apis.go @@ -61,7 +61,7 @@ const ( type APICreator = func( ctx *server.Context, clientCtx client.Context, - backupGRPCClient *grpc.ClientConn, + backupGRPCClientConns map[[2]int]*grpc.ClientConn, tendermintWebsocketClient *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, @@ -74,12 +74,12 @@ func init() { apiCreators = map[string]APICreator{ EthNamespace: func(ctx *server.Context, clientCtx client.Context, - backupGRPCClient *grpc.ClientConn, + backupGRPCClientConns map[[2]int]*grpc.ClientConn, tmWSClient *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClient, allowUnprotectedTxs, indexer) + evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClientConns, allowUnprotectedTxs, indexer) return []rpc.API{ { Namespace: EthNamespace, @@ -95,7 +95,7 @@ func init() { }, } }, - Web3Namespace: func(*server.Context, client.Context, *grpc.ClientConn, *rpcclient.WSClient, bool, ethermint.EVMTxIndexer) []rpc.API { + Web3Namespace: func(*server.Context, client.Context, map[[2]int]*grpc.ClientConn, *rpcclient.WSClient, bool, ethermint.EVMTxIndexer) []rpc.API { return []rpc.API{ { Namespace: Web3Namespace, @@ -105,7 +105,7 @@ func init() { }, } }, - NetNamespace: func(_ *server.Context, clientCtx client.Context, _ *grpc.ClientConn, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { + NetNamespace: func(_ *server.Context, clientCtx client.Context, _ map[[2]int]*grpc.ClientConn, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { return []rpc.API{ { Namespace: NetNamespace, @@ -117,12 +117,12 @@ func init() { }, PersonalNamespace: func(ctx *server.Context, clientCtx client.Context, - backupGRPCClient *grpc.ClientConn, + backupGRPCClientConns map[[2]int]*grpc.ClientConn, _ *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClient, allowUnprotectedTxs, indexer) + evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClientConns, allowUnprotectedTxs, indexer) return []rpc.API{ { Namespace: PersonalNamespace, @@ -132,7 +132,7 @@ func init() { }, } }, - TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ *grpc.ClientConn, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { + TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ map[[2]int]*grpc.ClientConn, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { return []rpc.API{ { Namespace: TxPoolNamespace, @@ -144,12 +144,12 @@ func init() { }, DebugNamespace: func(ctx *server.Context, clientCtx client.Context, - backupGRPCClient *grpc.ClientConn, + backupGRPCClientConns map[[2]int]*grpc.ClientConn, _ *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClient, allowUnprotectedTxs, indexer) + evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClientConns, allowUnprotectedTxs, indexer) return []rpc.API{ { Namespace: DebugNamespace, @@ -161,12 +161,12 @@ func init() { }, MinerNamespace: func(ctx *server.Context, clientCtx client.Context, - backupGRPCClient *grpc.ClientConn, + backupGRPCClientConns map[[2]int]*grpc.ClientConn, _ *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) []rpc.API { - evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClient, allowUnprotectedTxs, indexer) + evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, backupGRPCClientConns, allowUnprotectedTxs, indexer) return []rpc.API{ { Namespace: MinerNamespace, @@ -182,7 +182,7 @@ func init() { // GetRPCAPIs returns the list of all APIs func GetRPCAPIs(ctx *server.Context, clientCtx client.Context, - backupGRPCClient *grpc.ClientConn, + backupGRPCClientConns map[[2]int]*grpc.ClientConn, tmWSClient *rpcclient.WSClient, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, @@ -192,7 +192,7 @@ func GetRPCAPIs(ctx *server.Context, for _, ns := range selectedAPIs { if creator, ok := apiCreators[ns]; ok { - apis = append(apis, creator(ctx, clientCtx, backupGRPCClient, tmWSClient, allowUnprotectedTxs, indexer)...) + apis = append(apis, creator(ctx, clientCtx, backupGRPCClientConns, tmWSClient, allowUnprotectedTxs, indexer)...) } else { ctx.Logger.Error("invalid namespace value", "namespace", ns) } diff --git a/rpc/backend/backend.go b/rpc/backend/backend.go index 186df8188f..bba26e650e 100644 --- a/rpc/backend/backend.go +++ b/rpc/backend/backend.go @@ -152,7 +152,7 @@ type Backend struct { ctx context.Context clientCtx client.Context queryClient *rpctypes.QueryClient // gRPC query client - backupQueryClient *rpctypes.QueryClient + backupQueryClients map[[2]int]*rpctypes.QueryClient logger log.Logger chainID *big.Int cfg config.Config @@ -165,7 +165,7 @@ func NewBackend( ctx *server.Context, logger log.Logger, clientCtx client.Context, - backupGRPCClient *grpc.ClientConn, + backupGRPCClientConns map[[2]int]*grpc.ClientConn, allowUnprotectedTxs bool, indexer ethermint.EVMTxIndexer, ) *Backend { @@ -183,17 +183,18 @@ func NewBackend( ctx: context.Background(), clientCtx: clientCtx, queryClient: rpctypes.NewQueryClient(clientCtx), + backupQueryClients: make(map[[2]int]*rpctypes.QueryClient), logger: logger.With("module", "backend"), chainID: chainID, cfg: appConf, allowUnprotectedTxs: allowUnprotectedTxs, indexer: indexer, } - if backupGRPCClient != nil { - backend.backupQueryClient = &rpctypes.QueryClient{ - ServiceClient: tx.NewServiceClient(backupGRPCClient), - QueryClient: evmtypes.NewQueryClient(backupGRPCClient), - FeeMarket: feemarkettypes.NewQueryClient(backupGRPCClient), + for key, conn := range backupGRPCClientConns { + backend.backupQueryClients[key] = &rpctypes.QueryClient{ + ServiceClient: tx.NewServiceClient(conn), + QueryClient: evmtypes.NewQueryClient(conn), + FeeMarket: feemarkettypes.NewQueryClient(conn), } } return backend diff --git a/rpc/backend/tracing.go b/rpc/backend/tracing.go index 64aee968ed..d420e4acfe 100644 --- a/rpc/backend/tracing.go +++ b/rpc/backend/tracing.go @@ -27,6 +27,17 @@ import ( tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" ) +func (b *Backend) getGrpcClient(height int64) *rpctypes.QueryClient { + for blocks, client := range b.backupQueryClients { + // b1-b2 -> g1 + // b3-b4 -> g2 + if blocks[0] <= int(height) && blocks[1] >= int(height) { + return client + } + } + return b.queryClient +} + // TraceTransaction returns the structured logs created during the execution of EVM // and returns them as a JSON object. func (b *Backend) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (interface{}, error) { diff --git a/server/json_rpc.go b/server/json_rpc.go index 7084886be4..00e307c3d2 100644 --- a/server/json_rpc.go +++ b/server/json_rpc.go @@ -37,7 +37,7 @@ import ( // StartJSONRPC starts the JSON-RPC server func StartJSONRPC(ctx *server.Context, clientCtx client.Context, - backupGRPCClient *grpc.ClientConn, + backupGRPCClientConns map[[2]int]*grpc.ClientConn, tmRPCAddr, tmEndpoint string, config *config.Config, @@ -63,7 +63,7 @@ func StartJSONRPC(ctx *server.Context, allowUnprotectedTxs := config.JSONRPC.AllowUnprotectedTxs rpcAPIArr := config.JSONRPC.API - apis := rpc.GetRPCAPIs(ctx, clientCtx, backupGRPCClient, tmWsClient, allowUnprotectedTxs, indexer, rpcAPIArr) + apis := rpc.GetRPCAPIs(ctx, clientCtx, backupGRPCClientConns, tmWsClient, allowUnprotectedTxs, indexer, rpcAPIArr) for _, api := range apis { if err := rpcServer.RegisterName(api.Namespace, api.Service); err != nil { diff --git a/server/start.go b/server/start.go index ab22d0862a..af6f41add1 100644 --- a/server/start.go +++ b/server/start.go @@ -439,7 +439,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty } } - var backupGrpcClient *grpc.ClientConn + backupGRPCClientConns := make(map[[2]int]*grpc.ClientConn) if config.API.Enable || config.JSONRPC.Enable { genDoc, err := genDocProvider() if err != nil { @@ -485,22 +485,26 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty clientCtx = clientCtx.WithGRPCClient(grpcClient) ctx.Logger.Debug("gRPC client assigned to client context", "address", grpcAddress) - // Config backup GRPCClient - backupGrpcAddress, err := parseGrpcAddress("0.0.0.0:26754") - if err != nil { - return err - } - backupGrpcClient, err = grpc.Dial( - backupGrpcAddress, - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithDefaultCallOptions( - grpc.ForceCodec(codec.NewProtoCodec(clientCtx.InterfaceRegistry).GRPCCodec()), - grpc.MaxCallRecvMsgSize(maxRecvMsgSize), - grpc.MaxCallSendMsgSize(maxSendMsgSize), - ), - ) - if err != nil { - return err + // TODO: Config backup GRPCClient + grpcBlockAddresses := map[[2]int]string{} + for k, address := range grpcBlockAddresses { + grpcAddr, err := parseGrpcAddress(address) + if err != nil { + return err + } + c, err := grpc.Dial( + grpcAddr, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithDefaultCallOptions( + grpc.ForceCodec(codec.NewProtoCodec(clientCtx.InterfaceRegistry).GRPCCodec()), + grpc.MaxCallRecvMsgSize(maxRecvMsgSize), + grpc.MaxCallSendMsgSize(maxSendMsgSize), + ), + ) + if err != nil { + return err + } + backupGRPCClientConns[k] = c } } } @@ -572,7 +576,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty tmEndpoint := "/websocket" tmRPCAddr := cfg.RPC.ListenAddress - httpSrv, httpSrvDone, err = StartJSONRPC(ctx, clientCtx, backupGrpcClient, tmRPCAddr, tmEndpoint, &config, idxer) + httpSrv, httpSrvDone, err = StartJSONRPC(ctx, clientCtx, backupGRPCClientConns, tmRPCAddr, tmEndpoint, &config, idxer) if err != nil { return err } diff --git a/testutil/network/util.go b/testutil/network/util.go index 381b9999d0..928e1b6912 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -46,6 +46,7 @@ import ( "github.com/evmos/ethermint/server" evmtypes "github.com/evmos/ethermint/x/evm/types" + "google.golang.org/grpc" ) func startInProcess(cfg Config, val *Validator) error { @@ -145,8 +146,10 @@ func startInProcess(cfg Config, val *Validator) error { tmEndpoint := "/websocket" tmRPCAddr := val.RPCAddress - - val.jsonrpc, val.jsonrpcDone, err = server.StartJSONRPC(val.Ctx, val.ClientCtx, val.ClientCtx.GRPCClient, tmRPCAddr, tmEndpoint, val.AppConfig, nil) + gprcClients := map[[2]int]*grpc.ClientConn{ + {0, 1}: val.ClientCtx.GRPCClient, + } + val.jsonrpc, val.jsonrpcDone, err = server.StartJSONRPC(val.Ctx, val.ClientCtx, gprcClients, tmRPCAddr, tmEndpoint, val.AppConfig, nil) if err != nil { return err } From 54217939aea5c4f4a010a42e5ef65641a136f849 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 13 Jan 2023 09:42:32 +0800 Subject: [PATCH 04/29] config deprecate migrate height --- server/config/config.go | 3 +++ server/config/toml.go | 3 +++ server/flags/flags.go | 1 + server/start.go | 4 +++- tests/integration_tests/configs/default.jsonnet | 1 + 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/server/config/config.go b/server/config/config.go index ed897ee8b7..a0a8d992e6 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -138,6 +138,8 @@ type JSONRPCConfig struct { MetricsAddress string `mapstructure:"metrics-address"` // FixRevertGasRefundHeight defines the upgrade height for fix of revert gas refund logic when transaction reverted FixRevertGasRefundHeight int64 `mapstructure:"fix-revert-gas-refund-height"` + // Deprecate height for usage of x/params. + DeprecateMigrateHeight int64 `mapstructure:"deprecate-migrate-height"` } // TLSConfig defines the certificate and matching private key for the server. @@ -351,6 +353,7 @@ func GetConfig(v *viper.Viper) (Config, error) { EnableIndexer: v.GetBool("json-rpc.enable-indexer"), MetricsAddress: v.GetString("json-rpc.metrics-address"), FixRevertGasRefundHeight: v.GetInt64("json-rpc.fix-revert-gas-refund-height"), + DeprecateMigrateHeight: v.GetInt64("json-rpc.deprecate-migrate-height"), }, TLS: TLSConfig{ CertificatePath: v.GetString("tls.certificate-path"), diff --git a/server/config/toml.go b/server/config/toml.go index a61f110dc7..746ac4184f 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -95,6 +95,9 @@ metrics-address = "{{ .JSONRPC.MetricsAddress }}" # Upgrade height for fix of revert gas refund logic when transaction reverted. fix-revert-gas-refund-height = {{ .JSONRPC.FixRevertGasRefundHeight }} +# Deprecate height for usage of x/params. +deprecate-migrate-height = {{ .JSONRPC.DeprecateMigrateHeight }} + ############################################################################### ### TLS Configuration ### ############################################################################### diff --git a/server/flags/flags.go b/server/flags/flags.go index 5f3d9c7112..c17cac6661 100644 --- a/server/flags/flags.go +++ b/server/flags/flags.go @@ -70,6 +70,7 @@ const ( // https://github.com/ethereum/go-ethereum/blob/master/metrics/metrics.go#L35-L55 JSONRPCEnableMetrics = "metrics" JSONRPCFixRevertGasRefundHeight = "json-rpc.fix-revert-gas-refund-height" + JSONRPCDeprecateMigrateHeight = "json-rpc.deprecate-migrate-height" ) // EVM flags diff --git a/server/start.go b/server/start.go index af6f41add1..f8b2305006 100644 --- a/server/start.go +++ b/server/start.go @@ -486,7 +486,9 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty ctx.Logger.Debug("gRPC client assigned to client context", "address", grpcAddress) // TODO: Config backup GRPCClient - grpcBlockAddresses := map[[2]int]string{} + grpcBlockAddresses := map[[2]int]string{ + {0, int(config.JSONRPC.DeprecateMigrateHeight)}: "0.0.0.0:26664", + } for k, address := range grpcBlockAddresses { grpcAddr, err := parseGrpcAddress(address) if err != nil { diff --git a/tests/integration_tests/configs/default.jsonnet b/tests/integration_tests/configs/default.jsonnet index 349be756f4..16b9f05ba9 100644 --- a/tests/integration_tests/configs/default.jsonnet +++ b/tests/integration_tests/configs/default.jsonnet @@ -20,6 +20,7 @@ 'block-range-cap': 10000, 'logs-cap': 10000, 'fix-revert-gas-refund-height': 1, + 'deprecate-migrate-height': 1, }, }, validators: [{ From b2c9ad42e70e3d490f1bc59780bbebe287f1cd51 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 13 Jan 2023 09:42:37 +0800 Subject: [PATCH 05/29] apply backup grpc client --- rpc/backend/account_info.go | 20 +++++++++++--------- rpc/backend/blocks.go | 3 ++- rpc/backend/call_tx.go | 4 +++- rpc/backend/chain_info.go | 10 +++++++--- rpc/backend/node_info.go | 1 + rpc/backend/sign_tx.go | 1 + 6 files changed, 25 insertions(+), 14 deletions(-) diff --git a/rpc/backend/account_info.go b/rpc/backend/account_info.go index 66f1a1d24d..d7c6790e26 100644 --- a/rpc/backend/account_info.go +++ b/rpc/backend/account_info.go @@ -40,8 +40,9 @@ func (b *Backend) GetCode(address common.Address, blockNrOrHash rpctypes.BlockNu req := &evmtypes.QueryCodeRequest{ Address: address.String(), } - - res, err := b.queryClient.Code(rpctypes.ContextWithHeight(blockNum.Int64()), req) + height := blockNum.Int64() + queryClient := b.getGrpcClient(height) + res, err := queryClient.Code(rpctypes.ContextWithHeight(height), req) if err != nil { return nil, err } @@ -82,10 +83,10 @@ func (b *Backend) GetProof(address common.Address, storageKeys []string, blockNr // query storage proofs storageProofs := make([]rpctypes.StorageResult, len(storageKeys)) - + queryClient := b.getGrpcClient(height) for i, key := range storageKeys { hexKey := common.HexToHash(key) - valueBz, proof, err := b.queryClient.GetProof(clientCtx, evmtypes.StoreKey, evmtypes.StateKey(address, hexKey.Bytes())) + valueBz, proof, err := queryClient.GetProof(clientCtx, evmtypes.StoreKey, evmtypes.StateKey(address, hexKey.Bytes())) if err != nil { return nil, err } @@ -102,14 +103,14 @@ func (b *Backend) GetProof(address common.Address, storageKeys []string, blockNr Address: address.String(), } - res, err := b.queryClient.Account(ctx, req) + res, err := queryClient.Account(ctx, req) if err != nil { return nil, err } // query account proofs accountKey := authtypes.AddressStoreKey(sdk.AccAddress(address.Bytes())) - _, proof, err := b.queryClient.GetProof(clientCtx, authtypes.StoreKey, accountKey) + _, proof, err := queryClient.GetProof(clientCtx, authtypes.StoreKey, accountKey) if err != nil { return nil, err } @@ -141,8 +142,9 @@ func (b *Backend) GetStorageAt(address common.Address, key string, blockNrOrHash Address: address.String(), Key: key, } - - res, err := b.queryClient.Storage(rpctypes.ContextWithHeight(blockNum.Int64()), req) + height := blockNum.Int64() + queryClient := b.getGrpcClient(height) + res, err := queryClient.Storage(rpctypes.ContextWithHeight(height), req) if err != nil { return nil, err } @@ -167,7 +169,7 @@ func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpctypes.Bloc return nil, err } - res, err := b.queryClient.Balance(rpctypes.ContextWithHeight(blockNum.Int64()), req) + res, err := b.getGrpcClient(blockNum.Int64()).Balance(rpctypes.ContextWithHeight(blockNum.Int64()), req) if err != nil { return nil, err } diff --git a/rpc/backend/blocks.go b/rpc/backend/blocks.go index c4f09d7009..0d3b65f188 100644 --- a/rpc/backend/blocks.go +++ b/rpc/backend/blocks.go @@ -42,6 +42,7 @@ import ( func (b *Backend) BlockNumber() (hexutil.Uint64, error) { // do any grpc query, ignore the response and use the returned block height var header metadata.MD + // use latest queryClient to get block height _, err := b.queryClient.Params(b.ctx, &evmtypes.QueryParamsRequest{}, grpc.Header(&header)) if err != nil { return hexutil.Uint64(0), err @@ -412,7 +413,7 @@ func (b *Backend) RPCBlockFromTendermintBlock( var validatorAccAddr sdk.AccAddress ctx := rpctypes.ContextWithHeight(block.Height) - res, err := b.queryClient.ValidatorAccount(ctx, req) + res, err := b.getGrpcClient(block.Height).ValidatorAccount(ctx, req) if err != nil { b.logger.Debug( "failed to query validator operator address", diff --git a/rpc/backend/call_tx.go b/rpc/backend/call_tx.go index 7967d06fe2..3d65516ba8 100644 --- a/rpc/backend/call_tx.go +++ b/rpc/backend/call_tx.go @@ -142,6 +142,7 @@ func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { } // Query params to use the EVM denomination + // use latest queryClient in send res, err := b.queryClient.QueryClient.Params(b.ctx, &evmtypes.QueryParamsRequest{}) if err != nil { b.logger.Error("failed to query evm params", "error", err.Error()) @@ -332,6 +333,7 @@ func (b *Backend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rp // From ContextWithHeight: if the provided height is 0, // it will return an empty context and the gRPC query will use // the latest block height for querying. + // TODO: use latest queryClient to estimate, need estimate for old block? res, err := b.queryClient.EstimateGas(rpctypes.ContextWithHeight(blockNr.Int64()), &req) if err != nil { return 0, err @@ -379,7 +381,7 @@ func (b *Backend) DoCall( // Make sure the context is canceled when the call has completed // this makes sure resources are cleaned up. defer cancel() - + // TODO: use latest queryClient to call, need call for old block? res, err := b.queryClient.EthCall(ctx, &req) if err != nil { return nil, err diff --git a/rpc/backend/chain_info.go b/rpc/backend/chain_info.go index 732724bb50..0b45c04b83 100644 --- a/rpc/backend/chain_info.go +++ b/rpc/backend/chain_info.go @@ -54,6 +54,7 @@ func (b *Backend) ChainID() (*hexutil.Big, error) { // ChainConfig returns the latest ethereum chain configuration func (b *Backend) ChainConfig() *params.ChainConfig { + // use latest queryClient to get config params, err := b.queryClient.Params(b.ctx, &evmtypes.QueryParamsRequest{}) if err != nil { return nil @@ -64,6 +65,7 @@ func (b *Backend) ChainConfig() *params.ChainConfig { // GlobalMinGasPrice returns MinGasPrice param from FeeMarket func (b *Backend) GlobalMinGasPrice() (sdk.Dec, error) { + // use latest queryClient to get MinGasPrice res, err := b.queryClient.FeeMarket.Params(b.ctx, &feemarkettypes.QueryParamsRequest{}) if err != nil { return sdk.ZeroDec(), err @@ -77,7 +79,9 @@ func (b *Backend) GlobalMinGasPrice() (sdk.Dec, error) { // return nil. func (b *Backend) BaseFee(blockRes *tmrpctypes.ResultBlockResults) (*big.Int, error) { // return BaseFee if London hard fork is activated and feemarket is enabled - res, err := b.queryClient.BaseFee(rpctypes.ContextWithHeight(blockRes.Height), &evmtypes.QueryBaseFeeRequest{}) + height := blockRes.Height + queryClient := b.getGrpcClient(height) + res, err := queryClient.BaseFee(rpctypes.ContextWithHeight(height), &evmtypes.QueryBaseFeeRequest{}) if err != nil || res.BaseFee == nil { // we can't tell if it's london HF not enabled or the state is pruned, // in either case, we'll fallback to parsing from begin blocker event, @@ -143,7 +147,7 @@ func (b *Backend) GetCoinbase() (sdk.AccAddress, error) { req := &evmtypes.QueryValidatorAccountRequest{ ConsAddress: sdk.ConsAddress(status.ValidatorInfo.Address).String(), } - + // use latest queryClient to get coinbase res, err := b.queryClient.ValidatorAccount(b.ctx, req) if err != nil { return nil, err @@ -259,7 +263,7 @@ func (b *Backend) SuggestGasTipCap(baseFee *big.Int) (*big.Int, error) { // london hardfork not enabled or feemarket not enabled return big.NewInt(0), nil } - + // use latest queryClient to get gas info params, err := b.queryClient.FeeMarket.Params(b.ctx, &feemarkettypes.QueryParamsRequest{}) if err != nil { return nil, err diff --git a/rpc/backend/node_info.go b/rpc/backend/node_info.go index f46c907009..c26e5a6e7d 100644 --- a/rpc/backend/node_info.go +++ b/rpc/backend/node_info.go @@ -339,6 +339,7 @@ func (b *Backend) RPCBlockRangeCap() int32 { // the node config. If set value is 0, it will default to 20. func (b *Backend) RPCMinGasPrice() int64 { + // use latest queryClient to get gas price evmParams, err := b.queryClient.Params(b.ctx, &evmtypes.QueryParamsRequest{}) if err != nil { return ethermint.DefaultGasPrice diff --git a/rpc/backend/sign_tx.go b/rpc/backend/sign_tx.go index 0c16da0c34..6b173625a7 100644 --- a/rpc/backend/sign_tx.go +++ b/rpc/backend/sign_tx.go @@ -72,6 +72,7 @@ func (b *Backend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, e } // Query params to use the EVM denomination + // use latest queryClient in send res, err := b.queryClient.QueryClient.Params(b.ctx, &evmtypes.QueryParamsRequest{}) if err != nil { b.logger.Error("failed to query evm params", "error", err.Error()) From 39a5b18323936c5637ab80a175c415547c22b774 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 13 Jan 2023 17:29:35 +0800 Subject: [PATCH 06/29] Revert "keep grpc query compatible with version before migrate" This reverts commit 864a001304af1122098766877e1f8553483c56bb. --- app/app.go | 5 ++--- x/evm/keeper/keeper.go | 5 ----- x/evm/keeper/params.go | 31 ++++++------------------------- 3 files changed, 8 insertions(+), 33 deletions(-) diff --git a/app/app.go b/app/app.go index d9d42e82f8..0f8d6d10a0 100644 --- a/app/app.go +++ b/app/app.go @@ -419,11 +419,10 @@ func NewEthermintApp( ) // Set authority to x/gov module account to only expect the module account to update params - evmSs := app.GetSubspace(evmtypes.ModuleName) app.EvmKeeper = evmkeeper.NewKeeper( appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], authtypes.NewModuleAddress(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.FeeMarketKeeper, - nil, geth.NewEVM, tracer, evmSs, + nil, geth.NewEVM, tracer, ) // Create IBC Keeper @@ -510,7 +509,7 @@ func NewEthermintApp( transferModule, // Ethermint app modules feemarket.NewAppModule(app.FeeMarketKeeper, feeMarketSs), - evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, evmSs), + evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, app.GetSubspace(evmtypes.ModuleName)), ) // During begin block slashing happens after distr.BeginBlocker so that diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index b1cc2a3778..af06e6548f 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -23,7 +23,6 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -76,8 +75,6 @@ type Keeper struct { // evm constructor function evmConstructor evm.Constructor - // Legacy subspace - ss paramstypes.Subspace } // NewKeeper generates new evm module keeper @@ -92,7 +89,6 @@ func NewKeeper( customPrecompiles evm.PrecompiledContracts, evmConstructor evm.Constructor, tracer string, - ss paramstypes.Subspace, ) *Keeper { // ensure evm module account is set if addr := ak.GetModuleAddress(types.ModuleName); addr == nil { @@ -117,7 +113,6 @@ func NewKeeper( customPrecompiles: customPrecompiles, evmConstructor: evmConstructor, tracer: tracer, - ss: ss, } } diff --git a/x/evm/keeper/params.go b/x/evm/keeper/params.go index 2ad6bd4891..64f582c7f5 100644 --- a/x/evm/keeper/params.go +++ b/x/evm/keeper/params.go @@ -48,20 +48,13 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { return nil } -// GetLegacyParams returns param set for version before migrate -func (k Keeper) GetLegacyParams(ctx sdk.Context) types.Params { - var params types.Params - k.ss.GetParamSetIfExists(ctx, ¶ms) - return params -} - // GetExtraEIPs returns the extra EIPs enabled on the chain. func (k Keeper) GetExtraEIPs(ctx sdk.Context) types.ExtraEIPs { var extraEIPs types.ExtraEIPs store := ctx.KVStore(k.storeKey) bz := store.Get(types.ParamStoreKeyExtraEIPs) if len(bz) == 0 { - return k.GetLegacyParams(ctx).ExtraEIPs + return extraEIPs } k.cdc.MustUnmarshal(bz, &extraEIPs) return extraEIPs @@ -73,7 +66,7 @@ func (k Keeper) GetChainConfig(ctx sdk.Context) types.ChainConfig { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ParamStoreKeyChainConfig) if len(bz) == 0 { - return k.GetLegacyParams(ctx).ChainConfig + return chainCfg } k.cdc.MustUnmarshal(bz, &chainCfg) return chainCfg @@ -84,7 +77,7 @@ func (k Keeper) GetEVMDenom(ctx sdk.Context) string { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ParamStoreKeyEVMDenom) if len(bz) == 0 { - return k.GetLegacyParams(ctx).EvmDenom + return "" } return string(bz) } @@ -92,31 +85,19 @@ func (k Keeper) GetEVMDenom(ctx sdk.Context) string { // GetEnableCall returns true if the EVM Call operation is enabled. func (k Keeper) GetEnableCall(ctx sdk.Context) bool { store := ctx.KVStore(k.storeKey) - exist := store.Has(types.ParamStoreKeyEnableCall) - if !exist { - exist = k.GetLegacyParams(ctx).EnableCall - } - return exist + return store.Has(types.ParamStoreKeyEnableCall) } // GetEnableCreate returns true if the EVM Create contract operation is enabled. func (k Keeper) GetEnableCreate(ctx sdk.Context) bool { store := ctx.KVStore(k.storeKey) - exist := store.Has(types.ParamStoreKeyEnableCreate) - if !exist { - exist = k.GetLegacyParams(ctx).EnableCreate - } - return exist + return store.Has(types.ParamStoreKeyEnableCreate) } // GetAllowUnprotectedTxs returns true if unprotected txs (i.e non-replay protected as per EIP-155) are supported by the chain. func (k Keeper) GetAllowUnprotectedTxs(ctx sdk.Context) bool { store := ctx.KVStore(k.storeKey) - exist := store.Has(types.ParamStoreKeyAllowUnprotectedTxs) - if !exist { - exist = k.GetLegacyParams(ctx).AllowUnprotectedTxs - } - return exist + return store.Has(types.ParamStoreKeyAllowUnprotectedTxs) } // setChainConfig sets the ChainConfig in the store From 546689f1ce4d087474f467492a85cd9d94495765 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Sat, 14 Jan 2023 09:24:28 +0800 Subject: [PATCH 07/29] cleanup todo --- rpc/backend/call_tx.go | 4 +- server/config/config.go | 44 +++++++++++-------- server/config/toml.go | 3 -- server/flags/flags.go | 6 +-- server/start.go | 5 +-- .../integration_tests/configs/backup.jsonnet | 6 ++- .../integration_tests/configs/default.jsonnet | 1 - 7 files changed, 36 insertions(+), 33 deletions(-) diff --git a/rpc/backend/call_tx.go b/rpc/backend/call_tx.go index 3d65516ba8..ada6187caf 100644 --- a/rpc/backend/call_tx.go +++ b/rpc/backend/call_tx.go @@ -333,7 +333,7 @@ func (b *Backend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rp // From ContextWithHeight: if the provided height is 0, // it will return an empty context and the gRPC query will use // the latest block height for querying. - // TODO: use latest queryClient to estimate, need estimate for old block? + // use latest queryClient to estimate res, err := b.queryClient.EstimateGas(rpctypes.ContextWithHeight(blockNr.Int64()), &req) if err != nil { return 0, err @@ -381,7 +381,7 @@ func (b *Backend) DoCall( // Make sure the context is canceled when the call has completed // this makes sure resources are cleaned up. defer cancel() - // TODO: use latest queryClient to call, need call for old block? + // use latest queryClient to call res, err := b.queryClient.EthCall(ctx, &req) if err != nil { return nil, err diff --git a/server/config/config.go b/server/config/config.go index a0a8d992e6..35610ac34c 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -139,7 +139,7 @@ type JSONRPCConfig struct { // FixRevertGasRefundHeight defines the upgrade height for fix of revert gas refund logic when transaction reverted FixRevertGasRefundHeight int64 `mapstructure:"fix-revert-gas-refund-height"` // Deprecate height for usage of x/params. - DeprecateMigrateHeight int64 `mapstructure:"deprecate-migrate-height"` + BackupGRPCBlockAddressBlockRange map[[2]int]string `mapstructure:"backup-grpc-address-block-range"` } // TLSConfig defines the certificate and matching private key for the server. @@ -329,6 +329,12 @@ func GetConfig(v *viper.Viper) (Config, error) { return Config{}, err } + backupGRPCBlockAddressBlockRange := make(map[[2]int]string) + for addr, val := range v.GetStringMap("json-rpc.backup-grpc-address-block-range") { + blocks := val.([]int) + lower, upper := blocks[0], blocks[1] + backupGRPCBlockAddressBlockRange[[2]int{lower, upper}] = addr + } return Config{ Config: cfg, EVM: EVMConfig{ @@ -336,24 +342,24 @@ 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"), - EnableIndexer: v.GetBool("json-rpc.enable-indexer"), - MetricsAddress: v.GetString("json-rpc.metrics-address"), - FixRevertGasRefundHeight: v.GetInt64("json-rpc.fix-revert-gas-refund-height"), - DeprecateMigrateHeight: v.GetInt64("json-rpc.deprecate-migrate-height"), + 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"), + EnableIndexer: v.GetBool("json-rpc.enable-indexer"), + MetricsAddress: v.GetString("json-rpc.metrics-address"), + FixRevertGasRefundHeight: v.GetInt64("json-rpc.fix-revert-gas-refund-height"), + BackupGRPCBlockAddressBlockRange: backupGRPCBlockAddressBlockRange, }, TLS: TLSConfig{ CertificatePath: v.GetString("tls.certificate-path"), diff --git a/server/config/toml.go b/server/config/toml.go index 746ac4184f..a61f110dc7 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -95,9 +95,6 @@ metrics-address = "{{ .JSONRPC.MetricsAddress }}" # Upgrade height for fix of revert gas refund logic when transaction reverted. fix-revert-gas-refund-height = {{ .JSONRPC.FixRevertGasRefundHeight }} -# Deprecate height for usage of x/params. -deprecate-migrate-height = {{ .JSONRPC.DeprecateMigrateHeight }} - ############################################################################### ### TLS Configuration ### ############################################################################### diff --git a/server/flags/flags.go b/server/flags/flags.go index c17cac6661..e9a06f960e 100644 --- a/server/flags/flags.go +++ b/server/flags/flags.go @@ -68,9 +68,9 @@ const ( // JSONRPCEnableMetrics enables EVM RPC metrics server. // Set to `metrics` which is hardcoded flag from go-ethereum. // https://github.com/ethereum/go-ethereum/blob/master/metrics/metrics.go#L35-L55 - JSONRPCEnableMetrics = "metrics" - JSONRPCFixRevertGasRefundHeight = "json-rpc.fix-revert-gas-refund-height" - JSONRPCDeprecateMigrateHeight = "json-rpc.deprecate-migrate-height" + JSONRPCEnableMetrics = "metrics" + JSONRPCFixRevertGasRefundHeight = "json-rpc.fix-revert-gas-refund-height" + JSONRPCBackupGRPCBlockAddressBlockRange = "json-rpc.backup-grpc-address-block-range" ) // EVM flags diff --git a/server/start.go b/server/start.go index f8b2305006..cadd8e7e72 100644 --- a/server/start.go +++ b/server/start.go @@ -485,10 +485,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty clientCtx = clientCtx.WithGRPCClient(grpcClient) ctx.Logger.Debug("gRPC client assigned to client context", "address", grpcAddress) - // TODO: Config backup GRPCClient - grpcBlockAddresses := map[[2]int]string{ - {0, int(config.JSONRPC.DeprecateMigrateHeight)}: "0.0.0.0:26664", - } + grpcBlockAddresses := config.JSONRPC.BackupGRPCBlockAddressBlockRange for k, address := range grpcBlockAddresses { grpcAddr, err := parseGrpcAddress(address) if err != nil { diff --git a/tests/integration_tests/configs/backup.jsonnet b/tests/integration_tests/configs/backup.jsonnet index 6e1558112e..e7616950d4 100644 --- a/tests/integration_tests/configs/backup.jsonnet +++ b/tests/integration_tests/configs/backup.jsonnet @@ -3,7 +3,11 @@ local config = import 'main.jsonnet'; config { 'ethermint_9000-1'+: { 'app-config'+: { - 'backup-grpc-address': '0.0.0.0:26754', + 'json-rpc'+: { + 'backup-grpc-address-block-range': { + '0.0.0.0:26754': [0, 10], + }, + }, }, }, } diff --git a/tests/integration_tests/configs/default.jsonnet b/tests/integration_tests/configs/default.jsonnet index 16b9f05ba9..349be756f4 100644 --- a/tests/integration_tests/configs/default.jsonnet +++ b/tests/integration_tests/configs/default.jsonnet @@ -20,7 +20,6 @@ 'block-range-cap': 10000, 'logs-cap': 10000, 'fix-revert-gas-refund-height': 1, - 'deprecate-migrate-height': 1, }, }, validators: [{ From 87349ec19c72875939d51fcfe86830f1205cef6c Mon Sep 17 00:00:00 2001 From: mmsqe Date: Sat, 14 Jan 2023 09:24:38 +0800 Subject: [PATCH 08/29] cant use var as key in toml --- server/config/config.go | 11 +---- server/config/toml.go | 2 + server/start.go | 43 ++++++++++++++++--- .../integration_tests/configs/backup.jsonnet | 6 +-- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/server/config/config.go b/server/config/config.go index 35610ac34c..3b220c4824 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -139,7 +139,7 @@ type JSONRPCConfig struct { // FixRevertGasRefundHeight defines the upgrade height for fix of revert gas refund logic when transaction reverted FixRevertGasRefundHeight int64 `mapstructure:"fix-revert-gas-refund-height"` // Deprecate height for usage of x/params. - BackupGRPCBlockAddressBlockRange map[[2]int]string `mapstructure:"backup-grpc-address-block-range"` + BackupGRPCBlockAddressBlockRange []string `mapstructure:"backup-grpc-address-block-range"` } // TLSConfig defines the certificate and matching private key for the server. @@ -328,13 +328,6 @@ func GetConfig(v *viper.Viper) (Config, error) { if err != nil { return Config{}, err } - - backupGRPCBlockAddressBlockRange := make(map[[2]int]string) - for addr, val := range v.GetStringMap("json-rpc.backup-grpc-address-block-range") { - blocks := val.([]int) - lower, upper := blocks[0], blocks[1] - backupGRPCBlockAddressBlockRange[[2]int{lower, upper}] = addr - } return Config{ Config: cfg, EVM: EVMConfig{ @@ -359,7 +352,7 @@ func GetConfig(v *viper.Viper) (Config, error) { EnableIndexer: v.GetBool("json-rpc.enable-indexer"), MetricsAddress: v.GetString("json-rpc.metrics-address"), FixRevertGasRefundHeight: v.GetInt64("json-rpc.fix-revert-gas-refund-height"), - BackupGRPCBlockAddressBlockRange: backupGRPCBlockAddressBlockRange, + BackupGRPCBlockAddressBlockRange: v.GetStringSlice("json-rpc.backup-grpc-address-block-range"), }, TLS: TLSConfig{ CertificatePath: v.GetString("tls.certificate-path"), diff --git a/server/config/toml.go b/server/config/toml.go index a61f110dc7..a2f0319193 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -37,6 +37,8 @@ max-tx-gas-wanted = {{ .EVM.MaxTxGasWanted }} [json-rpc] +backup-grpc-address-block-range = "{{range $index, $elmt := .JSONRPC.BackupGRPCBlockAddressBlockRange}}{{if $index}},{{$elmt}}{{else}}{{$elmt}}{{end}}{{end}}" + # Enable defines if the gRPC server should be enabled. enable = {{ .JSONRPC.Enable }} diff --git a/server/start.go b/server/start.go index cadd8e7e72..d8f5b49d24 100644 --- a/server/start.go +++ b/server/start.go @@ -17,6 +17,7 @@ package server import ( "context" + "errors" "fmt" "io" "net" @@ -24,6 +25,8 @@ import ( "os" "path/filepath" "runtime/pprof" + "strconv" + "strings" "time" "github.com/cosmos/cosmos-sdk/codec" @@ -276,6 +279,33 @@ func parseGrpcAddress(address string) (string, error) { return fmt.Sprintf("127.0.0.1:%s", port), nil } +func parseBackupGRPCAddressWithRange(raw string) (addr string, r [2]int, err error) { + list := strings.Split(raw, ",") + if len(list) != 3 { + err = errors.New("invalid length") + return + } + addr, err = parseGrpcAddress(list[0]) + if err != nil { + return + } + var start, end int + start, err = strconv.Atoi(list[1]) + if err != nil { + return + } + end, err = strconv.Atoi(list[2]) + if err != nil { + return + } + if start >= end { + err = fmt.Errorf("invalid start: %d and end: %d", start, end) + return + } + r = [2]int{start, end} + return +} + // legacyAminoCdc is used for the legacy REST API func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator types.AppCreator) (err error) { cfg := ctx.Config @@ -485,14 +515,17 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty clientCtx = clientCtx.WithGRPCClient(grpcClient) ctx.Logger.Debug("gRPC client assigned to client context", "address", grpcAddress) - grpcBlockAddresses := config.JSONRPC.BackupGRPCBlockAddressBlockRange - for k, address := range grpcBlockAddresses { - grpcAddr, err := parseGrpcAddress(address) + for _, value := range config.JSONRPC.BackupGRPCBlockAddressBlockRange { + addr, r, err := parseBackupGRPCAddressWithRange(value) + if err != nil { + return err + } + if err != nil { return err } c, err := grpc.Dial( - grpcAddr, + addr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions( grpc.ForceCodec(codec.NewProtoCodec(clientCtx.InterfaceRegistry).GRPCCodec()), @@ -503,7 +536,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty if err != nil { return err } - backupGRPCClientConns[k] = c + backupGRPCClientConns[r] = c } } } diff --git a/tests/integration_tests/configs/backup.jsonnet b/tests/integration_tests/configs/backup.jsonnet index e7616950d4..d8081cae96 100644 --- a/tests/integration_tests/configs/backup.jsonnet +++ b/tests/integration_tests/configs/backup.jsonnet @@ -4,9 +4,9 @@ config { 'ethermint_9000-1'+: { 'app-config'+: { 'json-rpc'+: { - 'backup-grpc-address-block-range': { - '0.0.0.0:26754': [0, 10], - }, + 'backup-grpc-address-block-range': [ + '0.0.0.0:26754,0,10', + ], }, }, }, From ce340afd7581ebd829d8d314f8c7eb1eba2a671e Mon Sep 17 00:00:00 2001 From: mmsqe Date: Mon, 16 Jan 2023 09:34:30 +0800 Subject: [PATCH 09/29] revert keep grpc query compatible with version before feemarket migrate --- app/app.go | 5 ++--- x/feemarket/keeper/keeper.go | 6 +----- x/feemarket/keeper/params.go | 4 +--- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/app/app.go b/app/app.go index 0f8d6d10a0..161c21270b 100644 --- a/app/app.go +++ b/app/app.go @@ -412,10 +412,9 @@ func NewEthermintApp( tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer)) // Create Ethermint keepers - feeMarketSs := app.GetSubspace(feemarkettypes.ModuleName) app.FeeMarketKeeper = feemarketkeeper.NewKeeper( appCodec, authtypes.NewModuleAddress(govtypes.ModuleName), - keys[feemarkettypes.StoreKey], tkeys[feemarkettypes.TransientKey], feeMarketSs, + keys[feemarkettypes.StoreKey], tkeys[feemarkettypes.TransientKey], ) // Set authority to x/gov module account to only expect the module account to update params @@ -508,7 +507,7 @@ func NewEthermintApp( ibc.NewAppModule(app.IBCKeeper), transferModule, // Ethermint app modules - feemarket.NewAppModule(app.FeeMarketKeeper, feeMarketSs), + feemarket.NewAppModule(app.FeeMarketKeeper, app.GetSubspace(feemarkettypes.ModuleName)), evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, app.GetSubspace(evmtypes.ModuleName)), ) diff --git a/x/feemarket/keeper/keeper.go b/x/feemarket/keeper/keeper.go index 3d702a545c..466e4b418a 100644 --- a/x/feemarket/keeper/keeper.go +++ b/x/feemarket/keeper/keeper.go @@ -21,7 +21,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/tendermint/tendermint/libs/log" "github.com/evmos/ethermint/x/feemarket/types" @@ -39,13 +38,11 @@ type Keeper struct { transientKey storetypes.StoreKey // the address capable of executing a MsgUpdateParams message. Typically, this should be the x/gov module account. authority sdk.AccAddress - // Legacy subspace - ss paramstypes.Subspace } // NewKeeper generates new fee market module keeper func NewKeeper( - cdc codec.BinaryCodec, authority sdk.AccAddress, storeKey, transientKey storetypes.StoreKey, ss paramstypes.Subspace, + cdc codec.BinaryCodec, authority sdk.AccAddress, storeKey, transientKey storetypes.StoreKey, ) Keeper { // ensure authority account is correctly formatted if err := sdk.VerifyAddressFormat(authority); err != nil { @@ -57,7 +54,6 @@ func NewKeeper( storeKey: storeKey, authority: authority, transientKey: transientKey, - ss: ss, } } diff --git a/x/feemarket/keeper/params.go b/x/feemarket/keeper/params.go index f8a1f3744f..4508e5f442 100644 --- a/x/feemarket/keeper/params.go +++ b/x/feemarket/keeper/params.go @@ -28,9 +28,7 @@ func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ParamsKey) if len(bz) == 0 { - var p types.Params - k.ss.GetParamSetIfExists(ctx, &p) - return p + return params } k.cdc.MustUnmarshal(bz, ¶ms) From 6b1089d3e5b36ca99c0a1dffc17112238688c24a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Mon, 16 Jan 2023 09:42:32 +0800 Subject: [PATCH 10/29] fix config --- server/config/config.go | 55 +++++---- server/config/toml.go | 10 +- server/start.go | 45 ++----- .../integration_tests/configs/backup.jsonnet | 13 -- .../integration_tests/configs/default.jsonnet | 2 +- tests/integration_tests/configs/main.jsonnet | 9 -- tests/integration_tests/test_backup_grpc.py | 112 ------------------ tests/integration_tests/test_upgrade.py | 80 +++++++++++-- 8 files changed, 119 insertions(+), 207 deletions(-) delete mode 100644 tests/integration_tests/configs/backup.jsonnet delete mode 100644 tests/integration_tests/configs/main.jsonnet delete mode 100644 tests/integration_tests/test_backup_grpc.py diff --git a/server/config/config.go b/server/config/config.go index 3b220c4824..2fa601411f 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -16,6 +16,7 @@ package config import ( + "encoding/json" "errors" "fmt" "path" @@ -139,7 +140,7 @@ type JSONRPCConfig struct { // FixRevertGasRefundHeight defines the upgrade height for fix of revert gas refund logic when transaction reverted FixRevertGasRefundHeight int64 `mapstructure:"fix-revert-gas-refund-height"` // Deprecate height for usage of x/params. - BackupGRPCBlockAddressBlockRange []string `mapstructure:"backup-grpc-address-block-range"` + BackupGRPCBlockAddressBlockRange map[[2]int]string `mapstructure:"backup-grpc-address-block-range"` } // TLSConfig defines the certificate and matching private key for the server. @@ -225,24 +226,25 @@ func GetAPINamespaces() []string { // DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default func DefaultJSONRPCConfig() *JSONRPCConfig { return &JSONRPCConfig{ - Enable: true, - API: GetDefaultAPINamespaces(), - Address: DefaultJSONRPCAddress, - WsAddress: DefaultJSONRPCWsAddress, - GasCap: DefaultGasCap, - EVMTimeout: DefaultEVMTimeout, - TxFeeCap: DefaultTxFeeCap, - FilterCap: DefaultFilterCap, - FeeHistoryCap: DefaultFeeHistoryCap, - BlockRangeCap: DefaultBlockRangeCap, - LogsCap: DefaultLogsCap, - HTTPTimeout: DefaultHTTPTimeout, - HTTPIdleTimeout: DefaultHTTPIdleTimeout, - AllowUnprotectedTxs: DefaultAllowUnprotectedTxs, - MaxOpenConnections: DefaultMaxOpenConnections, - EnableIndexer: false, - MetricsAddress: DefaultJSONRPCMetricsAddress, - FixRevertGasRefundHeight: DefaultFixRevertGasRefundHeight, + Enable: true, + API: GetDefaultAPINamespaces(), + Address: DefaultJSONRPCAddress, + WsAddress: DefaultJSONRPCWsAddress, + GasCap: DefaultGasCap, + EVMTimeout: DefaultEVMTimeout, + TxFeeCap: DefaultTxFeeCap, + FilterCap: DefaultFilterCap, + FeeHistoryCap: DefaultFeeHistoryCap, + BlockRangeCap: DefaultBlockRangeCap, + LogsCap: DefaultLogsCap, + HTTPTimeout: DefaultHTTPTimeout, + HTTPIdleTimeout: DefaultHTTPIdleTimeout, + AllowUnprotectedTxs: DefaultAllowUnprotectedTxs, + MaxOpenConnections: DefaultMaxOpenConnections, + EnableIndexer: false, + MetricsAddress: DefaultJSONRPCMetricsAddress, + FixRevertGasRefundHeight: DefaultFixRevertGasRefundHeight, + BackupGRPCBlockAddressBlockRange: make(map[[2]int]string), } } @@ -328,6 +330,19 @@ func GetConfig(v *viper.Viper) (Config, error) { if err != nil { return Config{}, err } + + data := make(map[string][2]int) + raw := v.GetString("json-rpc.backup-grpc-address-block-range") + if len(raw) > 0 { + err = json.Unmarshal([]byte(raw), &data) + if err != nil { + return Config{}, err + } + } + backupGRPCBlockAddressBlockRange := make(map[[2]int]string) + for k, v := range data { + backupGRPCBlockAddressBlockRange[v] = k + } return Config{ Config: cfg, EVM: EVMConfig{ @@ -352,7 +367,7 @@ func GetConfig(v *viper.Viper) (Config, error) { EnableIndexer: v.GetBool("json-rpc.enable-indexer"), MetricsAddress: v.GetString("json-rpc.metrics-address"), FixRevertGasRefundHeight: v.GetInt64("json-rpc.fix-revert-gas-refund-height"), - BackupGRPCBlockAddressBlockRange: v.GetStringSlice("json-rpc.backup-grpc-address-block-range"), + BackupGRPCBlockAddressBlockRange: backupGRPCBlockAddressBlockRange, }, TLS: TLSConfig{ CertificatePath: v.GetString("tls.certificate-path"), diff --git a/server/config/toml.go b/server/config/toml.go index a2f0319193..6172fcfdee 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -37,8 +37,6 @@ max-tx-gas-wanted = {{ .EVM.MaxTxGasWanted }} [json-rpc] -backup-grpc-address-block-range = "{{range $index, $elmt := .JSONRPC.BackupGRPCBlockAddressBlockRange}}{{if $index}},{{$elmt}}{{else}}{{$elmt}}{{end}}{{end}}" - # Enable defines if the gRPC server should be enabled. enable = {{ .JSONRPC.Enable }} @@ -94,8 +92,12 @@ enable-indexer = {{ .JSONRPC.EnableIndexer }} # Prometheus metrics path: /debug/metrics/prometheus metrics-address = "{{ .JSONRPC.MetricsAddress }}" -# Upgrade height for fix of revert gas refund logic when transaction reverted. -fix-revert-gas-refund-height = {{ .JSONRPC.FixRevertGasRefundHeight }} +# A list of grpc address with block range +# Example: "0.0.0.0:26113" = [0, 20] +[json-rpc.backup-grpc-address-block-range] +{{ range $k, $v := .JSONRPC.BackupGRPCBlockAddressBlockRange }} +"{{ $v }}" = [{{index $k 0 }}, {{ index $k 1}}] +{{ end }} ############################################################################### ### TLS Configuration ### diff --git a/server/start.go b/server/start.go index d8f5b49d24..a9b21761d4 100644 --- a/server/start.go +++ b/server/start.go @@ -17,7 +17,6 @@ package server import ( "context" - "errors" "fmt" "io" "net" @@ -25,8 +24,6 @@ import ( "os" "path/filepath" "runtime/pprof" - "strconv" - "strings" "time" "github.com/cosmos/cosmos-sdk/codec" @@ -194,6 +191,7 @@ which accepts a path for the resulting pprof file. cmd.Flags().Int(srvflags.JSONRPCMaxOpenConnections, config.DefaultMaxOpenConnections, "Sets the maximum number of simultaneous connections for the server listener") //nolint:lll cmd.Flags().Bool(srvflags.JSONRPCEnableIndexer, false, "Enable the custom tx indexer for json-rpc") cmd.Flags().Bool(srvflags.JSONRPCEnableMetrics, false, "Define if EVM rpc metrics server should be enabled") + cmd.Flags().String(srvflags.JSONRPCBackupGRPCBlockAddressBlockRange, "", "Define if backup grpc and block range is available") cmd.Flags().String(srvflags.EVMTracer, config.DefaultEVMTracer, "the EVM tracer type to collect execution traces from the EVM transaction execution (json|struct|access_list|markdown)") //nolint:lll cmd.Flags().Uint64(srvflags.EVMMaxTxGasWanted, config.DefaultMaxTxGasWanted, "the gas wanted for each eth tx returned in ante handler in check tx mode") //nolint:lll @@ -279,33 +277,6 @@ func parseGrpcAddress(address string) (string, error) { return fmt.Sprintf("127.0.0.1:%s", port), nil } -func parseBackupGRPCAddressWithRange(raw string) (addr string, r [2]int, err error) { - list := strings.Split(raw, ",") - if len(list) != 3 { - err = errors.New("invalid length") - return - } - addr, err = parseGrpcAddress(list[0]) - if err != nil { - return - } - var start, end int - start, err = strconv.Atoi(list[1]) - if err != nil { - return - } - end, err = strconv.Atoi(list[2]) - if err != nil { - return - } - if start >= end { - err = fmt.Errorf("invalid start: %d and end: %d", start, end) - return - } - r = [2]int{start, end} - return -} - // legacyAminoCdc is used for the legacy REST API func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator types.AppCreator) (err error) { cfg := ctx.Config @@ -515,17 +486,15 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty clientCtx = clientCtx.WithGRPCClient(grpcClient) ctx.Logger.Debug("gRPC client assigned to client context", "address", grpcAddress) - for _, value := range config.JSONRPC.BackupGRPCBlockAddressBlockRange { - addr, r, err := parseBackupGRPCAddressWithRange(value) - if err != nil { - return err - } - + grpcBlockAddresses := config.JSONRPC.BackupGRPCBlockAddressBlockRange + fmt.Printf("mm-grpcBlockAddresses: %+v\n", grpcBlockAddresses) + for k, address := range grpcBlockAddresses { + grpcAddr, err := parseGrpcAddress(address) if err != nil { return err } c, err := grpc.Dial( - addr, + grpcAddr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions( grpc.ForceCodec(codec.NewProtoCodec(clientCtx.InterfaceRegistry).GRPCCodec()), @@ -536,7 +505,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty if err != nil { return err } - backupGRPCClientConns[r] = c + backupGRPCClientConns[k] = c } } } diff --git a/tests/integration_tests/configs/backup.jsonnet b/tests/integration_tests/configs/backup.jsonnet deleted file mode 100644 index d8081cae96..0000000000 --- a/tests/integration_tests/configs/backup.jsonnet +++ /dev/null @@ -1,13 +0,0 @@ -local config = import 'main.jsonnet'; - -config { - 'ethermint_9000-1'+: { - 'app-config'+: { - 'json-rpc'+: { - 'backup-grpc-address-block-range': [ - '0.0.0.0:26754,0,10', - ], - }, - }, - }, -} diff --git a/tests/integration_tests/configs/default.jsonnet b/tests/integration_tests/configs/default.jsonnet index 349be756f4..0b0467f3ee 100644 --- a/tests/integration_tests/configs/default.jsonnet +++ b/tests/integration_tests/configs/default.jsonnet @@ -19,7 +19,7 @@ 'feehistory-cap': 100, 'block-range-cap': 10000, 'logs-cap': 10000, - 'fix-revert-gas-refund-height': 1, + 'backup-grpc-address-block-range': '', //'{{"0.0.0.0:26113": [0, 20]}}', }, }, validators: [{ diff --git a/tests/integration_tests/configs/main.jsonnet b/tests/integration_tests/configs/main.jsonnet deleted file mode 100644 index bf3a1b3bd7..0000000000 --- a/tests/integration_tests/configs/main.jsonnet +++ /dev/null @@ -1,9 +0,0 @@ -local config = import 'default.jsonnet'; - -config { - 'ethermint_9000-1'+: { - 'app-config'+: { - 'minimum-gas-prices': '100000000000aphoton', - }, - }, -} diff --git a/tests/integration_tests/test_backup_grpc.py b/tests/integration_tests/test_backup_grpc.py deleted file mode 100644 index 3da0453dc9..0000000000 --- a/tests/integration_tests/test_backup_grpc.py +++ /dev/null @@ -1,112 +0,0 @@ -import os -import signal -import subprocess -from pathlib import Path -from typing import NamedTuple - -import pytest -import requests -from pystarport import ports - -from .network import Ethermint -from .utils import ADDRS, wait_for_fn, wait_for_port - - -class Network(NamedTuple): - main: Ethermint - backup: Ethermint - - -def exec(config, path, base_port): - cmd = [ - "pystarport", - "init", - "--config", - config, - "--data", - path, - "--base_port", - str(base_port), - "--no_remove", - ] - print(*cmd) - subprocess.run(cmd, check=True) - return subprocess.Popen( - ["pystarport", "start", "--data", path, "--quiet"], - preexec_fn=os.setsid, - ) - - -@pytest.fixture(scope="module") -def network(tmp_path_factory): - chain_id = "ethermint_9000-1" - base = Path(__file__).parent / "configs" - - # backup - path0 = tmp_path_factory.mktemp("ethermint-backup") - base_port0 = 26770 - procs = [exec(base / "backup.jsonnet", path0, base_port0)] - - wait_for_port(base_port0) - - # main - path1 = tmp_path_factory.mktemp("ethermint-main") - base_port1 = 26750 - procs.append(exec(base / "main.jsonnet", path1, base_port1)) - - try: - wait_for_port(ports.evmrpc_port(base_port0)) - wait_for_port(ports.evmrpc_ws_port(base_port0)) - wait_for_port(ports.grpc_port(base_port1)) - yield Network(Ethermint(path0 / chain_id), Ethermint(path1 / chain_id)) - finally: - for proc in procs: - os.killpg(os.getpgid(proc.pid), signal.SIGTERM) - proc.wait() - print("killed:", proc.pid) - - -def grpc_call(p, address): - url = f"http://127.0.0.1:{p}/cosmos/bank/v1beta1/balances/{address}" - response = requests.get(url) - if not response.ok: - # retry until file get synced - return -1 - # raise Exception( - # f"response code: {response.status_code}, " - # f"{response.reason}, {response.json()}" - # ) - result = response.json() - if result.get("code"): - raise Exception(result["raw_log"]) - return result["balances"] - - -def test_basic(network): - pw3 = network.main.w3 - pcli = network.main.cosmos_cli() - validator = pcli.address("validator") - community = pcli.address("community") - print("address: ", validator, community) - backup_grpc_port = ports.api_port(network.backup.base_port(0)) - - def check_balances(): - mbalances = [pcli.balances(community), pcli.balances(validator)] - bbalances = [ - grpc_call(backup_grpc_port, community), - grpc_call(backup_grpc_port, validator), - ] - print("main", mbalances) - print("backup", bbalances) - return mbalances == bbalances - - txhash = pw3.eth.send_transaction( - { - "from": ADDRS["validator"], - "to": ADDRS["community"], - "value": 1000, - } - ) - receipt = pw3.eth.wait_for_transaction_receipt(txhash) - assert receipt.status == 1 - wait_for_fn("cross-check-balances", check_balances) diff --git a/tests/integration_tests/test_upgrade.py b/tests/integration_tests/test_upgrade.py index 566f41e3d6..3639cd6620 100644 --- a/tests/integration_tests/test_upgrade.py +++ b/tests/integration_tests/test_upgrade.py @@ -16,6 +16,7 @@ deploy_contract, parse_events, send_transaction, + supervisorctl, wait_for_block, wait_for_block_time, wait_for_port, @@ -94,11 +95,12 @@ def test_cosmovisor_upgrade(custom_ethermint: Ethermint): cli = custom_ethermint.cosmos_cli() w3 = custom_ethermint.w3 + validator = ADDRS["validator"] contract, _ = deploy_contract(w3, CONTRACTS["TestERC20A"]) old_height = w3.eth.block_number - old_balance = w3.eth.get_balance(ADDRS["validator"], block_identifier=old_height) + old_balance = w3.eth.get_balance(validator, block_identifier=old_height) old_base_fee = w3.eth.get_block(old_height).baseFeePerGas - old_erc20_balance = contract.caller.balanceOf(ADDRS["validator"]) + old_erc20_balance = contract.caller.balanceOf(validator) print("old values", old_height, old_balance, old_base_fee) target_height = w3.eth.block_number + 10 @@ -160,13 +162,71 @@ def test_cosmovisor_upgrade(custom_ethermint: Ethermint): ) assert receipt.status == 1 - # check json-rpc query on older blocks works - assert old_balance == w3.eth.get_balance( - ADDRS["validator"], block_identifier=old_height + # check get_balance and eth_call don't work on pruned state + with pytest.raises(Exception): + w3.eth.get_balance( + validator, block_identifier=old_height + ) + + base_dir = custom_ethermint.base_dir + for i in [0, 1]: + supervisorctl( + base_dir / "../tasks.ini", "stop", f"ethermint_9000-1-node{i}" + ) + + procs = [] + + def append_proc(log, cmd): + with (base_dir / log).open("a") as logfile: + procs.append(subprocess.Popen( + cmd, + stdout=logfile, + stderr=subprocess.STDOUT, + )) + + path = Path(custom_ethermint.chain_binary).parent.parent.parent + append_proc( + "node1.log", + [ + f"{str(path)}/genesis/bin/ethermintd", + "start", + "--home", + base_dir / "node1", + ], + ) + grpc_port1 = ports.grpc_port(custom_ethermint.base_port(1)) + append_proc( + "node0.log", + [ + f"{str(path)}/{plan_name}/bin/ethermintd", + "start", + "--json-rpc.backup-grpc-address-block-range", + f"{{\"0.0.0.0:{grpc_port1}\": [0, {target_height}]}}", + "--home", + base_dir / "node0", + ], ) - assert old_base_fee == w3.eth.get_block(old_height).baseFeePerGas - # check eth_call on older blocks works - assert old_erc20_balance == contract.caller( - block_identifier=target_height - 2 - ).balanceOf(ADDRS["validator"]) + try: + for i in [0, 1]: + wait_for_port(ports.evmrpc_port(custom_ethermint.base_port(i))) + + # check json-rpc query on older blocks works + assert old_balance == w3.eth.get_balance( + validator, block_identifier=old_height + ) + assert receipt.status == 1 + assert old_balance == w3.eth.get_balance( + validator, block_identifier=old_height + ) + assert old_base_fee == w3.eth.get_block(old_height).baseFeePerGas + + # check eth_call on older blocks works + assert old_erc20_balance == contract.caller( + block_identifier=target_height - 2 + ).balanceOf(validator) + + finally: + for proc in procs: + proc.terminate() + proc.wait() From 87ea19ca44263b8d115bb78422bff44ad7a0f06a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Mon, 16 Jan 2023 09:45:10 +0800 Subject: [PATCH 11/29] support backup for eth_call --- rpc/backend/call_tx.go | 6 +++--- tests/integration_tests/configs/upgrade-test-package.nix | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rpc/backend/call_tx.go b/rpc/backend/call_tx.go index ada6187caf..bbafdb0bf2 100644 --- a/rpc/backend/call_tx.go +++ b/rpc/backend/call_tx.go @@ -366,7 +366,8 @@ func (b *Backend) DoCall( // From ContextWithHeight: if the provided height is 0, // it will return an empty context and the gRPC query will use // the latest block height for querying. - ctx := rpctypes.ContextWithHeight(blockNr.Int64()) + height := blockNr.Int64() + ctx := rpctypes.ContextWithHeight(height) timeout := b.RPCEVMTimeout() // Setup context so it may be canceled the call has completed @@ -381,8 +382,7 @@ func (b *Backend) DoCall( // Make sure the context is canceled when the call has completed // this makes sure resources are cleaned up. defer cancel() - // use latest queryClient to call - res, err := b.queryClient.EthCall(ctx, &req) + res, err := b.getGrpcClient(height).EthCall(ctx, &req) if err != nil { return nil, err } diff --git a/tests/integration_tests/configs/upgrade-test-package.nix b/tests/integration_tests/configs/upgrade-test-package.nix index 1863054dfb..75047be21c 100644 --- a/tests/integration_tests/configs/upgrade-test-package.nix +++ b/tests/integration_tests/configs/upgrade-test-package.nix @@ -1,9 +1,9 @@ let pkgs = import ../../../nix { }; - fetchEthermint = rev: builtins.fetchTarball "https://github.com/evmos/ethermint/archive/${rev}.tar.gz"; + fetchEthermint = rev: builtins.fetchTarball "https://github.com/mmsqe/ethermint/archive/${rev}.tar.gz"; released = pkgs.buildGo118Module rec { name = "ethermintd"; - src = fetchEthermint "d29cdad6e667f6089dfecbedd36bb8d3a2a7d025"; + src = fetchEthermint "0e4d41eef5f7983f84206b1bb07e88ed3a9cd44b"; subPackages = [ "cmd/ethermintd" ]; vendorSha256 = "sha256-cQAol54b6hNzsA4Q3MP9mTqFWM1MvR5uMPrYpaoj3SY="; doCheck = false; From 8bfaee0a18282459a53b197cbad23b8b0e89a506 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 17 Jan 2023 09:53:52 +0800 Subject: [PATCH 12/29] fix lint --- rpc/backend/tracing.go | 2 +- testutil/network/util.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/rpc/backend/tracing.go b/rpc/backend/tracing.go index d420e4acfe..2f9432cc87 100644 --- a/rpc/backend/tracing.go +++ b/rpc/backend/tracing.go @@ -31,7 +31,7 @@ func (b *Backend) getGrpcClient(height int64) *rpctypes.QueryClient { for blocks, client := range b.backupQueryClients { // b1-b2 -> g1 // b3-b4 -> g2 - if blocks[0] <= int(height) && blocks[1] >= int(height) { + if int64(blocks[0]) <= height && int64(blocks[1]) >= height { return client } } diff --git a/testutil/network/util.go b/testutil/network/util.go index 928e1b6912..709c397627 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -149,11 +149,12 @@ func startInProcess(cfg Config, val *Validator) error { gprcClients := map[[2]int]*grpc.ClientConn{ {0, 1}: val.ClientCtx.GRPCClient, } - val.jsonrpc, val.jsonrpcDone, err = server.StartJSONRPC(val.Ctx, val.ClientCtx, gprcClients, tmRPCAddr, tmEndpoint, val.AppConfig, nil) + jsonrpc, jsonrpcDone, err := server.StartJSONRPC(val.Ctx, val.ClientCtx, gprcClients, tmRPCAddr, tmEndpoint, val.AppConfig, nil) if err != nil { return err } - + val.jsonrpc = jsonrpc + val.jsonrpcDone = jsonrpcDone address := fmt.Sprintf("http://%s", val.AppConfig.JSONRPC.Address) val.JSONRPCClient, err = ethclient.Dial(address) From 163f4e2f1a4a10ba815cfdbb891cd8a7d99cc8d5 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 17 Jan 2023 09:53:59 +0800 Subject: [PATCH 13/29] fix test --- rpc/backend/backend_suite_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rpc/backend/backend_suite_test.go b/rpc/backend/backend_suite_test.go index 66320f27e5..882ba825d3 100644 --- a/rpc/backend/backend_suite_test.go +++ b/rpc/backend/backend_suite_test.go @@ -27,6 +27,7 @@ import ( rpctypes "github.com/evmos/ethermint/rpc/types" "github.com/evmos/ethermint/tests" evmtypes "github.com/evmos/ethermint/x/evm/types" + "google.golang.org/grpc" ) type BackendTestSuite struct { @@ -79,7 +80,7 @@ func (suite *BackendTestSuite) SetupTest() { allowUnprotectedTxs := false idxer := indexer.NewKVIndexer(dbm.NewMemDB(), ctx.Logger, clientCtx) - suite.backend = NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, idxer) + suite.backend = NewBackend(ctx, ctx.Logger, clientCtx, make(map[[2]int]*grpc.ClientConn), allowUnprotectedTxs, idxer) suite.backend.queryClient.QueryClient = mocks.NewEVMQueryClient(suite.T()) suite.backend.clientCtx.Client = mocks.NewClient(suite.T()) suite.backend.queryClient.FeeMarket = mocks.NewFeeMarketQueryClient(suite.T()) From 734c9a1c8e937339c809be8d074ab449a806a69a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 17 Jan 2023 09:54:04 +0800 Subject: [PATCH 14/29] update change doc --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 016284bd55..bca7229b8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## Unreleased +### Features + +* (rpc) [#1603](https://github.com/evmos/ethermint/pull/1603) Support multi gRPC query clients serve with old binary. + ## [v0.21.0-rc1] - 2022-1-13 ### State Machine Breaking From 3befbb2d14f2ceefad75c183b902498817d1643c Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 17 Jan 2023 12:07:04 +0800 Subject: [PATCH 15/29] fix lint --- rpc/apis.go | 27 +++++++++++++++++++--- tests/integration_tests/test_upgrade.py | 30 ++++++++++--------------- tests/integration_tests/utils.py | 11 --------- 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/rpc/apis.go b/rpc/apis.go index dae7114a75..3c3fe4e7c6 100644 --- a/rpc/apis.go +++ b/rpc/apis.go @@ -95,7 +95,14 @@ func init() { }, } }, - Web3Namespace: func(*server.Context, client.Context, map[[2]int]*grpc.ClientConn, *rpcclient.WSClient, bool, ethermint.EVMTxIndexer) []rpc.API { + Web3Namespace: func( + *server.Context, + client.Context, + map[[2]int]*grpc.ClientConn, + *rpcclient.WSClient, + bool, + ethermint.EVMTxIndexer, + ) []rpc.API { return []rpc.API{ { Namespace: Web3Namespace, @@ -105,7 +112,14 @@ func init() { }, } }, - NetNamespace: func(_ *server.Context, clientCtx client.Context, _ map[[2]int]*grpc.ClientConn, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { + NetNamespace: func( + _ *server.Context, + clientCtx client.Context, + _ map[[2]int]*grpc.ClientConn, + _ *rpcclient.WSClient, + _ bool, + _ ethermint.EVMTxIndexer, + ) []rpc.API { return []rpc.API{ { Namespace: NetNamespace, @@ -132,7 +146,14 @@ func init() { }, } }, - TxPoolNamespace: func(ctx *server.Context, _ client.Context, _ map[[2]int]*grpc.ClientConn, _ *rpcclient.WSClient, _ bool, _ ethermint.EVMTxIndexer) []rpc.API { + TxPoolNamespace: func( + ctx *server.Context, + _ client.Context, + _ map[[2]int]*grpc.ClientConn, + _ *rpcclient.WSClient, + _ bool, + _ ethermint.EVMTxIndexer, + ) []rpc.API { return []rpc.API{ { Namespace: TxPoolNamespace, diff --git a/tests/integration_tests/test_upgrade.py b/tests/integration_tests/test_upgrade.py index 3639cd6620..7b2a241385 100644 --- a/tests/integration_tests/test_upgrade.py +++ b/tests/integration_tests/test_upgrade.py @@ -164,25 +164,23 @@ def test_cosmovisor_upgrade(custom_ethermint: Ethermint): # check get_balance and eth_call don't work on pruned state with pytest.raises(Exception): - w3.eth.get_balance( - validator, block_identifier=old_height - ) + w3.eth.get_balance(validator, block_identifier=old_height) base_dir = custom_ethermint.base_dir for i in [0, 1]: - supervisorctl( - base_dir / "../tasks.ini", "stop", f"ethermint_9000-1-node{i}" - ) + supervisorctl(base_dir / "../tasks.ini", "stop", f"ethermint_9000-1-node{i}") procs = [] def append_proc(log, cmd): with (base_dir / log).open("a") as logfile: - procs.append(subprocess.Popen( - cmd, - stdout=logfile, - stderr=subprocess.STDOUT, - )) + procs.append( + subprocess.Popen( + cmd, + stdout=logfile, + stderr=subprocess.STDOUT, + ) + ) path = Path(custom_ethermint.chain_binary).parent.parent.parent append_proc( @@ -201,7 +199,7 @@ def append_proc(log, cmd): f"{str(path)}/{plan_name}/bin/ethermintd", "start", "--json-rpc.backup-grpc-address-block-range", - f"{{\"0.0.0.0:{grpc_port1}\": [0, {target_height}]}}", + f'{{"0.0.0.0:{grpc_port1}": [0, {target_height}]}}', "--home", base_dir / "node0", ], @@ -212,13 +210,9 @@ def append_proc(log, cmd): wait_for_port(ports.evmrpc_port(custom_ethermint.base_port(i))) # check json-rpc query on older blocks works - assert old_balance == w3.eth.get_balance( - validator, block_identifier=old_height - ) + assert old_balance == w3.eth.get_balance(validator, block_identifier=old_height) assert receipt.status == 1 - assert old_balance == w3.eth.get_balance( - validator, block_identifier=old_height - ) + assert old_balance == w3.eth.get_balance(validator, block_identifier=old_height) assert old_base_fee == w3.eth.get_block(old_height).baseFeePerGas # check eth_call on older blocks works diff --git a/tests/integration_tests/utils.py b/tests/integration_tests/utils.py index 4ae900e267..ce28e9c4c9 100644 --- a/tests/integration_tests/utils.py +++ b/tests/integration_tests/utils.py @@ -123,17 +123,6 @@ def wait_for_block_time(cli, t): time.sleep(0.5) -def wait_for_fn(name, fn, *, timeout=240, interval=1): - for i in range(int(timeout / interval)): - result = fn() - print("check", name, result) - if result: - break - time.sleep(interval) - else: - raise TimeoutError(f"wait for {name} timeout") - - def deploy_contract(w3, jsonfile, args=(), key=KEYS["validator"]): """ deploy contract and return the deployed contract instance From d528df771c724a22f55a8bfc50e6cb41afbfd18b Mon Sep 17 00:00:00 2001 From: mmsqe Date: Mon, 30 Jan 2023 11:41:13 +0800 Subject: [PATCH 16/29] clean up --- server/config/config.go | 2 +- server/config/toml.go | 2 +- server/start.go | 1 - tests/integration_tests/test_upgrade.py | 2 -- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/server/config/config.go b/server/config/config.go index 1f57cbed7c..591b93e557 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -139,7 +139,7 @@ type JSONRPCConfig struct { MetricsAddress string `mapstructure:"metrics-address"` // FixRevertGasRefundHeight defines the upgrade height for fix of revert gas refund logic when transaction reverted FixRevertGasRefundHeight int64 `mapstructure:"fix-revert-gas-refund-height"` - // Deprecate height for usage of x/params. + // A list of grpc address with block range BackupGRPCBlockAddressBlockRange map[[2]int]string `mapstructure:"backup-grpc-address-block-range"` } diff --git a/server/config/toml.go b/server/config/toml.go index 6172fcfdee..802fdef343 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -92,7 +92,7 @@ enable-indexer = {{ .JSONRPC.EnableIndexer }} # Prometheus metrics path: /debug/metrics/prometheus metrics-address = "{{ .JSONRPC.MetricsAddress }}" -# A list of grpc address with block range +# A list of backup grpc address with block range # Example: "0.0.0.0:26113" = [0, 20] [json-rpc.backup-grpc-address-block-range] {{ range $k, $v := .JSONRPC.BackupGRPCBlockAddressBlockRange }} diff --git a/server/start.go b/server/start.go index a9b21761d4..db3368f956 100644 --- a/server/start.go +++ b/server/start.go @@ -487,7 +487,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty ctx.Logger.Debug("gRPC client assigned to client context", "address", grpcAddress) grpcBlockAddresses := config.JSONRPC.BackupGRPCBlockAddressBlockRange - fmt.Printf("mm-grpcBlockAddresses: %+v\n", grpcBlockAddresses) for k, address := range grpcBlockAddresses { grpcAddr, err := parseGrpcAddress(address) if err != nil { diff --git a/tests/integration_tests/test_upgrade.py b/tests/integration_tests/test_upgrade.py index 7b2a241385..323eb6fa12 100644 --- a/tests/integration_tests/test_upgrade.py +++ b/tests/integration_tests/test_upgrade.py @@ -211,8 +211,6 @@ def append_proc(log, cmd): # check json-rpc query on older blocks works assert old_balance == w3.eth.get_balance(validator, block_identifier=old_height) - assert receipt.status == 1 - assert old_balance == w3.eth.get_balance(validator, block_identifier=old_height) assert old_base_fee == w3.eth.get_block(old_height).baseFeePerGas # check eth_call on older blocks works From a2d71a078ab78f0368b98567a51ff9d051c2758e Mon Sep 17 00:00:00 2001 From: mmsqe Date: Mon, 30 Jan 2023 12:48:36 +0800 Subject: [PATCH 17/29] allow query evm params with old blk --- tests/integration_tests/cosmoscli.py | 12 ++++++++++++ tests/integration_tests/test_upgrade.py | 3 ++- x/evm/client/cli/query.go | 24 ++++++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/tests/integration_tests/cosmoscli.py b/tests/integration_tests/cosmoscli.py index 41c24c91e7..df477dd301 100644 --- a/tests/integration_tests/cosmoscli.py +++ b/tests/integration_tests/cosmoscli.py @@ -839,3 +839,15 @@ def rollback(self): def migrate_keystore(self): return self.raw("keys", "migrate", home=self.data_dir) + + def query_params(self, height: int): + "query evm params" + return json.loads( + self.raw( + "q", + "evm", + "params", + height, + home=self.data_dir, + ) + ) diff --git a/tests/integration_tests/test_upgrade.py b/tests/integration_tests/test_upgrade.py index 323eb6fa12..b37dba73bc 100644 --- a/tests/integration_tests/test_upgrade.py +++ b/tests/integration_tests/test_upgrade.py @@ -217,7 +217,8 @@ def append_proc(log, cmd): assert old_erc20_balance == contract.caller( block_identifier=target_height - 2 ).balanceOf(validator) - + # check we could fetch the right params before and after migration + assert cli.query_params(old_height) == cli.query_params(w3.eth.block_number - 1) finally: for proc in procs: proc.terminate() diff --git a/x/evm/client/cli/query.go b/x/evm/client/cli/query.go index bc3c6886b3..635c6dfa0a 100644 --- a/x/evm/client/cli/query.go +++ b/x/evm/client/cli/query.go @@ -16,6 +16,8 @@ package cli import ( + "strconv" + rpctypes "github.com/evmos/ethermint/rpc/types" "github.com/spf13/cobra" @@ -120,22 +122,28 @@ func GetCodeCmd() *cobra.Command { return cmd } -// GetParamsCmd queries the fee market params +// GetParamsCmd queries the evm params func GetParamsCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "params", - Short: "Get the evm params", - Long: "Get the evm parameter values.", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, _ []string) error { + Use: "params [height]", + Short: "Get the evm params associated with a specific blockheight", + Long: "Get the evm parameter values associated with a specific blockheight, 0 or negative means the latest blockheight.", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } - + height, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return err + } + if height <= 0 { + height = clientCtx.Height + } queryClient := types.NewQueryClient(clientCtx) - res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{}) + res, err := queryClient.Params(rpctypes.ContextWithHeight(height), &types.QueryParamsRequest{}) if err != nil { return err } From 8131baac33ee5f8e6f800a6fad847506cd791899 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:02:30 +0800 Subject: [PATCH 18/29] update nix --- gomod2nix.toml | 105 +++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/gomod2nix.toml b/gomod2nix.toml index 65ab566060..8e30973f14 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -2,11 +2,11 @@ schema = 3 [mod] [mod."cloud.google.com/go"] - version = "v0.105.0" - hash = "sha256-2nYtHjuN9ghGcM6aPlOxyNNarHebHtj0Xec48sWwdaI=" + version = "v0.107.0" + hash = "sha256-sb3SjuWj84ZUtIGYIioOmycfHLL0KZSYt/Y1zzfcd5M=" [mod."cloud.google.com/go/compute"] - version = "v1.14.0" - hash = "sha256-Ay0oTR0I/ROajIiBSuZ1LfVVio142f8mUa64tGwreG8=" + version = "v1.15.1" + hash = "sha256-F63wL70xdjxzFUKn8FEcBSI7FB94v1lo0f/aLDHiwMA=" [mod."cloud.google.com/go/compute/metadata"] version = "v0.2.3" hash = "sha256-kYB1FTQRdTDqCqJzSU/jJYbVUGyxbkASUKbEs36FUyU=" @@ -20,8 +20,8 @@ schema = 3 version = "v1.0.0-beta.7" hash = "sha256-XblGvIx6Wvvq6wggXjp+KbeJGXoe7AZH7hXEdauCezU=" [mod."cosmossdk.io/math"] - version = "v1.0.0-beta.4" - hash = "sha256-UYdq/46EubyjxkldGike8FlwJLWGCB576VB7th285ao=" + version = "v1.0.0-rc.0" + hash = "sha256-bQ2hxg1dwVxbyBzbdepCz8nFGx6dfr63syqDNQ8AFQc=" [mod."filippo.io/edwards25519"] version = "v1.0.0-rc.1" hash = "sha256-3DboBqby2ejRU33FG96Z8JF5AJ8HP2rC/v++VyoQ2LQ=" @@ -45,8 +45,8 @@ schema = 3 version = "v0.4.1" hash = "sha256-usxTUHA0QQMdM6sHi2z51nmnEKMbA0qUilxJFpWHlYE=" [mod."github.com/aws/aws-sdk-go"] - version = "v1.40.45" - hash = "sha256-7m4jOfXs356SUZG9tR+z3Yfa/O0CorkSkOXg/AmbqRM=" + version = "v1.44.122" + hash = "sha256-bzkXf4Sf+6y6on7iulGtXkPdj0XoevkHYGQYPTNL7To=" [mod."github.com/beorn7/perks"] version = "v1.0.1" hash = "sha256-h75GUqfwJKngCJQVE5Ao5wnO3cfKD9lSIteoLp/3xJ4=" @@ -75,8 +75,8 @@ schema = 3 version = "v1.1.0" hash = "sha256-nVDTtXH9PC3yJ0THaQZEN243UP9xgLi/clt5xRqj3+M=" [mod."github.com/cespare/xxhash/v2"] - version = "v2.1.2" - hash = "sha256-YV9SmXDtmmgQylQUfrUgQLAPfqYexcHxegMBT+IX9qM=" + version = "v2.2.0" + hash = "sha256-nPufwYQfTkyrEkbBrpqM3C2vnMxfIz6tAaBmiUP7vd4=" [mod."github.com/chzyer/readline"] version = "v0.0.0-20180603132655-2972be24d48e" hash = "sha256-2Uj5LGpHEbLQG3d/7z9AL8DknUBZyoTAMs4j+VVDmIA=" @@ -93,8 +93,8 @@ schema = 3 version = "v1.0.5" hash = "sha256-t572Sr5iiHcuMKLMWa2i+LBAt192oa+G1oA371tG/eI=" [mod."github.com/cosmos/cosmos-proto"] - version = "v1.0.0-beta.1" - hash = "sha256-oATkuj+fM5eBn+ywO+w/tL0AFSIEkx0J3Yz+VhVe0QA=" + version = "v1.0.0-beta.3" + hash = "sha256-V0/ZhRdqK7Cqcv8X30gr33/hlI54bRXeHhI9LZKyLt8=" [mod."github.com/cosmos/cosmos-sdk"] version = "v0.46.8" hash = "sha256-jETbixsZq5XJ1pl1XaVJvD5jkcygBrEcHRK/L0+XI68=" @@ -102,8 +102,8 @@ schema = 3 version = "v1.0.0" hash = "sha256-Qm2aC2vaS8tjtMUbHmlBSagOSqbduEEDwc51qvQaBmA=" [mod."github.com/cosmos/gogoproto"] - version = "v1.4.3" - hash = "sha256-Y/NL76ay/oAl8mS3skkK5ula0/xudqbwW1o22lZjKRg=" + version = "v1.4.6" + hash = "sha256-9SCEKBJyK1FHkKyeaBjDT3GURRAtsIoeiDkNwH8a9Co=" [mod."github.com/cosmos/gorocksdb"] version = "v1.2.0" hash = "sha256-209TcVuXc5s/TcOvNlaQ1HEJAUDTEK3nxPhs+d8TEcY=" @@ -189,8 +189,11 @@ schema = 3 version = "v2.1.3+incompatible" hash = "sha256-eXhXPPLnAy/rmt/zDgeqni2G3o58UtnHjR8vHLXvISI=" [mod."github.com/go-stack/stack"] - version = "v1.8.0" - hash = "sha256-26RlTEcAkbewMUtmirKrDGQ1WJlNousp69v7HMopYnI=" + version = "v1.8.1" + hash = "sha256-ixcJ2RrK1ZH3YWGQZF9QFBo02NOuLeSp9wJ7gniipgY=" + [mod."github.com/go-task/slim-sprig"] + version = "v0.0.0-20210107165309-348f09dbbbc0" + hash = "sha256-jgza4peLzeJlwmMh/c1gNkmtwA9YtSdGaBzBUDXhIZo=" [mod."github.com/godbus/dbus"] version = "v0.0.0-20190726142602-4481cbc300e2" hash = "sha256-R7Gb9+Zjy80FbQSDGketoVEqfdOQKuOVTfWRjQ5kxZY=" @@ -208,8 +211,8 @@ schema = 3 version = "v0.0.0-20210331224755-41bb18bfe9da" hash = "sha256-7Gs7CS9gEYZkbu5P4hqPGBpeGZWC64VDwraSKFF+VR0=" [mod."github.com/golang/protobuf"] - version = "v1.5.2" - hash = "sha256-IVwooaIo46iq7euSSVWTBAdKd+2DUaJ67MtBao1DpBI=" + version = "v1.5.3" + hash = "sha256-svogITcP4orUIsJFjMtp+Uv1+fKJv2Q5Zwf2dMqnpOQ=" [mod."github.com/golang/snappy"] version = "v0.0.4" hash = "sha256-Umx+5xHAQCN/Gi4HbtMhnDCSPFAXSsjVbXd8n5LhjAA=" @@ -222,6 +225,9 @@ schema = 3 [mod."github.com/google/orderedcode"] version = "v0.0.1" hash = "sha256-KrExYovtUQrHGI1mPQf57jGw8soz7eWOC2xqEaV0uGk=" + [mod."github.com/google/pprof"] + version = "v0.0.0-20210720184732-4bb14d4b1be1" + hash = "sha256-m6l2Yay3iCu7Ses6nmwXifyztNqfP1B/MX81/tDK4Hw=" [mod."github.com/google/uuid"] version = "v1.3.0" hash = "sha256-QoR55eBtA94T2tBszyxfDtO7/pjZZSGb5vm7U0Xhs0Y=" @@ -259,8 +265,8 @@ schema = 3 version = "v0.5.2" hash = "sha256-N9GOKYo7tK6XQUFhvhImtL7PZW/mr4C4Manx/yPVvcQ=" [mod."github.com/hashicorp/go-getter"] - version = "v1.6.1" - hash = "sha256-WPCbbfFbE617EIUXxq81p3XrvhkSvYOeuiaR7n23nr0=" + version = "v1.7.0" + hash = "sha256-kjXfacmxofi5mtyh9wpPeo3yBHNJMcTrfyEbYEAzLfs=" [mod."github.com/hashicorp/go-immutable-radix"] version = "v1.3.1" hash = "sha256-65+A2HiVfS/GV9G+6/TkXXjzXhI/V98e6RlJWjxy+mg=" @@ -346,8 +352,8 @@ schema = 3 version = "v1.1.0" hash = "sha256-oduBKXHAQG8X6aqLEpqZHs5DOKe84u6WkBwi4W6cv3k=" [mod."github.com/mitchellh/go-testing-interface"] - version = "v1.0.0" - hash = "sha256-/Dpv/4i5xuK8hDH+q8YTdF6Jg6NNtfO4Wqig2JCWgrY=" + version = "v1.14.1" + hash = "sha256-TMGi38D13BEVN5cpeKDzKRIgLclm4ErOG+JEyqJrN/c=" [mod."github.com/mitchellh/mapstructure"] version = "v1.5.0" hash = "sha256-ztVhGQXs67MF8UadVvG72G3ly0ypQW0IRDdOOkjYwoE=" @@ -358,11 +364,11 @@ schema = 3 version = "v0.0.5" hash = "sha256-/5i70IkH/qSW5KjGzv8aQNKh9tHoz98tqtL0K2DMFn4=" [mod."github.com/onsi/ginkgo/v2"] - version = "v2.7.0" - hash = "sha256-BKqQKCsPA73FaQwYpAY+QsWFHIncrG5jgRhC2IiNmCk=" + version = "v2.9.1" + hash = "sha256-7yMsN5CMJS/4VU9/Z27/xdbKzZac6/R1JRJDXxGmwiQ=" [mod."github.com/onsi/gomega"] - version = "v1.26.0" - hash = "sha256-B18jsoJHK/oE+wudT0dOsUb41s5+ZIAu/ZBzQ5djOLE=" + version = "v1.27.4" + hash = "sha256-Fhltm/e6KVXdwfUl65cE8PD1MLyXJa7OH0lg4Bvewv0=" [mod."github.com/pelletier/go-toml/v2"] version = "v2.0.6" hash = "sha256-BxAeApnn5H+OLlH3TXGvIbtC6LmbRnjwbcfT1qMZ4PE=" @@ -433,14 +439,14 @@ schema = 3 version = "v1.15.0" hash = "sha256-FvpbekXegcdWNbek/vs2zakgRsT5FROF8O8fhn5DNpI=" [mod."github.com/status-im/keycard-go"] - version = "v0.0.0-20200402102358-957c09536969" - hash = "sha256-yddXXuu6mEFEO2/K6c1tWymeBKzOcvLQnNsFGRjtfXk=" + version = "v0.2.0" + hash = "sha256-UUiGmlgaIZDeMUJv3fdZBoQ9hJeSsg2ixRGmm6TgHug=" [mod."github.com/stretchr/objx"] version = "v0.5.0" hash = "sha256-nY4mvP0f0Ry1IKMKQAYNuioA5h4red4mmQqeGZw6EF0=" [mod."github.com/stretchr/testify"] - version = "v1.8.1" - hash = "sha256-3e0vOJLgCMAan+GfaGN8RGZdarh5iCavM6flf6YMNPk=" + version = "v1.8.2" + hash = "sha256-n32PGyJL6VLtwOGEbS0lFchxunNU9nlol7OSEZlrKUM=" [mod."github.com/subosito/gotenv"] version = "v1.4.2" hash = "sha256-LnrDR1k/AoCFWBMcU7vQsoQLkZ65evT2hoQHLDudTsg=" @@ -469,8 +475,8 @@ schema = 3 version = "v1.1.0" hash = "sha256-3YhWBtSwRLGwm7vNwqumphZG3uLBW1vwT9QkQ8JuSjU=" [mod."github.com/ulikunitz/xz"] - version = "v0.5.8" - hash = "sha256-bfG3dssBUn+mSOAuKL+a/DTGGLUA+eASgLoGv/Gkqs0=" + version = "v0.5.10" + hash = "sha256-bogOwQNmQVS7W+C7wci7XEUeYm9TB7PnxnyBIXKYbm0=" [mod."github.com/zondax/hid"] version = "v0.9.1" hash = "sha256-hSVmN/f/lQHFhF60o6ej78ELC0MMoqQgqIX2hHjdTXg=" @@ -487,26 +493,29 @@ schema = 3 version = "v0.3.0" hash = "sha256-Un9wPqz8u/xpV98T4IqE6RMXIPhGCIm2prsNkHP3cjg=" [mod."golang.org/x/exp"] - version = "v0.0.0-20220722155223-a9213eeb770e" - hash = "sha256-kNgzydWRpjm0sZl4uXEs3LX5L0xjJtJRAFf/CTlYUN4=" + version = "v0.0.0-20230131160201-f062dba9d201" + hash = "sha256-sxLT/VOe93v0h3miChJSHS9gscTZS/B71+390ju/e20=" [mod."golang.org/x/net"] - version = "v0.5.0" - hash = "sha256-HpbIAiLs7S1+tVsaSSdbCPw1IK43A0bFFuSzPSyjLbo=" + version = "v0.8.0" + hash = "sha256-2cOtqa7aJ5mn64kZ+8+PVjJ4uGbhpXTpC1vm/+iaZzM=" [mod."golang.org/x/oauth2"] - version = "v0.0.0-20221014153046-6fdb5e3db783" - hash = "sha256-IoygidVNqyAZmN+3macDeIefK8hhJToygpcqlwehdYQ=" + version = "v0.4.0" + hash = "sha256-Dj9wHbSbs0Ghr9Hef0hSfanaR8L0GShI18jGBT3yNn8=" [mod."golang.org/x/sync"] version = "v0.1.0" hash = "sha256-Hygjq9euZ0qz6TvHYQwOZEjNiTbTh1nSLRAWZ6KFGR8=" [mod."golang.org/x/sys"] - version = "v0.4.0" - hash = "sha256-jchMzHCH5dg+IL/F+LqaX/fyAcB/nvHQpfBjqwaRJH0=" + version = "v0.6.0" + hash = "sha256-zAgxiTuL24sGhbXrna9R1UYqLQh46ldztpumOScmduY=" [mod."golang.org/x/term"] - version = "v0.4.0" - hash = "sha256-wQKxHV10TU4vCU8Re2/hFmAbur/jRWEOB8QXBzgTFNY=" - [mod."golang.org/x/text"] version = "v0.6.0" - hash = "sha256-+bpeRWR3relKACdal6NPj+eP5dnWCplTViArSN7/qA4=" + hash = "sha256-Ao0yXpwY8GyG+/23dVfJUYrfEfNUTES3RF45v1VhUAk=" + [mod."golang.org/x/text"] + version = "v0.8.0" + hash = "sha256-hgWFnT01DRmywBEXKYEVaOee7i6z8Ydz7zGbjcWwOgI=" + [mod."golang.org/x/tools"] + version = "v0.7.0" + hash = "sha256-ZEjfFulQd6U9r4mEJ5RZOnW49NZnQnrCFLMKCgLg7go=" [mod."golang.org/x/xerrors"] version = "v0.0.0-20220907171357-04be3eba64a2" hash = "sha256-6+zueutgefIYmgXinOflz8qGDDDj0Zhv+2OkGhBTKno=" @@ -517,11 +526,11 @@ schema = 3 version = "v1.6.7" hash = "sha256-zIxGRHiq4QBvRqkrhMGMGCaVL4iM4TtlYpAi/hrivS4=" [mod."google.golang.org/genproto"] - version = "v0.0.0-20221227171554-f9683d7f8bef" - hash = "sha256-vvYjJcG73odJwPUb3sZIz4MSHnzK1Jj2uo0CwZ8S8rQ=" + version = "v0.0.0-20230110181048-76db0878b65f" + hash = "sha256-Jc90F9KU+ZKI0ynF/p3Vwl7TJPb7/MxDFs0ebagty2s=" [mod."google.golang.org/grpc"] - version = "v1.52.3" - hash = "sha256-vVkuG0kKgnh62f63unpk4JDa9rIu6kk0qtnPJOiew2M=" + version = "v1.53.0" + hash = "sha256-LkB13k1JaQ7e4nGpCoEA9q4T8oIV0KvkFIDZmHhDr08=" [mod."google.golang.org/protobuf"] version = "v1.28.2-0.20220831092852-f930b1dc76e8" hash = "sha256-li5hXlXwTJ5LIZ8bVki1AZ6UFI2gXHl33JwdX1dOrtM=" From 8c8bedcade6e4067b69b85a0070dd27903de774d Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:03:01 +0800 Subject: [PATCH 19/29] add patch --- .../configs/cache-access-list-ethermintd.nix | 8 + .../cache-access-list-ethermintd.patch | 218 ++++++++++++++++++ tests/integration_tests/network.py | 17 +- tests/integration_tests/test_patch.py | 122 ++++++++++ 4 files changed, 356 insertions(+), 9 deletions(-) create mode 100644 tests/integration_tests/configs/cache-access-list-ethermintd.nix create mode 100644 tests/integration_tests/configs/cache-access-list-ethermintd.patch create mode 100644 tests/integration_tests/test_patch.py diff --git a/tests/integration_tests/configs/cache-access-list-ethermintd.nix b/tests/integration_tests/configs/cache-access-list-ethermintd.nix new file mode 100644 index 0000000000..2cec523b0b --- /dev/null +++ b/tests/integration_tests/configs/cache-access-list-ethermintd.nix @@ -0,0 +1,8 @@ +{ pkgs ? import ../../../nix { } }: +let ethermintd = (pkgs.callPackage ../../../. { }); +in +ethermintd.overrideAttrs (oldAttrs: { + patches = oldAttrs.patches or [ ] ++ [ + ./cache-access-list-ethermintd.patch + ]; +}) diff --git a/tests/integration_tests/configs/cache-access-list-ethermintd.patch b/tests/integration_tests/configs/cache-access-list-ethermintd.patch new file mode 100644 index 0000000000..624bf8cdec --- /dev/null +++ b/tests/integration_tests/configs/cache-access-list-ethermintd.patch @@ -0,0 +1,218 @@ +diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go +index 59a367871..55d49a098 100644 +--- a/x/evm/keeper/grpc_query.go ++++ b/x/evm/keeper/grpc_query.go +@@ -390,6 +390,34 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type + return &types.EstimateGasResponse{Gas: hi}, nil + } + ++// GetTxTraceResultForTx returns statedb with cached address list when need patch ++func (k Keeper) GetTxTraceResultForTx( ++ ctx sdk.Context, ++ tx *types.MsgEthereumTx, ++ signer ethtypes.Signer, ++ cfg *statedb.EVMConfig, ++ txConfig statedb.TxConfig, ++ lastDB *statedb.StateDB, ++) (*statedb.StateDB, error) { ++ ethTx := tx.AsTransaction() ++ msg, err := ethTx.AsMessage(signer, cfg.BaseFee) ++ if err != nil { ++ return lastDB, err ++ } ++ txConfig.TxHash = ethTx.Hash() ++ stateDB := statedb.New(ctx, &k, txConfig) ++ if lastDB != nil { ++ stateDB.SetAddressToAccessList(lastDB.GetAddressToAccessList()) ++ } ++ lastDB = stateDB ++ rsp, err := k.ApplyMessageWithStateDB(ctx, msg, types.NewNoOpTracer(), true, cfg, txConfig, stateDB) ++ if err != nil { ++ return lastDB, err ++ } ++ txConfig.LogIndex += uint(len(rsp.Logs)) ++ return lastDB, nil ++} ++ + // TraceTx configures a new tracer according to the provided configuration, and + // executes the given message in the provided environment. The return value will + // be tracer dependent. +@@ -421,22 +449,13 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to load evm config: %s", err.Error()) + } +- signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(ctx.BlockHeight())) +- ++ height := ctx.BlockHeight() ++ signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(height)) + txConfig := statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes())) ++ var lastDB *statedb.StateDB + for i, tx := range req.Predecessors { +- ethTx := tx.AsTransaction() +- msg, err := ethTx.AsMessage(signer, cfg.BaseFee) +- if err != nil { +- continue +- } +- txConfig.TxHash = ethTx.Hash() + txConfig.TxIndex = uint(i) +- rsp, err := k.ApplyMessageWithConfig(ctx, msg, types.NewNoOpTracer(), true, cfg, txConfig) +- if err != nil { +- continue +- } +- txConfig.LogIndex += uint(len(rsp.Logs)) ++ lastDB, _ = k.GetTxTraceResultForTx(ctx, tx, signer, cfg, txConfig, lastDB) + } + + tx := req.Msg.AsTransaction() +@@ -450,8 +469,11 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ + // ignore error. default to no traceConfig + _ = json.Unmarshal([]byte(req.TraceConfig.TracerJsonConfig), &tracerConfig) + } +- +- result, _, err := k.traceTx(ctx, cfg, txConfig, signer, tx, req.TraceConfig, false, tracerConfig) ++ stateDB := statedb.New(ctx, &k, txConfig) ++ if lastDB != nil { ++ stateDB.SetAddressToAccessList(lastDB.GetAddressToAccessList()) ++ } ++ result, _, err := k.traceTx(ctx, cfg, txConfig, stateDB, signer, tx, req.TraceConfig, false, tracerConfig) + if err != nil { + // error will be returned with detail status from traceTx + return nil, err +@@ -467,6 +489,35 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ + }, nil + } + ++// GetTxTraceResultForBlock returns TxTraceResult and ++// statedb with cached address list when need patch and ++func (k Keeper) GetTxTraceResultForBlock( ++ ctx sdk.Context, ++ tx *types.MsgEthereumTx, ++ signer ethtypes.Signer, ++ cfg *statedb.EVMConfig, ++ txConfig statedb.TxConfig, ++ traceConfig *types.TraceConfig, ++ lastDB *statedb.StateDB, ++) (*statedb.StateDB, *types.TxTraceResult) { ++ result := new(types.TxTraceResult) ++ ethTx := tx.AsTransaction() ++ txConfig.TxHash = ethTx.Hash() ++ stateDB := statedb.New(ctx, &k, txConfig) ++ if lastDB != nil { ++ stateDB.SetAddressToAccessList(lastDB.GetAddressToAccessList()) ++ } ++ lastDB = stateDB ++ traceResult, logIndex, err := k.traceTx(ctx, cfg, txConfig, stateDB, signer, ethTx, traceConfig, true, nil) ++ if err != nil { ++ result.Error = err.Error() ++ } else { ++ txConfig.LogIndex = logIndex ++ result.Result = traceResult ++ } ++ return lastDB, result ++} ++ + // TraceBlock configures a new tracer according to the provided configuration, and + // executes the given message in the provided environment for all the transactions in the queried block. + // The return value will be tracer dependent. +@@ -499,24 +550,18 @@ func (k Keeper) TraceBlock(c context.Context, req *types.QueryTraceBlockRequest) + if err != nil { + return nil, status.Error(codes.Internal, "failed to load evm config") + } +- signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(ctx.BlockHeight())) ++ height := ctx.BlockHeight() ++ signer := ethtypes.MakeSigner(cfg.ChainConfig, big.NewInt(height)) + txsLength := len(req.Txs) + results := make([]*types.TxTraceResult, 0, txsLength) + + txConfig := statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash().Bytes())) ++ var lastDB *statedb.StateDB + for i, tx := range req.Txs { +- result := types.TxTraceResult{} +- ethTx := tx.AsTransaction() +- txConfig.TxHash = ethTx.Hash() + txConfig.TxIndex = uint(i) +- traceResult, logIndex, err := k.traceTx(ctx, cfg, txConfig, signer, ethTx, req.TraceConfig, true, nil) +- if err != nil { +- result.Error = err.Error() +- } else { +- txConfig.LogIndex = logIndex +- result.Result = traceResult +- } +- results = append(results, &result) ++ var result *types.TxTraceResult ++ lastDB, result = k.GetTxTraceResultForBlock(ctx, tx, signer, cfg, txConfig, req.TraceConfig, lastDB) ++ results = append(results, result) + } + + resultData, err := json.Marshal(results) +@@ -534,6 +579,7 @@ func (k *Keeper) traceTx( + ctx sdk.Context, + cfg *statedb.EVMConfig, + txConfig statedb.TxConfig, ++ stateDB *statedb.StateDB, + signer ethtypes.Signer, + tx *ethtypes.Transaction, + traceConfig *types.TraceConfig, +@@ -602,7 +648,7 @@ func (k *Keeper) traceTx( + } + }() + +- res, err := k.ApplyMessageWithConfig(ctx, msg, tracer, commitMessage, cfg, txConfig) ++ res, err := k.ApplyMessageWithStateDB(ctx, msg, tracer, commitMessage, cfg, txConfig, stateDB) + if err != nil { + return nil, 0, status.Error(codes.Internal, err.Error()) + } +diff --git a/x/evm/keeper/state_transition.go b/x/evm/keeper/state_transition.go +index ad90dba5f..894498b86 100644 +--- a/x/evm/keeper/state_transition.go ++++ b/x/evm/keeper/state_transition.go +@@ -316,6 +316,17 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context, + commit bool, + cfg *statedb.EVMConfig, + txConfig statedb.TxConfig, ++) (*types.MsgEthereumTxResponse, error) { ++ return k.ApplyMessageWithStateDB(ctx, msg, tracer, commit, cfg, txConfig, nil) ++} ++ ++func (k *Keeper) ApplyMessageWithStateDB(ctx sdk.Context, ++ msg core.Message, ++ tracer vm.EVMLogger, ++ commit bool, ++ cfg *statedb.EVMConfig, ++ txConfig statedb.TxConfig, ++ stateDB *statedb.StateDB, + ) (*types.MsgEthereumTxResponse, error) { + var ( + ret []byte // return bytes from evm execution +@@ -329,7 +340,9 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context, + return nil, errorsmod.Wrap(types.ErrCallDisabled, "failed to call contract") + } + +- stateDB := statedb.New(ctx, k, txConfig) ++ if stateDB == nil { ++ stateDB = statedb.New(ctx, k, txConfig) ++ } + evm := k.NewEVM(ctx, msg, cfg, tracer, stateDB) + + leftoverGas := msg.Gas() +diff --git a/x/evm/statedb/statedb.go b/x/evm/statedb/statedb.go +index 753ec7616..911a44e1f 100644 +--- a/x/evm/statedb/statedb.go ++++ b/x/evm/statedb/statedb.go +@@ -396,6 +396,16 @@ func (s *StateDB) AddAddressToAccessList(addr common.Address) { + } + } + ++// GetAddressToAccessList return full access list ++func (s *StateDB) GetAddressToAccessList() *accessList { ++ return s.accessList ++} ++ ++// SetAddressToAccessList overwrite with new access list ++func (s *StateDB) SetAddressToAccessList(accessList *accessList) { ++ s.accessList = accessList ++} ++ + // AddSlotToAccessList adds the given (address, slot)-tuple to the access list + func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { + addrMod, slotMod := s.accessList.AddSlot(addr, slot) diff --git a/tests/integration_tests/network.py b/tests/integration_tests/network.py index c638e2a563..0e75e37c65 100644 --- a/tests/integration_tests/network.py +++ b/tests/integration_tests/network.py @@ -26,27 +26,26 @@ def __init__(self, base_dir, chain_binary=DEFAULT_CHAIN_BINARY): def copy(self): return Ethermint(self.base_dir) - @property def w3_http_endpoint(self, i=0): port = ports.evmrpc_port(self.base_port(i)) return f"http://localhost:{port}" - @property def w3_ws_endpoint(self, i=0): port = ports.evmrpc_ws_port(self.base_port(i)) return f"ws://localhost:{port}" @property - def w3(self, i=0): + def w3(self): if self._w3 is None: - if self._use_websockets: - self._w3 = web3.Web3( - web3.providers.WebsocketProvider(self.w3_ws_endpoint) - ) - else: - self._w3 = web3.Web3(web3.providers.HTTPProvider(self.w3_http_endpoint)) + self._w3 = self.node_w3(0) return self._w3 + def node_w3(self, i=0): + if self._use_websockets: + return web3.Web3(web3.providers.WebsocketProvider(self.w3_ws_endpoint(i))) + else: + return web3.Web3(web3.providers.HTTPProvider(self.w3_http_endpoint(i))) + def base_port(self, i): return self.config["validators"][i]["base_port"] diff --git a/tests/integration_tests/test_patch.py b/tests/integration_tests/test_patch.py new file mode 100644 index 0000000000..db4c4bbb08 --- /dev/null +++ b/tests/integration_tests/test_patch.py @@ -0,0 +1,122 @@ +import configparser +import subprocess +from pathlib import Path + +import pytest +import requests +from pystarport.cluster import SUPERVISOR_CONFIG_FILE + +from .network import setup_custom_ethermint +from .utils import ( + ADDRS, + CONTRACTS, + KEYS, + deploy_contract, + send_transaction, + sign_transaction, + wait_for_new_blocks, +) + + +def update_node_cmd(path, cmd, i): + ini_path = path / SUPERVISOR_CONFIG_FILE + ini = configparser.RawConfigParser() + ini.read(ini_path) + for section in ini.sections(): + if section == f"program:ethermint_9000-1-node{i}": + ini[section].update( + { + "command": f"{cmd} start --home %(here)s/node{i}", + "autorestart": "false", # don't restart when stopped + } + ) + with ini_path.open("w") as fp: + ini.write(fp) + + +def post_init(patch_binary): + def inner(path, base_port, config): + chain_id = "ethermint_9000-1" + update_node_cmd(path / chain_id, patch_binary, 1) + + return inner + + +@pytest.fixture(scope="module") +def custom_ethermint(tmp_path_factory): + path = tmp_path_factory.mktemp("rollback") + + cmd = [ + "nix-build", + "--no-out-link", + Path(__file__).parent / "configs/cache-access-list-ethermintd.nix", + ] + print(*cmd) + patch_binary = ( + Path(subprocess.check_output(cmd).strip().decode()) / "bin/ethermintd" + ) + print(patch_binary) + + # init with genesis binary + yield from setup_custom_ethermint( + path, + 27000, + Path(__file__).parent / "configs/default.jsonnet", + post_init=post_init(patch_binary), + wait_port=True, + ) + + +def multi_transfer(w3, contract, sender, key, receiver): + amt = 100 + txhashes = [] + nonce = w3.eth.get_transaction_count(sender) + for i in range(2): + tx = contract.functions.transfer(sender, amt).build_transaction({ + "from": receiver, + "nonce": nonce + i, + }) + signed = sign_transaction(w3, tx, key) + txhash = w3.eth.send_raw_transaction(signed.rawTransaction) + txhashes.append(txhash) + return txhashes + + +def test_patch(custom_ethermint): + cli = custom_ethermint.cosmos_cli() + w3 = custom_ethermint.w3 + validator = ADDRS["validator"] + community = ADDRS["community"] + contract, _ = deploy_contract(w3, CONTRACTS["TestERC20A"]) + amt = 3000 + # fund community + params = {"from": validator} + tx = contract.functions.transfer(community, amt).build_transaction(params) + receipt = send_transaction(w3, tx) + assert receipt.status == 1 + + wait_for_new_blocks(cli, 1, sleep=0.1) + txhashes = multi_transfer(w3, contract, validator, KEYS["validator"], community) + txhashes += multi_transfer(w3, contract, community, KEYS["community"], validator) + + for txhash in txhashes: + receipt = w3.eth.wait_for_transaction_receipt(txhash) + assert receipt.status == 1 + + params = { + "method": "debug_traceTransaction", + "id": 1, + "jsonrpc": "2.0", + } + gas = 29506 + diff = 2000 + for i, txhash in enumerate(txhashes): + params["params"] = [txhash.hex()] + rsp0 = requests.post(custom_ethermint.w3_http_endpoint(0), json=params) + rsp1 = requests.post(custom_ethermint.w3_http_endpoint(1), json=params) + assert rsp0.status_code == 200 + assert rsp1.status_code == 200 + gas0 = rsp0.json()["result"]["gas"] + gas1 = rsp1.json()["result"]["gas"] + assert gas0 == gas + assert gas1 == gas if i % 2 == 0 else gas1 == gas - diff From 39a0fc980d4fabaa17583ee8572fab7e17c7001a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:03:26 +0800 Subject: [PATCH 20/29] test call with backup --- .../configs/cache-access-list-ethermintd.nix | 19 ++- tests/integration_tests/test_patch.py | 148 +++++++++++++----- 2 files changed, 125 insertions(+), 42 deletions(-) diff --git a/tests/integration_tests/configs/cache-access-list-ethermintd.nix b/tests/integration_tests/configs/cache-access-list-ethermintd.nix index 2cec523b0b..c9f2196ea6 100644 --- a/tests/integration_tests/configs/cache-access-list-ethermintd.nix +++ b/tests/integration_tests/configs/cache-access-list-ethermintd.nix @@ -1,8 +1,13 @@ -{ pkgs ? import ../../../nix { } }: -let ethermintd = (pkgs.callPackage ../../../. { }); +let + pkgs = import ../../../nix { }; + current = pkgs.callPackage ../../../. { }; + patched = current.overrideAttrs (oldAttrs: rec { + patches = oldAttrs.patches or [ ] ++ [ + ./cache-access-list-ethermintd.patch + ]; + }); in -ethermintd.overrideAttrs (oldAttrs: { - patches = oldAttrs.patches or [ ] ++ [ - ./cache-access-list-ethermintd.patch - ]; -}) +pkgs.linkFarm "cache-access-list-ethermintd" [ + { name = "genesis"; path = patched; } + { name = "integration-test-patch"; path = current; } +] \ No newline at end of file diff --git a/tests/integration_tests/test_patch.py b/tests/integration_tests/test_patch.py index db4c4bbb08..497ff77490 100644 --- a/tests/integration_tests/test_patch.py +++ b/tests/integration_tests/test_patch.py @@ -1,9 +1,12 @@ import configparser +import json +import re import subprocess from pathlib import Path import pytest import requests +from pystarport import ports from pystarport.cluster import SUPERVISOR_CONFIG_FILE from .network import setup_custom_ethermint @@ -14,55 +17,68 @@ deploy_contract, send_transaction, sign_transaction, + supervisorctl, wait_for_new_blocks, + wait_for_port, ) -def update_node_cmd(path, cmd, i): - ini_path = path / SUPERVISOR_CONFIG_FILE +def init_cosmovisor(home): + cosmovisor = home / "cosmovisor" + cosmovisor.mkdir() + (cosmovisor / "patched").symlink_to("../../../patched") + (cosmovisor / "genesis").symlink_to("./patched/genesis") + + +def post_init(path, base_port, config): + """ + prepare cosmovisor for each node + """ + chain_id = "ethermint_9000-1" + cfg = json.loads((path / chain_id / "config.json").read_text()) + for i, _ in enumerate(cfg["validators"]): + home = path / chain_id / f"node{i}" + init_cosmovisor(home) + + # patch supervisord ini config + ini_path = path / chain_id / SUPERVISOR_CONFIG_FILE ini = configparser.RawConfigParser() ini.read(ini_path) + reg = re.compile(rf"^program:{chain_id}-node(\d+)") for section in ini.sections(): - if section == f"program:ethermint_9000-1-node{i}": + m = reg.match(section) + if m: + i = m.group(1) ini[section].update( { - "command": f"{cmd} start --home %(here)s/node{i}", - "autorestart": "false", # don't restart when stopped + "command": f"cosmovisor start --home %(here)s/node{i}", + "environment": ( + f"DAEMON_NAME=ethermintd,DAEMON_HOME=%(here)s/node{i}" + ), } ) with ini_path.open("w") as fp: ini.write(fp) -def post_init(patch_binary): - def inner(path, base_port, config): - chain_id = "ethermint_9000-1" - update_node_cmd(path / chain_id, patch_binary, 1) - - return inner - - @pytest.fixture(scope="module") def custom_ethermint(tmp_path_factory): - path = tmp_path_factory.mktemp("rollback") - + path = tmp_path_factory.mktemp("patch") cmd = [ "nix-build", - "--no-out-link", Path(__file__).parent / "configs/cache-access-list-ethermintd.nix", + "-o", + path / "patched", ] print(*cmd) - patch_binary = ( - Path(subprocess.check_output(cmd).strip().decode()) / "bin/ethermintd" - ) - print(patch_binary) - - # init with genesis binary + subprocess.run(cmd, check=True) + # init with patch binary yield from setup_custom_ethermint( path, 27000, - Path(__file__).parent / "configs/default.jsonnet", - post_init=post_init(patch_binary), + Path(__file__).parent / "configs/cosmovisor.jsonnet", + post_init=post_init, + chain_binary=str(path / "patched/genesis/bin/ethermintd"), wait_port=True, ) @@ -95,7 +111,8 @@ def test_patch(custom_ethermint): receipt = send_transaction(w3, tx) assert receipt.status == 1 - wait_for_new_blocks(cli, 1, sleep=0.1) + sleep = 0.1 + target_height = wait_for_new_blocks(cli, 1, sleep) txhashes = multi_transfer(w3, contract, validator, KEYS["validator"], community) txhashes += multi_transfer(w3, contract, community, KEYS["community"], validator) @@ -103,6 +120,9 @@ def test_patch(custom_ethermint): receipt = w3.eth.wait_for_transaction_receipt(txhash) assert receipt.status == 1 + nodes = [0, 1] + (wait_for_new_blocks(custom_ethermint.cosmos_cli(n), 1, sleep) for n in nodes) + params = { "method": "debug_traceTransaction", "id": 1, @@ -110,13 +130,71 @@ def test_patch(custom_ethermint): } gas = 29506 diff = 2000 - for i, txhash in enumerate(txhashes): - params["params"] = [txhash.hex()] - rsp0 = requests.post(custom_ethermint.w3_http_endpoint(0), json=params) - rsp1 = requests.post(custom_ethermint.w3_http_endpoint(1), json=params) - assert rsp0.status_code == 200 - assert rsp1.status_code == 200 - gas0 = rsp0.json()["result"]["gas"] - gas1 = rsp1.json()["result"]["gas"] - assert gas0 == gas - assert gas1 == gas if i % 2 == 0 else gas1 == gas - diff + + def assert_debug_tx(i, all_eq=False): + results = [] + for txhash in txhashes: + params["params"] = [txhash.hex()] + rsp = requests.post(custom_ethermint.w3_http_endpoint(i), json=params) + assert rsp.status_code == 200 + result = rsp.json()["result"]["gas"] + results.append(result) + for i, result in enumerate(results): + if all_eq: + assert result == gas + else: + # costs less gas when cache access list + assert result == gas if i % 2 == 0 else result == gas - diff + + (assert_debug_tx(n) for n in nodes) + + base_dir = custom_ethermint.base_dir + for n in nodes: + supervisorctl(base_dir / "../tasks.ini", "stop", f"ethermint_9000-1-node{n}") + + procs = [] + + def append_proc(log, cmd): + with (base_dir / log).open("a") as logfile: + procs.append( + subprocess.Popen( + cmd, + stdout=logfile, + stderr=subprocess.STDOUT, + ) + ) + + path = Path(custom_ethermint.chain_binary).parent.parent.parent + grpc_port1 = ports.grpc_port(custom_ethermint.base_port(1)) + + for blk_end in [target_height - 1, target_height]: + try: + append_proc( + "node1.log", + [ + f"{str(path)}/genesis/bin/ethermintd", + "start", + "--home", + base_dir / "node1", + ], + ) + append_proc( + "node0.log", + [ + f"{str(path)}/integration-test-patch/bin/ethermintd", + "start", + "--json-rpc.backup-grpc-address-block-range", + f'{{"0.0.0.0:{grpc_port1}": [0, {blk_end}]}}', + "--home", + base_dir / "node0", + ], + ) + for n in nodes: + wait_for_port(ports.evmrpc_port(custom_ethermint.base_port(n))) + assert_debug_tx(0, blk_end != target_height) + assert_debug_tx(1) + finally: + for proc in procs: + proc.terminate() + proc.wait() + procs = [] From 8167e30608194e6efc7d16a6585e57362d465554 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:03:45 +0800 Subject: [PATCH 21/29] add for debug tx & blk --- rpc/backend/tracing.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rpc/backend/tracing.go b/rpc/backend/tracing.go index 2f9432cc87..72b82e82b5 100644 --- a/rpc/backend/tracing.go +++ b/rpc/backend/tracing.go @@ -123,7 +123,8 @@ func (b *Backend) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfi // 0 is a special value in `ContextWithHeight` contextHeight = 1 } - traceResult, err := b.queryClient.TraceTx(rpctypes.ContextWithHeight(contextHeight), &traceTxRequest) + queryClient := b.getGrpcClient(contextHeight) + traceResult, err := queryClient.TraceTx(rpctypes.ContextWithHeight(contextHeight), &traceTxRequest) if err != nil { return nil, err } @@ -191,8 +192,8 @@ func (b *Backend) TraceBlock(height rpctypes.BlockNumber, ProposerAddress: sdk.ConsAddress(block.Block.ProposerAddress), ChainId: b.chainID.Int64(), } - - res, err := b.queryClient.TraceBlock(ctxWithHeight, traceBlockRequest) + queryClient := b.getGrpcClient(int64(contextHeight)) + res, err := queryClient.TraceBlock(ctxWithHeight, traceBlockRequest) if err != nil { return nil, err } From 03d1a9e6a213becc68f2a9ec6b0e98f8eefd1110 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 07:16:26 +0800 Subject: [PATCH 22/29] keep migrate no change --- tests/integration_tests/cosmoscli.py | 12 ---- tests/integration_tests/test_upgrade.py | 73 ++++--------------------- 2 files changed, 10 insertions(+), 75 deletions(-) diff --git a/tests/integration_tests/cosmoscli.py b/tests/integration_tests/cosmoscli.py index df477dd301..41c24c91e7 100644 --- a/tests/integration_tests/cosmoscli.py +++ b/tests/integration_tests/cosmoscli.py @@ -839,15 +839,3 @@ def rollback(self): def migrate_keystore(self): return self.raw("keys", "migrate", home=self.data_dir) - - def query_params(self, height: int): - "query evm params" - return json.loads( - self.raw( - "q", - "evm", - "params", - height, - home=self.data_dir, - ) - ) diff --git a/tests/integration_tests/test_upgrade.py b/tests/integration_tests/test_upgrade.py index b37dba73bc..566f41e3d6 100644 --- a/tests/integration_tests/test_upgrade.py +++ b/tests/integration_tests/test_upgrade.py @@ -16,7 +16,6 @@ deploy_contract, parse_events, send_transaction, - supervisorctl, wait_for_block, wait_for_block_time, wait_for_port, @@ -95,12 +94,11 @@ def test_cosmovisor_upgrade(custom_ethermint: Ethermint): cli = custom_ethermint.cosmos_cli() w3 = custom_ethermint.w3 - validator = ADDRS["validator"] contract, _ = deploy_contract(w3, CONTRACTS["TestERC20A"]) old_height = w3.eth.block_number - old_balance = w3.eth.get_balance(validator, block_identifier=old_height) + old_balance = w3.eth.get_balance(ADDRS["validator"], block_identifier=old_height) old_base_fee = w3.eth.get_block(old_height).baseFeePerGas - old_erc20_balance = contract.caller.balanceOf(validator) + old_erc20_balance = contract.caller.balanceOf(ADDRS["validator"]) print("old values", old_height, old_balance, old_base_fee) target_height = w3.eth.block_number + 10 @@ -162,64 +160,13 @@ def test_cosmovisor_upgrade(custom_ethermint: Ethermint): ) assert receipt.status == 1 - # check get_balance and eth_call don't work on pruned state - with pytest.raises(Exception): - w3.eth.get_balance(validator, block_identifier=old_height) - - base_dir = custom_ethermint.base_dir - for i in [0, 1]: - supervisorctl(base_dir / "../tasks.ini", "stop", f"ethermint_9000-1-node{i}") - - procs = [] - - def append_proc(log, cmd): - with (base_dir / log).open("a") as logfile: - procs.append( - subprocess.Popen( - cmd, - stdout=logfile, - stderr=subprocess.STDOUT, - ) - ) - - path = Path(custom_ethermint.chain_binary).parent.parent.parent - append_proc( - "node1.log", - [ - f"{str(path)}/genesis/bin/ethermintd", - "start", - "--home", - base_dir / "node1", - ], - ) - grpc_port1 = ports.grpc_port(custom_ethermint.base_port(1)) - append_proc( - "node0.log", - [ - f"{str(path)}/{plan_name}/bin/ethermintd", - "start", - "--json-rpc.backup-grpc-address-block-range", - f'{{"0.0.0.0:{grpc_port1}": [0, {target_height}]}}', - "--home", - base_dir / "node0", - ], + # check json-rpc query on older blocks works + assert old_balance == w3.eth.get_balance( + ADDRS["validator"], block_identifier=old_height ) + assert old_base_fee == w3.eth.get_block(old_height).baseFeePerGas - try: - for i in [0, 1]: - wait_for_port(ports.evmrpc_port(custom_ethermint.base_port(i))) - - # check json-rpc query on older blocks works - assert old_balance == w3.eth.get_balance(validator, block_identifier=old_height) - assert old_base_fee == w3.eth.get_block(old_height).baseFeePerGas - - # check eth_call on older blocks works - assert old_erc20_balance == contract.caller( - block_identifier=target_height - 2 - ).balanceOf(validator) - # check we could fetch the right params before and after migration - assert cli.query_params(old_height) == cli.query_params(w3.eth.block_number - 1) - finally: - for proc in procs: - proc.terminate() - proc.wait() + # check eth_call on older blocks works + assert old_erc20_balance == contract.caller( + block_identifier=target_height - 2 + ).balanceOf(ADDRS["validator"]) From af4604ea4cafe20c809916933db77fbde9641e4a Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:04:20 +0800 Subject: [PATCH 23/29] Revert "revert keep grpc query compatible with version before feemarket migrate" This reverts commit ce340afd7581ebd829d8d314f8c7eb1eba2a671e. --- app/app.go | 5 +++-- x/feemarket/keeper/keeper.go | 6 +++++- x/feemarket/keeper/params.go | 4 +++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/app.go b/app/app.go index a681952d78..3222fb73a0 100644 --- a/app/app.go +++ b/app/app.go @@ -412,9 +412,10 @@ func NewEthermintApp( tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer)) // Create Ethermint keepers + feeMarketSs := app.GetSubspace(feemarkettypes.ModuleName) app.FeeMarketKeeper = feemarketkeeper.NewKeeper( appCodec, authtypes.NewModuleAddress(govtypes.ModuleName), - keys[feemarkettypes.StoreKey], tkeys[feemarkettypes.TransientKey], + keys[feemarkettypes.StoreKey], tkeys[feemarkettypes.TransientKey], feeMarketSs, ) // Set authority to x/gov module account to only expect the module account to update params @@ -507,7 +508,7 @@ func NewEthermintApp( ibc.NewAppModule(app.IBCKeeper), transferModule, // Ethermint app modules - feemarket.NewAppModule(app.FeeMarketKeeper, app.GetSubspace(feemarkettypes.ModuleName)), + feemarket.NewAppModule(app.FeeMarketKeeper, feeMarketSs), evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, app.GetSubspace(evmtypes.ModuleName)), ) diff --git a/x/feemarket/keeper/keeper.go b/x/feemarket/keeper/keeper.go index 466e4b418a..3d702a545c 100644 --- a/x/feemarket/keeper/keeper.go +++ b/x/feemarket/keeper/keeper.go @@ -21,6 +21,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/tendermint/tendermint/libs/log" "github.com/evmos/ethermint/x/feemarket/types" @@ -38,11 +39,13 @@ type Keeper struct { transientKey storetypes.StoreKey // the address capable of executing a MsgUpdateParams message. Typically, this should be the x/gov module account. authority sdk.AccAddress + // Legacy subspace + ss paramstypes.Subspace } // NewKeeper generates new fee market module keeper func NewKeeper( - cdc codec.BinaryCodec, authority sdk.AccAddress, storeKey, transientKey storetypes.StoreKey, + cdc codec.BinaryCodec, authority sdk.AccAddress, storeKey, transientKey storetypes.StoreKey, ss paramstypes.Subspace, ) Keeper { // ensure authority account is correctly formatted if err := sdk.VerifyAddressFormat(authority); err != nil { @@ -54,6 +57,7 @@ func NewKeeper( storeKey: storeKey, authority: authority, transientKey: transientKey, + ss: ss, } } diff --git a/x/feemarket/keeper/params.go b/x/feemarket/keeper/params.go index 4508e5f442..f8a1f3744f 100644 --- a/x/feemarket/keeper/params.go +++ b/x/feemarket/keeper/params.go @@ -28,7 +28,9 @@ func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ParamsKey) if len(bz) == 0 { - return params + var p types.Params + k.ss.GetParamSetIfExists(ctx, &p) + return p } k.cdc.MustUnmarshal(bz, ¶ms) From f1772f8dd9f0afdd15f4607ce251b7fb6b6c6d45 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:05:15 +0800 Subject: [PATCH 24/29] Revert "Revert "keep grpc query compatible with version before migrate"" This reverts commit 39a5b18323936c5637ab80a175c415547c22b774. --- app/app.go | 5 +++-- x/evm/keeper/keeper.go | 5 +++++ x/evm/keeper/params.go | 9 ++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/app.go b/app/app.go index 3222fb73a0..7e5b3e8982 100644 --- a/app/app.go +++ b/app/app.go @@ -419,10 +419,11 @@ func NewEthermintApp( ) // Set authority to x/gov module account to only expect the module account to update params + evmSs := app.GetSubspace(evmtypes.ModuleName) app.EvmKeeper = evmkeeper.NewKeeper( appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], authtypes.NewModuleAddress(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.FeeMarketKeeper, - nil, geth.NewEVM, tracer, + nil, geth.NewEVM, tracer, evmSs, ) // Create IBC Keeper @@ -509,7 +510,7 @@ func NewEthermintApp( transferModule, // Ethermint app modules feemarket.NewAppModule(app.FeeMarketKeeper, feeMarketSs), - evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, app.GetSubspace(evmtypes.ModuleName)), + evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, evmSs), ) // During begin block slashing happens after distr.BeginBlocker so that diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index f797a2f1bb..2d3e90a175 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -23,6 +23,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -75,6 +76,8 @@ type Keeper struct { // evm constructor function evmConstructor evm.Constructor + // Legacy subspace + ss paramstypes.Subspace } // NewKeeper generates new evm module keeper @@ -89,6 +92,7 @@ func NewKeeper( customPrecompiles evm.PrecompiledContracts, evmConstructor evm.Constructor, tracer string, + ss paramstypes.Subspace, ) *Keeper { // ensure evm module account is set if addr := ak.GetModuleAddress(types.ModuleName); addr == nil { @@ -113,6 +117,7 @@ func NewKeeper( customPrecompiles: customPrecompiles, evmConstructor: evmConstructor, tracer: tracer, + ss: ss, } } diff --git a/x/evm/keeper/params.go b/x/evm/keeper/params.go index 4dd950f794..4ecd953192 100644 --- a/x/evm/keeper/params.go +++ b/x/evm/keeper/params.go @@ -25,7 +25,7 @@ func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.KeyPrefixParams) if len(bz) == 0 { - return params + return k.GetLegacyParams(ctx) } k.cdc.MustUnmarshal(bz, ¶ms) return @@ -46,3 +46,10 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { store.Set(types.KeyPrefixParams, bz) return nil } + +// GetLegacyParams returns param set for version before migrate +func (k Keeper) GetLegacyParams(ctx sdk.Context) types.Params { + var params types.Params + k.ss.GetParamSetIfExists(ctx, ¶ms) + return params +} From f26c579ec97e55b3b52933ae3830c4b85426a113 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:09:50 +0800 Subject: [PATCH 25/29] fix lint --- tests/integration_tests/test_patch.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/integration_tests/test_patch.py b/tests/integration_tests/test_patch.py index 497ff77490..7c06d8bbb8 100644 --- a/tests/integration_tests/test_patch.py +++ b/tests/integration_tests/test_patch.py @@ -88,10 +88,12 @@ def multi_transfer(w3, contract, sender, key, receiver): txhashes = [] nonce = w3.eth.get_transaction_count(sender) for i in range(2): - tx = contract.functions.transfer(sender, amt).build_transaction({ - "from": receiver, - "nonce": nonce + i, - }) + tx = contract.functions.transfer(sender, amt).build_transaction( + { + "from": receiver, + "nonce": nonce + i, + } + ) signed = sign_transaction(w3, tx, key) txhash = w3.eth.send_raw_transaction(signed.rawTransaction) txhashes.append(txhash) From 08435946b6f22f7dc836d72f7da76f8b1e4ea5ea Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:18:13 +0800 Subject: [PATCH 26/29] keep migrate related stuff no change --- tests/integration_tests/configs/upgrade-test-package.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration_tests/configs/upgrade-test-package.nix b/tests/integration_tests/configs/upgrade-test-package.nix index 75047be21c..1863054dfb 100644 --- a/tests/integration_tests/configs/upgrade-test-package.nix +++ b/tests/integration_tests/configs/upgrade-test-package.nix @@ -1,9 +1,9 @@ let pkgs = import ../../../nix { }; - fetchEthermint = rev: builtins.fetchTarball "https://github.com/mmsqe/ethermint/archive/${rev}.tar.gz"; + fetchEthermint = rev: builtins.fetchTarball "https://github.com/evmos/ethermint/archive/${rev}.tar.gz"; released = pkgs.buildGo118Module rec { name = "ethermintd"; - src = fetchEthermint "0e4d41eef5f7983f84206b1bb07e88ed3a9cd44b"; + src = fetchEthermint "d29cdad6e667f6089dfecbedd36bb8d3a2a7d025"; subPackages = [ "cmd/ethermintd" ]; vendorSha256 = "sha256-cQAol54b6hNzsA4Q3MP9mTqFWM1MvR5uMPrYpaoj3SY="; doCheck = false; From a1eda26de80d685d60bcdc0cc26ddaeef29cfd16 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 17 Mar 2023 09:23:30 +0800 Subject: [PATCH 27/29] fix resolve --- server/config/toml.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/config/toml.go b/server/config/toml.go index 802fdef343..1cf2b7bcb0 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -92,6 +92,9 @@ enable-indexer = {{ .JSONRPC.EnableIndexer }} # Prometheus metrics path: /debug/metrics/prometheus metrics-address = "{{ .JSONRPC.MetricsAddress }}" +# Upgrade height for fix of revert gas refund logic when transaction reverted. +fix-revert-gas-refund-height = {{ .JSONRPC.FixRevertGasRefundHeight }} + # A list of backup grpc address with block range # Example: "0.0.0.0:26113" = [0, 20] [json-rpc.backup-grpc-address-block-range] From 5aa65044fdb0ac60311abbc7815cb07c7512f5c8 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Tue, 21 Mar 2023 10:57:15 +0800 Subject: [PATCH 28/29] revert query param change --- x/evm/client/cli/query.go | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/x/evm/client/cli/query.go b/x/evm/client/cli/query.go index 635c6dfa0a..bc3c6886b3 100644 --- a/x/evm/client/cli/query.go +++ b/x/evm/client/cli/query.go @@ -16,8 +16,6 @@ package cli import ( - "strconv" - rpctypes "github.com/evmos/ethermint/rpc/types" "github.com/spf13/cobra" @@ -122,28 +120,22 @@ func GetCodeCmd() *cobra.Command { return cmd } -// GetParamsCmd queries the evm params +// GetParamsCmd queries the fee market params func GetParamsCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "params [height]", - Short: "Get the evm params associated with a specific blockheight", - Long: "Get the evm parameter values associated with a specific blockheight, 0 or negative means the latest blockheight.", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { + Use: "params", + Short: "Get the evm params", + Long: "Get the evm parameter values.", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } - height, err := strconv.ParseInt(args[0], 10, 64) - if err != nil { - return err - } - if height <= 0 { - height = clientCtx.Height - } + queryClient := types.NewQueryClient(clientCtx) - res, err := queryClient.Params(rpctypes.ContextWithHeight(height), &types.QueryParamsRequest{}) + res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{}) if err != nil { return err } From fd8bc47259b4fe51cb7a19f4cf43ce7bd2ebd5ab Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 24 Mar 2023 09:24:59 +0800 Subject: [PATCH 29/29] fix template --- server/config/toml.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server/config/toml.go b/server/config/toml.go index 1cf2b7bcb0..d83e472c26 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -97,10 +97,7 @@ fix-revert-gas-refund-height = {{ .JSONRPC.FixRevertGasRefundHeight }} # A list of backup grpc address with block range # Example: "0.0.0.0:26113" = [0, 20] -[json-rpc.backup-grpc-address-block-range] -{{ range $k, $v := .JSONRPC.BackupGRPCBlockAddressBlockRange }} -"{{ $v }}" = [{{index $k 0 }}, {{ index $k 1}}] -{{ end }} +backup-grpc-address-block-range = "{{ "{" }}{{ range $k, $v := .JSONRPC.BackupGRPCBlockAddressBlockRange }}\"{{ $v }}\": [{{index $k 0 }}, {{ index $k 1}}]{{ end }}{{ "}" }}" ############################################################################### ### TLS Configuration ###