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`
|
* (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).
|
* (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
|
### 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.
|
* (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
|
github.com/tyler-smith/go-bip39 v1.1.0
|
||||||
go.etcd.io/bbolt v1.3.6 // indirect
|
go.etcd.io/bbolt v1.3.6 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // 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
|
google.golang.org/grpc v1.41.0
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
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-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-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-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||||
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9 h1:eF1wcrhdz56Vugf8qNX5dD93ItkrhothojQyHXqloe0=
|
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e h1:Im71rbA1N3CbIag/PumYhQcNR8bLNmuOtRIyOnnLsT8=
|
||||||
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
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 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
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=
|
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.
|
// BaseFeeResponse returns the EIP1559 base fee.
|
||||||
message QueryBaseFeeResponse {
|
message QueryBaseFeeResponse {
|
||||||
string base_fee = 1 [
|
string base_fee = 1 [
|
||||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int"
|
||||||
(gogoproto.nullable) = false
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,29 +41,37 @@ import (
|
|||||||
// Backend implements the functionality shared within namespaces.
|
// Backend implements the functionality shared within namespaces.
|
||||||
// Implemented by EVMBackend.
|
// Implemented by EVMBackend.
|
||||||
type Backend interface {
|
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)
|
BlockNumber() (hexutil.Uint64, error)
|
||||||
|
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
|
||||||
GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error)
|
GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error)
|
||||||
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
|
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
|
||||||
CurrentHeader() *ethtypes.Header
|
CurrentHeader() *ethtypes.Header
|
||||||
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
|
|
||||||
HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error)
|
HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Header, error)
|
||||||
HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
|
HeaderByHash(blockHash common.Hash) (*ethtypes.Header, error)
|
||||||
PendingTransactions() ([]*sdk.Tx, error)
|
PendingTransactions() ([]*sdk.Tx, error)
|
||||||
GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error)
|
GetTransactionLogs(txHash common.Hash) ([]*ethtypes.Log, error)
|
||||||
GetTransactionCount(address common.Address, blockNum types.BlockNumber) (*hexutil.Uint64, error)
|
GetTransactionCount(address common.Address, blockNum types.BlockNumber) (*hexutil.Uint64, error)
|
||||||
SendTransaction(args evmtypes.TransactionArgs) (common.Hash, 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)
|
GetCoinbase() (sdk.AccAddress, error)
|
||||||
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
|
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
|
||||||
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
|
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
|
||||||
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
|
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
|
||||||
RPCGasCap() uint64
|
BaseFee() (*big.Int, error)
|
||||||
RPCMinGasPrice() int64
|
|
||||||
ChainConfig() *params.ChainConfig
|
// Filter API
|
||||||
SuggestGasTipCap() (*big.Int, error)
|
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)
|
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)
|
var _ Backend = (*EVMBackend)(nil)
|
||||||
@ -228,6 +236,14 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
|||||||
) (map[string]interface{}, error) {
|
) (map[string]interface{}, error) {
|
||||||
ethRPCTxs := []interface{}{}
|
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 {
|
for i, txBz := range block.Txs {
|
||||||
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
|
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -237,43 +253,30 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
|||||||
|
|
||||||
for _, msg := range tx.GetMsgs() {
|
for _, msg := range tx.GetMsgs() {
|
||||||
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
hash := ethMsg.AsTransaction().Hash()
|
tx := ethMsg.AsTransaction()
|
||||||
|
|
||||||
if !fullTx {
|
if !fullTx {
|
||||||
|
hash := tx.Hash()
|
||||||
ethRPCTxs = append(ethRPCTxs, hash)
|
ethRPCTxs = append(ethRPCTxs, hash)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// get full transaction from message data
|
rpcTx, err := types.NewRPCTransaction(
|
||||||
from, err := ethMsg.GetSender(e.chainID)
|
tx,
|
||||||
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,
|
|
||||||
common.BytesToHash(block.Hash()),
|
common.BytesToHash(block.Hash()),
|
||||||
uint64(block.Height),
|
uint64(block.Height),
|
||||||
uint64(i),
|
uint64(i),
|
||||||
|
bfRes.BaseFee.BigInt(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
ethRPCTxs = append(ethRPCTxs, ethTx)
|
ethRPCTxs = append(ethRPCTxs, rpcTx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,8 +289,6 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
|||||||
ConsAddress: sdk.ConsAddress(block.Header.ProposerAddress).String(),
|
ConsAddress: sdk.ConsAddress(block.Header.ProposerAddress).String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := types.ContextWithHeight(block.Height)
|
|
||||||
|
|
||||||
res, err := e.queryClient.ValidatorAccount(ctx, req)
|
res, err := e.queryClient.ValidatorAccount(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.logger.Debug(
|
e.logger.Debug(
|
||||||
@ -306,12 +307,6 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
|||||||
|
|
||||||
validatorAddr := common.BytesToAddress(addr)
|
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)
|
gasLimit, err := types.BlockMaxGasFromConsensusParams(ctx, e.clientCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.logger.Error("failed to query consensus params", "error", err.Error())
|
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)
|
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
|
ethHeader.Bloom = bloom
|
||||||
return ethHeader, nil
|
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)
|
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
|
ethHeader.Bloom = bloom
|
||||||
return ethHeader, nil
|
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())
|
return common.Hash{}, fmt.Errorf("%s; %s", keystore.ErrNoMatch, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
args, err = e.setTxDefaults(args)
|
args, err = e.SetTxDefaults(args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := args.ToTransaction()
|
msg := args.ToTransaction()
|
||||||
|
|
||||||
if err := msg.ValidateBasic(); err != nil {
|
if err := msg.ValidateBasic(); err != nil {
|
||||||
e.logger.Debug("tx failed basic validation", "error", err.Error())
|
e.logger.Debug("tx failed basic validation", "error", err.Error())
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get from chain config
|
bn, err := e.BlockNumber()
|
||||||
signer := ethtypes.LatestSignerForChainID(args.ChainID.ToInt())
|
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
|
// Sign transaction
|
||||||
if err := msg.Sign(signer, e.clientCtx.Keyring); err != nil {
|
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)
|
builder.SetExtensionOptions(option)
|
||||||
err = builder.SetMsgs(msg)
|
if err = builder.SetMsgs(msg); err != nil {
|
||||||
if err != nil {
|
|
||||||
e.logger.Error("builder.SetMsgs failed", "error", err.Error())
|
e.logger.Error("builder.SetMsgs failed", "error", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,7 +711,22 @@ func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional
|
|||||||
return 0, err
|
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,
|
// From ContextWithHeight: if the provided height is 0,
|
||||||
// it will return an empty context and the gRPC query will use
|
// 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.
|
// the node config. If set value is 0, it will default to 20.
|
||||||
|
|
||||||
func (e *EVMBackend) RPCMinGasPrice() int64 {
|
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 {
|
if err != nil {
|
||||||
return ethermint.DefaultGasPrice
|
return ethermint.DefaultGasPrice
|
||||||
}
|
}
|
||||||
@ -771,8 +796,29 @@ func (e *EVMBackend) ChainConfig() *params.ChainConfig {
|
|||||||
|
|
||||||
// SuggestGasTipCap returns the suggested tip cap
|
// SuggestGasTipCap returns the suggested tip cap
|
||||||
func (e *EVMBackend) SuggestGasTipCap() (*big.Int, error) {
|
func (e *EVMBackend) SuggestGasTipCap() (*big.Int, error) {
|
||||||
// TODO: implement
|
out := new(big.Int).SetInt64(e.RPCMinGasPrice())
|
||||||
return big.NewInt(1), nil
|
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.
|
// GetFilteredBlocks returns the block height list match the given bloom filters.
|
||||||
|
@ -19,9 +19,9 @@ import (
|
|||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
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
|
// 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) {
|
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")
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
@ -45,6 +46,7 @@ type PublicAPI struct {
|
|||||||
logger log.Logger
|
logger log.Logger
|
||||||
backend backend.Backend
|
backend backend.Backend
|
||||||
nonceLock *rpctypes.AddrLocker
|
nonceLock *rpctypes.AddrLocker
|
||||||
|
signer ethtypes.Signer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPublicAPI creates an instance of the public ETH Web3 API.
|
// NewPublicAPI creates an instance of the public ETH Web3 API.
|
||||||
@ -76,6 +78,10 @@ func NewPublicAPI(
|
|||||||
clientCtx = clientCtx.WithKeyring(kr)
|
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{
|
api := &PublicAPI{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
clientCtx: clientCtx,
|
clientCtx: clientCtx,
|
||||||
@ -84,6 +90,7 @@ func NewPublicAPI(
|
|||||||
logger: logger.With("client", "json-rpc"),
|
logger: logger.With("client", "json-rpc"),
|
||||||
backend: backend,
|
backend: backend,
|
||||||
nonceLock: nonceLock,
|
nonceLock: nonceLock,
|
||||||
|
signer: signer,
|
||||||
}
|
}
|
||||||
|
|
||||||
return api
|
return api
|
||||||
@ -108,14 +115,30 @@ func (e *PublicAPI) ProtocolVersion() hexutil.Uint {
|
|||||||
return hexutil.Uint(ethermint.ProtocolVersion)
|
return hexutil.Uint(ethermint.ProtocolVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainId returns the chain's identifier in hex format
|
// ChainId is the EIP-155 replay-protection chain id for the current ethereum chain config.
|
||||||
func (e *PublicAPI) ChainId() (hexutil.Uint, error) { // nolint
|
func (e *PublicAPI) ChainId() (*hexutil.Big, error) { // nolint
|
||||||
e.logger.Debug("eth_chainId")
|
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
|
// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not
|
||||||
// outlining the state of the sync if it is.
|
// 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) {
|
func (e *PublicAPI) Syncing() (interface{}, error) {
|
||||||
e.logger.Debug("eth_syncing")
|
e.logger.Debug("eth_syncing")
|
||||||
|
|
||||||
@ -129,7 +152,7 @@ func (e *PublicAPI) Syncing() (interface{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
// "startingBlock": nil, // NA
|
"startingBlock": hexutil.Uint64(status.SyncInfo.EarliestBlockHeight),
|
||||||
"currentBlock": hexutil.Uint64(status.SyncInfo.LatestBlockHeight),
|
"currentBlock": hexutil.Uint64(status.SyncInfo.LatestBlockHeight),
|
||||||
// "highestBlock": nil, // NA
|
// "highestBlock": nil, // NA
|
||||||
// "pulledStates": nil, // NA
|
// "pulledStates": 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.
|
// 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")
|
e.logger.Debug("eth_gasPrice")
|
||||||
out := new(big.Int).SetInt64(e.backend.RPCMinGasPrice())
|
tipcap, err := e.backend.SuggestGasTipCap()
|
||||||
return (*hexutil.Big)(out)
|
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.
|
// 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)
|
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.
|
// SendRawTransaction send a raw Ethereum transaction.
|
||||||
func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
|
func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
|
||||||
e.logger.Debug("eth_sendRawTransaction", "length", len(data))
|
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
|
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.SetFeeAmount(fees)
|
||||||
builder.SetGasLimit(ethereumTx.GetGas())
|
builder.SetGasLimit(ethereumTx.GetGas())
|
||||||
|
|
||||||
@ -433,6 +509,57 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
|
|||||||
return txHash, nil
|
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.
|
// Call performs a raw contract call.
|
||||||
func (e *PublicAPI) Call(args evmtypes.TransactionArgs, blockNrOrHash rpctypes.BlockNumberOrHash, _ *rpctypes.StateOverride) (hexutil.Bytes, error) {
|
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)
|
e.logger.Debug("eth_call", "args", args.String(), "block number or hash", blockNrOrHash)
|
||||||
@ -458,7 +585,23 @@ func (e *PublicAPI) doCall(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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,
|
// From ContextWithHeight: if the provided height is 0,
|
||||||
// it will return an empty context and the gRPC query will use
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
baseFee, err := e.backend.BaseFee()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return rpctypes.NewTransactionFromMsg(
|
return rpctypes.NewTransactionFromMsg(
|
||||||
msg,
|
msg,
|
||||||
hash,
|
hash,
|
||||||
uint64(resBlock.Block.Height),
|
uint64(resBlock.Block.Height),
|
||||||
uint64(idx),
|
uint64(idx),
|
||||||
e.chainIDEpoch,
|
baseFee,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package filters
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth/filters"
|
"github.com/ethereum/go-ethereum/eth/filters"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
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()))
|
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.filtersMu.Lock()
|
||||||
api.filters[headerSub.ID()] = &filter{typ: filters.BlocksSubscription, deadline: time.NewTimer(deadline), hashes: []common.Hash{}, s: headerSub}
|
api.filters[headerSub.ID()] = &filter{typ: filters.BlocksSubscription, deadline: time.NewTimer(deadline), hashes: []common.Hash{}, s: headerSub}
|
||||||
api.filtersMu.Unlock()
|
api.filtersMu.Unlock()
|
||||||
@ -246,7 +251,7 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
header := types.EthHeaderFromTendermint(data.Header)
|
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
||||||
api.filtersMu.Lock()
|
api.filtersMu.Lock()
|
||||||
if f, found := api.filters[headerSub.ID()]; found {
|
if f, found := api.filters[headerSub.ID()]; found {
|
||||||
f.hashes = append(f.hashes, header.Hash())
|
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
|
return &rpc.Subscription{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: use events to get the base fee amount
|
||||||
|
baseFee := big.NewInt(params.InitialBaseFee)
|
||||||
|
|
||||||
go func(headersCh <-chan coretypes.ResultEvent) {
|
go func(headersCh <-chan coretypes.ResultEvent) {
|
||||||
defer cancelSubs()
|
defer cancelSubs()
|
||||||
|
|
||||||
@ -296,7 +304,7 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
header := types.EthHeaderFromTendermint(data.Header)
|
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
||||||
err = notifier.Notify(rpcSub.ID, header)
|
err = notifier.Notify(rpcSub.ID, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
headersSub.err <- err
|
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
|
// 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
|
// tries to sign it with the key associated with args.To. If the given password isn't
|
||||||
// able to decrypt the key it fails.
|
// 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())
|
api.logger.Debug("personal_sendTransaction", "address", args.To.String())
|
||||||
|
|
||||||
if args.From == nil {
|
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.
|
// The key used to calculate the signature is decrypted with the given password.
|
||||||
//
|
//
|
||||||
// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign
|
// 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())
|
api.logger.Debug("personal_sign", "data", data, "address", addr.String())
|
||||||
|
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
|
@ -66,3 +66,16 @@ type OverrideAccount struct {
|
|||||||
State *map[common.Hash]common.Hash `json:"state"`
|
State *map[common.Hash]common.Hash `json:"state"`
|
||||||
StateDiff *map[common.Hash]common.Hash `json:"stateDiff"`
|
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"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
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
|
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
|
// EthHeaderFromTendermint is an util function that returns an Ethereum Header
|
||||||
// from a tendermint 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
|
txHash := ethtypes.EmptyRootHash
|
||||||
if len(header.DataHash) == 0 {
|
if len(header.DataHash) == 0 {
|
||||||
txHash = common.BytesToHash(header.DataHash)
|
txHash = common.BytesToHash(header.DataHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ðtypes.Header{
|
return ðtypes.Header{
|
||||||
ParentHash: common.BytesToHash(header.LastBlockID.Hash.Bytes()),
|
ParentHash: common.BytesToHash(header.LastBlockID.Hash.Bytes()),
|
||||||
UncleHash: ethtypes.EmptyUncleHash,
|
UncleHash: ethtypes.EmptyUncleHash,
|
||||||
@ -99,6 +58,7 @@ func EthHeaderFromTendermint(header tmtypes.Header) *ethtypes.Header {
|
|||||||
Extra: nil,
|
Extra: nil,
|
||||||
MixDigest: common.Hash{},
|
MixDigest: common.Hash{},
|
||||||
Nonce: ethtypes.BlockNonce{},
|
Nonce: ethtypes.BlockNonce{},
|
||||||
|
BaseFee: baseFee,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,65 +180,67 @@ func NewTransactionFromMsg(
|
|||||||
msg *evmtypes.MsgEthereumTx,
|
msg *evmtypes.MsgEthereumTx,
|
||||||
blockHash common.Hash,
|
blockHash common.Hash,
|
||||||
blockNumber, index uint64,
|
blockNumber, index uint64,
|
||||||
chainID *big.Int,
|
baseFee *big.Int,
|
||||||
) (*RPCTransaction, error) {
|
) (*RPCTransaction, error) {
|
||||||
from, err := msg.GetSender(chainID)
|
tx := msg.AsTransaction()
|
||||||
if err != nil {
|
return NewRPCTransaction(tx, blockHash, blockNumber, index, baseFee)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTransactionFromData returns a transaction that will serialize to the RPC
|
// NewTransactionFromData returns a transaction that will serialize to the RPC
|
||||||
// representation, with the given location metadata set (if available).
|
// representation, with the given location metadata set (if available).
|
||||||
func NewTransactionFromData(
|
func NewRPCTransaction(
|
||||||
txData evmtypes.TxData,
|
tx *ethtypes.Transaction, blockHash common.Hash, blockNumber, index uint64, baseFee *big.Int,
|
||||||
from common.Address,
|
|
||||||
txHash, blockHash common.Hash,
|
|
||||||
blockNumber, index uint64,
|
|
||||||
) (*RPCTransaction, error) {
|
) (*RPCTransaction, error) {
|
||||||
if txHash == (common.Hash{}) {
|
// Determine the signer. For replay-protected transactions, use the most permissive
|
||||||
txHash = ethtypes.EmptyRootHash
|
// 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 := txData.GetRawSignatureValues()
|
v, r, s := tx.RawSignatureValues()
|
||||||
|
result := &RPCTransaction{
|
||||||
rpcTx := &RPCTransaction{
|
Type: hexutil.Uint64(tx.Type()),
|
||||||
Type: hexutil.Uint64(txData.TxType()),
|
|
||||||
From: from,
|
From: from,
|
||||||
Gas: hexutil.Uint64(txData.GetGas()),
|
Gas: hexutil.Uint64(tx.Gas()),
|
||||||
GasPrice: (*hexutil.Big)(txData.GetGasPrice()),
|
GasPrice: (*hexutil.Big)(tx.GasPrice()),
|
||||||
Hash: txHash,
|
Hash: tx.Hash(),
|
||||||
Input: hexutil.Bytes(txData.GetData()),
|
Input: hexutil.Bytes(tx.Data()),
|
||||||
Nonce: hexutil.Uint64(txData.GetNonce()),
|
Nonce: hexutil.Uint64(tx.Nonce()),
|
||||||
To: txData.GetTo(),
|
To: tx.To(),
|
||||||
Value: (*hexutil.Big)(txData.GetValue()),
|
Value: (*hexutil.Big)(tx.Value()),
|
||||||
V: (*hexutil.Big)(v),
|
V: (*hexutil.Big)(v),
|
||||||
R: (*hexutil.Big)(r),
|
R: (*hexutil.Big)(r),
|
||||||
S: (*hexutil.Big)(s),
|
S: (*hexutil.Big)(s),
|
||||||
}
|
}
|
||||||
if rpcTx.To == nil {
|
|
||||||
addr := common.Address{}
|
|
||||||
rpcTx.To = &addr
|
|
||||||
}
|
|
||||||
|
|
||||||
if blockHash != (common.Hash{}) {
|
if blockHash != (common.Hash{}) {
|
||||||
rpcTx.BlockHash = &blockHash
|
result.BlockHash = &blockHash
|
||||||
rpcTx.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
|
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
|
||||||
rpcTx.TransactionIndex = (*hexutil.Uint64)(&index)
|
result.TransactionIndex = (*hexutil.Uint64)(&index)
|
||||||
}
|
}
|
||||||
|
switch tx.Type() {
|
||||||
if txData.TxType() == ethtypes.AccessListTxType {
|
case ethtypes.AccessListTxType:
|
||||||
accesses := txData.GetAccessList()
|
al := tx.AccessList()
|
||||||
rpcTx.Accesses = &accesses
|
result.Accesses = &al
|
||||||
rpcTx.ChainID = (*hexutil.Big)(txData.GetChainID())
|
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/common"
|
||||||
"github.com/ethereum/go-ethereum/eth/filters"
|
"github.com/ethereum/go-ethereum/eth/filters"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
"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")
|
return "", errors.Wrap(err, "error creating block filter")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: use events
|
||||||
|
baseFee := big.NewInt(params.InitialBaseFee)
|
||||||
|
|
||||||
unsubscribed := make(chan struct{})
|
unsubscribed := make(chan struct{})
|
||||||
api.filtersMu.Lock()
|
api.filtersMu.Lock()
|
||||||
api.filters[subID] = &wsSubscription{
|
api.filters[subID] = &wsSubscription{
|
||||||
@ -377,7 +381,7 @@ func (api *pubSubAPI) subscribeNewHeads(wsConn *wsConn) (rpc.ID, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
header := types.EthHeaderFromTendermint(data.Header)
|
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
||||||
|
|
||||||
api.filtersMu.RLock()
|
api.filtersMu.RLock()
|
||||||
for subID, wsSub := range api.filters {
|
for subID, wsSub := range api.filters {
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
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/ethereum/types"
|
||||||
|
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
@ -79,6 +81,17 @@ func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte,
|
|||||||
return nil, err
|
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())
|
blockHash := common.BytesToHash(block.Block.Header.Hash())
|
||||||
|
|
||||||
ethTx, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx)
|
ethTx, err := rpctypes.RawTxToEthTx(clientCtx, tx.Tx)
|
||||||
@ -87,7 +100,11 @@ func getEthTransactionByHash(clientCtx client.Context, hashHex string) ([]byte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
height := uint64(tx.Height)
|
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)
|
return json.Marshal(rpcTx)
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
|
|||||||
GasFeeCap: &maxFeePerGas,
|
GasFeeCap: &maxFeePerGas,
|
||||||
GasTipCap: &maxPriorityFeePerGas,
|
GasTipCap: &maxPriorityFeePerGas,
|
||||||
Amount: &value,
|
Amount: &value,
|
||||||
Data: args.data(),
|
Data: args.GetData(),
|
||||||
Accesses: al,
|
Accesses: al,
|
||||||
}
|
}
|
||||||
case args.AccessList != nil:
|
case args.AccessList != nil:
|
||||||
@ -124,7 +124,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
|
|||||||
GasLimit: gas,
|
GasLimit: gas,
|
||||||
GasPrice: &gasPrice,
|
GasPrice: &gasPrice,
|
||||||
Amount: &value,
|
Amount: &value,
|
||||||
Data: args.data(),
|
Data: args.GetData(),
|
||||||
Accesses: NewAccessList(args.AccessList),
|
Accesses: NewAccessList(args.AccessList),
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -134,7 +134,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx {
|
|||||||
GasLimit: gas,
|
GasLimit: gas,
|
||||||
GasPrice: &gasPrice,
|
GasPrice: &gasPrice,
|
||||||
Amount: &value,
|
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.
|
// 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
|
// Set default gas & gas price if none were set
|
||||||
gas := globalGasCap
|
gas := globalGasCap
|
||||||
@ -214,7 +214,7 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (e
|
|||||||
if args.Value != nil {
|
if args.Value != nil {
|
||||||
value = args.Value.ToInt()
|
value = args.Value.ToInt()
|
||||||
}
|
}
|
||||||
data := args.data()
|
data := args.GetData()
|
||||||
var accessList ethtypes.AccessList
|
var accessList ethtypes.AccessList
|
||||||
if args.AccessList != nil {
|
if args.AccessList != nil {
|
||||||
accessList = *args.AccessList
|
accessList = *args.AccessList
|
||||||
@ -223,16 +223,16 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (e
|
|||||||
return msg, nil
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// from retrieves the transaction sender address.
|
// GetFrom retrieves the transaction sender address.
|
||||||
func (args *TransactionArgs) from() common.Address {
|
func (args *TransactionArgs) GetFrom() common.Address {
|
||||||
if args.From == nil {
|
if args.From == nil {
|
||||||
return common.Address{}
|
return common.Address{}
|
||||||
}
|
}
|
||||||
return *args.From
|
return *args.From
|
||||||
}
|
}
|
||||||
|
|
||||||
// data retrieves the transaction calldata. Input field is preferred.
|
// GetData retrieves the transaction calldata. Input field is preferred.
|
||||||
func (args *TransactionArgs) data() []byte {
|
func (args *TransactionArgs) GetData() []byte {
|
||||||
if args.Input != nil {
|
if args.Input != nil {
|
||||||
return *args.Input
|
return *args.Input
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package keeper
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"math/big"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
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) {
|
func (k Keeper) BaseFee(c context.Context, _ *types.QueryBaseFeeRequest) (*types.QueryBaseFeeResponse, error) {
|
||||||
ctx := sdk.UnwrapSDKContext(c)
|
ctx := sdk.UnwrapSDKContext(c)
|
||||||
|
|
||||||
|
res := &types.QueryBaseFeeResponse{}
|
||||||
baseFee := k.GetBaseFee(ctx)
|
baseFee := k.GetBaseFee(ctx)
|
||||||
if baseFee == nil {
|
|
||||||
// TODO: should this be 0? 1? error?
|
if baseFee != nil {
|
||||||
baseFee = big.NewInt(0)
|
aux := sdk.NewIntFromBigInt(baseFee)
|
||||||
|
res.BaseFee = &aux
|
||||||
}
|
}
|
||||||
|
|
||||||
return &types.QueryBaseFeeResponse{
|
return res, nil
|
||||||
BaseFee: sdk.NewIntFromBigInt(baseFee),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockGas implements the Query/BlockGas gRPC method
|
// BlockGas implements the Query/BlockGas gRPC method
|
||||||
|
64
x/feemarket/types/query.pb.go
generated
64
x/feemarket/types/query.pb.go
generated
@ -153,7 +153,7 @@ var xxx_messageInfo_QueryBaseFeeRequest proto.InternalMessageInfo
|
|||||||
|
|
||||||
// BaseFeeResponse returns the EIP1559 base fee.
|
// BaseFeeResponse returns the EIP1559 base fee.
|
||||||
type QueryBaseFeeResponse struct {
|
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{} }
|
func (m *QueryBaseFeeResponse) Reset() { *m = QueryBaseFeeResponse{} }
|
||||||
@ -287,34 +287,34 @@ func init() {
|
|||||||
|
|
||||||
var fileDescriptor_71a07c1ffd85fde2 = []byte{
|
var fileDescriptor_71a07c1ffd85fde2 = []byte{
|
||||||
// 450 bytes of a gzipped FileDescriptorProto
|
// 450 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xbf, 0x8f, 0xd3, 0x30,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xcf, 0x6f, 0xd3, 0x30,
|
||||||
0x14, 0x8e, 0x29, 0xf4, 0x0e, 0xb3, 0x20, 0xd3, 0x3b, 0x9d, 0xc2, 0x91, 0x3b, 0x05, 0xe9, 0xc4,
|
0x14, 0x8e, 0x29, 0x74, 0xc3, 0x5c, 0x90, 0xe9, 0xa6, 0x29, 0x8c, 0x6c, 0x0a, 0xd2, 0x04, 0x83,
|
||||||
0xaf, 0xb3, 0x75, 0xc7, 0xca, 0x94, 0x01, 0xb8, 0x0d, 0xc2, 0xc6, 0x52, 0x39, 0xe5, 0x35, 0x8d,
|
0xd9, 0xda, 0xb8, 0x72, 0x8a, 0xc4, 0xaf, 0x1b, 0x84, 0x1b, 0x12, 0x9a, 0x9c, 0xf2, 0x9a, 0x46,
|
||||||
0xda, 0xc4, 0x69, 0xec, 0x56, 0x74, 0x85, 0x85, 0x81, 0x01, 0x89, 0x3f, 0x82, 0x7f, 0xa5, 0x63,
|
0x6d, 0xe2, 0x34, 0x76, 0x2b, 0x7a, 0x85, 0x0b, 0x07, 0x0e, 0x48, 0xfc, 0x11, 0xfc, 0x2b, 0x3d,
|
||||||
0x25, 0x16, 0xc4, 0x50, 0xa1, 0x96, 0x3f, 0x04, 0xc5, 0x71, 0xda, 0x86, 0xb6, 0xd0, 0x29, 0xd6,
|
0x56, 0xe2, 0x82, 0x38, 0x54, 0xa8, 0xe5, 0x0f, 0x41, 0x71, 0x9c, 0xb6, 0xa1, 0x2d, 0xf4, 0x14,
|
||||||
0xcb, 0xe7, 0xef, 0xfb, 0xde, 0xf7, 0xfc, 0xb0, 0x0b, 0xaa, 0x03, 0x59, 0x1c, 0x25, 0x8a, 0xb5,
|
0xeb, 0xe5, 0xf3, 0xf7, 0x7d, 0xef, 0x7b, 0x7e, 0xd8, 0x05, 0xd5, 0x86, 0x2c, 0x8e, 0x12, 0xc5,
|
||||||
0x01, 0x62, 0x9e, 0x75, 0x41, 0xb1, 0xe1, 0x05, 0xeb, 0x0f, 0x20, 0x1b, 0xd1, 0x34, 0x13, 0x4a,
|
0x5a, 0x00, 0x31, 0xcf, 0x3a, 0xa0, 0xd8, 0xe0, 0x9c, 0xf5, 0xfa, 0x90, 0x0d, 0x69, 0x9a, 0x09,
|
||||||
0x90, 0xc3, 0x05, 0x86, 0x2e, 0x30, 0x74, 0x78, 0x61, 0x37, 0x42, 0x11, 0x0a, 0x0d, 0x61, 0xf9,
|
0x25, 0xc8, 0xfe, 0x1c, 0x43, 0xe7, 0x18, 0x3a, 0x38, 0xb7, 0x1b, 0xa1, 0x08, 0x85, 0x86, 0xb0,
|
||||||
0xa9, 0x40, 0xdb, 0xc7, 0xa1, 0x10, 0x61, 0x0f, 0x18, 0x4f, 0x23, 0xc6, 0x93, 0x44, 0x28, 0xae,
|
0xfc, 0x54, 0xa0, 0xed, 0xc3, 0x50, 0x88, 0xb0, 0x0b, 0x8c, 0xa7, 0x11, 0xe3, 0x49, 0x22, 0x14,
|
||||||
0x22, 0x91, 0x48, 0xf3, 0xf7, 0x6c, 0x8b, 0xde, 0x92, 0x58, 0xe3, 0xdc, 0x06, 0x26, 0xaf, 0x73,
|
0x57, 0x91, 0x48, 0xa4, 0xf9, 0x7b, 0xb2, 0x41, 0x6f, 0x41, 0xac, 0x71, 0x6e, 0x03, 0x93, 0x57,
|
||||||
0x0b, 0xaf, 0x78, 0xc6, 0x63, 0xe9, 0x43, 0x7f, 0x00, 0x52, 0xb9, 0x6f, 0xf0, 0x9d, 0x4a, 0x55,
|
0xb9, 0x85, 0x97, 0x3c, 0xe3, 0xb1, 0xf4, 0xa1, 0xd7, 0x07, 0xa9, 0xdc, 0xd7, 0xf8, 0x56, 0xa5,
|
||||||
0xa6, 0x22, 0x91, 0x40, 0x9e, 0xe1, 0x7a, 0xaa, 0x2b, 0x47, 0xe8, 0x14, 0x3d, 0xb8, 0x75, 0xe9,
|
0x2a, 0x53, 0x91, 0x48, 0x20, 0x8f, 0x71, 0x3d, 0xd5, 0x95, 0x03, 0x74, 0x8c, 0xee, 0xdd, 0xb8,
|
||||||
0xd0, 0xcd, 0x8e, 0x69, 0x71, 0xcf, 0xbb, 0x3e, 0x9e, 0x9e, 0x58, 0xbe, 0xb9, 0xe3, 0x1e, 0x18,
|
0x70, 0xe8, 0x7a, 0xc7, 0xb4, 0xb8, 0xe7, 0x5d, 0x1d, 0x4d, 0x8e, 0x2c, 0xdf, 0xdc, 0x71, 0xf7,
|
||||||
0x52, 0x8f, 0x4b, 0x78, 0x0e, 0x50, 0x6a, 0x71, 0xdc, 0xa8, 0x96, 0x8d, 0xd8, 0x15, 0xde, 0x0f,
|
0x0c, 0xa9, 0xc7, 0x25, 0x3c, 0x05, 0x28, 0xb5, 0xde, 0xe2, 0x46, 0xb5, 0x6c, 0xc4, 0x9e, 0xe0,
|
||||||
0xb8, 0x84, 0x66, 0x1b, 0x40, 0xcb, 0xdd, 0xf4, 0x68, 0x4e, 0xf7, 0x73, 0x7a, 0x72, 0x16, 0x46,
|
0xdd, 0x80, 0x4b, 0xb8, 0x6c, 0x01, 0x68, 0xb9, 0xeb, 0xde, 0xe9, 0xcf, 0xc9, 0xd1, 0x49, 0x18,
|
||||||
0xaa, 0x33, 0x08, 0x68, 0x4b, 0xc4, 0xac, 0x25, 0x64, 0x2c, 0xa4, 0xf9, 0x9c, 0xcb, 0x77, 0x5d,
|
0xa9, 0x76, 0x3f, 0xa0, 0x4d, 0x11, 0xb3, 0xa6, 0x90, 0xb1, 0x90, 0xe6, 0x73, 0x26, 0xdf, 0x75,
|
||||||
0xa6, 0x46, 0x29, 0x48, 0x7a, 0x95, 0x28, 0x7f, 0x2f, 0x28, 0x28, 0xdd, 0xc3, 0x52, 0xa2, 0x27,
|
0x98, 0x1a, 0xa6, 0x20, 0xe9, 0x8b, 0x44, 0xf9, 0x3b, 0x41, 0x41, 0xe7, 0xee, 0x97, 0xf4, 0x5d,
|
||||||
0x5a, 0xdd, 0x17, 0x7c, 0xd1, 0xe6, 0x43, 0x7c, 0xf0, 0x57, 0xdd, 0x68, 0xdf, 0xc6, 0xb5, 0x90,
|
0xd1, 0xec, 0x3c, 0xe3, 0xf3, 0x16, 0xef, 0xe3, 0xbd, 0xbf, 0xea, 0x46, 0xf7, 0x26, 0xae, 0x85,
|
||||||
0x17, 0x5d, 0xd6, 0xfc, 0xfc, 0x78, 0xf9, 0xad, 0x86, 0x6f, 0x68, 0x2c, 0xf9, 0x88, 0x70, 0xbd,
|
0xbc, 0xe8, 0xb0, 0xe6, 0xe7, 0xc7, 0x8b, 0x6f, 0x35, 0x7c, 0x4d, 0x63, 0xc9, 0x47, 0x84, 0xeb,
|
||||||
0xe8, 0x8f, 0x3c, 0xda, 0xd6, 0xff, 0x7a, 0xa4, 0xf6, 0xe3, 0x9d, 0xb0, 0x85, 0xbe, 0x7b, 0xfa,
|
0x45, 0x6f, 0xe4, 0x74, 0x53, 0xef, 0xab, 0x71, 0xda, 0x0f, 0xb6, 0xc2, 0x16, 0xfa, 0xee, 0xf1,
|
||||||
0xe1, 0xfb, 0xef, 0xaf, 0xd7, 0x6c, 0x72, 0xb4, 0x32, 0x3c, 0x18, 0xc6, 0xf9, 0x00, 0x8b, 0x30,
|
0x87, 0xef, 0xbf, 0xbf, 0x5e, 0xb1, 0xc9, 0xc1, 0xd2, 0xe0, 0x60, 0x10, 0xe7, 0xc3, 0x2b, 0x82,
|
||||||
0xc9, 0x27, 0x84, 0xf7, 0x4c, 0x62, 0xe4, 0xdf, 0xd4, 0xd5, 0xb8, 0xed, 0x27, 0xbb, 0x81, 0x8d,
|
0x24, 0x9f, 0x10, 0xde, 0x31, 0x69, 0x91, 0x7f, 0x53, 0x57, 0xa3, 0xb6, 0x1f, 0x6e, 0x07, 0x36,
|
||||||
0x11, 0x57, 0x1b, 0x39, 0x26, 0xf6, 0xba, 0x91, 0x72, 0x38, 0xe4, 0x33, 0xc2, 0xfb, 0x65, 0x82,
|
0x46, 0x5c, 0x6d, 0xe4, 0x90, 0xd8, 0xab, 0x46, 0xca, 0xc1, 0x90, 0xcf, 0x08, 0xef, 0x96, 0x09,
|
||||||
0xe4, 0x3f, 0xf4, 0xd5, 0x01, 0xd8, 0xe7, 0x3b, 0xa2, 0x8d, 0x9b, 0xfb, 0xda, 0xcd, 0x3d, 0x72,
|
0x92, 0xff, 0xd0, 0x57, 0x07, 0x60, 0x9f, 0x6d, 0x89, 0x36, 0x6e, 0xee, 0x6a, 0x37, 0x77, 0xc8,
|
||||||
0x77, 0x83, 0x9b, 0x1c, 0xdb, 0x0c, 0xb9, 0xf4, 0x5e, 0x8e, 0x67, 0x0e, 0x9a, 0xcc, 0x1c, 0xf4,
|
0xed, 0x35, 0x6e, 0x72, 0xec, 0x65, 0xc8, 0xa5, 0xf7, 0x7c, 0x34, 0x75, 0xd0, 0x78, 0xea, 0xa0,
|
||||||
0x6b, 0xe6, 0xa0, 0x2f, 0x73, 0xc7, 0x9a, 0xcc, 0x1d, 0xeb, 0xc7, 0xdc, 0xb1, 0xde, 0xd2, 0x95,
|
0x5f, 0x53, 0x07, 0x7d, 0x99, 0x39, 0xd6, 0x78, 0xe6, 0x58, 0x3f, 0x66, 0x8e, 0xf5, 0x86, 0x2e,
|
||||||
0x77, 0xa3, 0x3a, 0x3c, 0x93, 0x91, 0x64, 0xcb, 0x35, 0x79, 0xbf, 0x42, 0xaa, 0xdf, 0x50, 0x50,
|
0xbd, 0x1b, 0xd5, 0xe6, 0x99, 0x8c, 0x24, 0x5b, 0xac, 0xc8, 0xfb, 0x25, 0x52, 0xfd, 0x86, 0x82,
|
||||||
0xd7, 0x2b, 0xf2, 0xf4, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xeb, 0xc7, 0xba, 0xe5, 0xbc, 0x03,
|
0xba, 0x5e, 0x8f, 0x47, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x85, 0x23, 0x79, 0x71, 0xb8, 0x03,
|
||||||
0x00, 0x00,
|
0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,6 +575,7 @@ func (m *QueryBaseFeeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
|
if m.BaseFee != nil {
|
||||||
{
|
{
|
||||||
size := m.BaseFee.Size()
|
size := m.BaseFee.Size()
|
||||||
i -= size
|
i -= size
|
||||||
@ -585,6 +586,7 @@ func (m *QueryBaseFeeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
i--
|
i--
|
||||||
dAtA[i] = 0xa
|
dAtA[i] = 0xa
|
||||||
|
}
|
||||||
return len(dAtA) - i, nil
|
return len(dAtA) - i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,8 +687,10 @@ func (m *QueryBaseFeeResponse) Size() (n int) {
|
|||||||
}
|
}
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
|
if m.BaseFee != nil {
|
||||||
l = m.BaseFee.Size()
|
l = m.BaseFee.Size()
|
||||||
n += 1 + l + sovQuery(uint64(l))
|
n += 1 + l + sovQuery(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,6 +963,8 @@ func (m *QueryBaseFeeResponse) Unmarshal(dAtA []byte) error {
|
|||||||
if postIndex > l {
|
if postIndex > l {
|
||||||
return io.ErrUnexpectedEOF
|
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 {
|
if err := m.BaseFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user