rpc: refactor rpc packages and backend to support cosmos namespace (#1070)
* rpc: refactor rpc packages and backend to support cosmos namespace * changelog * typo
This commit is contained in:
parent
556c2cc8a3
commit
c25669c761
@ -38,6 +38,15 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
## Unreleased
|
## 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
|
### Bug Fixes
|
||||||
|
|
||||||
* (rpc) [tharsis#1059](https://github.com/tharsis/ethermint/pull/1059) Remove unnecessary event filtering logic on the `eth_baseFee` JSON-RPC endpoint.
|
* (rpc) [tharsis#1059](https://github.com/tharsis/ethermint/pull/1059) Remove unnecessary event filtering logic on the `eth_baseFee` JSON-RPC endpoint.
|
||||||
|
38
rpc/apis.go
38
rpc/apis.go
@ -10,22 +10,28 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/backend"
|
"github.com/tharsis/ethermint/rpc/backend"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/debug"
|
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/debug"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/eth"
|
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/eth"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/eth/filters"
|
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/eth/filters"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/miner"
|
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/miner"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/net"
|
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/net"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/personal"
|
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/personal"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/txpool"
|
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/txpool"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/namespaces/web3"
|
"github.com/tharsis/ethermint/rpc/namespaces/ethereum/web3"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/types"
|
"github.com/tharsis/ethermint/rpc/types"
|
||||||
|
|
||||||
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
|
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RPC namespaces and API version
|
// RPC namespaces and API version
|
||||||
const (
|
const (
|
||||||
|
// Cosmos namespaces
|
||||||
|
|
||||||
|
CosmosNamespace = "cosmos"
|
||||||
|
|
||||||
|
// Ethereum namespaces
|
||||||
|
|
||||||
Web3Namespace = "web3"
|
Web3Namespace = "web3"
|
||||||
EthNamespace = "eth"
|
EthNamespace = "eth"
|
||||||
PersonalNamespace = "personal"
|
PersonalNamespace = "personal"
|
||||||
@ -37,17 +43,17 @@ const (
|
|||||||
apiVersion = "1.0"
|
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
|
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
|
var apiCreators map[string]APICreator
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
apiCreators = map[string]APICreator{
|
apiCreators = map[string]APICreator{
|
||||||
EthNamespace: func(ctx *server.Context, clientCtx client.Context, tmWSClient *rpcclient.WSClient) []rpc.API {
|
EthNamespace: func(ctx *server.Context, clientCtx client.Context, tmWSClient *rpcclient.WSClient) []rpc.API {
|
||||||
nonceLock := new(types.AddrLocker)
|
nonceLock := new(types.AddrLocker)
|
||||||
evmBackend := backend.NewEVMBackend(ctx, ctx.Logger, clientCtx)
|
evmBackend := backend.NewBackend(ctx, ctx.Logger, clientCtx)
|
||||||
return []rpc.API{
|
return []rpc.API{
|
||||||
{
|
{
|
||||||
Namespace: EthNamespace,
|
Namespace: EthNamespace,
|
||||||
@ -84,7 +90,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
PersonalNamespace: func(ctx *server.Context, clientCtx client.Context, _ *rpcclient.WSClient) []rpc.API {
|
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{
|
return []rpc.API{
|
||||||
{
|
{
|
||||||
Namespace: PersonalNamespace,
|
Namespace: PersonalNamespace,
|
||||||
@ -105,7 +111,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
DebugNamespace: func(ctx *server.Context, clientCtx client.Context, _ *rpcclient.WSClient) []rpc.API {
|
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{
|
return []rpc.API{
|
||||||
{
|
{
|
||||||
Namespace: DebugNamespace,
|
Namespace: DebugNamespace,
|
||||||
@ -116,7 +122,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
MinerNamespace: func(ctx *server.Context, clientCtx client.Context, _ *rpcclient.WSClient) []rpc.API {
|
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{
|
return []rpc.API{
|
||||||
{
|
{
|
||||||
Namespace: MinerNamespace,
|
Namespace: MinerNamespace,
|
||||||
|
114
rpc/backend/backend.go
Normal file
114
rpc/backend/backend.go
Normal file
@ -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,
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -6,27 +6,47 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sort"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/tharsis/ethermint/rpc/types"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/types"
|
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type txGasAndReward struct {
|
||||||
|
gasUsed uint64
|
||||||
|
reward *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
type sortGasAndReward []txGasAndReward
|
||||||
|
|
||||||
|
func (s sortGasAndReward) Len() int { return len(s) }
|
||||||
|
func (s sortGasAndReward) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s sortGasAndReward) Less(i, j int) bool {
|
||||||
|
return s[i].reward.Cmp(s[j].reward) < 0
|
||||||
|
}
|
||||||
|
|
||||||
// SetTxDefaults populates tx message with default values in case they are not
|
// SetTxDefaults populates tx message with default values in case they are not
|
||||||
// provided on the args
|
// provided on the args
|
||||||
func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) {
|
func (b *Backend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) {
|
||||||
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
||||||
return args, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
return args, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
head := e.CurrentHeader()
|
head := b.CurrentHeader()
|
||||||
if head == nil {
|
if head == nil {
|
||||||
return args, errors.New("latest header is nil")
|
return args, errors.New("latest header is nil")
|
||||||
}
|
}
|
||||||
@ -37,7 +57,7 @@ func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.Tran
|
|||||||
// In this clause, user left some fields unspecified.
|
// In this clause, user left some fields unspecified.
|
||||||
if head.BaseFee != nil && args.GasPrice == nil {
|
if head.BaseFee != nil && args.GasPrice == nil {
|
||||||
if args.MaxPriorityFeePerGas == nil {
|
if args.MaxPriorityFeePerGas == nil {
|
||||||
tip, err := e.SuggestGasTipCap(head.BaseFee)
|
tip, err := b.SuggestGasTipCap(head.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return args, err
|
return args, err
|
||||||
}
|
}
|
||||||
@ -62,7 +82,7 @@ func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.Tran
|
|||||||
}
|
}
|
||||||
|
|
||||||
if args.GasPrice == nil {
|
if args.GasPrice == nil {
|
||||||
price, err := e.SuggestGasTipCap(head.BaseFee)
|
price, err := b.SuggestGasTipCap(head.BaseFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return args, err
|
return args, err
|
||||||
}
|
}
|
||||||
@ -88,7 +108,7 @@ func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.Tran
|
|||||||
if args.Nonce == nil {
|
if args.Nonce == nil {
|
||||||
// get the nonce from the account retriever
|
// get the nonce from the account retriever
|
||||||
// ignore error in case tge account doesn't exist yet
|
// ignore error in case tge account doesn't exist yet
|
||||||
nonce, _ := e.getAccountNonce(*args.From, true, 0, e.logger)
|
nonce, _ := b.getAccountNonce(*args.From, true, 0, b.logger)
|
||||||
args.Nonce = (*hexutil.Uint64)(&nonce)
|
args.Nonce = (*hexutil.Uint64)(&nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,16 +151,16 @@ func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.Tran
|
|||||||
}
|
}
|
||||||
|
|
||||||
blockNr := types.NewBlockNumber(big.NewInt(0))
|
blockNr := types.NewBlockNumber(big.NewInt(0))
|
||||||
estimated, err := e.EstimateGas(callArgs, &blockNr)
|
estimated, err := b.EstimateGas(callArgs, &blockNr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return args, err
|
return args, err
|
||||||
}
|
}
|
||||||
args.Gas = &estimated
|
args.Gas = &estimated
|
||||||
e.logger.Debug("estimate gas usage automatically", "gas", args.Gas)
|
b.logger.Debug("estimate gas usage automatically", "gas", args.Gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.ChainID == nil {
|
if args.ChainID == nil {
|
||||||
args.ChainID = (*hexutil.Big)(e.chainID)
|
args.ChainID = (*hexutil.Big)(b.chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return args, nil
|
return args, nil
|
||||||
@ -150,14 +170,14 @@ func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.Tran
|
|||||||
// If the pending value is true, it will iterate over the mempool (pending)
|
// If the pending value is true, it will iterate over the mempool (pending)
|
||||||
// txs in order to compute and return the pending tx sequence.
|
// txs in order to compute and return the pending tx sequence.
|
||||||
// Todo: include the ability to specify a blockNumber
|
// Todo: include the ability to specify a blockNumber
|
||||||
func (e *EVMBackend) getAccountNonce(accAddr common.Address, pending bool, height int64, logger log.Logger) (uint64, error) {
|
func (b *Backend) getAccountNonce(accAddr common.Address, pending bool, height int64, logger log.Logger) (uint64, error) {
|
||||||
queryClient := authtypes.NewQueryClient(e.clientCtx)
|
queryClient := authtypes.NewQueryClient(b.clientCtx)
|
||||||
res, err := queryClient.Account(types.ContextWithHeight(height), &authtypes.QueryAccountRequest{Address: sdk.AccAddress(accAddr.Bytes()).String()})
|
res, err := queryClient.Account(types.ContextWithHeight(height), &authtypes.QueryAccountRequest{Address: sdk.AccAddress(accAddr.Bytes()).String()})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
var acc authtypes.AccountI
|
var acc authtypes.AccountI
|
||||||
if err := e.clientCtx.InterfaceRegistry.UnpackAny(res.Account, &acc); err != nil {
|
if err := b.clientCtx.InterfaceRegistry.UnpackAny(res.Account, &acc); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +189,7 @@ func (e *EVMBackend) getAccountNonce(accAddr common.Address, pending bool, heigh
|
|||||||
|
|
||||||
// the account retriever doesn't include the uncommitted transactions on the nonce so we need to
|
// the account retriever doesn't include the uncommitted transactions on the nonce so we need to
|
||||||
// to manually add them.
|
// to manually add them.
|
||||||
pendingTxs, err := e.PendingTransactions()
|
pendingTxs, err := b.PendingTransactions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("failed to fetch pending transactions", "error", err.Error())
|
logger.Error("failed to fetch pending transactions", "error", err.Error())
|
||||||
return nonce, nil
|
return nonce, nil
|
||||||
@ -185,7 +205,7 @@ func (e *EVMBackend) getAccountNonce(accAddr common.Address, pending bool, heigh
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
sender, err := ethMsg.GetSender(e.chainID)
|
sender, err := ethMsg.GetSender(b.chainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -198,6 +218,104 @@ func (e *EVMBackend) getAccountNonce(accAddr common.Address, pending bool, heigh
|
|||||||
return nonce, nil
|
return nonce, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// output: targetOneFeeHistory
|
||||||
|
func (b *Backend) processBlock(
|
||||||
|
tendermintBlock *tmrpctypes.ResultBlock,
|
||||||
|
ethBlock *map[string]interface{},
|
||||||
|
rewardPercentiles []float64,
|
||||||
|
tendermintBlockResult *tmrpctypes.ResultBlockResults,
|
||||||
|
targetOneFeeHistory *types.OneFeeHistory,
|
||||||
|
) error {
|
||||||
|
blockHeight := tendermintBlock.Block.Height
|
||||||
|
blockBaseFee, err := b.BaseFee(blockHeight)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// set basefee
|
||||||
|
targetOneFeeHistory.BaseFee = blockBaseFee
|
||||||
|
|
||||||
|
// set gas used ratio
|
||||||
|
gasLimitUint64, ok := (*ethBlock)["gasLimit"].(hexutil.Uint64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid gas limit type: %T", (*ethBlock)["gasLimit"])
|
||||||
|
}
|
||||||
|
|
||||||
|
gasUsedBig, ok := (*ethBlock)["gasUsed"].(*hexutil.Big)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid gas used type: %T", (*ethBlock)["gasUsed"])
|
||||||
|
}
|
||||||
|
|
||||||
|
gasusedfloat, _ := new(big.Float).SetInt(gasUsedBig.ToInt()).Float64()
|
||||||
|
|
||||||
|
if gasLimitUint64 <= 0 {
|
||||||
|
return fmt.Errorf("gasLimit of block height %d should be bigger than 0 , current gaslimit %d", blockHeight, gasLimitUint64)
|
||||||
|
}
|
||||||
|
|
||||||
|
gasUsedRatio := gasusedfloat / float64(gasLimitUint64)
|
||||||
|
blockGasUsed := gasusedfloat
|
||||||
|
targetOneFeeHistory.GasUsedRatio = gasUsedRatio
|
||||||
|
|
||||||
|
rewardCount := len(rewardPercentiles)
|
||||||
|
targetOneFeeHistory.Reward = make([]*big.Int, rewardCount)
|
||||||
|
for i := 0; i < rewardCount; i++ {
|
||||||
|
targetOneFeeHistory.Reward[i] = big.NewInt(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check tendermintTxs
|
||||||
|
tendermintTxs := tendermintBlock.Block.Txs
|
||||||
|
tendermintTxResults := tendermintBlockResult.TxsResults
|
||||||
|
tendermintTxCount := len(tendermintTxs)
|
||||||
|
|
||||||
|
var sorter sortGasAndReward
|
||||||
|
|
||||||
|
for i := 0; i < tendermintTxCount; i++ {
|
||||||
|
eachTendermintTx := tendermintTxs[i]
|
||||||
|
eachTendermintTxResult := tendermintTxResults[i]
|
||||||
|
|
||||||
|
tx, err := b.clientCtx.TxConfig.TxDecoder()(eachTendermintTx)
|
||||||
|
if err != nil {
|
||||||
|
b.logger.Debug("failed to decode transaction in block", "height", blockHeight, "error", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
txGasUsed := uint64(eachTendermintTxResult.GasUsed)
|
||||||
|
for _, msg := range tx.GetMsgs() {
|
||||||
|
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tx := ethMsg.AsTransaction()
|
||||||
|
reward := tx.EffectiveGasTipValue(blockBaseFee)
|
||||||
|
if reward == nil {
|
||||||
|
reward = big.NewInt(0)
|
||||||
|
}
|
||||||
|
sorter = append(sorter, txGasAndReward{gasUsed: txGasUsed, reward: reward})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return an all zero row if there are no transactions to gather data from
|
||||||
|
ethTxCount := len(sorter)
|
||||||
|
if ethTxCount == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(sorter)
|
||||||
|
|
||||||
|
var txIndex int
|
||||||
|
sumGasUsed := sorter[0].gasUsed
|
||||||
|
|
||||||
|
for i, p := range rewardPercentiles {
|
||||||
|
thresholdGasUsed := uint64(blockGasUsed * p / 100)
|
||||||
|
for sumGasUsed < thresholdGasUsed && txIndex < ethTxCount-1 {
|
||||||
|
txIndex++
|
||||||
|
sumGasUsed += sorter[txIndex].gasUsed
|
||||||
|
}
|
||||||
|
targetOneFeeHistory.Reward[i] = sorter[txIndex].reward
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// AllTxLogsFromEvents parses all ethereum logs from cosmos events
|
// AllTxLogsFromEvents parses all ethereum logs from cosmos events
|
||||||
func AllTxLogsFromEvents(events []abci.Event) ([][]*ethtypes.Log, error) {
|
func AllTxLogsFromEvents(events []abci.Event) ([][]*ethtypes.Log, error) {
|
||||||
allLogs := make([][]*ethtypes.Log, 0, 4)
|
allLogs := make([][]*ethtypes.Log, 0, 4)
|
@ -1,223 +0,0 @@
|
|||||||
package backend
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
|
||||||
tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
|
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
txGasAndReward struct {
|
|
||||||
gasUsed uint64
|
|
||||||
reward *big.Int
|
|
||||||
}
|
|
||||||
sortGasAndReward []txGasAndReward
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s sortGasAndReward) Len() int { return len(s) }
|
|
||||||
func (s sortGasAndReward) Swap(i, j int) {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s sortGasAndReward) Less(i, j int) bool {
|
|
||||||
return s[i].reward.Cmp(s[j].reward) < 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// output: targetOneFeeHistory
|
|
||||||
func (e *EVMBackend) processBlock(
|
|
||||||
tendermintBlock *tmrpctypes.ResultBlock,
|
|
||||||
ethBlock *map[string]interface{},
|
|
||||||
rewardPercentiles []float64,
|
|
||||||
tendermintBlockResult *tmrpctypes.ResultBlockResults,
|
|
||||||
targetOneFeeHistory *rpctypes.OneFeeHistory,
|
|
||||||
) error {
|
|
||||||
blockHeight := tendermintBlock.Block.Height
|
|
||||||
blockBaseFee, err := e.BaseFee(blockHeight)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// set basefee
|
|
||||||
targetOneFeeHistory.BaseFee = blockBaseFee
|
|
||||||
|
|
||||||
// set gas used ratio
|
|
||||||
gasLimitUint64, ok := (*ethBlock)["gasLimit"].(hexutil.Uint64)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("invalid gas limit type: %T", (*ethBlock)["gasLimit"])
|
|
||||||
}
|
|
||||||
|
|
||||||
gasUsedBig, ok := (*ethBlock)["gasUsed"].(*hexutil.Big)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("invalid gas used type: %T", (*ethBlock)["gasUsed"])
|
|
||||||
}
|
|
||||||
|
|
||||||
gasusedfloat, _ := new(big.Float).SetInt(gasUsedBig.ToInt()).Float64()
|
|
||||||
|
|
||||||
if gasLimitUint64 <= 0 {
|
|
||||||
return fmt.Errorf("gasLimit of block height %d should be bigger than 0 , current gaslimit %d", blockHeight, gasLimitUint64)
|
|
||||||
}
|
|
||||||
|
|
||||||
gasUsedRatio := gasusedfloat / float64(gasLimitUint64)
|
|
||||||
blockGasUsed := gasusedfloat
|
|
||||||
targetOneFeeHistory.GasUsedRatio = gasUsedRatio
|
|
||||||
|
|
||||||
rewardCount := len(rewardPercentiles)
|
|
||||||
targetOneFeeHistory.Reward = make([]*big.Int, rewardCount)
|
|
||||||
for i := 0; i < rewardCount; i++ {
|
|
||||||
targetOneFeeHistory.Reward[i] = big.NewInt(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check tendermintTxs
|
|
||||||
tendermintTxs := tendermintBlock.Block.Txs
|
|
||||||
tendermintTxResults := tendermintBlockResult.TxsResults
|
|
||||||
tendermintTxCount := len(tendermintTxs)
|
|
||||||
|
|
||||||
var sorter sortGasAndReward
|
|
||||||
|
|
||||||
for i := 0; i < tendermintTxCount; i++ {
|
|
||||||
eachTendermintTx := tendermintTxs[i]
|
|
||||||
eachTendermintTxResult := tendermintTxResults[i]
|
|
||||||
|
|
||||||
tx, err := e.clientCtx.TxConfig.TxDecoder()(eachTendermintTx)
|
|
||||||
if err != nil {
|
|
||||||
e.logger.Debug("failed to decode transaction in block", "height", blockHeight, "error", err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
txGasUsed := uint64(eachTendermintTxResult.GasUsed)
|
|
||||||
for _, msg := range tx.GetMsgs() {
|
|
||||||
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
tx := ethMsg.AsTransaction()
|
|
||||||
reward := tx.EffectiveGasTipValue(blockBaseFee)
|
|
||||||
if reward == nil {
|
|
||||||
reward = big.NewInt(0)
|
|
||||||
}
|
|
||||||
sorter = append(sorter, txGasAndReward{gasUsed: txGasUsed, reward: reward})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return an all zero row if there are no transactions to gather data from
|
|
||||||
ethTxCount := len(sorter)
|
|
||||||
if ethTxCount == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(sorter)
|
|
||||||
|
|
||||||
var txIndex int
|
|
||||||
sumGasUsed := sorter[0].gasUsed
|
|
||||||
|
|
||||||
for i, p := range rewardPercentiles {
|
|
||||||
thresholdGasUsed := uint64(blockGasUsed * p / 100)
|
|
||||||
for sumGasUsed < thresholdGasUsed && txIndex < ethTxCount-1 {
|
|
||||||
txIndex++
|
|
||||||
sumGasUsed += sorter[txIndex].gasUsed
|
|
||||||
}
|
|
||||||
targetOneFeeHistory.Reward[i] = sorter[txIndex].reward
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FeeHistory returns data relevant for fee estimation based on the specified range of blocks.
|
|
||||||
func (e *EVMBackend) FeeHistory(
|
|
||||||
userBlockCount rpc.DecimalOrHex, // number blocks to fetch, maximum is 100
|
|
||||||
lastBlock rpc.BlockNumber, // the block to start search , to oldest
|
|
||||||
rewardPercentiles []float64, // percentiles to fetch reward
|
|
||||||
) (*rpctypes.FeeHistoryResult, error) {
|
|
||||||
blockEnd := int64(lastBlock)
|
|
||||||
|
|
||||||
if blockEnd <= 0 {
|
|
||||||
blockNumber, err := e.BlockNumber()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
blockEnd = int64(blockNumber)
|
|
||||||
}
|
|
||||||
userBlockCountInt := int64(userBlockCount)
|
|
||||||
maxBlockCount := int64(e.cfg.JSONRPC.FeeHistoryCap)
|
|
||||||
if userBlockCountInt > maxBlockCount {
|
|
||||||
return nil, fmt.Errorf("FeeHistory user block count %d higher than %d", userBlockCountInt, maxBlockCount)
|
|
||||||
}
|
|
||||||
blockStart := blockEnd - userBlockCountInt
|
|
||||||
if blockStart < 0 {
|
|
||||||
blockStart = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
blockCount := blockEnd - blockStart
|
|
||||||
|
|
||||||
oldestBlock := (*hexutil.Big)(big.NewInt(blockStart))
|
|
||||||
|
|
||||||
// prepare space
|
|
||||||
reward := make([][]*hexutil.Big, blockCount)
|
|
||||||
rewardCount := len(rewardPercentiles)
|
|
||||||
for i := 0; i < int(blockCount); i++ {
|
|
||||||
reward[i] = make([]*hexutil.Big, rewardCount)
|
|
||||||
}
|
|
||||||
thisBaseFee := make([]*hexutil.Big, blockCount)
|
|
||||||
thisGasUsedRatio := make([]float64, blockCount)
|
|
||||||
|
|
||||||
// rewards should only be calculated if reward percentiles were included
|
|
||||||
calculateRewards := rewardCount != 0
|
|
||||||
|
|
||||||
// fetch block
|
|
||||||
for blockID := blockStart; blockID < blockEnd; blockID++ {
|
|
||||||
index := int32(blockID - blockStart)
|
|
||||||
// eth block
|
|
||||||
ethBlock, err := e.GetBlockByNumber(rpctypes.BlockNumber(blockID), true)
|
|
||||||
if ethBlock == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// tendermint block
|
|
||||||
tendermintblock, err := e.GetTendermintBlockByNumber(rpctypes.BlockNumber(blockID))
|
|
||||||
if tendermintblock == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// tendermint block result
|
|
||||||
tendermintBlockResult, err := e.clientCtx.Client.BlockResults(e.ctx, &tendermintblock.Block.Height)
|
|
||||||
if tendermintBlockResult == nil {
|
|
||||||
e.logger.Debug("block result not found", "height", tendermintblock.Block.Height, "error", err.Error())
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
oneFeeHistory := rpctypes.OneFeeHistory{}
|
|
||||||
err = e.processBlock(tendermintblock, ðBlock, rewardPercentiles, tendermintBlockResult, &oneFeeHistory)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy
|
|
||||||
thisBaseFee[index] = (*hexutil.Big)(oneFeeHistory.BaseFee)
|
|
||||||
thisGasUsedRatio[index] = oneFeeHistory.GasUsedRatio
|
|
||||||
if calculateRewards {
|
|
||||||
for j := 0; j < rewardCount; j++ {
|
|
||||||
reward[index][j] = (*hexutil.Big)(oneFeeHistory.Reward[j])
|
|
||||||
if reward[index][j] == nil {
|
|
||||||
reward[index][j] = (*hexutil.Big)(big.NewInt(0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
feeHistory := rpctypes.FeeHistoryResult{
|
|
||||||
OldestBlock: oldestBlock,
|
|
||||||
BaseFee: thisBaseFee,
|
|
||||||
GasUsedRatio: thisGasUsedRatio,
|
|
||||||
}
|
|
||||||
|
|
||||||
if calculateRewards {
|
|
||||||
feeHistory.Reward = reward
|
|
||||||
}
|
|
||||||
|
|
||||||
return &feeHistory, nil
|
|
||||||
}
|
|
@ -28,8 +28,8 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/backend"
|
"github.com/tharsis/ethermint/rpc/backend"
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpctypes "github.com/tharsis/ethermint/rpc/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandlerT keeps track of the cpu profiler and trace execution
|
// HandlerT keeps track of the cpu profiler and trace execution
|
||||||
@ -45,7 +45,7 @@ type HandlerT struct {
|
|||||||
type API struct {
|
type API struct {
|
||||||
ctx *server.Context
|
ctx *server.Context
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
backend backend.Backend
|
backend backend.EVMBackend
|
||||||
clientCtx client.Context
|
clientCtx client.Context
|
||||||
queryClient *rpctypes.QueryClient
|
queryClient *rpctypes.QueryClient
|
||||||
handler *HandlerT
|
handler *HandlerT
|
||||||
@ -54,7 +54,7 @@ type API struct {
|
|||||||
// NewAPI creates a new API definition for the tracing methods of the Ethereum service.
|
// NewAPI creates a new API definition for the tracing methods of the Ethereum service.
|
||||||
func NewAPI(
|
func NewAPI(
|
||||||
ctx *server.Context,
|
ctx *server.Context,
|
||||||
backend backend.Backend,
|
backend backend.EVMBackend,
|
||||||
clientCtx client.Context,
|
clientCtx client.Context,
|
||||||
) *API {
|
) *API {
|
||||||
return &API{
|
return &API{
|
@ -36,8 +36,8 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/crypto/hd"
|
"github.com/tharsis/ethermint/crypto/hd"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/backend"
|
"github.com/tharsis/ethermint/rpc/backend"
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpctypes "github.com/tharsis/ethermint/rpc/types"
|
||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
)
|
)
|
||||||
@ -49,7 +49,7 @@ type PublicAPI struct {
|
|||||||
queryClient *rpctypes.QueryClient
|
queryClient *rpctypes.QueryClient
|
||||||
chainIDEpoch *big.Int
|
chainIDEpoch *big.Int
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
backend backend.Backend
|
backend backend.EVMBackend
|
||||||
nonceLock *rpctypes.AddrLocker
|
nonceLock *rpctypes.AddrLocker
|
||||||
signer ethtypes.Signer
|
signer ethtypes.Signer
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ type PublicAPI struct {
|
|||||||
func NewPublicAPI(
|
func NewPublicAPI(
|
||||||
logger log.Logger,
|
logger log.Logger,
|
||||||
clientCtx client.Context,
|
clientCtx client.Context,
|
||||||
backend backend.Backend,
|
backend backend.EVMBackend,
|
||||||
nonceLock *rpctypes.AddrLocker,
|
nonceLock *rpctypes.AddrLocker,
|
||||||
) *PublicAPI {
|
) *PublicAPI {
|
||||||
eip155ChainID, err := ethermint.ParseChainID(clientCtx.ChainID)
|
eip155ChainID, err := ethermint.ParseChainID(clientCtx.ChainID)
|
@ -7,7 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/types"
|
"github.com/tharsis/ethermint/rpc/types"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/types"
|
"github.com/tharsis/ethermint/rpc/types"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
@ -31,7 +31,7 @@ func (s Subscription) ID() rpc.ID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unsubscribe from the current subscription to Tendermint Websocket. It sends an error to the
|
// Unsubscribe from the current subscription to Tendermint Websocket. It sends an error to the
|
||||||
// subscription error channel if unsubscription fails.
|
// subscription error channel if unsubscribe fails.
|
||||||
func (s *Subscription) Unsubscribe(es *EventSystem) {
|
func (s *Subscription) Unsubscribe(es *EventSystem) {
|
||||||
go func() {
|
go func() {
|
||||||
uninstallLoop:
|
uninstallLoop:
|
@ -21,8 +21,8 @@ import (
|
|||||||
"github.com/tendermint/tendermint/libs/log"
|
"github.com/tendermint/tendermint/libs/log"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/backend"
|
"github.com/tharsis/ethermint/rpc/backend"
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpctypes "github.com/tharsis/ethermint/rpc/types"
|
||||||
"github.com/tharsis/ethermint/server/config"
|
"github.com/tharsis/ethermint/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,14 +31,14 @@ type API struct {
|
|||||||
ctx *server.Context
|
ctx *server.Context
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
clientCtx client.Context
|
clientCtx client.Context
|
||||||
backend backend.Backend
|
backend backend.EVMBackend
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPrivateAPI creates an instance of the Miner API.
|
// NewPrivateAPI creates an instance of the Miner API.
|
||||||
func NewPrivateAPI(
|
func NewPrivateAPI(
|
||||||
ctx *server.Context,
|
ctx *server.Context,
|
||||||
clientCtx client.Context,
|
clientCtx client.Context,
|
||||||
backend backend.Backend,
|
backend backend.EVMBackend,
|
||||||
) *API {
|
) *API {
|
||||||
return &API{
|
return &API{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
@ -6,7 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/backend"
|
"github.com/tharsis/ethermint/rpc/backend"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
|
|
||||||
@ -31,13 +31,17 @@ import (
|
|||||||
// PrivateAccountAPI is the personal_ prefixed set of APIs in the Web3 JSON-RPC spec.
|
// PrivateAccountAPI is the personal_ prefixed set of APIs in the Web3 JSON-RPC spec.
|
||||||
type PrivateAccountAPI struct {
|
type PrivateAccountAPI struct {
|
||||||
clientCtx client.Context
|
clientCtx client.Context
|
||||||
backend backend.Backend
|
backend backend.EVMBackend
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
hdPathIter ethermint.HDPathIterator
|
hdPathIter ethermint.HDPathIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAPI creates an instance of the public Personal Eth API.
|
// NewAPI creates an instance of the public Personal Eth API.
|
||||||
func NewAPI(logger log.Logger, clientCtx client.Context, backend backend.Backend) *PrivateAccountAPI {
|
func NewAPI(
|
||||||
|
logger log.Logger,
|
||||||
|
clientCtx client.Context,
|
||||||
|
backend backend.EVMBackend,
|
||||||
|
) *PrivateAccountAPI {
|
||||||
cfg := sdk.GetConfig()
|
cfg := sdk.GetConfig()
|
||||||
basePath := cfg.GetFullBIP44Path()
|
basePath := cfg.GetFullBIP44Path()
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/types"
|
"github.com/tharsis/ethermint/rpc/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PublicAPI offers and API for the transaction pool. It only operates on data that is non-confidential.
|
// PublicAPI offers and API for the transaction pool. It only operates on data that is non-confidential.
|
@ -26,9 +26,9 @@ import (
|
|||||||
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
|
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
rpcfilters "github.com/tharsis/ethermint/rpc/ethereum/namespaces/eth/filters"
|
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/pubsub"
|
"github.com/tharsis/ethermint/rpc/ethereum/pubsub"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpcfilters "github.com/tharsis/ethermint/rpc/namespaces/ethereum/eth/filters"
|
||||||
|
"github.com/tharsis/ethermint/rpc/types"
|
||||||
"github.com/tharsis/ethermint/server/config"
|
"github.com/tharsis/ethermint/server/config"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
)
|
)
|
||||||
|
@ -41,7 +41,7 @@ import (
|
|||||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
ethdebug "github.com/tharsis/ethermint/rpc/ethereum/namespaces/debug"
|
ethdebug "github.com/tharsis/ethermint/rpc/namespaces/ethereum/debug"
|
||||||
"github.com/tharsis/ethermint/server/config"
|
"github.com/tharsis/ethermint/server/config"
|
||||||
srvflags "github.com/tharsis/ethermint/server/flags"
|
srvflags "github.com/tharsis/ethermint/server/flags"
|
||||||
)
|
)
|
||||||
|
@ -4,12 +4,13 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||||
"github.com/tharsis/ethermint/rpc/ethereum/types"
|
"github.com/tharsis/ethermint/rpc/types"
|
||||||
"math/big"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
@ -147,7 +148,7 @@ func (s *IntegrationTestSuite) TestBlock() {
|
|||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NotNil(blockByHash)
|
s.Require().NotNil(blockByHash)
|
||||||
|
|
||||||
//Compare blockByNumber and blockByHash results
|
// Compare blockByNumber and blockByHash results
|
||||||
s.Require().Equal(blockByNum.Hash(), blockByHash.Hash())
|
s.Require().Equal(blockByNum.Hash(), blockByHash.Hash())
|
||||||
s.Require().Equal(blockByNum.Transactions().Len(), blockByHash.Transactions().Len())
|
s.Require().Equal(blockByNum.Transactions().Len(), blockByHash.Transactions().Len())
|
||||||
s.Require().Equal(blockByNum.ParentHash(), blockByHash.ParentHash())
|
s.Require().Equal(blockByNum.ParentHash(), blockByHash.ParentHash())
|
||||||
@ -382,7 +383,7 @@ func (s *IntegrationTestSuite) TestGetBalance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationTestSuite) TestGetLogs() {
|
func (s *IntegrationTestSuite) TestGetLogs() {
|
||||||
//TODO create tests to cover different filterQuery params
|
// TODO create tests to cover different filterQuery params
|
||||||
_, contractAddr := s.deployERC20Contract()
|
_, contractAddr := s.deployERC20Contract()
|
||||||
|
|
||||||
blockNum, err := s.network.Validators[0].JSONRPCClient.BlockNumber(s.ctx)
|
blockNum, err := s.network.Validators[0].JSONRPCClient.BlockNumber(s.ctx)
|
||||||
@ -408,7 +409,7 @@ func (s *IntegrationTestSuite) TestGetLogs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationTestSuite) TestTransactionReceiptERC20Transfer() {
|
func (s *IntegrationTestSuite) TestTransactionReceiptERC20Transfer() {
|
||||||
//start with clean block
|
// start with clean block
|
||||||
err := s.network.WaitForNextBlock()
|
err := s.network.WaitForNextBlock()
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
// deploy erc20 contract
|
// deploy erc20 contract
|
||||||
@ -641,7 +642,6 @@ func (s *IntegrationTestSuite) transferERC20Transaction(contractAddr, to common.
|
|||||||
receipt := s.expectSuccessReceipt(ercTransferTx.AsTransaction().Hash())
|
receipt := s.expectSuccessReceipt(ercTransferTx.AsTransaction().Hash())
|
||||||
s.Require().NotEmpty(receipt.Logs)
|
s.Require().NotEmpty(receipt.Logs)
|
||||||
return ercTransferTx.AsTransaction().Hash()
|
return ercTransferTx.AsTransaction().Hash()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *IntegrationTestSuite) storeValueStorageContract(contractAddr common.Address, amount *big.Int) common.Hash {
|
func (s *IntegrationTestSuite) storeValueStorageContract(contractAddr common.Address, amount *big.Int) common.Hash {
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpctypes "github.com/tharsis/ethermint/rpc/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// func TestMain(m *testing.M) {
|
// func TestMain(m *testing.M) {
|
||||||
|
@ -17,7 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpctypes "github.com/tharsis/ethermint/rpc/types"
|
||||||
ethermint "github.com/tharsis/ethermint/types"
|
ethermint "github.com/tharsis/ethermint/types"
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpctypes "github.com/tharsis/ethermint/rpc/types"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpctypes "github.com/tharsis/ethermint/rpc/types"
|
||||||
"github.com/tharsis/ethermint/x/evm/types"
|
"github.com/tharsis/ethermint/x/evm/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||||
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||||
|
|
||||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
rpctypes "github.com/tharsis/ethermint/rpc/types"
|
||||||
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
Loading…
Reference in New Issue
Block a user