Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

rpc: refactor rpc packages and backend to support cosmos namespace #1070

Merged
merged 5 commits into from
May 2, 2022
Merged
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ Ref: https://keepachangelog.com/en/1.0.0/

## Unreleased

### API Breaking

* (rpc) [tharsis#1070](https://github.com/tharsis/ethermint/pull/1070) Refactor `rpc/` package:
* `Backend` interface is now `BackendI`, which implements `EVMBackend` (for Ethereum namespaces) and `CosmosBackend` (for Cosmos namespaces)
* Previous `EVMBackend` type is now `Backend`, which is the concrete implementation of `BackendI`
* Move `rpc/ethereum/types` -> `rpc/types`
* Move `rpc/ethereum/backend` -> `rpc/backend`
* Move `rpc/ethereum/namespaces` -> `rpc/namespaces/ethereum`

### Bug Fixes

* (rpc) [tharsis#1059](https://github.com/tharsis/ethermint/pull/1059) Remove unnecessary event filtering logic on the `eth_baseFee` JSON-RPC endpoint.
Expand Down
38 changes: 22 additions & 16 deletions rpc/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,28 @@ import (

"github.com/ethereum/go-ethereum/rpc"

"github.com/tharsis/ethermint/rpc/ethereum/backend"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/debug"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/eth"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/eth/filters"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/miner"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/net"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/personal"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/txpool"
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/web3"
"github.com/tharsis/ethermint/rpc/ethereum/types"
"github.com/tharsis/ethermint/rpc/backend"
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/debug"
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/eth"
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/eth/filters"
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/miner"
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/net"
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/personal"
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/txpool"
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/web3"
"github.com/tharsis/ethermint/rpc/types"

rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
)

// RPC namespaces and API version
const (
// Cosmos namespaces

CosmosNamespace = "cosmos"

// Ethereum namespaces

Web3Namespace = "web3"
EthNamespace = "eth"
PersonalNamespace = "personal"
Expand All @@ -37,17 +43,17 @@ const (
apiVersion = "1.0"
)

// APICreator creates the json-rpc api implementations.
// APICreator creates the JSON-RPC API implementations.
type APICreator = func(*server.Context, client.Context, *rpcclient.WSClient) []rpc.API

// apiCreators defines the json-rpc api namespaces.
// apiCreators defines the JSON-RPC API namespaces.
var apiCreators map[string]APICreator

func init() {
apiCreators = map[string]APICreator{
EthNamespace: func(ctx *server.Context, clientCtx client.Context, tmWSClient *rpcclient.WSClient) []rpc.API {
nonceLock := new(types.AddrLocker)
evmBackend := backend.NewEVMBackend(ctx, ctx.Logger, clientCtx)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx)
return []rpc.API{
{
Namespace: EthNamespace,
Expand Down Expand Up @@ -84,7 +90,7 @@ func init() {
}
},
PersonalNamespace: func(ctx *server.Context, clientCtx client.Context, _ *rpcclient.WSClient) []rpc.API {
evmBackend := backend.NewEVMBackend(ctx, ctx.Logger, clientCtx)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx)
return []rpc.API{
{
Namespace: PersonalNamespace,
Expand All @@ -105,7 +111,7 @@ func init() {
}
},
DebugNamespace: func(ctx *server.Context, clientCtx client.Context, _ *rpcclient.WSClient) []rpc.API {
evmBackend := backend.NewEVMBackend(ctx, ctx.Logger, clientCtx)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx)
return []rpc.API{
{
Namespace: DebugNamespace,
Expand All @@ -116,7 +122,7 @@ func init() {
}
},
MinerNamespace: func(ctx *server.Context, clientCtx client.Context, _ *rpcclient.WSClient) []rpc.API {
evmBackend := backend.NewEVMBackend(ctx, ctx.Logger, clientCtx)
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx)
return []rpc.API{
{
Namespace: MinerNamespace,
Expand Down
114 changes: 114 additions & 0 deletions rpc/backend/backend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package backend

import (
"context"
"math/big"
"time"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
"github.com/tendermint/tendermint/libs/log"
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tharsis/ethermint/rpc/types"
"github.com/tharsis/ethermint/server/config"
ethermint "github.com/tharsis/ethermint/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)

// BackendI implements the Cosmos and EVM backend.
type BackendI interface { // nolint: revive
CosmosBackend
EVMBackend
}

// CosmosBackend implements the functionality shared within cosmos namespaces
// as defined by Wallet Connect V2: https://docs.walletconnect.com/2.0/json-rpc/cosmos.
// Implemented by Backend.
type CosmosBackend interface {
// TODO: define
// GetAccounts()
// SignDirect()
// SignAmino()
}

// EVMBackend implements the functionality shared within ethereum namespaces
// as defined by EIP-1474: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md
// Implemented by Backend.
type EVMBackend interface {
// General Ethereum API
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection
RPCTxFeeCap() float64 // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for send-transaction variants. The unit is ether.

RPCMinGasPrice() int64
SuggestGasTipCap(baseFee *big.Int) (*big.Int, error)

// Blockchain API
BlockNumber() (hexutil.Uint64, error)
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
GetTendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error)
GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error)
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
BlockByNumber(blockNum types.BlockNumber) (*ethtypes.Block, error)
BlockByHash(blockHash common.Hash) (*ethtypes.Block, error)
CurrentHeader() *ethtypes.Header
HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error)
HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
PendingTransactions() ([]*sdk.Tx, error)
GetTransactionCount(address common.Address, blockNum types.BlockNumber) (*hexutil.Uint64, error)
SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error)
GetCoinbase() (sdk.AccAddress, error)
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
GetTxByTxIndex(height int64, txIndex uint) (*tmrpctypes.ResultTx, error)
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
BaseFee(height int64) (*big.Int, error)

// Fee API
FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*types.FeeHistoryResult, error)

// Filter API
BloomStatus() (uint64, uint64)
GetLogs(hash common.Hash) ([][]*ethtypes.Log, error)
GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error)
ChainConfig() *params.ChainConfig
SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error)
GetEthereumMsgsFromTendermintBlock(block *tmrpctypes.ResultBlock, blockRes *tmrpctypes.ResultBlockResults) []*evmtypes.MsgEthereumTx
}

var _ BackendI = (*Backend)(nil)

// Backend implements the BackendI interface
type Backend struct {
ctx context.Context
clientCtx client.Context
queryClient *types.QueryClient // gRPC query client
logger log.Logger
chainID *big.Int
cfg config.Config
}

// NewBackend creates a new Backend instance for cosmos and ethereum namespaces
func NewBackend(ctx *server.Context, logger log.Logger, clientCtx client.Context) *Backend {
chainID, err := ethermint.ParseChainID(clientCtx.ChainID)
if err != nil {
panic(err)
}

appConf := config.GetConfig(ctx.Viper)

return &Backend{
ctx: context.Background(),
clientCtx: clientCtx,
queryClient: types.NewQueryClient(clientCtx),
logger: logger.With("module", "backend"),
chainID: chainID,
cfg: appConf,
}
}
Loading