fix: improve error message in SendTransaction json-rpc api (#786)

* fix error message in `SendTransaction` json-rpc api

Closes: #785

Solution:
- Remove `stacktrace.Propagate`s, and recover error message in jsonrpc server

changelog

fix error messages

* Update x/evm/keeper/msg_server.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
yihuang 2021-11-26 22:19:28 +08:00 committed by GitHub
parent 2d8be4e85b
commit c8d4d3f9a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 112 additions and 190 deletions

View File

@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
## Improvements ## Improvements
* (ci) [tharsis#784](https://github.com/tharsis/ethermint/pull/784) Enable automatic backport of PRs. * (ci) [tharsis#784](https://github.com/tharsis/ethermint/pull/784) Enable automatic backport of PRs.
* (rpc) [tharsis#786](https://github.com/tharsis/ethermint/pull/786) Improve error message of `SendTransaction`/`SendRawTransaction` JSON-RPC APIs.
### Bug Fixes ### Bug Fixes

View File

@ -4,8 +4,6 @@ import (
"fmt" "fmt"
"runtime/debug" "runtime/debug"
"github.com/palantir/stacktrace"
tmlog "github.com/tendermint/tendermint/libs/log" tmlog "github.com/tendermint/tendermint/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
@ -69,9 +67,10 @@ func NewAnteHandler(
) )
default: default:
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(
sdkerrors.Wrap(sdkerrors.ErrUnknownExtensionOptions, typeURL), sdkerrors.ErrUnknownExtensionOptions,
"rejecting tx with unsupported extension option", "rejecting tx with unsupported extension option: %s",
typeURL,
) )
} }
@ -100,10 +99,7 @@ func NewAnteHandler(
authante.NewIncrementSequenceDecorator(ak), // innermost AnteDecorator authante.NewIncrementSequenceDecorator(ak), // innermost AnteDecorator
) )
default: default:
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx),
"transaction is not an SDK tx",
)
} }
return anteHandler(ctx, tx, sim) return anteHandler(ctx, tx, sim)

View File

@ -4,8 +4,6 @@ import (
"errors" "errors"
"math/big" "math/big"
"github.com/palantir/stacktrace"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
tx "github.com/cosmos/cosmos-sdk/types/tx" tx "github.com/cosmos/cosmos-sdk/types/tx"
@ -59,10 +57,7 @@ func NewEthSigVerificationDecorator(ek EVMKeeper) EthSigVerificationDecorator {
// won't see the error message. // won't see the error message.
func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
if tx == nil || len(tx.GetMsgs()) != 1 { if tx == nil || len(tx.GetMsgs()) != 1 {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "only 1 ethereum msg supported per tx")
sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "only 1 ethereum msg supported per tx"),
"",
)
} }
chainID := esvd.evmKeeper.ChainID() chainID := esvd.evmKeeper.ChainID()
@ -76,18 +71,16 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
msg := tx.GetMsgs()[0] msg := tx.GetMsgs()[0]
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { if !ok {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil)),
"failed to cast transaction",
)
} }
sender, err := signer.Sender(msgEthTx.AsTransaction()) sender, err := signer.Sender(msgEthTx.AsTransaction())
if err != nil { if err != nil {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(
sdkerrors.Wrap(sdkerrors.ErrorInvalidSigner, err.Error()), sdkerrors.ErrorInvalidSigner,
"couldn't retrieve sender address ('%s') from the ethereum transaction", "couldn't retrieve sender address ('%s') from the ethereum transaction: %s",
msgEthTx.From, msgEthTx.From,
err.Error(),
) )
} }
@ -130,32 +123,26 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx
for i, msg := range tx.GetMsgs() { for i, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { if !ok {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil)),
"failed to cast transaction %d", i,
)
} }
txData, err := evmtypes.UnpackTxData(msgEthTx.Data) txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil { if err != nil {
return ctx, stacktrace.Propagate(err, "failed to unpack tx data any for tx %d", i) return ctx, sdkerrors.Wrapf(err, "failed to unpack tx data any for tx %d", i)
} }
// sender address should be in the tx cache from the previous AnteHandle call // sender address should be in the tx cache from the previous AnteHandle call
from := msgEthTx.GetFrom() from := msgEthTx.GetFrom()
if from.Empty() { if from.Empty() {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "from address cannot be empty")
sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "from address cannot be empty"),
"sender address should have been in the tx field from the previous AnteHandle call",
)
} }
// check whether the sender address is EOA // check whether the sender address is EOA
fromAddr := common.BytesToAddress(from) fromAddr := common.BytesToAddress(from)
codeHash := avd.evmKeeper.GetCodeHash(fromAddr) codeHash := avd.evmKeeper.GetCodeHash(fromAddr)
if codeHash != common.BytesToHash(evmtypes.EmptyCodeHash) { if codeHash != common.BytesToHash(evmtypes.EmptyCodeHash) {
return ctx, stacktrace.Propagate(sdkerrors.Wrapf(sdkerrors.ErrInvalidType, return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidType,
"the sender is not EOA: address <%v>, codeHash <%s>", fromAddr, codeHash), "") "the sender is not EOA: address <%v>, codeHash <%s>", fromAddr, codeHash)
} }
acc := avd.ak.GetAccount(ctx, from) acc := avd.ak.GetAccount(ctx, from)
@ -165,7 +152,7 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx
} }
if err := evmkeeper.CheckSenderBalance(ctx, avd.bankKeeper, from, txData, evmDenom); err != nil { if err := evmkeeper.CheckSenderBalance(ctx, avd.bankKeeper, from, txData, evmDenom); err != nil {
return ctx, stacktrace.Propagate(err, "failed to check sender balance") return ctx, sdkerrors.Wrap(err, "failed to check sender balance")
} }
} }
@ -195,36 +182,30 @@ func (nvd EthNonceVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx,
return next(ctx, tx, simulate) return next(ctx, tx, simulate)
} }
for i, msg := range tx.GetMsgs() { for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { if !ok {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil)),
"failed to cast transaction %d", i,
)
} }
// sender address should be in the tx cache from the previous AnteHandle call // sender address should be in the tx cache from the previous AnteHandle call
seq, err := nvd.ak.GetSequence(ctx, msgEthTx.GetFrom()) seq, err := nvd.ak.GetSequence(ctx, msgEthTx.GetFrom())
if err != nil { if err != nil {
return ctx, stacktrace.Propagate(err, "sequence not found for address %s", msgEthTx.From) return ctx, sdkerrors.Wrapf(err, "sequence not found for address %s", msgEthTx.From)
} }
txData, err := evmtypes.UnpackTxData(msgEthTx.Data) txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil { if err != nil {
return ctx, stacktrace.Propagate(err, "failed to unpack tx data") return ctx, sdkerrors.Wrap(err, "failed to unpack tx data")
} }
// if multiple transactions are submitted in succession with increasing nonces, // if multiple transactions are submitted in succession with increasing nonces,
// all will be rejected except the first, since the first needs to be included in a block // all will be rejected except the first, since the first needs to be included in a block
// before the sequence increments // before the sequence increments
if txData.GetNonce() != seq { if txData.GetNonce() != seq {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(
sdkerrors.Wrapf(
sdkerrors.ErrInvalidSequence, sdkerrors.ErrInvalidSequence,
"invalid nonce; got %d, expected %d", txData.GetNonce(), seq, "invalid nonce; got %d, expected %d", txData.GetNonce(), seq,
),
"",
) )
} }
} }
@ -277,18 +258,15 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
var events sdk.Events var events sdk.Events
for i, msg := range tx.GetMsgs() { for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { if !ok {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil)),
"failed to cast transaction %d", i,
)
} }
txData, err := evmtypes.UnpackTxData(msgEthTx.Data) txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil { if err != nil {
return ctx, stacktrace.Propagate(err, "failed to unpack tx data") return ctx, sdkerrors.Wrap(err, "failed to unpack tx data")
} }
fees, err := egcd.evmKeeper.DeductTxCostsFromUserBalance( fees, err := egcd.evmKeeper.DeductTxCostsFromUserBalance(
@ -301,7 +279,7 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
london, london,
) )
if err != nil { if err != nil {
return ctx, stacktrace.Propagate(err, "failed to deduct transaction costs from user balance") return ctx, sdkerrors.Wrapf(err, "failed to deduct transaction costs from user balance")
} }
events = append(events, sdk.NewEvent(sdk.EventTypeTx, sdk.NewAttribute(sdk.AttributeKeyFee, fees.String()))) events = append(events, sdk.NewEvent(sdk.EventTypeTx, sdk.NewAttribute(sdk.AttributeKeyFee, fees.String())))
@ -353,13 +331,10 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
ethCfg := params.ChainConfig.EthereumConfig(ctd.evmKeeper.ChainID()) ethCfg := params.ChainConfig.EthereumConfig(ctd.evmKeeper.ChainID())
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight())) signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
for i, msg := range tx.GetMsgs() { for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { if !ok {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil)),
"failed to cast transaction %d", i,
)
} }
var baseFee *big.Int var baseFee *big.Int
@ -369,7 +344,7 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
coreMsg, err := msgEthTx.AsMessage(signer, baseFee) coreMsg, err := msgEthTx.AsMessage(signer, baseFee)
if err != nil { if err != nil {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(
err, err,
"failed to create an ethereum core.Message from signer %T", signer, "failed to create an ethereum core.Message from signer %T", signer,
) )
@ -387,24 +362,20 @@ func (ctd CanTransferDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate
// check that caller has enough balance to cover asset transfer for **topmost** call // check that caller has enough balance to cover asset transfer for **topmost** call
// NOTE: here the gas consumed is from the context with the infinite gas meter // NOTE: here the gas consumed is from the context with the infinite gas meter
if coreMsg.Value().Sign() > 0 && !evm.Context.CanTransfer(ctd.evmKeeper, coreMsg.From(), coreMsg.Value()) { if coreMsg.Value().Sign() > 0 && !evm.Context.CanTransfer(ctd.evmKeeper, coreMsg.From(), coreMsg.Value()) {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(
sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "address %s", coreMsg.From()), sdkerrors.ErrInsufficientFunds,
"failed to transfer %s using the EVM block context transfer function", coreMsg.Value(), "failed to transfer %s from address %s using the EVM block context transfer function",
coreMsg.Value(),
coreMsg.From(),
) )
} }
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee && baseFee == nil { if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee && baseFee == nil {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(evmtypes.ErrInvalidBaseFee, "base fee is supported but evm block context value is nil")
sdkerrors.Wrap(evmtypes.ErrInvalidBaseFee, "base fee is supported but evm block context value is nil"),
"address %s", coreMsg.From(),
)
} }
if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee && baseFee != nil && coreMsg.GasFeeCap().Cmp(baseFee) < 0 { if evmtypes.IsLondon(ethCfg, ctx.BlockHeight()) && !feeMktParams.NoBaseFee && baseFee != nil && coreMsg.GasFeeCap().Cmp(baseFee) < 0 {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(evmtypes.ErrInvalidBaseFee, "max fee per gas less than block base fee (%s < %s)", coreMsg.GasFeeCap(), baseFee)
sdkerrors.Wrapf(evmtypes.ErrInvalidBaseFee, "max fee per gas less than block base fee (%s < %s)", coreMsg.GasFeeCap(), baseFee),
"address %s", coreMsg.From(),
)
} }
} }
@ -450,20 +421,17 @@ func (ald AccessListDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b
// setup the keeper context before setting the access list // setup the keeper context before setting the access list
ald.evmKeeper.WithContext(ctx) ald.evmKeeper.WithContext(ctx)
for i, msg := range tx.GetMsgs() { for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { if !ok {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil)),
"failed to cast transaction %d", i,
)
} }
sender := common.BytesToAddress(msgEthTx.GetFrom()) sender := common.BytesToAddress(msgEthTx.GetFrom())
txData, err := evmtypes.UnpackTxData(msgEthTx.Data) txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil { if err != nil {
return ctx, stacktrace.Propagate(err, "failed to unpack tx data") return ctx, sdkerrors.Wrap(err, "failed to unpack tx data")
} }
ald.evmKeeper.PrepareAccessList(sender, txData.GetTo(), vm.ActivePrecompiles(rules), txData.GetAccessList()) ald.evmKeeper.PrepareAccessList(sender, txData.GetTo(), vm.ActivePrecompiles(rules), txData.GetAccessList())
@ -490,18 +458,15 @@ func NewEthIncrementSenderSequenceDecorator(ak evmtypes.AccountKeeper) EthIncrem
// contract creation, the nonce will be incremented during the transaction execution and not within // contract creation, the nonce will be incremented during the transaction execution and not within
// this AnteHandler decorator. // this AnteHandler decorator.
func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
for i, msg := range tx.GetMsgs() { for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { if !ok {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil)),
"failed to cast transaction %d", i,
)
} }
txData, err := evmtypes.UnpackTxData(msgEthTx.Data) txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil { if err != nil {
return ctx, stacktrace.Propagate(err, "failed to unpack tx data") return ctx, sdkerrors.Wrap(err, "failed to unpack tx data")
} }
// NOTE: on contract creation, the nonce is incremented within the EVM Create function during tx execution // NOTE: on contract creation, the nonce is incremented within the EVM Create function during tx execution
@ -517,17 +482,14 @@ func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx s
acc := issd.ak.GetAccount(ctx, addr) acc := issd.ak.GetAccount(ctx, addr)
if acc == nil { if acc == nil {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(
sdkerrors.Wrapf(
sdkerrors.ErrUnknownAddress, sdkerrors.ErrUnknownAddress,
"account %s (%s) is nil", common.BytesToAddress(addr.Bytes()), addr, "account %s (%s) is nil", common.BytesToAddress(addr.Bytes()), addr,
),
"signer account not found",
) )
} }
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil { if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
return ctx, stacktrace.Propagate(err, "failed to set sequence to %d", acc.GetSequence()+1) return ctx, sdkerrors.Wrapf(err, "failed to set sequence to %d", acc.GetSequence()+1)
} }
issd.ak.SetAccount(ctx, acc) issd.ak.SetAccount(ctx, acc)
@ -560,7 +522,7 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
err := tx.ValidateBasic() err := tx.ValidateBasic()
// ErrNoSignatures is fine with eth tx // ErrNoSignatures is fine with eth tx
if err != nil && !errors.Is(err, sdkerrors.ErrNoSignatures) { if err != nil && !errors.Is(err, sdkerrors.ErrNoSignatures) {
return ctx, stacktrace.Propagate(err, "tx basic validation failed") return ctx, sdkerrors.Wrap(err, "tx basic validation failed")
} }
// For eth type cosmos tx, some fields should be veified as zero values, // For eth type cosmos tx, some fields should be veified as zero values,
@ -569,78 +531,51 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
protoTx := wrapperTx.GetProtoTx() protoTx := wrapperTx.GetProtoTx()
body := protoTx.Body body := protoTx.Body
if body.Memo != "" || body.TimeoutHeight != uint64(0) || len(body.NonCriticalExtensionOptions) > 0 { if body.Memo != "" || body.TimeoutHeight != uint64(0) || len(body.NonCriticalExtensionOptions) > 0 {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest,
sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "for eth tx body Memo TimeoutHeight NonCriticalExtensionOptions should be empty")
"for eth tx body Memo TimeoutHeight NonCriticalExtensionOptions should be empty"),
"invalid data in tx",
)
} }
if len(body.ExtensionOptions) != 1 { if len(body.ExtensionOptions) != 1 {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx length of ExtensionOptions should be 1")
sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "for eth tx length of ExtensionOptions should be 1"),
"invalid data in tx",
)
} }
if len(protoTx.GetMsgs()) != 1 { if len(protoTx.GetMsgs()) != 1 {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "only 1 ethereum msg supported per tx")
sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "only 1 ethereum msg supported per tx"),
"",
)
} }
msg := protoTx.GetMsgs()[0] msg := protoTx.GetMsgs()[0]
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx) msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { if !ok {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil)),
"failed to cast transaction",
)
} }
ethGasLimit := msgEthTx.GetGas() ethGasLimit := msgEthTx.GetGas()
txData, err := evmtypes.UnpackTxData(msgEthTx.Data) txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil { if err != nil {
return ctx, stacktrace.Propagate(err, "failed to unpack MsgEthereumTx Data") return ctx, sdkerrors.Wrap(err, "failed to unpack MsgEthereumTx Data")
} }
params := vbd.evmKeeper.GetParams(ctx) params := vbd.evmKeeper.GetParams(ctx)
ethFeeAmount := sdk.Coins{sdk.NewCoin(params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee()))} ethFeeAmount := sdk.Coins{sdk.NewCoin(params.EvmDenom, sdk.NewIntFromBigInt(txData.Fee()))}
authInfo := protoTx.AuthInfo authInfo := protoTx.AuthInfo
if len(authInfo.SignerInfos) > 0 { if len(authInfo.SignerInfos) > 0 {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx AuthInfo SignerInfos should be empty")
sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "for eth tx AuthInfo SignerInfos should be empty"),
"invalid data in tx",
)
} }
if authInfo.Fee.Payer != "" || authInfo.Fee.Granter != "" { if authInfo.Fee.Payer != "" || authInfo.Fee.Granter != "" {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx AuthInfo Fee payer and granter should be empty")
sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "for eth tx AuthInfo Fee payer and granter should be empty"),
"invalid data in tx",
)
} }
if !authInfo.Fee.Amount.IsEqual(ethFeeAmount) { if !authInfo.Fee.Amount.IsEqual(ethFeeAmount) {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid eth tx AuthInfo Fee Amount")
sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid eth tx AuthInfo Fee Amount"),
"invalid data in tx",
)
} }
if authInfo.Fee.GasLimit != ethGasLimit { if authInfo.Fee.GasLimit != ethGasLimit {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid eth tx AuthInfo Fee GasLimit")
sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid eth tx AuthInfo Fee GasLimit"),
"invalid data in tx",
)
} }
sigs := protoTx.Signatures sigs := protoTx.Signatures
if len(sigs) > 0 { if len(sigs) > 0 {
return ctx, stacktrace.Propagate( return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "for eth tx Signatures should be empty")
sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "for eth tx Signatures should be empty"),
"invalid data in tx",
)
} }
} }

1
go.mod
View File

@ -20,7 +20,6 @@ require (
github.com/klauspost/compress v1.11.9 // indirect github.com/klauspost/compress v1.11.9 // indirect
github.com/miguelmota/go-ethereum-hdwallet v0.1.1 github.com/miguelmota/go-ethereum-hdwallet v0.1.1
github.com/onsi/ginkgo v1.16.5 github.com/onsi/ginkgo v1.16.5
github.com/palantir/stacktrace v0.0.0-20161112013806-78658fd2d177
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/rakyll/statik v0.1.7 github.com/rakyll/statik v0.1.7
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect

2
go.sum
View File

@ -799,8 +799,6 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/palantir/stacktrace v0.0.0-20161112013806-78658fd2d177 h1:nRlQD0u1871kaznCnn1EvYiMbum36v7hw1DLPEjds4o=
github.com/palantir/stacktrace v0.0.0-20161112013806-78658fd2d177/go.mod h1:ao5zGxj8Z4x60IOVYZUbDSmt3R8Ddo080vEgPosHpak=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=

View File

@ -12,6 +12,7 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
codectypes "github.com/cosmos/cosmos-sdk/codec/types" codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -810,10 +811,10 @@ func (e *EVMBackend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash
// NOTE: If error is encountered on the node, the broadcast will not return an error // NOTE: If error is encountered on the node, the broadcast will not return an error
syncCtx := e.clientCtx.WithBroadcastMode(flags.BroadcastSync) syncCtx := e.clientCtx.WithBroadcastMode(flags.BroadcastSync)
rsp, err := syncCtx.BroadcastTx(txBytes) rsp, err := syncCtx.BroadcastTx(txBytes)
if err != nil || rsp.Code != 0 { if rsp != nil && rsp.Code != 0 {
if err == nil { err = sdkerrors.ABCIError(rsp.Codespace, rsp.Code, rsp.RawLog)
err = errors.New(rsp.RawLog)
} }
if err != nil {
e.logger.Error("failed to broadcast tx", "error", err.Error()) e.logger.Error("failed to broadcast tx", "error", err.Error())
return txHash, err return txHash, err
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keyring"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
@ -479,10 +480,10 @@ func (e *PublicAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error)
syncCtx := e.clientCtx.WithBroadcastMode(flags.BroadcastSync) syncCtx := e.clientCtx.WithBroadcastMode(flags.BroadcastSync)
rsp, err := syncCtx.BroadcastTx(txBytes) rsp, err := syncCtx.BroadcastTx(txBytes)
if err != nil || rsp.Code != 0 { if rsp != nil && rsp.Code != 0 {
if err == nil { err = sdkerrors.ABCIError(rsp.Codespace, rsp.Code, rsp.RawLog)
err = errors.New(rsp.RawLog)
} }
if err != nil {
e.logger.Error("failed to broadcast tx", "error", err.Error()) e.logger.Error("failed to broadcast tx", "error", err.Error())
return txHash, err return txHash, err
} }

View File

@ -1,7 +1,6 @@
package miner package miner
import ( import (
"errors"
"math/big" "math/big"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
@ -11,6 +10,7 @@ import (
"github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server"
sdkconfig "github.com/cosmos/cosmos-sdk/server/config" sdkconfig "github.com/cosmos/cosmos-sdk/server/config"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
@ -143,10 +143,10 @@ func (api *API) SetEtherbase(etherbase common.Address) bool {
// NOTE: If error is encountered on the node, the broadcast will not return an error // NOTE: If error is encountered on the node, the broadcast will not return an error
syncCtx := api.clientCtx.WithBroadcastMode(flags.BroadcastSync) syncCtx := api.clientCtx.WithBroadcastMode(flags.BroadcastSync)
rsp, err := syncCtx.BroadcastTx(txBytes) rsp, err := syncCtx.BroadcastTx(txBytes)
if err != nil || rsp.Code != 0 { if rsp != nil && rsp.Code != 0 {
if err == nil { err = sdkerrors.ABCIError(rsp.Codespace, rsp.Code, rsp.RawLog)
err = errors.New(rsp.RawLog)
} }
if err != nil {
api.logger.Debug("failed to broadcast tx", "error", err.Error()) api.logger.Debug("failed to broadcast tx", "error", err.Error())
return false return false
} }

View File

@ -10,7 +10,6 @@ import (
"github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers"
"github.com/palantir/stacktrace"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -313,7 +312,7 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
rsp, err = k.ApplyMessageWithConfig(msg, nil, false, cfg) rsp, err = k.ApplyMessageWithConfig(msg, nil, false, cfg)
if err != nil { if err != nil {
if errors.Is(stacktrace.RootCause(err), core.ErrIntrinsicGas) { if errors.Is(err, core.ErrIntrinsicGas) {
return true, nil, nil // Special case, raise gas limit return true, nil, nil // Special case, raise gas limit
} }
return true, nil, err // Bail out return true, nil, err // Bail out

View File

@ -7,12 +7,12 @@ import (
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/palantir/stacktrace"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -341,11 +341,11 @@ func (k Keeper) ClearBalance(addr sdk.AccAddress) (prevBalance sdk.Coin, err err
prevBalance = k.bankKeeper.GetBalance(k.Ctx(), addr, params.EvmDenom) prevBalance = k.bankKeeper.GetBalance(k.Ctx(), addr, params.EvmDenom)
if prevBalance.IsPositive() { if prevBalance.IsPositive() {
if err := k.bankKeeper.SendCoinsFromAccountToModule(k.Ctx(), addr, types.ModuleName, sdk.Coins{prevBalance}); err != nil { if err := k.bankKeeper.SendCoinsFromAccountToModule(k.Ctx(), addr, types.ModuleName, sdk.Coins{prevBalance}); err != nil {
return sdk.Coin{}, stacktrace.Propagate(err, "failed to transfer to module account") return sdk.Coin{}, sdkerrors.Wrap(err, "failed to transfer to module account")
} }
if err := k.bankKeeper.BurnCoins(k.Ctx(), types.ModuleName, sdk.Coins{prevBalance}); err != nil { if err := k.bankKeeper.BurnCoins(k.Ctx(), types.ModuleName, sdk.Coins{prevBalance}); err != nil {
return sdk.Coin{}, stacktrace.Propagate(err, "failed to burn coins from evm module account") return sdk.Coin{}, sdkerrors.Wrap(err, "failed to burn coins from evm module account")
} }
} }

View File

@ -5,12 +5,11 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/palantir/stacktrace"
tmbytes "github.com/tendermint/tendermint/libs/bytes" tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/tharsis/ethermint/x/evm/types" "github.com/tharsis/ethermint/x/evm/types"
) )
@ -30,7 +29,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
response, err := k.ApplyTransaction(tx) response, err := k.ApplyTransaction(tx)
if err != nil { if err != nil {
return nil, stacktrace.Propagate(err, "failed to apply transaction") return nil, sdkerrors.Wrap(err, "failed to apply transaction")
} }
attrs := []sdk.Attribute{ attrs := []sdk.Attribute{
@ -57,7 +56,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
for _, log := range response.Logs { for _, log := range response.Logs {
value, err := json.Marshal(log) value, err := json.Marshal(log)
if err != nil { if err != nil {
return nil, stacktrace.Propagate(err, "failed to encode log") return nil, sdkerrors.Wrap(err, "failed to encode log")
} }
txLogAttrs = append(txLogAttrs, sdk.NewAttribute(types.AttributeKeyTxLog, string(value))) txLogAttrs = append(txLogAttrs, sdk.NewAttribute(types.AttributeKeyTxLog, string(value)))
} }

View File

@ -3,7 +3,6 @@ package keeper
import ( import (
"math/big" "math/big"
"github.com/palantir/stacktrace"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
@ -29,7 +28,7 @@ func (k *Keeper) EVMConfig(ctx sdk.Context) (*types.EVMConfig, error) {
// get the coinbase address from the block proposer // get the coinbase address from the block proposer
coinbase, err := k.GetCoinbaseAddress(ctx) coinbase, err := k.GetCoinbaseAddress(ctx)
if err != nil { if err != nil {
return nil, stacktrace.Propagate(err, "failed to obtain coinbase address") return nil, sdkerrors.Wrap(err, "failed to obtain coinbase address")
} }
var baseFee *big.Int var baseFee *big.Int
@ -176,7 +175,7 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
cfg, err := k.EVMConfig(ctx) cfg, err := k.EVMConfig(ctx)
if err != nil { if err != nil {
return nil, stacktrace.Propagate(err, "failed to load evm config") return nil, sdkerrors.Wrap(err, "failed to load evm config")
} }
// get the latest signer according to the chain rules from the config // get the latest signer according to the chain rules from the config
@ -189,7 +188,7 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
msg, err := tx.AsMessage(signer, baseFee) msg, err := tx.AsMessage(signer, baseFee)
if err != nil { if err != nil {
return nil, stacktrace.Propagate(err, "failed to return ethereum transaction as core message") return nil, sdkerrors.Wrap(err, "failed to return ethereum transaction as core message")
} }
txHash := tx.Hash() txHash := tx.Hash()
@ -215,7 +214,7 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
res, err := k.ApplyMessageWithConfig(msg, nil, true, cfg) res, err := k.ApplyMessageWithConfig(msg, nil, true, cfg)
if err != nil { if err != nil {
return nil, stacktrace.Propagate(err, "failed to apply ethereum core message") return nil, sdkerrors.Wrap(err, "failed to apply ethereum core message")
} }
res.Hash = txHash.Hex() res.Hash = txHash.Hex()
@ -240,7 +239,7 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
// refund gas according to Ethereum gas accounting rules. // refund gas according to Ethereum gas accounting rules.
if err := k.RefundGas(msg, msg.Gas()-res.GasUsed, cfg.Params.EvmDenom); err != nil { if err := k.RefundGas(msg, msg.Gas()-res.GasUsed, cfg.Params.EvmDenom); err != nil {
return nil, stacktrace.Propagate(err, "failed to refund gas leftover gas to sender %s", msg.From()) return nil, sdkerrors.Wrapf(err, "failed to refund gas leftover gas to sender %s", msg.From())
} }
if len(logs) > 0 { if len(logs) > 0 {
@ -314,9 +313,9 @@ func (k *Keeper) ApplyMessageWithConfig(msg core.Message, tracer vm.Tracer, comm
// return error if contract creation or call are disabled through governance // return error if contract creation or call are disabled through governance
if !cfg.Params.EnableCreate && msg.To() == nil { if !cfg.Params.EnableCreate && msg.To() == nil {
return nil, stacktrace.Propagate(types.ErrCreateDisabled, "failed to create new contract") return nil, sdkerrors.Wrap(types.ErrCreateDisabled, "failed to create new contract")
} else if !cfg.Params.EnableCall && msg.To() != nil { } else if !cfg.Params.EnableCall && msg.To() != nil {
return nil, stacktrace.Propagate(types.ErrCallDisabled, "failed to call contract") return nil, sdkerrors.Wrap(types.ErrCallDisabled, "failed to call contract")
} }
sender := vm.AccountRef(msg.From()) sender := vm.AccountRef(msg.From())
@ -326,12 +325,12 @@ func (k *Keeper) ApplyMessageWithConfig(msg core.Message, tracer vm.Tracer, comm
intrinsicGas, err := k.GetEthIntrinsicGas(msg, cfg.ChainConfig, contractCreation) intrinsicGas, err := k.GetEthIntrinsicGas(msg, cfg.ChainConfig, contractCreation)
if err != nil { if err != nil {
// should have already been checked on Ante Handler // should have already been checked on Ante Handler
return nil, stacktrace.Propagate(err, "intrinsic gas failed") return nil, sdkerrors.Wrap(err, "intrinsic gas failed")
} }
// Should check again even if it is checked on Ante Handler, because eth_call don't go through Ante Handler. // Should check again even if it is checked on Ante Handler, because eth_call don't go through Ante Handler.
if msg.Gas() < intrinsicGas { if msg.Gas() < intrinsicGas {
// eth_estimateGas will check for this exact error // eth_estimateGas will check for this exact error
return nil, stacktrace.Propagate(core.ErrIntrinsicGas, "apply message") return nil, sdkerrors.Wrap(core.ErrIntrinsicGas, "apply message")
} }
leftoverGas := msg.Gas() - intrinsicGas leftoverGas := msg.Gas() - intrinsicGas
@ -356,12 +355,12 @@ func (k *Keeper) ApplyMessageWithConfig(msg core.Message, tracer vm.Tracer, comm
// calculate gas refund // calculate gas refund
if msg.Gas() < leftoverGas { if msg.Gas() < leftoverGas {
return nil, stacktrace.Propagate(types.ErrGasOverflow, "apply message") return nil, sdkerrors.Wrap(types.ErrGasOverflow, "apply message")
} }
gasUsed := msg.Gas() - leftoverGas gasUsed := msg.Gas() - leftoverGas
refund := k.GasToRefund(gasUsed, refundQuotient) refund := k.GasToRefund(gasUsed, refundQuotient)
if refund > gasUsed { if refund > gasUsed {
return nil, stacktrace.Propagate(types.ErrGasOverflow, "apply message") return nil, sdkerrors.Wrap(types.ErrGasOverflow, "apply message")
} }
gasUsed -= refund gasUsed -= refund
@ -390,7 +389,7 @@ func (k *Keeper) ApplyMessageWithConfig(msg core.Message, tracer vm.Tracer, comm
func (k *Keeper) ApplyMessage(msg core.Message, tracer vm.Tracer, commit bool) (*types.MsgEthereumTxResponse, error) { func (k *Keeper) ApplyMessage(msg core.Message, tracer vm.Tracer, commit bool) (*types.MsgEthereumTxResponse, error) {
cfg, err := k.EVMConfig(k.Ctx()) cfg, err := k.EVMConfig(k.Ctx())
if err != nil { if err != nil {
return nil, stacktrace.Propagate(err, "failed to load evm config") return nil, sdkerrors.Wrap(err, "failed to load evm config")
} }
return k.ApplyMessageWithConfig(msg, tracer, commit, cfg) return k.ApplyMessageWithConfig(msg, tracer, commit, cfg)
} }
@ -438,7 +437,7 @@ func (k *Keeper) RefundGas(msg core.Message, leftoverGas uint64, denom string) e
err := k.bankKeeper.SendCoinsFromModuleToAccount(k.Ctx(), authtypes.FeeCollectorName, msg.From().Bytes(), refundedCoins) err := k.bankKeeper.SendCoinsFromModuleToAccount(k.Ctx(), authtypes.FeeCollectorName, msg.From().Bytes(), refundedCoins)
if err != nil { if err != nil {
err = sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "fee collector account failed to refund fees: %s", err.Error()) err = sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "fee collector account failed to refund fees: %s", err.Error())
return stacktrace.Propagate(err, "failed to refund %d leftover gas (%s)", leftoverGas, refundedCoins.String()) return sdkerrors.Wrapf(err, "failed to refund %d leftover gas (%s)", leftoverGas, refundedCoins.String())
} }
default: default:
// no refund, consume gas and update the tx gas meter // no refund, consume gas and update the tx gas meter
@ -461,9 +460,10 @@ func (k Keeper) GetCoinbaseAddress(ctx sdk.Context) (common.Address, error) {
consAddr := sdk.ConsAddress(ctx.BlockHeader().ProposerAddress) consAddr := sdk.ConsAddress(ctx.BlockHeader().ProposerAddress)
validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr) validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
if !found { if !found {
return common.Address{}, stacktrace.Propagate( return common.Address{}, sdkerrors.Wrapf(
sdkerrors.Wrap(stakingtypes.ErrNoValidatorFound, consAddr.String()), stakingtypes.ErrNoValidatorFound,
"failed to retrieve validator from block proposer address", "failed to retrieve validator from block proposer address %s",
consAddr.String(),
) )
} }

View File

@ -6,7 +6,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante" authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/palantir/stacktrace"
evmtypes "github.com/tharsis/ethermint/x/evm/types" evmtypes "github.com/tharsis/ethermint/x/evm/types"
@ -28,7 +27,7 @@ func (k Keeper) DeductTxCostsFromUserBalance(
// fetch sender account from signature // fetch sender account from signature
signerAcc, err := authante.GetSignerAcc(ctx, k.accountKeeper, msgEthTx.GetFrom()) signerAcc, err := authante.GetSignerAcc(ctx, k.accountKeeper, msgEthTx.GetFrom())
if err != nil { if err != nil {
return nil, stacktrace.Propagate(err, "account not found for sender %s", msgEthTx.From) return nil, sdkerrors.Wrapf(err, "account not found for sender %s", msgEthTx.From)
} }
gasLimit := txData.GetGas() gasLimit := txData.GetGas()
@ -40,9 +39,9 @@ func (k Keeper) DeductTxCostsFromUserBalance(
intrinsicGas, err := core.IntrinsicGas(txData.GetData(), accessList, isContractCreation, homestead, istanbul) intrinsicGas, err := core.IntrinsicGas(txData.GetData(), accessList, isContractCreation, homestead, istanbul)
if err != nil { if err != nil {
return nil, stacktrace.Propagate(sdkerrors.Wrap( return nil, sdkerrors.Wrapf(
err, err,
"failed to compute intrinsic gas cost"), "failed to retrieve intrinsic gas, contract creation = %t; homestead = %t, istanbul = %t", "failed to retrieve intrinsic gas, contract creation = %t; homestead = %t, istanbul = %t",
isContractCreation, homestead, istanbul, isContractCreation, homestead, istanbul,
) )
} }
@ -77,7 +76,7 @@ func (k Keeper) DeductTxCostsFromUserBalance(
// deduct the full gas cost from the user balance // deduct the full gas cost from the user balance
if err := authante.DeductFees(k.bankKeeper, ctx, signerAcc, fees); err != nil { if err := authante.DeductFees(k.bankKeeper, ctx, signerAcc, fees); err != nil {
return nil, stacktrace.Propagate( return nil, sdkerrors.Wrapf(
err, err,
"failed to deduct full gas cost %s from the user %s balance", "failed to deduct full gas cost %s from the user %s balance",
fees, msgEthTx.From, fees, msgEthTx.From,
@ -99,22 +98,16 @@ func CheckSenderBalance(
cost := txData.Cost() cost := txData.Cost()
if cost.Sign() < 0 { if cost.Sign() < 0 {
return stacktrace.Propagate( return sdkerrors.Wrapf(
sdkerrors.Wrapf(
sdkerrors.ErrInvalidCoins, sdkerrors.ErrInvalidCoins,
"tx cost (%s%s) is negative and invalid", cost, denom, "tx cost (%s%s) is negative and invalid", cost, denom,
), )
"tx cost amount should never be negative")
} }
if balance.IsNegative() || balance.Amount.BigInt().Cmp(cost) < 0 { if balance.IsNegative() || balance.Amount.BigInt().Cmp(cost) < 0 {
return stacktrace.Propagate( return sdkerrors.Wrapf(
sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFunds, sdkerrors.ErrInsufficientFunds,
"sender balance < tx cost (%s < %s%s)", balance, txData.Cost(), denom, "sender balance < tx cost (%s < %s%s)", balance, txData.Cost(), denom,
),
"sender should have had enough funds to pay for tx cost = fee + amount (%s = %s + %s)",
cost, txData.Fee(), txData.GetValue(),
) )
} }
return nil return nil

View File

@ -129,7 +129,7 @@ func (cc ChainConfig) Validate() error {
func validateHash(hex string) error { func validateHash(hex string) error {
if hex != "" && strings.TrimSpace(hex) == "" { if hex != "" && strings.TrimSpace(hex) == "" {
return sdkerrors.Wrapf(ErrInvalidChainConfig, "hash cannot be blank") return sdkerrors.Wrap(ErrInvalidChainConfig, "hash cannot be blank")
} }
return nil return nil