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:
parent
2d8be4e85b
commit
c8d4d3f9a3
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
175
app/ante/eth.go
175
app/ante/eth.go
@ -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
1
go.mod
@ -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
2
go.sum
@ -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=
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)))
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user