diff --git a/ethereum/rpc/backend/backend.go b/ethereum/rpc/backend/backend.go index b6ad57a3..871e4772 100644 --- a/ethereum/rpc/backend/backend.go +++ b/ethereum/rpc/backend/backend.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/server" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/params" tmrpctypes "github.com/tendermint/tendermint/rpc/core/types" "google.golang.org/grpc" @@ -43,6 +44,7 @@ type Backend interface { GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error) + CurrentHeader() *ethtypes.Header HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error) PendingTransactions() ([]*sdk.Tx, error) @@ -58,6 +60,8 @@ type Backend interface { EstimateGas(args evmtypes.CallArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error) RPCGasCap() uint64 RPCMinGasPrice() int64 + ChainConfig() *params.ChainConfig + SuggestGasTipCap() (*big.Int, error) GetFilteredBlocks(from int64, to int64, filter [][]filters.BloomIV, filterAddresses bool) ([]int64, error) } @@ -274,9 +278,16 @@ func (e *EVMBackend) EthBlockFromTendermint( ConsAddress: sdk.ConsAddress(block.Header.ProposerAddress).String(), } - res, err := e.queryClient.ValidatorAccount(e.ctx, req) + ctx := types.ContextWithHeight(block.Height) + + res, err := e.queryClient.ValidatorAccount(ctx, req) if err != nil { - e.logger.Debug("failed to query validator operator address", "cons-address", req.ConsAddress, "error", err.Error()) + e.logger.Debug( + "failed to query validator operator address", + "height", block.Height, + "cons-address", req.ConsAddress, + "error", err.Error(), + ) return nil, err } @@ -287,7 +298,7 @@ func (e *EVMBackend) EthBlockFromTendermint( validatorAddr := common.BytesToAddress(addr) - gasLimit, err := types.BlockMaxGasFromConsensusParams(types.ContextWithHeight(block.Height), e.clientCtx) + gasLimit, err := types.BlockMaxGasFromConsensusParams(ctx, e.clientCtx) if err != nil { e.logger.Error("failed to query consensus params", "error", err.Error()) } @@ -308,6 +319,12 @@ func (e *EVMBackend) EthBlockFromTendermint( return formattedBlock, nil } +// CurrentHeader returns the latest block header +func (e *EVMBackend) CurrentHeader() *ethtypes.Header { + header, _ := e.HeaderByNumber(types.EthLatestBlockNumber) + return header +} + // HeaderByNumber returns the block header identified by height. func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error) { height := blockNum.Int64() @@ -716,6 +733,22 @@ func (e *EVMBackend) RPCMinGasPrice() int64 { return ethermint.DefaultGasPrice } +// ChainConfig return the ethereum chain configuration +func (e *EVMBackend) ChainConfig() *params.ChainConfig { + params, err := e.queryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{}) + if err != nil { + return nil + } + + return params.Params.ChainConfig.EthereumConfig(e.chainID) +} + +// SuggestGasTipCap returns the suggested tip cap +func (e *EVMBackend) SuggestGasTipCap() (*big.Int, error) { + // TODO: implement + return big.NewInt(1), nil +} + // GetFilteredBlocks returns the block height list match the given bloom filters. func (e *EVMBackend) GetFilteredBlocks( from int64, diff --git a/ethereum/rpc/backend/utils.go b/ethereum/rpc/backend/utils.go index 33e5d2a1..192a5899 100644 --- a/ethereum/rpc/backend/utils.go +++ b/ethereum/rpc/backend/utils.go @@ -47,7 +47,7 @@ func (e *EVMBackend) setTxDefaults(args types.SendTxArgs) (types.SendTxArgs, err } if len(input) == 0 { - return args, errors.New(`contract creation without any data provided`) + return args, errors.New("contract creation without any data provided") } } diff --git a/ethereum/rpc/namespaces/personal/api.go b/ethereum/rpc/namespaces/personal/api.go index bd4b7004..14cf918f 100644 --- a/ethereum/rpc/namespaces/personal/api.go +++ b/ethereum/rpc/namespaces/personal/api.go @@ -152,6 +152,15 @@ func (api *PrivateAccountAPI) UnlockAccount(_ context.Context, addr common.Addre // able to decrypt the key it fails. func (api *PrivateAccountAPI) SendTransaction(_ context.Context, args rpctypes.SendTxArgs, pwrd string) (common.Hash, error) { api.logger.Debug("personal_sendTransaction", "address", args.To.String()) + + addr := sdk.AccAddress(args.From.Bytes()) + + // check if the key is on the keyring + _, err := api.clientCtx.Keyring.KeyByAddress(addr) + if err != nil { + return common.Hash{}, err + } + return api.backend.SendTransaction(args) } diff --git a/ethereum/rpc/types/query_client.go b/ethereum/rpc/types/query_client.go index 16b09c16..e5e2be4b 100644 --- a/ethereum/rpc/types/query_client.go +++ b/ethereum/rpc/types/query_client.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" evmtypes "github.com/tharsis/ethermint/x/evm/types" + feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types" ) // QueryClient defines a gRPC Client used for: @@ -19,6 +20,7 @@ import ( type QueryClient struct { tx.ServiceClient evmtypes.QueryClient + FeeMarket feemarkettypes.QueryClient } // NewQueryClient creates a new gRPC query client @@ -26,6 +28,7 @@ func NewQueryClient(clientCtx client.Context) *QueryClient { return &QueryClient{ ServiceClient: tx.NewServiceClient(clientCtx), QueryClient: evmtypes.NewQueryClient(clientCtx), + FeeMarket: feemarkettypes.NewQueryClient(clientCtx), } }