fix: increase nonce in ante handler for contract creation tx (#809)

Closes: #808
Solution:
- move nonce increment to ante handler
- revert nonce increment in apply message

build(deps): bump github.com/spf13/viper from 1.9.0 to 1.10.0 (#833)

Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/spf13/viper/releases)
- [Commits](https://github.com/spf13/viper/compare/v1.9.0...v1.10.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/viper
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

fix: remove unused code (#834)

Co-authored-by: Marko Baricevic <markobaricevic3778@gmail.com>
Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

rm

rm pkg

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
yihuang 2021-12-17 06:35:28 +08:00 committed by GitHub
parent 514785bd89
commit e437c4331d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 181 additions and 112 deletions

View File

@ -42,6 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (evm) [tharsis#840](https://github.com/tharsis/ethermint/pull/840) Store empty topics as empty array rather than nil. - (evm) [tharsis#840](https://github.com/tharsis/ethermint/pull/840) Store empty topics as empty array rather than nil.
- (feemarket) [tharsis#822](https://github.com/tharsis/ethermint/pull/822) Update EIP1559 base fee in `BeginBlock`. - (feemarket) [tharsis#822](https://github.com/tharsis/ethermint/pull/822) Update EIP1559 base fee in `BeginBlock`.
- (evm) [tharsis#817](https://github.com/tharsis/ethermint/pull/817) Use `effectiveGasPrice` in ante handler, add `effectiveGasPrice` to tx receipt. - (evm) [tharsis#817](https://github.com/tharsis/ethermint/pull/817) Use `effectiveGasPrice` in ante handler, add `effectiveGasPrice` to tx receipt.
- (evm) [tharsis#808](https://github.com/tharsis/ethermint/issues/808) increase nonce in ante handler for contract creation transaction.
### Improvements ### Improvements

View File

@ -60,7 +60,7 @@ func (suite AnteTestSuite) TestAnteHandler() {
func() sdk.Tx { func() sdk.Tx {
signedContractTx := evmtypes.NewTxContract( signedContractTx := evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(), suite.app.EvmKeeper.ChainID(),
1, 2,
big.NewInt(10), big.NewInt(10),
100000, 100000,
big.NewInt(150), big.NewInt(150),
@ -81,7 +81,7 @@ func (suite AnteTestSuite) TestAnteHandler() {
func() sdk.Tx { func() sdk.Tx {
signedContractTx := evmtypes.NewTxContract( signedContractTx := evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(), suite.app.EvmKeeper.ChainID(),
1, 3,
big.NewInt(10), big.NewInt(10),
100000, 100000,
big.NewInt(150), big.NewInt(150),
@ -102,7 +102,7 @@ func (suite AnteTestSuite) TestAnteHandler() {
func() sdk.Tx { func() sdk.Tx {
signedTx := evmtypes.NewTx( signedTx := evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(), suite.app.EvmKeeper.ChainID(),
1, 4,
&to, &to,
big.NewInt(10), big.NewInt(10),
100000, 100000,
@ -124,7 +124,7 @@ func (suite AnteTestSuite) TestAnteHandler() {
func() sdk.Tx { func() sdk.Tx {
signedTx := evmtypes.NewTx( signedTx := evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(), suite.app.EvmKeeper.ChainID(),
2, 5,
&to, &to,
big.NewInt(10), big.NewInt(10),
100000, 100000,
@ -349,7 +349,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
signedContractTx := signedContractTx :=
evmtypes.NewTxContract( evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(), suite.app.EvmKeeper.ChainID(),
1, 2,
big.NewInt(10), big.NewInt(10),
100000, 100000,
nil, nil,
@ -371,7 +371,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
signedContractTx := signedContractTx :=
evmtypes.NewTxContract( evmtypes.NewTxContract(
suite.app.EvmKeeper.ChainID(), suite.app.EvmKeeper.ChainID(),
1, 3,
big.NewInt(10), big.NewInt(10),
100000, 100000,
nil, nil,
@ -393,7 +393,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
signedTx := signedTx :=
evmtypes.NewTx( evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(), suite.app.EvmKeeper.ChainID(),
1, 4,
&to, &to,
big.NewInt(10), big.NewInt(10),
100000, 100000,
@ -416,7 +416,7 @@ func (suite AnteTestSuite) TestAnteHandlerWithDynamicTxFee() {
signedTx := signedTx :=
evmtypes.NewTx( evmtypes.NewTx(
suite.app.EvmKeeper.ChainID(), suite.app.EvmKeeper.ChainID(),
2, 5,
&to, &to,
big.NewInt(10), big.NewInt(10),
100000, 100000,

View File

@ -402,24 +402,6 @@ func NewEthIncrementSenderSequenceDecorator(ak evmtypes.AccountKeeper) EthIncrem
// 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 _, msg := range tx.GetMsgs() { for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid transaction type %T, expected %T", tx, (*evmtypes.MsgEthereumTx)(nil))
}
txData, err := evmtypes.UnpackTxData(msgEthTx.Data)
if err != nil {
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
// and not previous to the state transition ¯\_(ツ)_/¯
if txData.GetTo() == nil {
// contract creation, don't increment sequence on AnteHandler but on tx execution
// continue to the next item
continue
}
// increment sequence of all signers // increment sequence of all signers
for _, addr := range msg.GetSigners() { for _, addr := range msg.GetSigners() {
acc := issd.ak.GetAccount(ctx, addr) acc := issd.ak.GetAccount(ctx, addr)
@ -439,7 +421,6 @@ func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx s
} }
} }
// set the original gas meter
return next(ctx, tx, simulate) return next(ctx, tx, simulate)
} }

View File

@ -382,15 +382,18 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
contract := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 0, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) contract := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 0, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
contract.From = addr.Hex() contract.From = addr.Hex()
err := contract.Sign(suite.ethSigner, tests.NewSigner(privKey))
suite.Require().NoError(err)
to := tests.GenerateAddress() to := tests.GenerateAddress()
tx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 0, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil) tx := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 0, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
tx.From = addr.Hex() tx.From = addr.Hex()
err = tx.Sign(suite.ethSigner, tests.NewSigner(privKey))
err := contract.Sign(suite.ethSigner, tests.NewSigner(privKey))
suite.Require().NoError(err) suite.Require().NoError(err)
err = tx.Sign(suite.ethSigner, tests.NewSigner(privKey)) tx2 := evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &to, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
tx2.From = addr.Hex()
err = tx2.Sign(suite.ethSigner, tests.NewSigner(privKey))
suite.Require().NoError(err) suite.Require().NoError(err)
testCases := []struct { testCases := []struct {
@ -404,7 +407,7 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
"invalid transaction type", "invalid transaction type",
&invalidTx{}, &invalidTx{},
func() {}, func() {},
false, false, false, true,
}, },
{ {
"no signers", "no signers",
@ -429,7 +432,7 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
}, },
{ {
"success - call", "success - call",
tx, tx2,
func() {}, func() {},
true, false, true, false,
}, },
@ -456,11 +459,7 @@ func (suite AnteTestSuite) TestEthIncrementSenderSequenceDecorator() {
suite.Require().NoError(err) suite.Require().NoError(err)
nonce := suite.app.EvmKeeper.GetNonce(addr) nonce := suite.app.EvmKeeper.GetNonce(addr)
if txData.GetTo() == nil {
suite.Require().Equal(txData.GetNonce(), nonce)
} else {
suite.Require().Equal(txData.GetNonce()+1, nonce) suite.Require().Equal(txData.GetNonce()+1, nonce)
}
} else { } else {
suite.Require().Error(err) suite.Require().Error(err)
} }

View File

@ -1,6 +1,7 @@
package evm_test package evm_test
import ( import (
"errors"
"math/big" "math/big"
"testing" "testing"
"time" "time"
@ -165,6 +166,12 @@ func (suite *EvmTestSuite) SetupTest() {
suite.DoSetupTest(suite.T()) suite.DoSetupTest(suite.T())
} }
func (suite *EvmTestSuite) SignTx(tx *types.MsgEthereumTx) {
tx.From = suite.from.String()
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
}
func TestEvmTestSuite(t *testing.T) { func TestEvmTestSuite(t *testing.T) {
suite.Run(t, new(EvmTestSuite)) suite.Run(t, new(EvmTestSuite))
} }
@ -182,11 +189,7 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
func() { func() {
to := common.BytesToAddress(suite.to) to := common.BytesToAddress(suite.to)
tx = types.NewTx(suite.chainID, 0, &to, big.NewInt(100), 10_000_000, big.NewInt(10000), nil, nil, nil, nil) tx = types.NewTx(suite.chainID, 0, &to, big.NewInt(100), 10_000_000, big.NewInt(10000), nil, nil, nil, nil)
tx.From = suite.from.String() suite.SignTx(tx)
// sign transaction
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
}, },
true, true,
}, },
@ -194,10 +197,7 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
"insufficient balance", "insufficient balance",
func() { func() {
tx = types.NewTxContract(suite.chainID, 0, big.NewInt(100), 0, big.NewInt(10000), nil, nil, nil, nil) tx = types.NewTxContract(suite.chainID, 0, big.NewInt(100), 0, big.NewInt(10000), nil, nil, nil, nil)
tx.From = suite.from.Hex() suite.SignTx(tx)
// sign transaction
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
}, },
false, false,
}, },
@ -269,10 +269,7 @@ func (suite *EvmTestSuite) TestHandlerLogs() {
bytecode := common.FromHex("0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029") bytecode := common.FromHex("0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029")
tx := types.NewTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil) tx := types.NewTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil)
tx.From = suite.from.String() suite.SignTx(tx)
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
result, err := suite.handler(suite.ctx, tx) result, err := suite.handler(suite.ctx, tx)
suite.Require().NoError(err, "failed to handle eth tx msg") suite.Require().NoError(err, "failed to handle eth tx msg")
@ -357,10 +354,7 @@ func (suite *EvmTestSuite) TestDeployAndCallContract() {
bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032") bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032")
tx := types.NewTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil) tx := types.NewTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil)
tx.From = suite.from.String() suite.SignTx(tx)
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
result, err := suite.handler(suite.ctx, tx) result, err := suite.handler(suite.ctx, tx)
suite.Require().NoError(err, "failed to handle eth tx msg") suite.Require().NoError(err, "failed to handle eth tx msg")
@ -379,10 +373,7 @@ func (suite *EvmTestSuite) TestDeployAndCallContract() {
storeAddr := "0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424" storeAddr := "0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424"
bytecode = common.FromHex(storeAddr) bytecode = common.FromHex(storeAddr)
tx = types.NewTx(suite.chainID, 2, &receiver, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil) tx = types.NewTx(suite.chainID, 2, &receiver, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil)
tx.From = suite.from.String() suite.SignTx(tx)
err = tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
_, err = suite.handler(suite.ctx, tx) _, err = suite.handler(suite.ctx, tx)
suite.Require().NoError(err, "failed to handle eth tx msg") suite.Require().NoError(err, "failed to handle eth tx msg")
@ -394,9 +385,7 @@ func (suite *EvmTestSuite) TestDeployAndCallContract() {
// query - getOwner // query - getOwner
bytecode = common.FromHex("0x893d20e8") bytecode = common.FromHex("0x893d20e8")
tx = types.NewTx(suite.chainID, 2, &receiver, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil) tx = types.NewTx(suite.chainID, 2, &receiver, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil)
tx.From = suite.from.String() suite.SignTx(tx)
err = tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
_, err = suite.handler(suite.ctx, tx) _, err = suite.handler(suite.ctx, tx)
suite.Require().NoError(err, "failed to handle eth tx msg") suite.Require().NoError(err, "failed to handle eth tx msg")
@ -416,9 +405,7 @@ func (suite *EvmTestSuite) TestSendTransaction() {
// send simple value transfer with gasLimit=21000 // send simple value transfer with gasLimit=21000
tx := types.NewTx(suite.chainID, 1, &common.Address{0x1}, big.NewInt(1), gasLimit, gasPrice, nil, nil, nil, nil) tx := types.NewTx(suite.chainID, 1, &common.Address{0x1}, big.NewInt(1), gasLimit, gasPrice, nil, nil, nil, nil)
tx.From = suite.from.String() suite.SignTx(tx)
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
result, err := suite.handler(suite.ctx, tx) result, err := suite.handler(suite.ctx, tx)
suite.Require().NoError(err) suite.Require().NoError(err)
@ -487,10 +474,7 @@ func (suite *EvmTestSuite) TestOutOfGasWhenDeployContract() {
bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032") bytecode := common.FromHex("0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a36102c4806100dc6000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c010000000000000000000000000000000000000000000000000000000090048063893d20e814610058578063a6f9dae1146100a2575b600080fd5b6100606100e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100e4600480360360208110156100b857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061010f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea265627a7a72315820f397f2733a89198bc7fed0764083694c5b828791f39ebcbc9e414bccef14b48064736f6c63430005100032")
tx := types.NewTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil) tx := types.NewTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil)
tx.From = suite.from.String() suite.SignTx(tx)
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
@ -511,10 +495,7 @@ func (suite *EvmTestSuite) TestErrorWhenDeployContract() {
bytecode := common.FromHex("0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424") bytecode := common.FromHex("0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424")
tx := types.NewTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil) tx := types.NewTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, nil, nil, bytecode, nil)
tx.From = suite.from.String() suite.SignTx(tx)
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
result, _ := suite.handler(suite.ctx, tx) result, _ := suite.handler(suite.ctx, tx)
var res types.MsgEthereumTxResponse var res types.MsgEthereumTxResponse
@ -529,7 +510,7 @@ func (suite *EvmTestSuite) TestErrorWhenDeployContract() {
func (suite *EvmTestSuite) deployERC20Contract() common.Address { func (suite *EvmTestSuite) deployERC20Contract() common.Address {
k := suite.app.EvmKeeper k := suite.app.EvmKeeper
nonce := k.GetNonce(suite.from) nonce := k.GetNonce(suite.from)
ctorArgs, err := types.ERC20Contract.ABI.Pack("", suite.from, big.NewInt(0)) ctorArgs, err := types.ERC20Contract.ABI.Pack("", suite.from, big.NewInt(10000000000))
suite.Require().NoError(err) suite.Require().NoError(err)
msg := ethtypes.NewMessage( msg := ethtypes.NewMessage(
suite.from, suite.from,
@ -550,38 +531,66 @@ func (suite *EvmTestSuite) deployERC20Contract() common.Address {
return crypto.CreateAddress(suite.from, nonce) return crypto.CreateAddress(suite.from, nonce)
} }
// TestGasRefundWhenReverted check that when transaction reverted, gas refund should still work. // TestERC20TransferReverted checks:
func (suite *EvmTestSuite) TestGasRefundWhenReverted() { // - when transaction reverted, gas refund works.
// - when transaction reverted, nonce is still increased.
func (suite *EvmTestSuite) TestERC20TransferReverted() {
intrinsicGas := uint64(21572)
// test different hooks scenarios
testCases := []struct {
msg string
gasLimit uint64
hooks types.EvmHooks
expErr string
}{
{
"no hooks",
intrinsicGas, // enough for intrinsicGas, but not enough for execution
nil,
"out of gas",
},
{
"success hooks",
intrinsicGas, // enough for intrinsicGas, but not enough for execution
&DummyHook{},
"out of gas",
},
{
"failure hooks",
1000000, // enough gas limit, but hooks fails.
&FailureHook{},
"failed to execute post processing",
},
}
for _, tc := range testCases {
suite.Run(tc.msg, func() {
suite.SetupTest() suite.SetupTest()
k := suite.app.EvmKeeper k := suite.app.EvmKeeper
k.SetHooks(tc.hooks)
// the bug only reproduce when there are hooks
k.SetHooks(&DummyHook{})
// add some fund to pay gas fee // add some fund to pay gas fee
k.AddBalance(suite.from, big.NewInt(10000000000)) k.AddBalance(suite.from, big.NewInt(10000000000))
contract := suite.deployERC20Contract() contract := suite.deployERC20Contract()
// the call will fail because no balance data, err := types.ERC20Contract.ABI.Pack("transfer", suite.from, big.NewInt(10))
data, err := types.ERC20Contract.ABI.Pack("transfer", common.BigToAddress(big.NewInt(1)), big.NewInt(10))
suite.Require().NoError(err) suite.Require().NoError(err)
nonce := k.GetNonce(suite.from)
tx := types.NewTx( tx := types.NewTx(
suite.chainID, suite.chainID,
k.GetNonce(suite.from), nonce,
&contract, &contract,
big.NewInt(0), big.NewInt(0),
41000, tc.gasLimit,
big.NewInt(1), big.NewInt(1),
nil, nil,
nil, nil,
data, data,
nil, nil,
) )
tx.From = suite.from.String() suite.SignTx(tx)
err = tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
before := k.GetBalance(suite.from) before := k.GetBalance(suite.from)
@ -592,13 +601,78 @@ func (suite *EvmTestSuite) TestGasRefundWhenReverted() {
res, err := k.EthereumTx(sdk.WrapSDKContext(suite.ctx), tx) res, err := k.EthereumTx(sdk.WrapSDKContext(suite.ctx), tx)
suite.Require().NoError(err) suite.Require().NoError(err)
suite.Require().True(res.Failed()) suite.Require().True(res.Failed())
suite.Require().Equal(tc.expErr, res.VmError)
after := k.GetBalance(suite.from) after := k.GetBalance(suite.from)
suite.Require().Equal(uint64(23861), res.GasUsed) if tc.expErr == "out of gas" {
// check gas refund works suite.Require().Equal(tc.gasLimit, res.GasUsed)
suite.Require().Equal(big.NewInt(23861), new(big.Int).Sub(before, after)) } else {
suite.Require().Greater(tc.gasLimit, res.GasUsed)
}
// check gas refund works: only deducted fee for gas used, rather than gas limit.
suite.Require().Equal(big.NewInt(int64(res.GasUsed)), new(big.Int).Sub(before, after))
// nonce should not be increased.
suite.Require().Equal(nonce, k.GetNonce(suite.from))
})
}
}
func (suite *EvmTestSuite) TestContractDeploymentRevert() {
intrinsicGas := uint64(134180)
testCases := []struct {
msg string
gasLimit uint64
hooks types.EvmHooks
}{
{
"no hooks",
intrinsicGas,
nil,
},
{
"success hooks",
intrinsicGas,
&DummyHook{},
},
}
for _, tc := range testCases {
suite.Run(tc.msg, func() {
suite.SetupTest()
k := suite.app.EvmKeeper
// test with different hooks scenarios
k.SetHooks(tc.hooks)
nonce := k.GetNonce(suite.from)
ctorArgs, err := types.ERC20Contract.ABI.Pack("", suite.from, big.NewInt(0))
suite.Require().NoError(err)
tx := types.NewTx(
nil,
nonce,
nil, // to
nil, // amount
tc.gasLimit,
nil, nil, nil,
append(types.ERC20Contract.Bin, ctorArgs...),
nil,
)
suite.SignTx(tx)
rsp, err := k.EthereumTx(sdk.WrapSDKContext(suite.ctx), tx)
suite.Require().NoError(err)
suite.Require().True(rsp.Failed())
// nonce don't increase, it's increased in ante handler.
suite.Require().Equal(nonce, k.GetNonce(suite.from))
})
}
} }
// DummyHook implements EvmHooks interface // DummyHook implements EvmHooks interface
@ -607,3 +681,10 @@ type DummyHook struct{}
func (dh *DummyHook) PostTxProcessing(ctx sdk.Context, txHash common.Hash, logs []*ethtypes.Log) error { func (dh *DummyHook) PostTxProcessing(ctx sdk.Context, txHash common.Hash, logs []*ethtypes.Log) error {
return nil return nil
} }
// FailureHook implements EvmHooks interface
type FailureHook struct{}
func (dh *FailureHook) PostTxProcessing(ctx sdk.Context, txHash common.Hash, logs []*ethtypes.Log) error {
return errors.New("mock error")
}

View File

@ -678,6 +678,8 @@ func (suite *KeeperTestSuite) TestTraceTx() {
malleate: func() { malleate: func() {
txIndex = 1 txIndex = 1
traceConfig = nil traceConfig = nil
// increase nonce to avoid address collision
suite.app.EvmKeeper.SetNonce(suite.address, suite.app.EvmKeeper.GetNonce(suite.address)+1)
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
suite.Commit() suite.Commit()
@ -803,6 +805,8 @@ func (suite *KeeperTestSuite) TestTraceBlock() {
msg: "tracer with multiple transactions", msg: "tracer with multiple transactions",
malleate: func() { malleate: func() {
traceConfig = nil traceConfig = nil
// increase nonce to avoid address collision
suite.app.EvmKeeper.SetNonce(suite.address, suite.app.EvmKeeper.GetNonce(suite.address)+1)
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt()) contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
suite.Commit() suite.Commit()
// create multiple transactions in the same block // create multiple transactions in the same block

View File

@ -343,7 +343,10 @@ func (k *Keeper) ApplyMessageWithConfig(msg core.Message, tracer vm.Tracer, comm
} }
if contractCreation { if contractCreation {
nonce := k.GetNonce(sender.Address())
ret, _, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value()) ret, _, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value())
// revert nonce increment, because it's increased in ante handler
k.SetNonce(sender.Address(), nonce)
} else { } else {
ret, leftoverGas, vmErr = evm.Call(sender, *msg.To(), msg.Data(), leftoverGas, msg.Value()) ret, leftoverGas, vmErr = evm.Call(sender, *msg.To(), msg.Data(), leftoverGas, msg.Value())
} }