forked from cerc-io/laconicd-deprecated
all: bump go-ethereum to v1.10.9 (#231)
* all: bump go-ethereum to v1.10.4 * build * state transition and rpc * wip rpc changes * fix refund * fixes * no base fee param * ante handler * undo change * fix test * bump deps * calculate base fee * gRPC base fee query * update RPC * fix * update' * go.mod * fix build * fix panic * rm changes in third_party * json rpc changes * reserved fields * fixes fixes fixes * rm no stringer * fixes 2 * tests wip * bump geth version * update * grpc traceTx * rm fee market from ante * fix TransactionArgs * lint * update proto * update tx args * changelog
This commit is contained in:
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/tharsis/ethermint/server/config"
|
||||
ethermint "github.com/tharsis/ethermint/types"
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
||||
)
|
||||
|
||||
// Backend implements the functionality shared within namespaces.
|
||||
@@ -43,21 +44,21 @@ type Backend interface {
|
||||
BlockNumber() (hexutil.Uint64, error)
|
||||
GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error)
|
||||
GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error)
|
||||
GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error)
|
||||
CurrentHeader() *ethtypes.Header
|
||||
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 types.SendTxArgs) (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)
|
||||
GetTransactionByHash(txHash common.Hash) (*types.RPCTransaction, error)
|
||||
GetTxByEthHash(txHash common.Hash) (*tmrpctypes.ResultTx, error)
|
||||
EstimateGas(args evmtypes.CallArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
|
||||
EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error)
|
||||
RPCGasCap() uint64
|
||||
RPCMinGasPrice() int64
|
||||
ChainConfig() *params.ChainConfig
|
||||
@@ -305,6 +306,12 @@ 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())
|
||||
@@ -322,7 +329,11 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
||||
gasUsed += uint64(txsResult.GetGasUsed())
|
||||
}
|
||||
|
||||
formattedBlock := types.FormatBlock(block.Header, block.Size(), gasLimit, new(big.Int).SetUint64(gasUsed), ethRPCTxs, bloom, validatorAddr)
|
||||
formattedBlock := types.FormatBlock(
|
||||
block.Header, block.Size(),
|
||||
gasLimit, new(big.Int).SetUint64(gasUsed),
|
||||
ethRPCTxs, bloom, validatorAddr, bfRes.BaseFee.BigInt(),
|
||||
)
|
||||
return formattedBlock, nil
|
||||
}
|
||||
|
||||
@@ -588,7 +599,7 @@ func (e *EVMBackend) GetTxByEthHash(hash common.Hash) (*tmrpctypes.ResultTx, err
|
||||
return resTxs.Txs[0], nil
|
||||
}
|
||||
|
||||
func (e *EVMBackend) SendTransaction(args types.SendTxArgs) (common.Hash, error) {
|
||||
func (e *EVMBackend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) {
|
||||
// Look up the wallet containing the requested signer
|
||||
_, err := e.clientCtx.Keyring.KeyByAddress(sdk.AccAddress(args.From.Bytes()))
|
||||
if err != nil {
|
||||
@@ -679,7 +690,7 @@ func (e *EVMBackend) SendTransaction(args types.SendTxArgs) (common.Hash, error)
|
||||
}
|
||||
|
||||
// EstimateGas returns an estimate of gas usage for the given smart contract call.
|
||||
func (e *EVMBackend) EstimateGas(args evmtypes.CallArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error) {
|
||||
func (e *EVMBackend) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *types.BlockNumber) (hexutil.Uint64, error) {
|
||||
blockNr := types.EthPendingBlockNumber
|
||||
if blockNrOptional != nil {
|
||||
blockNr = *blockNrOptional
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@@ -20,16 +21,78 @@ import (
|
||||
|
||||
// setTxDefaults populates tx message with default values in case they are not
|
||||
// provided on the args
|
||||
func (e *EVMBackend) setTxDefaults(args types.SendTxArgs) (types.SendTxArgs, error) {
|
||||
if args.GasPrice == nil {
|
||||
// TODO: Suggest a gas price based on the previous included txs
|
||||
args.GasPrice = (*hexutil.Big)(new(big.Int).SetInt64(e.RPCMinGasPrice()))
|
||||
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")
|
||||
}
|
||||
|
||||
head := e.CurrentHeader()
|
||||
if head == nil {
|
||||
return args, errors.New("latest header is nil")
|
||||
}
|
||||
|
||||
cfg := e.ChainConfig()
|
||||
|
||||
// If user specifies both maxPriorityfee and maxFee, then we do not
|
||||
// need to consult the chain for defaults. It's definitely a London tx.
|
||||
if args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil {
|
||||
// In this clause, user left some fields unspecified.
|
||||
if cfg.IsLondon(head.Number) && args.GasPrice == nil {
|
||||
if args.MaxPriorityFeePerGas == nil {
|
||||
tip, err := e.SuggestGasTipCap()
|
||||
if err != nil {
|
||||
return args, err
|
||||
}
|
||||
|
||||
args.MaxPriorityFeePerGas = (*hexutil.Big)(tip)
|
||||
}
|
||||
|
||||
if args.MaxFeePerGas == nil {
|
||||
gasFeeCap := new(big.Int).Add(
|
||||
(*big.Int)(args.MaxPriorityFeePerGas),
|
||||
new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
|
||||
)
|
||||
args.MaxFeePerGas = (*hexutil.Big)(gasFeeCap)
|
||||
}
|
||||
|
||||
if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
|
||||
return args, fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas)
|
||||
}
|
||||
|
||||
} else {
|
||||
if args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil {
|
||||
return args, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
|
||||
}
|
||||
|
||||
if args.GasPrice == nil {
|
||||
price, err := e.SuggestGasTipCap()
|
||||
if err != nil {
|
||||
return args, err
|
||||
}
|
||||
|
||||
if cfg.IsLondon(head.Number) {
|
||||
// The legacy tx gas price suggestion should not add 2x base fee
|
||||
// because all fees are consumed, so it would result in a spiral
|
||||
// upwards.
|
||||
price.Add(price, head.BaseFee)
|
||||
}
|
||||
args.GasPrice = (*hexutil.Big)(price)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Both maxPriorityfee and maxFee set by caller. Sanity-check their internal relation
|
||||
if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
|
||||
return args, fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas)
|
||||
}
|
||||
}
|
||||
|
||||
if args.Value == nil {
|
||||
args.Value = new(hexutil.Big)
|
||||
}
|
||||
if args.Nonce == nil {
|
||||
// get the nonce from the account retriever
|
||||
// ignore error in case tge account doesn't exist yet
|
||||
nonce, _ := e.getAccountNonce(args.From, true, 0, e.logger)
|
||||
nonce, _ := e.getAccountNonce(*args.From, true, 0, e.logger)
|
||||
args.Nonce = (*hexutil.Uint64)(&nonce)
|
||||
}
|
||||
|
||||
@@ -59,15 +122,18 @@ func (e *EVMBackend) setTxDefaults(args types.SendTxArgs) (types.SendTxArgs, err
|
||||
input = args.Data
|
||||
}
|
||||
|
||||
callArgs := evmtypes.CallArgs{
|
||||
From: &args.From, // From shouldn't be nil
|
||||
To: args.To,
|
||||
Gas: args.Gas,
|
||||
GasPrice: args.GasPrice,
|
||||
Value: args.Value,
|
||||
Data: input,
|
||||
AccessList: args.AccessList,
|
||||
callArgs := evmtypes.TransactionArgs{
|
||||
From: args.From,
|
||||
To: args.To,
|
||||
Gas: args.Gas,
|
||||
GasPrice: args.GasPrice,
|
||||
MaxFeePerGas: args.MaxFeePerGas,
|
||||
MaxPriorityFeePerGas: args.MaxPriorityFeePerGas,
|
||||
Value: args.Value,
|
||||
Data: input,
|
||||
AccessList: args.AccessList,
|
||||
}
|
||||
|
||||
blockNr := types.NewBlockNumber(big.NewInt(0))
|
||||
estimated, err := e.EstimateGas(callArgs, &blockNr)
|
||||
if err != nil {
|
||||
|
||||
@@ -350,7 +350,7 @@ func (e *PublicAPI) Sign(address common.Address, data hexutil.Bytes) (hexutil.By
|
||||
}
|
||||
|
||||
// SendTransaction sends an Ethereum transaction.
|
||||
func (e *PublicAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, error) {
|
||||
func (e *PublicAPI) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, error) {
|
||||
e.logger.Debug("eth_sendTransaction", "args", args.String())
|
||||
return e.backend.SendTransaction(args)
|
||||
}
|
||||
@@ -434,7 +434,7 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
|
||||
}
|
||||
|
||||
// Call performs a raw contract call.
|
||||
func (e *PublicAPI) Call(args evmtypes.CallArgs, 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)
|
||||
|
||||
blockNum, err := e.getBlockNumber(blockNrOrHash)
|
||||
@@ -452,7 +452,7 @@ func (e *PublicAPI) Call(args evmtypes.CallArgs, blockNrOrHash rpctypes.BlockNum
|
||||
// DoCall performs a simulated call operation through the evmtypes. It returns the
|
||||
// estimated gas used on the operation or an error if fails.
|
||||
func (e *PublicAPI) doCall(
|
||||
args evmtypes.CallArgs, blockNr rpctypes.BlockNumber,
|
||||
args evmtypes.TransactionArgs, blockNr rpctypes.BlockNumber,
|
||||
) (*evmtypes.MsgEthereumTxResponse, error) {
|
||||
bz, err := json.Marshal(&args)
|
||||
if err != nil {
|
||||
@@ -479,7 +479,7 @@ func (e *PublicAPI) doCall(
|
||||
}
|
||||
|
||||
// EstimateGas returns an estimate of gas usage for the given smart contract call.
|
||||
func (e *PublicAPI) EstimateGas(args evmtypes.CallArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error) {
|
||||
func (e *PublicAPI) EstimateGas(args evmtypes.TransactionArgs, blockNrOptional *rpctypes.BlockNumber) (hexutil.Uint64, error) {
|
||||
e.logger.Debug("eth_estimateGas")
|
||||
return e.backend.EstimateGas(args, blockNrOptional)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
||||
"github.com/tharsis/ethermint/crypto/ethsecp256k1"
|
||||
rpctypes "github.com/tharsis/ethermint/rpc/ethereum/types"
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
// PrivateAccountAPI is the personal_ prefixed set of APIs in the Web3 JSON-RPC spec.
|
||||
@@ -150,9 +150,13 @@ 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 rpctypes.SendTxArgs, pwrd string) (common.Hash, error) {
|
||||
func (api *PrivateAccountAPI) SendTransaction(_ context.Context, args evmtypes.TransactionArgs, pwrd string) (common.Hash, error) {
|
||||
api.logger.Debug("personal_sendTransaction", "address", args.To.String())
|
||||
|
||||
if args.From == nil {
|
||||
return common.Hash{}, fmt.Errorf("from address cannot be nil in send transaction")
|
||||
}
|
||||
|
||||
addr := sdk.AccAddress(args.From.Bytes())
|
||||
|
||||
// check if the key is on the keyring
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
// QueryClient defines a gRPC Client used for:
|
||||
// - Transaction simulation
|
||||
// - EVM module queries
|
||||
// - Fee market module queries
|
||||
type QueryClient struct {
|
||||
tx.ServiceClient
|
||||
evmtypes.QueryClient
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||
)
|
||||
|
||||
// Copied the Account and StorageResult types since they are registered under an
|
||||
@@ -39,6 +34,8 @@ type RPCTransaction struct {
|
||||
From common.Address `json:"from"`
|
||||
Gas hexutil.Uint64 `json:"gas"`
|
||||
GasPrice *hexutil.Big `json:"gasPrice"`
|
||||
GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
|
||||
GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
|
||||
Hash common.Hash `json:"hash"`
|
||||
Input hexutil.Bytes `json:"input"`
|
||||
Nonce hexutil.Uint64 `json:"nonce"`
|
||||
@@ -53,80 +50,6 @@ type RPCTransaction struct {
|
||||
S *hexutil.Big `json:"s"`
|
||||
}
|
||||
|
||||
// SendTxArgs represents the arguments to submit a new transaction into the transaction pool.
|
||||
// Duplicate struct definition since geth struct is in internal package
|
||||
// Ref: https://github.com/ethereum/go-ethereum/blob/release/1.9/internal/ethapi/api.go#L1346
|
||||
type SendTxArgs struct {
|
||||
From common.Address `json:"from"`
|
||||
To *common.Address `json:"to"`
|
||||
Gas *hexutil.Uint64 `json:"gas"`
|
||||
GasPrice *hexutil.Big `json:"gasPrice"`
|
||||
Value *hexutil.Big `json:"value"`
|
||||
Nonce *hexutil.Uint64 `json:"nonce"`
|
||||
// We accept "data" and "input" for backwards-compatibility reasons. "input" is the
|
||||
// newer name and should be preferred by clients.
|
||||
Data *hexutil.Bytes `json:"data"`
|
||||
Input *hexutil.Bytes `json:"input"`
|
||||
// For non-legacy transactions
|
||||
AccessList *ethtypes.AccessList `json:"accessList,omitempty"`
|
||||
ChainID *hexutil.Big `json:"chainId,omitempty"`
|
||||
}
|
||||
|
||||
// String return the struct in a string format
|
||||
func (args *SendTxArgs) String() string {
|
||||
// Todo: There is currently a bug with hexutil.Big when the value its nil, printing would trigger an exception
|
||||
return fmt.Sprintf("SendTxArgs{From:%v, To:%v, Gas:%v,"+
|
||||
" Nonce:%v, Data:%v, Input:%v, AccessList:%v}",
|
||||
args.From,
|
||||
args.To,
|
||||
args.Gas,
|
||||
args.Nonce,
|
||||
args.Data,
|
||||
args.Input,
|
||||
args.AccessList)
|
||||
}
|
||||
|
||||
// ToTransaction converts the arguments to an ethereum transaction.
|
||||
// This assumes that setTxDefaults has been called.
|
||||
func (args *SendTxArgs) ToTransaction() *evmtypes.MsgEthereumTx {
|
||||
var (
|
||||
input []byte
|
||||
chainID, value, gasPrice *big.Int
|
||||
gas, nonce uint64
|
||||
)
|
||||
|
||||
if args.Input != nil {
|
||||
input = *args.Input
|
||||
} else if args.Data != nil {
|
||||
input = *args.Data
|
||||
}
|
||||
|
||||
if args.ChainID != nil {
|
||||
chainID = args.ChainID.ToInt()
|
||||
}
|
||||
|
||||
if args.Nonce != nil {
|
||||
nonce = uint64(*args.Nonce)
|
||||
}
|
||||
|
||||
if args.Gas != nil {
|
||||
gas = uint64(*args.Gas)
|
||||
}
|
||||
|
||||
if args.GasPrice != nil {
|
||||
gasPrice = args.GasPrice.ToInt()
|
||||
}
|
||||
|
||||
if args.Value != nil {
|
||||
value = args.Value.ToInt()
|
||||
}
|
||||
|
||||
tx := evmtypes.NewTx(chainID, nonce, args.To, value, gas, gasPrice, input, args.AccessList)
|
||||
tx.From = args.From.Hex()
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
// StateOverride is the collection of overridden accounts.
|
||||
type StateOverride map[common.Address]OverrideAccount
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ func BlockMaxGasFromConsensusParams(ctx context.Context, clientCtx client.Contex
|
||||
func FormatBlock(
|
||||
header tmtypes.Header, size int, gasLimit int64,
|
||||
gasUsed *big.Int, transactions interface{}, bloom ethtypes.Bloom,
|
||||
validatorAddr common.Address,
|
||||
validatorAddr common.Address, baseFee *big.Int,
|
||||
) map[string]interface{} {
|
||||
if len(header.DataHash) == 0 {
|
||||
header.DataHash = tmbytes.HexBytes(common.Hash{}.Bytes())
|
||||
@@ -175,6 +175,7 @@ func FormatBlock(
|
||||
"timestamp": hexutil.Uint64(header.Time.Unix()),
|
||||
"transactionsRoot": hexutil.Bytes(header.DataHash),
|
||||
"receiptsRoot": ethtypes.EmptyRootHash,
|
||||
"baseFeePerGas": (*hexutil.Big)(baseFee),
|
||||
|
||||
"uncles": []common.Hash{},
|
||||
"transactions": transactions,
|
||||
|
||||
Reference in New Issue
Block a user