fix AnteHandler gas consumption (#275)
* fix antehandler gas consumption * fix gas * typo
This commit is contained in:
parent
ce0feb307b
commit
a99fbfdc2b
@ -55,7 +55,7 @@ func (suite *AnteTestSuite) TestValidEthTx() {
|
|||||||
to := ethcmn.BytesToAddress(addr2.Bytes())
|
to := ethcmn.BytesToAddress(addr2.Bytes())
|
||||||
amt := big.NewInt(32)
|
amt := big.NewInt(32)
|
||||||
gas := big.NewInt(20)
|
gas := big.NewInt(20)
|
||||||
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 34910, gas, []byte("test"))
|
ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
|
||||||
|
|
||||||
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
@ -94,16 +94,17 @@ func (emfd EthMempoolFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
|||||||
|
|
||||||
minGasPrices := ctx.MinGasPrices()
|
minGasPrices := ctx.MinGasPrices()
|
||||||
|
|
||||||
allGTE := true
|
// check that fee provided is greater than the minimum
|
||||||
for _, v := range minGasPrices {
|
// NOTE: we only check if photons are present in min gas prices. It is up to the
|
||||||
if !fee.IsGTE(v) {
|
// sender if they want to send additional fees in other denominations.
|
||||||
allGTE = false
|
var hasEnoughFees bool
|
||||||
}
|
if fee.Amount.GTE(minGasPrices.AmountOf(emint.DenomDefault)) {
|
||||||
|
hasEnoughFees = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// it is assumed that the minimum fees will only include the single valid denom
|
// reject transaction if minimum gas price is positive and the transaction does not
|
||||||
if !ctx.MinGasPrices().IsZero() && !allGTE {
|
// meet the minimum fee
|
||||||
// reject the transaction that does not meet the minimum fee
|
if !ctx.MinGasPrices().IsZero() && !hasEnoughFees {
|
||||||
return ctx, sdkerrors.Wrap(
|
return ctx, sdkerrors.Wrap(
|
||||||
sdkerrors.ErrInsufficientFee,
|
sdkerrors.ErrInsufficientFee,
|
||||||
fmt.Sprintf("insufficient fee, got: %q required: %q", fee, ctx.MinGasPrices()),
|
fmt.Sprintf("insufficient fee, got: %q required: %q", fee, ctx.MinGasPrices()),
|
||||||
@ -135,12 +136,14 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validate sender/signature
|
// validate sender/signature
|
||||||
// NOTE: signer is retrieved from the transaction on the next AnteDecorator
|
|
||||||
_, err = msgEthTx.VerifySig(chainID)
|
_, err = msgEthTx.VerifySig(chainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "signature verification failed")
|
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, fmt.Sprintf("signature verification failed: %s", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: when signature verification succeeds, a non-empty signer address can be
|
||||||
|
// retrieved from the transaction on the next AnteDecorators.
|
||||||
|
|
||||||
return next(ctx, msgEthTx, simulate)
|
return next(ctx, msgEthTx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,10 +172,10 @@ func (avd AccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
|
|||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sender address should be in the tx cache
|
// sender address should be in the tx cache from the previous AnteHandle call
|
||||||
address := msgEthTx.From()
|
address := msgEthTx.From()
|
||||||
if address == nil {
|
if address.Empty() {
|
||||||
panic("sender address is nil")
|
panic("sender address cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
acc := avd.ak.GetAccount(ctx, address)
|
acc := avd.ak.GetAccount(ctx, address)
|
||||||
@ -188,19 +191,20 @@ func (avd AccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate sender has enough funds
|
// validate sender has enough funds to pay for gas cost
|
||||||
balance := avd.bk.GetBalance(ctx, acc.GetAddress(), emint.DenomDefault)
|
balance := avd.bk.GetBalance(ctx, acc.GetAddress(), emint.DenomDefault)
|
||||||
if balance.Amount.BigInt().Cmp(msgEthTx.Cost()) < 0 {
|
if balance.Amount.BigInt().Cmp(msgEthTx.Cost()) < 0 {
|
||||||
return ctx, sdkerrors.Wrapf(
|
return ctx, sdkerrors.Wrapf(
|
||||||
sdkerrors.ErrInsufficientFunds,
|
sdkerrors.ErrInsufficientFunds,
|
||||||
"%s < %s%s", balance.String(), msgEthTx.Cost().String(), emint.DenomDefault,
|
"sender balance < tx gas cost (%s < %s%s)", balance.String(), msgEthTx.Cost().String(), emint.DenomDefault,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NonceVerificationDecorator that the nonce matches
|
// NonceVerificationDecorator that the account nonce from the transaction matches
|
||||||
|
// the sender account sequence.
|
||||||
type NonceVerificationDecorator struct {
|
type NonceVerificationDecorator struct {
|
||||||
ak auth.AccountKeeper
|
ak auth.AccountKeeper
|
||||||
}
|
}
|
||||||
@ -220,10 +224,10 @@ func (nvd NonceVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim
|
|||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sender address should be in the tx cache
|
// sender address should be in the tx cache from the previous AnteHandle call
|
||||||
address := msgEthTx.From()
|
address := msgEthTx.From()
|
||||||
if address == nil {
|
if address.Empty() {
|
||||||
panic("sender address is nil")
|
panic("sender address cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
acc := nvd.ak.GetAccount(ctx, address)
|
acc := nvd.ak.GetAccount(ctx, address)
|
||||||
@ -272,8 +276,8 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
|
|||||||
|
|
||||||
// sender address should be in the tx cache
|
// sender address should be in the tx cache
|
||||||
address := msgEthTx.From()
|
address := msgEthTx.From()
|
||||||
if address == nil {
|
if address.Empty() {
|
||||||
panic("sender address is nil")
|
panic("sender address cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch sender account from signature
|
// Fetch sender account from signature
|
||||||
@ -337,28 +341,33 @@ func NewIncrementSenderSequenceDecorator(ak auth.AccountKeeper) IncrementSenderS
|
|||||||
|
|
||||||
// AnteHandle handles incrementing the sequence of the sender.
|
// AnteHandle handles incrementing the sequence of the sender.
|
||||||
func (issd IncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
func (issd IncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
||||||
// no need to increment sequence on RecheckTx
|
// get and set account must be called with an infinite gas meter in order to prevent
|
||||||
|
// additional gas from being deducted.
|
||||||
|
gasMeter := ctx.GasMeter()
|
||||||
|
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
|
|
||||||
|
// no need to increment sequence on RecheckTx mode
|
||||||
if ctx.IsReCheckTx() && !simulate {
|
if ctx.IsReCheckTx() && !simulate {
|
||||||
|
ctx = ctx.WithGasMeter(gasMeter)
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get and set account must be called with an infinite gas meter in order to prevent
|
|
||||||
// additional gas from being deducted.
|
|
||||||
oldCtx := ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter())
|
|
||||||
|
|
||||||
msgEthTx, ok := tx.(evmtypes.MsgEthereumTx)
|
msgEthTx, ok := tx.(evmtypes.MsgEthereumTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
ctx = ctx.WithGasMeter(gasMeter)
|
||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type: %T", tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment sequence of all signers
|
// increment sequence of all signers
|
||||||
for _, addr := range msgEthTx.GetSigners() {
|
for _, addr := range msgEthTx.GetSigners() {
|
||||||
acc := issd.ak.GetAccount(oldCtx, addr)
|
acc := issd.ak.GetAccount(ctx, addr)
|
||||||
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
|
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
issd.ak.SetAccount(oldCtx, acc)
|
issd.ak.SetAccount(ctx, acc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the original gas meter
|
||||||
|
ctx = ctx.WithGasMeter(gasMeter)
|
||||||
return next(ctx, tx, simulate)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user