rpc: geth v1.10.9 changes (#624)
* rpc: geth v1.10.9 changes * updates * suggestGasTipCap * update gRPC * resend * fixes * rm unused func * address TODO
This commit is contained in:
parent
202bc5f1cd
commit
bcdb982886
@ -52,6 +52,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* (evm) [tharsis#613](https://github.com/tharsis/ethermint/pull/613) Refactor `traceTx`
|
||||
* (deps) [tharsis#610](https://github.com/tharsis/ethermint/pull/610) Bump Cosmos SDK to [v0.44.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.44.1).
|
||||
|
||||
### Features
|
||||
|
||||
* (rpc) [tharsis#624](https://github.com/tharsis/ethermint/pull/624) Implement new JSON-RPC endpoints from latest geth version
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* (evm) [tharsis#616](https://github.com/tharsis/ethermint/issues/616) Fix halt on deeply nested stack of cache context. Stack is now flattened before iterating over the tx logs.
|
||||
|
2
client/docs/statik/statik.go
vendored
2
client/docs/statik/statik.go
vendored
File diff suppressed because one or more lines are too long
2
go.mod
2
go.mod
@ -34,7 +34,7 @@ require (
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9
|
||||
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e
|
||||
google.golang.org/grpc v1.41.0
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
|
4
go.sum
4
go.sum
@ -1759,8 +1759,8 @@ google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKr
|
||||
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
|
||||
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9 h1:eF1wcrhdz56Vugf8qNX5dD93ItkrhothojQyHXqloe0=
|
||||
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e h1:Im71rbA1N3CbIag/PumYhQcNR8bLNmuOtRIyOnnLsT8=
|
||||
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
|
@ -42,8 +42,7 @@ message QueryBaseFeeRequest {}
|
||||
// BaseFeeResponse returns the EIP1559 base fee.
|
||||
message QueryBaseFeeResponse {
|
||||
string base_fee = 1 [
|
||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
||||
(gogoproto.nullable) = false
|
||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int"
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -41,29 +41,37 @@ import (
|
||||
// Backend implements the functionality shared within namespaces.
|
||||
// Implemented by EVMBackend.
|
||||
type Backend interface {
|
||||
// General Ethereum API
|
||||
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
|
||||
RPCMinGasPrice() int64
|
||||
SuggestGasTipCap() (*big.Int, error)
|
||||
|
||||
// Blockchain API
|
||||
BlockNumber() (hexutil.Uint64, error)
|
||||
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
|
||||
GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error)
|
||||
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
|
||||
CurrentHeader() *ethtypes.Header
|
||||
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
|
||||
HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error)
|
||||
HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
|
||||
PendingTransactions() ([]*sdk.Tx, error)
|
||||
GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error)
|
||||
GetTransactionCount(address common.Address, blockNum types.BlockNumber) (*hexutil.Uint64, error)
|
||||
SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error)
|
||||
GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error)
|
||||
GetLogs(hash common.Hash) ([][]*ethtypes.Log, error)
|
||||
BloomStatus() (uint64, uint64)
|
||||
GetCoinbase() (sdk.AccAddress, error)
|
||||
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
|
||||
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
|
||||
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
|
||||
RPCGasCap() uint64
|
||||
RPCMinGasPrice() int64
|
||||
ChainConfig() *params.ChainConfig
|
||||
SuggestGasTipCap() (*big.Int, error)
|
||||
BaseFee() (*big.Int, error)
|
||||
|
||||
// Filter API
|
||||
BloomStatus() (uint64, uint64)
|
||||
GetLogs(hash common.Hash) ([][]*ethtypes.Log, error)
|
||||
GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error)
|
||||
GetFilteredBlocks(from int64, to int64, filter [][]filters.BloomIV, filterAddresses bool) ([]int64, error)
|
||||
|
||||
ChainConfig() *params.ChainConfig
|
||||
SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error)
|
||||
}
|
||||
|
||||
var _ Backend = (*EVMBackend)(nil)
|
||||
@ -228,6 +236,14 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
||||
) (map[string]interface{}, error) {
|
||||
ethRPCTxs := []interface{}{}
|
||||
|
||||
ctx := types.ContextWithHeight(block.Height)
|
||||
|
||||
bfRes, err := e.queryClient.FeeMarket.BaseFee(ctx, &feemarkettypes.QueryBaseFeeRequest{})
|
||||
if err != nil {
|
||||
e.logger.Debug("failed to base fee", "height", block.Height, "error", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, txBz := range block.Txs {
|
||||
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
|
||||
if err != nil {
|
||||
@ -237,43 +253,30 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
||||
|
||||
for _, msg := range tx.GetMsgs() {
|
||||
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
hash := ethMsg.AsTransaction().Hash()
|
||||
tx := ethMsg.AsTransaction()
|
||||
|
||||
if !fullTx {
|
||||
hash := tx.Hash()
|
||||
ethRPCTxs = append(ethRPCTxs, hash)
|
||||
continue
|
||||
}
|
||||
|
||||
// get full transaction from message data
|
||||
from, err := ethMsg.GetSender(e.chainID)
|
||||
if err != nil {
|
||||
e.logger.Debug("failed to get sender from already included transaction", "hash", hash.Hex(), "error", err.Error())
|
||||
from = common.HexToAddress(ethMsg.From)
|
||||
}
|
||||
|
||||
txData, err := evmtypes.UnpackTxData(ethMsg.Data)
|
||||
if err != nil {
|
||||
e.logger.Debug("decoding failed", "error", err.Error())
|
||||
return nil, fmt.Errorf("failed to unpack tx data: %w", err)
|
||||
}
|
||||
|
||||
ethTx, err := types.NewTransactionFromData(
|
||||
txData,
|
||||
from,
|
||||
hash,
|
||||
rpcTx, err := types.NewRPCTransaction(
|
||||
tx,
|
||||
common.BytesToHash(block.Hash()),
|
||||
uint64(block.Height),
|
||||
uint64(i),
|
||||
bfRes.BaseFee.BigInt(),
|
||||
)
|
||||
if err != nil {
|
||||
e.logger.Debug("NewTransactionFromData for receipt failed", "hash", hash.Hex(), "error", err.Error())
|
||||
e.logger.Debug("NewTransactionFromData for receipt failed", "hash", tx.Hash().Hex(), "error", err.Error())
|
||||
continue
|
||||
}
|
||||
ethRPCTxs = append(ethRPCTxs, ethTx)
|
||||
ethRPCTxs = append(ethRPCTxs, rpcTx)
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,8 +289,6 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
||||
ConsAddress: sdk.ConsAddress(block.Header.ProposerAddress).String(),
|
||||
}
|
||||
|
||||
ctx := types.ContextWithHeight(block.Height)
|
||||
|
||||
res, err := e.queryClient.ValidatorAccount(ctx, req)
|
||||
if err != nil {
|
||||
e.logger.Debug(
|
||||
@ -306,12 +307,6 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
||||
|
||||
validatorAddr := common.BytesToAddress(addr)
|
||||
|
||||
bfRes, err := e.queryClient.FeeMarket.BaseFee(ctx, &feemarkettypes.QueryBaseFeeRequest{})
|
||||
if err != nil {
|
||||
e.logger.Debug("failed to base fee", "height", block.Height, "error", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gasLimit, err := types.BlockMaxGasFromConsensusParams(ctx, e.clientCtx)
|
||||
if err != nil {
|
||||
e.logger.Error("failed to query consensus params", "error", err.Error())
|
||||
@ -376,7 +371,13 @@ func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Heade
|
||||
e.logger.Debug("HeaderByNumber BlockBloom failed", "height", resBlock.Block.Height)
|
||||
}
|
||||
|
||||
ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header)
|
||||
baseFee, err := e.BaseFee()
|
||||
if err != nil {
|
||||
e.logger.Debug("HeaderByNumber BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header, baseFee)
|
||||
ethHeader.Bloom = bloom
|
||||
return ethHeader, nil
|
||||
}
|
||||
@ -398,7 +399,13 @@ func (e *EVMBackend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, erro
|
||||
e.logger.Debug("HeaderByHash BlockBloom failed", "height", resBlock.Block.Height)
|
||||
}
|
||||
|
||||
ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header)
|
||||
baseFee, err := e.BaseFee()
|
||||
if err != nil {
|
||||
e.logger.Debug("HeaderByHash BaseFee failed", "height", resBlock.Block.Height, "error", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header, baseFee)
|
||||
ethHeader.Bloom = bloom
|
||||
return ethHeader, nil
|
||||
}
|
||||
@ -607,20 +614,24 @@ func (e *EVMBackend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash
|
||||
return common.Hash{}, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
|
||||
}
|
||||
|
||||
args, err = e.setTxDefaults(args)
|
||||
args, err = e.SetTxDefaults(args)
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
msg := args.ToTransaction()
|
||||
|
||||
if err := msg.ValidateBasic(); err != nil {
|
||||
e.logger.Debug("tx failed basic validation", "error", err.Error())
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
// TODO: get from chain config
|
||||
signer := ethtypes.LatestSignerForChainID(args.ChainID.ToInt())
|
||||
bn, err := e.BlockNumber()
|
||||
if err != nil {
|
||||
e.logger.Debug("failed to fetch latest block number", "error", err.Error())
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
signer := ethtypes.MakeSigner(e.ChainConfig(), new(big.Int).SetUint64(uint64(bn)))
|
||||
|
||||
// Sign transaction
|
||||
if err := msg.Sign(signer, e.clientCtx.Keyring); err != nil {
|
||||
@ -641,8 +652,7 @@ func (e *EVMBackend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash
|
||||
}
|
||||
|
||||
builder.SetExtensionOptions(option)
|
||||
err = builder.SetMsgs(msg)
|
||||
if err != nil {
|
||||
if err = builder.SetMsgs(msg); err != nil {
|
||||
e.logger.Error("builder.SetMsgs failed", "error", err.Error())
|
||||
}
|
||||
|
||||
@ -701,7 +711,22 @@ func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional
|
||||
return 0, err
|
||||
}
|
||||
|
||||
req := evmtypes.EthCallRequest{Args: bz, GasCap: e.RPCGasCap()}
|
||||
baseFee, err := e.BaseFee()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var bf *sdk.Int
|
||||
if baseFee != nil {
|
||||
aux := sdk.NewIntFromBigInt(baseFee)
|
||||
bf = &aux
|
||||
}
|
||||
|
||||
req := evmtypes.EthCallRequest{
|
||||
Args: bz,
|
||||
GasCap: e.RPCGasCap(),
|
||||
BaseFee: bf,
|
||||
}
|
||||
|
||||
// From ContextWithHeight: if the provided height is 0,
|
||||
// it will return an empty context and the gRPC query will use
|
||||
@ -745,7 +770,7 @@ func (e *EVMBackend) RPCGasCap() uint64 {
|
||||
// the node config. If set value is 0, it will default to 20.
|
||||
|
||||
func (e *EVMBackend) RPCMinGasPrice() int64 {
|
||||
evmParams, err := e.queryClient.Params(context.Background(), &evmtypes.QueryParamsRequest{})
|
||||
evmParams, err := e.queryClient.Params(e.ctx, &evmtypes.QueryParamsRequest{})
|
||||
if err != nil {
|
||||
return ethermint.DefaultGasPrice
|
||||
}
|
||||
@ -771,8 +796,29 @@ func (e *EVMBackend) ChainConfig() *params.ChainConfig {
|
||||
|
||||
// SuggestGasTipCap returns the suggested tip cap
|
||||
func (e *EVMBackend) SuggestGasTipCap() (*big.Int, error) {
|
||||
// TODO: implement
|
||||
return big.NewInt(1), nil
|
||||
out := new(big.Int).SetInt64(e.RPCMinGasPrice())
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// BaseFee returns the base fee tracked by the Fee Market module. If the base fee is not enabled,
|
||||
// it returns the initial base fee amount.
|
||||
func (e *EVMBackend) BaseFee() (*big.Int, error) {
|
||||
res, err := e.queryClient.FeeMarket.BaseFee(e.ctx, &feemarkettypes.QueryBaseFeeRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if res.BaseFee != nil {
|
||||
return res.BaseFee.BigInt(), nil
|
||||
}
|
||||
|
||||
resParams, err := e.queryClient.FeeMarket.Params(e.ctx, &feemarkettypes.QueryParamsRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseFee := big.NewInt(resParams.Params.InitialBaseFee)
|
||||
return baseFee, nil
|
||||
}
|
||||
|
||||
// GetFilteredBlocks returns the block height list match the given bloom filters.
|
||||
|
@ -19,9 +19,9 @@ import (
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
// 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
|
||||
func (e *EVMBackend) setTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) {
|
||||
func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.TransactionArgs, error) {
|
||||
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
||||
return args, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
@ -45,6 +46,7 @@ type PublicAPI struct {
|
||||
logger log.Logger
|
||||
backend backend.Backend
|
||||
nonceLock *rpctypes.AddrLocker
|
||||
signer ethtypes.Signer
|
||||
}
|
||||
|
||||
// NewPublicAPI creates an instance of the public ETH Web3 API.
|
||||
@ -76,6 +78,10 @@ func NewPublicAPI(
|
||||
clientCtx = clientCtx.WithKeyring(kr)
|
||||
}
|
||||
|
||||
// The signer used by the API should always be the 'latest' known one because we expect
|
||||
// signers to be backwards-compatible with old transactions.
|
||||
signer := ethtypes.LatestSigner(backend.ChainConfig())
|
||||
|
||||
api := &PublicAPI{
|
||||
ctx: context.Background(),
|
||||
clientCtx: clientCtx,
|
||||
@ -84,6 +90,7 @@ func NewPublicAPI(
|
||||
logger: logger.With("client", "json-rpc"),
|
||||
backend: backend,
|
||||
nonceLock: nonceLock,
|
||||
signer: signer,
|
||||
}
|
||||
|
||||
return api
|
||||
@ -108,14 +115,30 @@ func (e *PublicAPI) ProtocolVersion() hexutil.Uint {
|
||||
return hexutil.Uint(ethermint.ProtocolVersion)
|
||||
}
|
||||
|
||||
// ChainId returns the chain's identifier in hex format
|
||||
func (e *PublicAPI) ChainId() (hexutil.Uint, error) { // nolint
|
||||
// ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config.
|
||||
func (e *PublicAPI) ChainId() (*hexutil.Big, error) { // nolint
|
||||
e.logger.Debug("eth_chainId")
|
||||
return hexutil.Uint(uint(e.chainIDEpoch.Uint64())), nil
|
||||
// if current block is at or past the EIP-155 replay-protection fork block, return chainID from config
|
||||
bn, err := e.backend.BlockNumber()
|
||||
if err != nil {
|
||||
e.logger.Debug("failed to fetch latest block number", "error", err.Error())
|
||||
return (*hexutil.Big)(e.chainIDEpoch), nil
|
||||
}
|
||||
|
||||
if config := e.backend.ChainConfig(); config.IsEIP155(new(big.Int).SetUint64(uint64(bn))) {
|
||||
return (*hexutil.Big)(config.ChainID), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("chain not synced beyond EIP-155 replay-protection fork block")
|
||||
}
|
||||
|
||||
// Syncing returns whether or not the current node is syncing with other peers. Returns false if not, or a struct
|
||||
// outlining the state of the sync if it is.
|
||||
// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not
|
||||
// yet received the latest block headers from its pears. In case it is synchronizing:
|
||||
// - startingBlock: block number this node started to synchronize from
|
||||
// - currentBlock: block number this node is currently importing
|
||||
// - highestBlock: block number of the highest block header this node has received from peers
|
||||
// - pulledStates: number of state entries processed until now
|
||||
// - knownStates: number of known state entries that still need to be pulled
|
||||
func (e *PublicAPI) Syncing() (interface{}, error) {
|
||||
e.logger.Debug("eth_syncing")
|
||||
|
||||
@ -129,8 +152,8 @@ func (e *PublicAPI) Syncing() (interface{}, error) {
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
// "startingBlock": nil, // NA
|
||||
"currentBlock": hexutil.Uint64(status.SyncInfo.LatestBlockHeight),
|
||||
"startingBlock": hexutil.Uint64(status.SyncInfo.EarliestBlockHeight),
|
||||
"currentBlock": hexutil.Uint64(status.SyncInfo.LatestBlockHeight),
|
||||
// "highestBlock": nil, // NA
|
||||
// "pulledStates": nil, // NA
|
||||
// "knownStates": nil, // NA
|
||||
@ -162,10 +185,35 @@ func (e *PublicAPI) Hashrate() hexutil.Uint64 {
|
||||
}
|
||||
|
||||
// GasPrice returns the current gas price based on Ethermint's gas price oracle.
|
||||
func (e *PublicAPI) GasPrice() *hexutil.Big {
|
||||
func (e *PublicAPI) GasPrice() (*hexutil.Big, error) {
|
||||
e.logger.Debug("eth_gasPrice")
|
||||
out := new(big.Int).SetInt64(e.backend.RPCMinGasPrice())
|
||||
return (*hexutil.Big)(out)
|
||||
tipcap, err := e.backend.SuggestGasTipCap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if head := e.backend.CurrentHeader(); head.BaseFee != nil {
|
||||
tipcap.Add(tipcap, head.BaseFee)
|
||||
}
|
||||
|
||||
return (*hexutil.Big)(tipcap), nil
|
||||
}
|
||||
|
||||
// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions.
|
||||
func (e *PublicAPI) MaxPriorityFeePerGas() (*hexutil.Big, error) {
|
||||
e.logger.Debug("eth_maxPriorityFeePerGas")
|
||||
tipcap, err := e.backend.SuggestGasTipCap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return (*hexutil.Big)(tipcap), nil
|
||||
}
|
||||
|
||||
func (e *PublicAPI) FeeHistory(blockCount rpc.DecimalOrHex, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*rpctypes.FeeHistoryResult, error) {
|
||||
e.logger.Debug("eth_feeHistory")
|
||||
|
||||
return nil, fmt.Errorf("eth_feeHistory not implemented")
|
||||
}
|
||||
|
||||
// Accounts returns the list of accounts available to this node.
|
||||
@ -355,6 +403,29 @@ func (e *PublicAPI) SendTransaction(args evmtypes.TransactionArgs) (common.Hash,
|
||||
return e.backend.SendTransaction(args)
|
||||
}
|
||||
|
||||
// FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields)
|
||||
// on a given unsigned transaction, and returns it to the caller for further
|
||||
// processing (signing + broadcast).
|
||||
func (e *PublicAPI) FillTransaction(args evmtypes.TransactionArgs) (*rpctypes.SignTransactionResult, error) {
|
||||
// Set some sanity defaults and terminate on failure
|
||||
args, err := e.backend.SetTxDefaults(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Assemble the transaction and obtain rlp
|
||||
tx := args.ToTransaction().AsTransaction()
|
||||
data, err := tx.MarshalBinary()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &rpctypes.SignTransactionResult{
|
||||
Raw: data,
|
||||
Tx: tx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SendRawTransaction send a raw Ethereum transaction.
|
||||
func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
|
||||
e.logger.Debug("eth_sendRawTransaction", "length", len(data))
|
||||
@ -407,7 +478,12 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
fees := sdk.Coins{sdk.NewCoin(res.Params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee()))}
|
||||
fees := sdk.Coins{
|
||||
{
|
||||
Denom: res.Params.EvmDenom,
|
||||
Amount: sdk.NewIntFromBigInt(txData.Fee()),
|
||||
},
|
||||
}
|
||||
builder.SetFeeAmount(fees)
|
||||
builder.SetGasLimit(ethereumTx.GetGas())
|
||||
|
||||
@ -433,6 +509,57 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
|
||||
return txHash, nil
|
||||
}
|
||||
|
||||
// Resend accepts an existing transaction and a new gas price and limit. It will remove
|
||||
// the given transaction from the pool and reinsert it with the new gas price and limit.
|
||||
func (e *PublicAPI) Resend(ctx context.Context, args evmtypes.TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) {
|
||||
e.logger.Debug("eth_resend", "args", args.String())
|
||||
if args.Nonce == nil {
|
||||
return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec")
|
||||
}
|
||||
|
||||
args, err := e.backend.SetTxDefaults(args)
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
matchTx := args.ToTransaction().AsTransaction()
|
||||
|
||||
pending, err := e.backend.PendingTransactions()
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
||||
for _, tx := range pending {
|
||||
p, err := evmtypes.UnwrapEthereumMsg(tx)
|
||||
if err != nil {
|
||||
// not valid ethereum tx
|
||||
continue
|
||||
}
|
||||
|
||||
pTx := p.AsTransaction()
|
||||
|
||||
wantSigHash := e.signer.Hash(matchTx)
|
||||
pFrom, err := ethtypes.Sender(e.signer, pTx)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if pFrom == *args.From && e.signer.Hash(pTx) == wantSigHash {
|
||||
// Match. Re-sign and send the transaction.
|
||||
if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 {
|
||||
args.GasPrice = gasPrice
|
||||
}
|
||||
if gasLimit != nil && *gasLimit != 0 {
|
||||
args.Gas = gasLimit
|
||||
}
|
||||
|
||||
return e.backend.SendTransaction(args) // TODO: this calls SetTxDefaults again, refactor to avoid calling it twice
|
||||
}
|
||||
}
|
||||
|
||||
return common.Hash{}, fmt.Errorf("transaction %#x not found", matchTx.Hash())
|
||||
}
|
||||
|
||||
// Call performs a raw contract call.
|
||||
func (e *PublicAPI) Call(args evmtypes.TransactionArgs, blockNrOrHash rpctypes.BlockNumberOrHash, _ *rpctypes.StateOverride) (hexutil.Bytes, error) {
|
||||
e.logger.Debug("eth_call", "args", args.String(), "block number or hash", blockNrOrHash)
|
||||
@ -458,7 +585,23 @@ func (e *PublicAPI) doCall(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := evmtypes.EthCallRequest{Args: bz, GasCap: e.backend.RPCGasCap()}
|
||||
|
||||
baseFee, err := e.backend.BaseFee()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var bf *sdk.Int
|
||||
if baseFee != nil {
|
||||
aux := sdk.NewIntFromBigInt(baseFee)
|
||||
bf = &aux
|
||||
}
|
||||
|
||||
req := evmtypes.EthCallRequest{
|
||||
Args: bz,
|
||||
GasCap: e.backend.RPCGasCap(),
|
||||
BaseFee: bf,
|
||||
}
|
||||
|
||||
// From ContextWithHeight: if the provided height is 0,
|
||||
// it will return an empty context and the gRPC query will use
|
||||
@ -536,12 +679,17 @@ func (e *PublicAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexu
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseFee, err := e.backend.BaseFee()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rpctypes.NewTransactionFromMsg(
|
||||
msg,
|
||||
hash,
|
||||
uint64(resBlock.Block.Height),
|
||||
uint64(idx),
|
||||
e.chainIDEpoch,
|
||||
baseFee,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package filters
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -17,6 +18,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
@ -223,6 +225,9 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
|
||||
return rpc.ID(fmt.Sprintf("error creating block filter: %s", err.Error()))
|
||||
}
|
||||
|
||||
// TODO: use events to get the base fee amount
|
||||
baseFee := big.NewInt(params.InitialBaseFee)
|
||||
|
||||
api.filtersMu.Lock()
|
||||
api.filters[headerSub.ID()] = &filter{typ: filters.BlocksSubscription, deadline: time.NewTimer(deadline), hashes: []common.Hash{}, s: headerSub}
|
||||
api.filtersMu.Unlock()
|
||||
@ -246,7 +251,7 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
header := types.EthHeaderFromTendermint(data.Header)
|
||||
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
||||
api.filtersMu.Lock()
|
||||
if f, found := api.filters[headerSub.ID()]; found {
|
||||
f.hashes = append(f.hashes, header.Hash())
|
||||
@ -279,6 +284,9 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
|
||||
return &rpc.Subscription{}, err
|
||||
}
|
||||
|
||||
// TODO: use events to get the base fee amount
|
||||
baseFee := big.NewInt(params.InitialBaseFee)
|
||||
|
||||
go func(headersCh <-chan coretypes.ResultEvent) {
|
||||
defer cancelSubs()
|
||||
|
||||
@ -296,7 +304,7 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
|
||||
continue
|
||||
}
|
||||
|
||||
header := types.EthHeaderFromTendermint(data.Header)
|
||||
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
||||
err = notifier.Notify(rpcSub.ID, header)
|
||||
if err != nil {
|
||||
headersSub.err <- err
|
||||
|
@ -150,7 +150,7 @@ func (api *PrivateAccountAPI) UnlockAccount(_ context.Context, addr common.Addre
|
||||
// SendTransaction will create a transaction from the given arguments and
|
||||
// tries to sign it with the key associated with args.To. If the given password isn't
|
||||
// able to decrypt the key it fails.
|
||||
func (api *PrivateAccountAPI) SendTransaction(_ context.Context, args evmtypes.TransactionArgs, pwrd string) (common.Hash, error) {
|
||||
func (api *PrivateAccountAPI) SendTransaction(_ context.Context, args evmtypes.TransactionArgs, _ string) (common.Hash, error) {
|
||||
api.logger.Debug("personal_sendTransaction", "address", args.To.String())
|
||||
|
||||
if args.From == nil {
|
||||
@ -177,7 +177,7 @@ func (api *PrivateAccountAPI) SendTransaction(_ context.Context, args evmtypes.T
|
||||
// The key used to calculate the signature is decrypted with the given password.
|
||||
//
|
||||
// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign
|
||||
func (api *PrivateAccountAPI) Sign(_ context.Context, data hexutil.Bytes, addr common.Address, pwrd string) (hexutil.Bytes, error) {
|
||||
func (api *PrivateAccountAPI) Sign(_ context.Context, data hexutil.Bytes, addr common.Address, _ string) (hexutil.Bytes, error) {
|
||||
api.logger.Debug("personal_sign", "data", data, "address", addr.String())
|
||||
|
||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||
|
@ -66,3 +66,16 @@ type OverrideAccount struct {
|
||||
State *map[common.Hash]common.Hash `json:"state"`
|
||||
StateDiff *map[common.Hash]common.Hash `json:"stateDiff"`
|
||||
}
|
||||
|
||||
type FeeHistoryResult struct {
|
||||
OldestBlock *hexutil.Big `json:"oldestBlock"`
|
||||
Reward [][]*hexutil.Big `json:"reward,omitempty"`
|
||||
BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"`
|
||||
GasUsedRatio []float64 `json:"gasUsedRatio"`
|
||||
}
|
||||
|
||||
// SignTransactionResult represents a RLP encoded signed transaction.
|
||||
type SignTransactionResult struct {
|
||||
Raw hexutil.Bytes `json:"raw"`
|
||||
Tx *ethtypes.Transaction `json:"tx"`
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
@ -33,56 +34,14 @@ func RawTxToEthTx(clientCtx client.Context, txBz tmtypes.Tx) (*evmtypes.MsgEther
|
||||
return ethTx, nil
|
||||
}
|
||||
|
||||
// NewTransaction returns a transaction that will serialize to the RPC
|
||||
// representation, with the given location metadata set (if available).
|
||||
func NewTransaction(tx *ethtypes.Transaction, blockHash common.Hash, blockNumber, index uint64) *RPCTransaction {
|
||||
// Determine the signer. For replay-protected transactions, use the most permissive
|
||||
// signer, because we assume that signers are backwards-compatible with old
|
||||
// transactions. For non-protected transactions, the homestead signer signer is used
|
||||
// because the return value of ChainId is zero for those transactions.
|
||||
var signer ethtypes.Signer
|
||||
if tx.Protected() {
|
||||
signer = ethtypes.LatestSignerForChainID(tx.ChainId())
|
||||
} else {
|
||||
signer = ethtypes.HomesteadSigner{}
|
||||
}
|
||||
|
||||
from, _ := ethtypes.Sender(signer, tx)
|
||||
v, r, s := tx.RawSignatureValues()
|
||||
result := &RPCTransaction{
|
||||
Type: hexutil.Uint64(tx.Type()),
|
||||
From: from,
|
||||
Gas: hexutil.Uint64(tx.Gas()),
|
||||
GasPrice: (*hexutil.Big)(tx.GasPrice()),
|
||||
Hash: tx.Hash(), // NOTE: transaction hash here uses the ethereum format for compatibility
|
||||
Input: hexutil.Bytes(tx.Data()),
|
||||
Nonce: hexutil.Uint64(tx.Nonce()),
|
||||
To: tx.To(),
|
||||
Value: (*hexutil.Big)(tx.Value()),
|
||||
V: (*hexutil.Big)(v),
|
||||
R: (*hexutil.Big)(r),
|
||||
S: (*hexutil.Big)(s),
|
||||
}
|
||||
if blockHash != (common.Hash{}) {
|
||||
result.BlockHash = &blockHash
|
||||
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
|
||||
result.TransactionIndex = (*hexutil.Uint64)(&index)
|
||||
}
|
||||
if tx.Type() == ethtypes.AccessListTxType {
|
||||
al := tx.AccessList()
|
||||
result.Accesses = &al
|
||||
result.ChainID = (*hexutil.Big)(tx.ChainId())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// EthHeaderFromTendermint is an util function that returns an Ethereum Header
|
||||
// from a tendermint Header.
|
||||
func EthHeaderFromTendermint(header tmtypes.Header) *ethtypes.Header {
|
||||
func EthHeaderFromTendermint(header tmtypes.Header, baseFee *big.Int) *ethtypes.Header {
|
||||
txHash := ethtypes.EmptyRootHash
|
||||
if len(header.DataHash) == 0 {
|
||||
txHash = common.BytesToHash(header.DataHash)
|
||||
}
|
||||
|
||||
return ðtypes.Header{
|
||||
ParentHash: common.BytesToHash(header.LastBlockID.Hash.Bytes()),
|
||||
UncleHash: ethtypes.EmptyUncleHash,
|
||||
@ -99,6 +58,7 @@ func EthHeaderFromTendermint(header tmtypes.Header) *ethtypes.Header {
|
||||
Extra: nil,
|
||||
MixDigest: common.Hash{},
|
||||
Nonce: ethtypes.BlockNonce{},
|
||||
BaseFee: baseFee,
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,65 +180,67 @@ func NewTransactionFromMsg(
|
||||
msg *evmtypes.MsgEthereumTx,
|
||||
blockHash common.Hash,
|
||||
blockNumber, index uint64,
|
||||
chainID *big.Int,
|
||||
baseFee *big.Int,
|
||||
) (*RPCTransaction, error) {
|
||||
from, err := msg.GetSender(chainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := evmtypes.UnpackTxData(msg.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unpack tx data: %w", err)
|
||||
}
|
||||
|
||||
return NewTransactionFromData(data, from, msg.AsTransaction().Hash(), blockHash, blockNumber, index)
|
||||
tx := msg.AsTransaction()
|
||||
return NewRPCTransaction(tx, blockHash, blockNumber, index, baseFee)
|
||||
}
|
||||
|
||||
// NewTransactionFromData returns a transaction that will serialize to the RPC
|
||||
// representation, with the given location metadata set (if available).
|
||||
func NewTransactionFromData(
|
||||
txData evmtypes.TxData,
|
||||
from common.Address,
|
||||
txHash, blockHash common.Hash,
|
||||
blockNumber, index uint64,
|
||||
func NewRPCTransaction(
|
||||
tx *ethtypes.Transaction, blockHash common.Hash, blockNumber, index uint64, baseFee *big.Int,
|
||||
) (*RPCTransaction, error) {
|
||||
if txHash == (common.Hash{}) {
|
||||
txHash = ethtypes.EmptyRootHash
|
||||
// Determine the signer. For replay-protected transactions, use the most permissive
|
||||
// signer, because we assume that signers are backwards-compatible with old
|
||||
// transactions. For non-protected transactions, the homestead signer signer is used
|
||||
// because the return value of ChainId is zero for those transactions.
|
||||
var signer ethtypes.Signer
|
||||
if tx.Protected() {
|
||||
signer = ethtypes.LatestSignerForChainID(tx.ChainId())
|
||||
} else {
|
||||
signer = ethtypes.HomesteadSigner{}
|
||||
}
|
||||
|
||||
v, r, s := txData.GetRawSignatureValues()
|
||||
|
||||
rpcTx := &RPCTransaction{
|
||||
Type: hexutil.Uint64(txData.TxType()),
|
||||
from, _ := ethtypes.Sender(signer, tx)
|
||||
v, r, s := tx.RawSignatureValues()
|
||||
result := &RPCTransaction{
|
||||
Type: hexutil.Uint64(tx.Type()),
|
||||
From: from,
|
||||
Gas: hexutil.Uint64(txData.GetGas()),
|
||||
GasPrice: (*hexutil.Big)(txData.GetGasPrice()),
|
||||
Hash: txHash,
|
||||
Input: hexutil.Bytes(txData.GetData()),
|
||||
Nonce: hexutil.Uint64(txData.GetNonce()),
|
||||
To: txData.GetTo(),
|
||||
Value: (*hexutil.Big)(txData.GetValue()),
|
||||
Gas: hexutil.Uint64(tx.Gas()),
|
||||
GasPrice: (*hexutil.Big)(tx.GasPrice()),
|
||||
Hash: tx.Hash(),
|
||||
Input: hexutil.Bytes(tx.Data()),
|
||||
Nonce: hexutil.Uint64(tx.Nonce()),
|
||||
To: tx.To(),
|
||||
Value: (*hexutil.Big)(tx.Value()),
|
||||
V: (*hexutil.Big)(v),
|
||||
R: (*hexutil.Big)(r),
|
||||
S: (*hexutil.Big)(s),
|
||||
}
|
||||
if rpcTx.To == nil {
|
||||
addr := common.Address{}
|
||||
rpcTx.To = &addr
|
||||
}
|
||||
|
||||
if blockHash != (common.Hash{}) {
|
||||
rpcTx.BlockHash = &blockHash
|
||||
rpcTx.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
|
||||
rpcTx.TransactionIndex = (*hexutil.Uint64)(&index)
|
||||
result.BlockHash = &blockHash
|
||||
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
|
||||
result.TransactionIndex = (*hexutil.Uint64)(&index)
|
||||
}
|
||||
|
||||
if txData.TxType() == ethtypes.AccessListTxType {
|
||||
accesses := txData.GetAccessList()
|
||||
rpcTx.Accesses = &accesses
|
||||
rpcTx.ChainID = (*hexutil.Big)(txData.GetChainID())
|
||||
switch tx.Type() {
|
||||
case ethtypes.AccessListTxType:
|
||||
al := tx.AccessList()
|
||||
result.Accesses = &al
|
||||
result.ChainID = (*hexutil.Big)(tx.ChainId())
|
||||
case ethtypes.DynamicFeeTxType:
|
||||
al := tx.AccessList()
|
||||
result.Accesses = &al
|
||||
result.ChainID = (*hexutil.Big)(tx.ChainId())
|
||||
result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap())
|
||||
result.GasTipCap = (*hexutil.Big)(tx.GasTipCap())
|
||||
// if the transaction has been mined, compute the effective gas price
|
||||
if baseFee != nil && blockHash != (common.Hash{}) {
|
||||
// price = min(tip, gasFeeCap - baseFee) + baseFee
|
||||
price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap())
|
||||
result.GasPrice = (*hexutil.Big)(price)
|
||||
} else {
|
||||
result.GasPrice = (*hexutil.Big)(tx.GasFeeCap())
|
||||
}
|
||||
}
|
||||
|
||||
return rpcTx, nil
|
||||
return result, nil
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
@ -352,6 +353,9 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
|
||||
return "", errors.Wrap(err, "error creating block filter")
|
||||
}
|
||||
|
||||
// TODO: use events
|
||||
baseFee := big.NewInt(params.InitialBaseFee)
|
||||
|
||||
unsubscribed := make(chan struct{})
|
||||
api.filtersMu.Lock()
|
||||
api.filters[subID] = &wsSubscription{
|
||||
@ -377,7 +381,7 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
header := types.EthHeaderFromTendermint(data.Header)
|
||||
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
||||
|
||||
api.filtersMu.RLock()
|
||||
for subID, wsSub := range api.filters {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@ -15,6 +16,7 @@ import (
|
||||
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
|
||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
||||
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
@ -79,6 +81,17 @@ func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := feemarkettypes.NewQueryClient(clientCtx)
|
||||
res, err := client.BaseFee(context.Background(), &feemarkettypes.QueryBaseFeeRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var baseFee *big.Int
|
||||
if res.BaseFee != nil {
|
||||
baseFee = res.BaseFee.BigInt()
|
||||
}
|
||||
|
||||
blockHash := common.BytesToHash(block.Block.Header.Hash())
|
||||
|
||||
ethTx, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx)
|
||||
@ -87,7 +100,11 @@ func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte,
|
||||
}
|
||||
|
||||
height := uint64(tx.Height)
|
||||
rpcTx := rpctypes.NewTransaction(ethTx.AsTransaction(), blockHash, height, uint64(tx.Index))
|
||||
|
||||
rpcTx, err := rpctypes.NewRPCTransaction(ethTx.AsTransaction(), blockHash, height, uint64(tx.Index), baseFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(rpcTx)
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
|
||||
GasFeeCap: &maxFeePerGas,
|
||||
GasTipCap: &maxPriorityFeePerGas,
|
||||
Amount: &value,
|
||||
Data: args.data(),
|
||||
Data: args.GetData(),
|
||||
Accesses: al,
|
||||
}
|
||||
case args.AccessList != nil:
|
||||
@ -124,7 +124,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
|
||||
GasLimit: gas,
|
||||
GasPrice: &gasPrice,
|
||||
Amount: &value,
|
||||
Data: args.data(),
|
||||
Data: args.GetData(),
|
||||
Accesses: NewAccessList(args.AccessList),
|
||||
}
|
||||
default:
|
||||
@ -134,7 +134,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
|
||||
GasLimit: gas,
|
||||
GasPrice: &gasPrice,
|
||||
Amount: &value,
|
||||
Data: args.data(),
|
||||
Data: args.GetData(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (e
|
||||
}
|
||||
|
||||
// Set sender address or use zero address if none specified.
|
||||
addr := args.from()
|
||||
addr := args.GetFrom()
|
||||
|
||||
// Set default gas & gas price if none were set
|
||||
gas := globalGasCap
|
||||
@ -214,7 +214,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (e
|
||||
if args.Value != nil {
|
||||
value = args.Value.ToInt()
|
||||
}
|
||||
data := args.data()
|
||||
data := args.GetData()
|
||||
var accessList ethtypes.AccessList
|
||||
if args.AccessList != nil {
|
||||
accessList = *args.AccessList
|
||||
@ -223,16 +223,16 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (e
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// from retrieves the transaction sender address.
|
||||
func (args *TransactionArgs) from() common.Address {
|
||||
// GetFrom retrieves the transaction sender address.
|
||||
func (args *TransactionArgs) GetFrom() common.Address {
|
||||
if args.From == nil {
|
||||
return common.Address{}
|
||||
}
|
||||
return *args.From
|
||||
}
|
||||
|
||||
// data retrieves the transaction calldata. Input field is preferred.
|
||||
func (args *TransactionArgs) data() []byte {
|
||||
// GetData retrieves the transaction calldata. Input field is preferred.
|
||||
func (args *TransactionArgs) GetData() []byte {
|
||||
if args.Input != nil {
|
||||
return *args.Input
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
@ -25,15 +24,15 @@ func (k Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.Q
|
||||
func (k Keeper) BaseFee(c context.Context, _ *types.QueryBaseFeeRequest) (*types.QueryBaseFeeResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
res := &types.QueryBaseFeeResponse{}
|
||||
baseFee := k.GetBaseFee(ctx)
|
||||
if baseFee == nil {
|
||||
// TODO: should this be 0? 1? error?
|
||||
baseFee = big.NewInt(0)
|
||||
|
||||
if baseFee != nil {
|
||||
aux := sdk.NewIntFromBigInt(baseFee)
|
||||
res.BaseFee = &aux
|
||||
}
|
||||
|
||||
return &types.QueryBaseFeeResponse{
|
||||
BaseFee: sdk.NewIntFromBigInt(baseFee),
|
||||
}, nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// BlockGas implements the Query/BlockGas gRPC method
|
||||
|
84
x/feemarket/types/query.pb.go
generated
84
x/feemarket/types/query.pb.go
generated
@ -153,7 +153,7 @@ var xxx_messageInfo_QueryBaseFeeRequest proto.InternalMessageInfo
|
||||
|
||||
// BaseFeeResponse returns the EIP1559 base fee.
|
||||
type QueryBaseFeeResponse struct {
|
||||
BaseFee github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=base_fee,json=baseFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"base_fee"`
|
||||
BaseFee *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=base_fee,json=baseFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"base_fee,omitempty"`
|
||||
}
|
||||
|
||||
func (m *QueryBaseFeeResponse) Reset() { *m = QueryBaseFeeResponse{} }
|
||||
@ -287,34 +287,34 @@ func init() {
|
||||
|
||||
var fileDescriptor_71a07c1ffd85fde2 = []byte{
|
||||
// 450 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xbf, 0x8f, 0xd3, 0x30,
|
||||
0x14, 0x8e, 0x29, 0xf4, 0x0e, 0xb3, 0x20, 0xd3, 0x3b, 0x9d, 0xc2, 0x91, 0x3b, 0x05, 0xe9, 0xc4,
|
||||
0xaf, 0xb3, 0x75, 0xc7, 0xca, 0x94, 0x01, 0xb8, 0x0d, 0xc2, 0xc6, 0x52, 0x39, 0xe5, 0x35, 0x8d,
|
||||
0xda, 0xc4, 0x69, 0xec, 0x56, 0x74, 0x85, 0x85, 0x81, 0x01, 0x89, 0x3f, 0x82, 0x7f, 0xa5, 0x63,
|
||||
0x25, 0x16, 0xc4, 0x50, 0xa1, 0x96, 0x3f, 0x04, 0xc5, 0x71, 0xda, 0x86, 0xb6, 0xd0, 0x29, 0xd6,
|
||||
0xcb, 0xe7, 0xef, 0xfb, 0xde, 0xf7, 0xfc, 0xb0, 0x0b, 0xaa, 0x03, 0x59, 0x1c, 0x25, 0x8a, 0xb5,
|
||||
0x01, 0x62, 0x9e, 0x75, 0x41, 0xb1, 0xe1, 0x05, 0xeb, 0x0f, 0x20, 0x1b, 0xd1, 0x34, 0x13, 0x4a,
|
||||
0x90, 0xc3, 0x05, 0x86, 0x2e, 0x30, 0x74, 0x78, 0x61, 0x37, 0x42, 0x11, 0x0a, 0x0d, 0x61, 0xf9,
|
||||
0xa9, 0x40, 0xdb, 0xc7, 0xa1, 0x10, 0x61, 0x0f, 0x18, 0x4f, 0x23, 0xc6, 0x93, 0x44, 0x28, 0xae,
|
||||
0x22, 0x91, 0x48, 0xf3, 0xf7, 0x6c, 0x8b, 0xde, 0x92, 0x58, 0xe3, 0xdc, 0x06, 0x26, 0xaf, 0x73,
|
||||
0x0b, 0xaf, 0x78, 0xc6, 0x63, 0xe9, 0x43, 0x7f, 0x00, 0x52, 0xb9, 0x6f, 0xf0, 0x9d, 0x4a, 0x55,
|
||||
0xa6, 0x22, 0x91, 0x40, 0x9e, 0xe1, 0x7a, 0xaa, 0x2b, 0x47, 0xe8, 0x14, 0x3d, 0xb8, 0x75, 0xe9,
|
||||
0xd0, 0xcd, 0x8e, 0x69, 0x71, 0xcf, 0xbb, 0x3e, 0x9e, 0x9e, 0x58, 0xbe, 0xb9, 0xe3, 0x1e, 0x18,
|
||||
0x52, 0x8f, 0x4b, 0x78, 0x0e, 0x50, 0x6a, 0x71, 0xdc, 0xa8, 0x96, 0x8d, 0xd8, 0x15, 0xde, 0x0f,
|
||||
0xb8, 0x84, 0x66, 0x1b, 0x40, 0xcb, 0xdd, 0xf4, 0x68, 0x4e, 0xf7, 0x73, 0x7a, 0x72, 0x16, 0x46,
|
||||
0xaa, 0x33, 0x08, 0x68, 0x4b, 0xc4, 0xac, 0x25, 0x64, 0x2c, 0xa4, 0xf9, 0x9c, 0xcb, 0x77, 0x5d,
|
||||
0xa6, 0x46, 0x29, 0x48, 0x7a, 0x95, 0x28, 0x7f, 0x2f, 0x28, 0x28, 0xdd, 0xc3, 0x52, 0xa2, 0x27,
|
||||
0x5a, 0xdd, 0x17, 0x7c, 0xd1, 0xe6, 0x43, 0x7c, 0xf0, 0x57, 0xdd, 0x68, 0xdf, 0xc6, 0xb5, 0x90,
|
||||
0x17, 0x5d, 0xd6, 0xfc, 0xfc, 0x78, 0xf9, 0xad, 0x86, 0x6f, 0x68, 0x2c, 0xf9, 0x88, 0x70, 0xbd,
|
||||
0xe8, 0x8f, 0x3c, 0xda, 0xd6, 0xff, 0x7a, 0xa4, 0xf6, 0xe3, 0x9d, 0xb0, 0x85, 0xbe, 0x7b, 0xfa,
|
||||
0xe1, 0xfb, 0xef, 0xaf, 0xd7, 0x6c, 0x72, 0xb4, 0x32, 0x3c, 0x18, 0xc6, 0xf9, 0x00, 0x8b, 0x30,
|
||||
0xc9, 0x27, 0x84, 0xf7, 0x4c, 0x62, 0xe4, 0xdf, 0xd4, 0xd5, 0xb8, 0xed, 0x27, 0xbb, 0x81, 0x8d,
|
||||
0x11, 0x57, 0x1b, 0x39, 0x26, 0xf6, 0xba, 0x91, 0x72, 0x38, 0xe4, 0x33, 0xc2, 0xfb, 0x65, 0x82,
|
||||
0xe4, 0x3f, 0xf4, 0xd5, 0x01, 0xd8, 0xe7, 0x3b, 0xa2, 0x8d, 0x9b, 0xfb, 0xda, 0xcd, 0x3d, 0x72,
|
||||
0x77, 0x83, 0x9b, 0x1c, 0xdb, 0x0c, 0xb9, 0xf4, 0x5e, 0x8e, 0x67, 0x0e, 0x9a, 0xcc, 0x1c, 0xf4,
|
||||
0x6b, 0xe6, 0xa0, 0x2f, 0x73, 0xc7, 0x9a, 0xcc, 0x1d, 0xeb, 0xc7, 0xdc, 0xb1, 0xde, 0xd2, 0x95,
|
||||
0x77, 0xa3, 0x3a, 0x3c, 0x93, 0x91, 0x64, 0xcb, 0x35, 0x79, 0xbf, 0x42, 0xaa, 0xdf, 0x50, 0x50,
|
||||
0xd7, 0x2b, 0xf2, 0xf4, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xeb, 0xc7, 0xba, 0xe5, 0xbc, 0x03,
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xcf, 0x6f, 0xd3, 0x30,
|
||||
0x14, 0x8e, 0x29, 0x74, 0xc3, 0x5c, 0x90, 0xe9, 0xa6, 0x29, 0x8c, 0x6c, 0x0a, 0xd2, 0x04, 0x83,
|
||||
0xd9, 0xda, 0xb8, 0x72, 0x8a, 0xc4, 0xaf, 0x1b, 0x84, 0x1b, 0x12, 0x9a, 0x9c, 0xf2, 0x9a, 0x46,
|
||||
0x6d, 0xe2, 0x34, 0x76, 0x2b, 0x7a, 0x85, 0x0b, 0x07, 0x0e, 0x48, 0xfc, 0x11, 0xfc, 0x2b, 0x3d,
|
||||
0x56, 0xe2, 0x82, 0x38, 0x54, 0xa8, 0xe5, 0x0f, 0x41, 0x71, 0x9c, 0xb6, 0xa1, 0x2d, 0xf4, 0x14,
|
||||
0xeb, 0xe5, 0xf3, 0xf7, 0x7d, 0xef, 0x7b, 0x7e, 0xd8, 0x05, 0xd5, 0x86, 0x2c, 0x8e, 0x12, 0xc5,
|
||||
0x5a, 0x00, 0x31, 0xcf, 0x3a, 0xa0, 0xd8, 0xe0, 0x9c, 0xf5, 0xfa, 0x90, 0x0d, 0x69, 0x9a, 0x09,
|
||||
0x25, 0xc8, 0xfe, 0x1c, 0x43, 0xe7, 0x18, 0x3a, 0x38, 0xb7, 0x1b, 0xa1, 0x08, 0x85, 0x86, 0xb0,
|
||||
0xfc, 0x54, 0xa0, 0xed, 0xc3, 0x50, 0x88, 0xb0, 0x0b, 0x8c, 0xa7, 0x11, 0xe3, 0x49, 0x22, 0x14,
|
||||
0x57, 0x91, 0x48, 0xa4, 0xf9, 0x7b, 0xb2, 0x41, 0x6f, 0x41, 0xac, 0x71, 0x6e, 0x03, 0x93, 0x57,
|
||||
0xb9, 0x85, 0x97, 0x3c, 0xe3, 0xb1, 0xf4, 0xa1, 0xd7, 0x07, 0xa9, 0xdc, 0xd7, 0xf8, 0x56, 0xa5,
|
||||
0x2a, 0x53, 0x91, 0x48, 0x20, 0x8f, 0x71, 0x3d, 0xd5, 0x95, 0x03, 0x74, 0x8c, 0xee, 0xdd, 0xb8,
|
||||
0x70, 0xe8, 0x7a, 0xc7, 0xb4, 0xb8, 0xe7, 0x5d, 0x1d, 0x4d, 0x8e, 0x2c, 0xdf, 0xdc, 0x71, 0xf7,
|
||||
0x0c, 0xa9, 0xc7, 0x25, 0x3c, 0x05, 0x28, 0xb5, 0xde, 0xe2, 0x46, 0xb5, 0x6c, 0xc4, 0x9e, 0xe0,
|
||||
0xdd, 0x80, 0x4b, 0xb8, 0x6c, 0x01, 0x68, 0xb9, 0xeb, 0xde, 0xe9, 0xcf, 0xc9, 0xd1, 0x49, 0x18,
|
||||
0xa9, 0x76, 0x3f, 0xa0, 0x4d, 0x11, 0xb3, 0xa6, 0x90, 0xb1, 0x90, 0xe6, 0x73, 0x26, 0xdf, 0x75,
|
||||
0x98, 0x1a, 0xa6, 0x20, 0xe9, 0x8b, 0x44, 0xf9, 0x3b, 0x41, 0x41, 0xe7, 0xee, 0x97, 0xf4, 0x5d,
|
||||
0xd1, 0xec, 0x3c, 0xe3, 0xf3, 0x16, 0xef, 0xe3, 0xbd, 0xbf, 0xea, 0x46, 0xf7, 0x26, 0xae, 0x85,
|
||||
0xbc, 0xe8, 0xb0, 0xe6, 0xe7, 0xc7, 0x8b, 0x6f, 0x35, 0x7c, 0x4d, 0x63, 0xc9, 0x47, 0x84, 0xeb,
|
||||
0x45, 0x6f, 0xe4, 0x74, 0x53, 0xef, 0xab, 0x71, 0xda, 0x0f, 0xb6, 0xc2, 0x16, 0xfa, 0xee, 0xf1,
|
||||
0x87, 0xef, 0xbf, 0xbf, 0x5e, 0xb1, 0xc9, 0xc1, 0xd2, 0xe0, 0x60, 0x10, 0xe7, 0xc3, 0x2b, 0x82,
|
||||
0x24, 0x9f, 0x10, 0xde, 0x31, 0x69, 0x91, 0x7f, 0x53, 0x57, 0xa3, 0xb6, 0x1f, 0x6e, 0x07, 0x36,
|
||||
0x46, 0x5c, 0x6d, 0xe4, 0x90, 0xd8, 0xab, 0x46, 0xca, 0xc1, 0x90, 0xcf, 0x08, 0xef, 0x96, 0x09,
|
||||
0x92, 0xff, 0xd0, 0x57, 0x07, 0x60, 0x9f, 0x6d, 0x89, 0x36, 0x6e, 0xee, 0x6a, 0x37, 0x77, 0xc8,
|
||||
0xed, 0x35, 0x6e, 0x72, 0xec, 0x65, 0xc8, 0xa5, 0xf7, 0x7c, 0x34, 0x75, 0xd0, 0x78, 0xea, 0xa0,
|
||||
0x5f, 0x53, 0x07, 0x7d, 0x99, 0x39, 0xd6, 0x78, 0xe6, 0x58, 0x3f, 0x66, 0x8e, 0xf5, 0x86, 0x2e,
|
||||
0xbd, 0x1b, 0xd5, 0xe6, 0x99, 0x8c, 0x24, 0x5b, 0xac, 0xc8, 0xfb, 0x25, 0x52, 0xfd, 0x86, 0x82,
|
||||
0xba, 0x5e, 0x8f, 0x47, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x85, 0x23, 0x79, 0x71, 0xb8, 0x03,
|
||||
0x00, 0x00,
|
||||
}
|
||||
|
||||
@ -575,16 +575,18 @@ func (m *QueryBaseFeeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
{
|
||||
size := m.BaseFee.Size()
|
||||
i -= size
|
||||
if _, err := m.BaseFee.MarshalTo(dAtA[i:]); err != nil {
|
||||
return 0, err
|
||||
if m.BaseFee != nil {
|
||||
{
|
||||
size := m.BaseFee.Size()
|
||||
i -= size
|
||||
if _, err := m.BaseFee.MarshalTo(dAtA[i:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i = encodeVarintQuery(dAtA, i, uint64(size))
|
||||
}
|
||||
i = encodeVarintQuery(dAtA, i, uint64(size))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
@ -685,8 +687,10 @@ func (m *QueryBaseFeeResponse) Size() (n int) {
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.BaseFee.Size()
|
||||
n += 1 + l + sovQuery(uint64(l))
|
||||
if m.BaseFee != nil {
|
||||
l = m.BaseFee.Size()
|
||||
n += 1 + l + sovQuery(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@ -959,6 +963,8 @@ func (m *QueryBaseFeeResponse) Unmarshal(dAtA []byte) error {
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
var v github_com_cosmos_cosmos_sdk_types.Int
|
||||
m.BaseFee = &v
|
||||
if err := m.BaseFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user