Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

- [\#589](https://github.com/cosmos/evm/pull/589) Remove parallelization blockers via migration from transient to object store, refactoring of gas, indexing, and bloom utilities.
- [\#768](https://github.com/cosmos/evm/pull/768) Added ICS-02 Client Router precompile
- [\#815](https://github.com/cosmos/evm/pull/815) Support for multi gRPC query clients serve with old binary.

### BUG FIXES

Expand Down
5 changes: 5 additions & 0 deletions evmd/tests/network/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
cmttime "github.com/cometbft/cometbft/types/time"

"github.com/cosmos/evm/server"
"github.com/cosmos/evm/server/config"
evmtypes "github.com/cosmos/evm/x/vm/types"

"cosmossdk.io/log"
Expand Down Expand Up @@ -129,6 +130,9 @@ func startInProcess(cfg Config, val *Validator) error {
return fmt.Errorf("validator %s context is nil", val.Moniker)
}

gprcClients := config.BackupGRPCConnections{
{0, 1}: val.ClientCtx.GRPCClient,
}
val.jsonrpc, err = server.StartJSONRPC(
ctx,
val.Ctx,
Expand All @@ -138,6 +142,7 @@ func startInProcess(cfg Config, val *Validator) error {
nil,
app.(server.AppWithPendingTxStream),
nil,
gprcClients,
)
if err != nil {
return err
Expand Down
24 changes: 16 additions & 8 deletions rpc/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/cosmos/evm/rpc/namespaces/ethereum/txpool"
"github.com/cosmos/evm/rpc/namespaces/ethereum/web3"
"github.com/cosmos/evm/rpc/stream"
"github.com/cosmos/evm/server/config"
servertypes "github.com/cosmos/evm/server/types"

"github.com/cosmos/cosmos-sdk/client"
Expand Down Expand Up @@ -49,6 +50,7 @@ type APICreator = func(
allowUnprotectedTxs bool,
indexer servertypes.EVMTxIndexer,
mempool *evmmempool.ExperimentalEVMMempool,
backupGRPCClientConns config.BackupGRPCConnections,
) []rpc.API

// apiCreators defines the JSON-RPC API namespaces.
Expand All @@ -62,8 +64,9 @@ func init() {
allowUnprotectedTxs bool,
indexer servertypes.EVMTxIndexer,
mempool *evmmempool.ExperimentalEVMMempool,
backupGRPCClientConns config.BackupGRPCConnections,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool, backupGRPCClientConns)
return []rpc.API{
{
Namespace: EthNamespace,
Expand All @@ -79,7 +82,7 @@ func init() {
},
}
},
Web3Namespace: func(*server.Context, client.Context, *stream.RPCStream, bool, servertypes.EVMTxIndexer, *evmmempool.ExperimentalEVMMempool) []rpc.API {
Web3Namespace: func(*server.Context, client.Context, *stream.RPCStream, bool, servertypes.EVMTxIndexer, *evmmempool.ExperimentalEVMMempool, config.BackupGRPCConnections) []rpc.API {
return []rpc.API{
{
Namespace: Web3Namespace,
Expand All @@ -89,7 +92,7 @@ func init() {
},
}
},
NetNamespace: func(ctx *server.Context, clientCtx client.Context, _ *stream.RPCStream, _ bool, _ servertypes.EVMTxIndexer, _ *evmmempool.ExperimentalEVMMempool) []rpc.API {
NetNamespace: func(ctx *server.Context, clientCtx client.Context, _ *stream.RPCStream, _ bool, _ servertypes.EVMTxIndexer, _ *evmmempool.ExperimentalEVMMempool, _ config.BackupGRPCConnections) []rpc.API {
return []rpc.API{
{
Namespace: NetNamespace,
Expand All @@ -105,8 +108,9 @@ func init() {
allowUnprotectedTxs bool,
indexer servertypes.EVMTxIndexer,
mempool *evmmempool.ExperimentalEVMMempool,
backupGRPCClientConns config.BackupGRPCConnections,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool, backupGRPCClientConns)
return []rpc.API{
{
Namespace: PersonalNamespace,
Expand All @@ -122,8 +126,9 @@ func init() {
allowUnprotectedTxs bool,
indexer servertypes.EVMTxIndexer,
mempool *evmmempool.ExperimentalEVMMempool,
backupGRPCClientConns config.BackupGRPCConnections,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool, backupGRPCClientConns)
return []rpc.API{
{
Namespace: TxPoolNamespace,
Expand All @@ -139,8 +144,9 @@ func init() {
allowUnprotectedTxs bool,
indexer servertypes.EVMTxIndexer,
mempool *evmmempool.ExperimentalEVMMempool,
backupGRPCClientConns config.BackupGRPCConnections,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool, backupGRPCClientConns)
return []rpc.API{
{
Namespace: DebugNamespace,
Expand All @@ -156,8 +162,9 @@ func init() {
allowUnprotectedTxs bool,
indexer servertypes.EVMTxIndexer,
mempool *evmmempool.ExperimentalEVMMempool,
backupGRPCClientConns config.BackupGRPCConnections,
) []rpc.API {
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, indexer, mempool, backupGRPCClientConns)
return []rpc.API{
{
Namespace: MinerNamespace,
Expand All @@ -178,12 +185,13 @@ func GetRPCAPIs(ctx *server.Context,
indexer servertypes.EVMTxIndexer,
selectedAPIs []string,
mempool *evmmempool.ExperimentalEVMMempool,
backupGRPCClientConns config.BackupGRPCConnections,
) []rpc.API {
var apis []rpc.API

for _, ns := range selectedAPIs {
if creator, ok := apiCreators[ns]; ok {
apis = append(apis, creator(ctx, clientCtx, stream, allowUnprotectedTxs, indexer, mempool)...)
apis = append(apis, creator(ctx, clientCtx, stream, allowUnprotectedTxs, indexer, mempool, backupGRPCClientConns)...)
} else {
ctx.Logger.Error("invalid namespace value", "namespace", ns)
}
Expand Down
16 changes: 10 additions & 6 deletions rpc/backend/account_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ func (b *Backend) GetCode(address common.Address, blockNrOrHash rpctypes.BlockNu
Address: address.String(),
}

res, err := b.QueryClient.Code(rpctypes.ContextWithHeight(blockNum.Int64()), req)
height := blockNum.Int64()
res, err := b.getGrpcClient(height).Code(rpctypes.ContextWithHeight(height), req)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -76,9 +77,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
}
Expand All @@ -95,14 +97,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 := bytes.HexBytes(append(authtypes.AddressStoreKeyPrefix, 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
}
Expand Down Expand Up @@ -135,7 +137,8 @@ func (b *Backend) GetStorageAt(address common.Address, key string, blockNrOrHash
Key: key,
}

res, err := b.QueryClient.Storage(rpctypes.ContextWithHeight(blockNum.Int64()), req)
height := blockNum.Int64()
res, err := b.getGrpcClient(height).Storage(rpctypes.ContextWithHeight(height), req)
if err != nil {
return nil, err
}
Expand All @@ -160,7 +163,8 @@ func (b *Backend) GetBalance(address common.Address, blockNrOrHash rpctypes.Bloc
return nil, err
}

res, err := b.QueryClient.Balance(rpctypes.ContextWithHeight(blockNum.Int64()), req)
height := blockNum.Int64()
res, err := b.getGrpcClient(height).Balance(rpctypes.ContextWithHeight(height), req)
if err != nil {
return nil, err
}
Expand Down
12 changes: 12 additions & 0 deletions rpc/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/cosmos/evm/rpc/types"
"github.com/cosmos/evm/server/config"
servertypes "github.com/cosmos/evm/server/types"
feemarkettypes "github.com/cosmos/evm/x/feemarket/types"
evmtypes "github.com/cosmos/evm/x/vm/types"

"cosmossdk.io/log"
Expand All @@ -30,6 +31,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"
)

// BackendI implements the Cosmos and EVM backend.
Expand Down Expand Up @@ -173,6 +175,7 @@ type Backend struct {
Indexer servertypes.EVMTxIndexer
ProcessBlocker ProcessBlocker
Mempool *evmmempool.ExperimentalEVMMempool
BackupQueryClients map[config.BlockRange]*types.QueryClient
}

func (b *Backend) GetConfig() config.Config {
Expand All @@ -187,6 +190,7 @@ func NewBackend(
allowUnprotectedTxs bool,
indexer servertypes.EVMTxIndexer,
mempool *evmmempool.ExperimentalEVMMempool,
backupGRPCClientConns config.BackupGRPCConnections,
) *Backend {
appConf, err := config.GetConfig(ctx.Viper)
if err != nil {
Expand All @@ -209,7 +213,15 @@ func NewBackend(
AllowUnprotectedTxs: allowUnprotectedTxs,
Indexer: indexer,
Mempool: mempool,
BackupQueryClients: make(map[config.BlockRange]*types.QueryClient),
}
b.ProcessBlocker = b.ProcessBlock
for key, conn := range backupGRPCClientConns {
b.BackupQueryClients[key] = &types.QueryClient{
ServiceClient: tx.NewServiceClient(conn),
QueryClient: evmtypes.NewQueryClient(conn),
FeeMarket: feemarkettypes.NewQueryClient(conn),
}
}
return b
}
1 change: 1 addition & 0 deletions rpc/backend/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,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
Expand Down
5 changes: 3 additions & 2 deletions rpc/backend/call_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@ func (b *Backend) EstimateGas(
// 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.
res, err := b.QueryClient.EstimateGas(rpctypes.ContextWithHeight(blockNr.Int64()), &req)
height := blockNr.Int64()
res, err := b.getGrpcClient(height).EstimateGas(rpctypes.ContextWithHeight(height), &req)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -416,7 +417,7 @@ func (b *Backend) DoCall(
// this makes sure resources are cleaned up.
defer cancel()

res, err := b.QueryClient.EthCall(ctx, &req)
res, err := b.getGrpcClient(blockNr.Int64()).EthCall(ctx, &req)
if err != nil {
return nil, err
}
Expand Down
6 changes: 5 additions & 1 deletion rpc/backend/chain_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (b *Backend) ChainConfig() *params.ChainConfig {

// GlobalMinGasPrice returns MinGasPrice param from FeeMarket
func (b *Backend) GlobalMinGasPrice() (*big.Int, error) {
// use latest queryClient to get GlobalMinGasPrice
res, err := b.QueryClient.GlobalMinGasPrice(b.Ctx, &evmtypes.QueryGlobalMinGasPriceRequest{})
if err != nil {
return nil, err
Expand All @@ -65,7 +66,8 @@ func (b *Backend) GlobalMinGasPrice() (*big.Int, error) {
// return nil.
func (b *Backend) BaseFee(blockRes *cmtrpctypes.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
res, err := b.getGrpcClient(height).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,
Expand Down Expand Up @@ -138,6 +140,7 @@ func (b *Backend) GetCoinbase() (sdk.AccAddress, error) {
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
Expand Down Expand Up @@ -326,6 +329,7 @@ func (b *Backend) SuggestGasTipCap(baseFee *big.Int) (*big.Int, error) {
return big.NewInt(0), nil
}

// use latest queryClient to get params
params, err := b.QueryClient.FeeMarket.Params(b.Ctx, &feemarkettypes.QueryParamsRequest{})
if err != nil {
return nil, err
Expand Down
1 change: 1 addition & 0 deletions rpc/backend/comet_to_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ func (b *Backend) MinerFromCometBlock(
var validatorAccAddr sdk.AccAddress

ctx := rpctypes.ContextWithHeight(cmtBlock.Height)
// use latest queryClient to get miner
res, err := b.QueryClient.ValidatorAccount(ctx, req)
if err != nil {
b.Logger.Debug(
Expand Down
6 changes: 3 additions & 3 deletions rpc/backend/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (b *Backend) TraceTransaction(hash common.Hash, config *rpctypes.TraceConfi
// So here we set the minimum requested height to 1.
contextHeight = 1
}
traceResult, err := b.QueryClient.TraceTx(rpctypes.ContextWithHeight(contextHeight), &traceTxRequest)
traceResult, err := b.getGrpcClient(contextHeight).TraceTx(rpctypes.ContextWithHeight(contextHeight), &traceTxRequest)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -218,7 +218,7 @@ func (b *Backend) TraceBlock(height rpctypes.BlockNumber,
BlockMaxGas: cp.ConsensusParams.Block.MaxGas,
}

res, err := b.QueryClient.TraceBlock(ctxWithHeight, traceBlockRequest)
res, err := b.getGrpcClient(int64(contextHeight)).TraceBlock(ctxWithHeight, traceBlockRequest)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -281,7 +281,7 @@ func (b *Backend) TraceCall(

// Use the block height as context for the query
ctxWithHeight := rpctypes.ContextWithHeight(contextHeight)
traceResult, err := b.QueryClient.TraceCall(ctxWithHeight, &traceCallRequest)
traceResult, err := b.getGrpcClient(contextHeight).TraceCall(ctxWithHeight, &traceCallRequest)
if err != nil {
return nil, err
}
Expand Down
3 changes: 2 additions & 1 deletion rpc/backend/tx_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/cosmos/evm/indexer"
"github.com/cosmos/evm/rpc/backend/mocks"
rpctypes "github.com/cosmos/evm/rpc/types"
"github.com/cosmos/evm/server/config"
servertypes "github.com/cosmos/evm/server/types"
"github.com/cosmos/evm/testutil/constants"
utiltx "github.com/cosmos/evm/testutil/tx"
Expand Down Expand Up @@ -68,7 +69,7 @@ func setupMockBackend(t *testing.T) *Backend {
allowUnprotectedTxs := false
idxer := indexer.NewKVIndexer(dbm.NewMemDB(), ctx.Logger, clientCtx)

backend := NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, idxer, nil)
backend := NewBackend(ctx, ctx.Logger, clientCtx, allowUnprotectedTxs, idxer, nil, make(config.BackupGRPCConnections))
backend.Cfg.JSONRPC.GasCap = 25000000
backend.Cfg.JSONRPC.EVMTimeout = 0
backend.Cfg.JSONRPC.AllowInsecureUnlock = true
Expand Down
16 changes: 16 additions & 0 deletions rpc/backend/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@

if cfg.IsLondon(big.NewInt(blockHeight + 1)) {
ctx := types.ContextWithHeight(blockHeight)
// use latest queryClient to get params
params, err := b.QueryClient.FeeMarket.Params(ctx, &feemarkettypes.QueryParamsRequest{})
if err != nil {
return err
Expand Down Expand Up @@ -337,3 +338,18 @@
}
return proofs
}

func (b *Backend) getGrpcClient(height int64) *types.QueryClient {
// height = 0 means latest block, use the default client
if height <= 0 {
return b.QueryClient
}
for blocks, client := range b.BackupQueryClients {
// b1-b2 -> g1
// b3-b4 -> g2
if int64(blocks[0]) <= height && int64(blocks[1]) >= height {
return client
}
}
Comment on lines +347 to +353

Check warning

Code scanning / CodeQL

Iteration over map Warning

Iteration over map may be a possible source of non-determinism
return b.QueryClient
}
Loading
Loading