diff --git a/app/ante/eth.go b/app/ante/eth.go index 496fed91..d0eeb95e 100644 --- a/app/ante/eth.go +++ b/app/ante/eth.go @@ -28,6 +28,7 @@ type EVMKeeper interface { WithContext(ctx sdk.Context) ResetRefundTransient(ctx sdk.Context) NewEVM(msg core.Message, config *params.ChainConfig) *vm.EVM + GetCodeHash(addr common.Address) common.Hash } // EthSigVerificationDecorator validates an ethereum signatures @@ -126,7 +127,7 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx // get and set account must be called with an infinite gas meter in order to prevent // additional gas from being deducted. infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - + avd.evmKeeper.WithContext(infCtx) evmDenom := avd.evmKeeper.GetParams(infCtx).EvmDenom for i, msg := range tx.GetMsgs() { @@ -147,6 +148,14 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx ) } + // check whether the sender address is EOA + fromAddr := common.BytesToAddress(from) + codeHash := avd.evmKeeper.GetCodeHash(fromAddr) + if codeHash != common.BytesToHash(evmtypes.EmptyCodeHash) { + return ctx, stacktrace.Propagate(sdkerrors.Wrapf(sdkerrors.ErrInvalidType, + "the sender is not EOA: address <%v>, codeHash <%s>", fromAddr, codeHash), "") + } + acc := avd.ak.GetAccount(infCtx, from) if acc == nil { acc = avd.ak.NewAccountWithAddress(infCtx, from) @@ -164,8 +173,10 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx "sender should have had enough funds to pay for tx cost = fee + amount (%s = %s + amount)", msgEthTx.Cost(), msgEthTx.Fee(), ) } - } + } + // recover the original gas meter + avd.evmKeeper.WithContext(ctx) return next(ctx, tx, simulate) } diff --git a/app/ante/eth_test.go b/app/ante/eth_test.go index e0e6446e..f342431c 100644 --- a/app/ante/eth_test.go +++ b/app/ante/eth_test.go @@ -86,10 +86,23 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() { true, false, }, + { + "sender not EOA", + tx, + func() { + // set not as an EOA + suite.app.EvmKeeper.SetCode(addr, []byte("1")) + }, + true, + false, + }, { "not enough balance to cover tx cost", tx, - func() {}, + func() { + // reset back to EOA + suite.app.EvmKeeper.SetCode(addr, nil) + }, true, false, }, diff --git a/app/ante/utils_test.go b/app/ante/utils_test.go index 620aa56e..cbc5e753 100644 --- a/app/ante/utils_test.go +++ b/app/ante/utils_test.go @@ -86,6 +86,7 @@ func (suite *AnteTestSuite) CreateTestTx( suite.Require().NoError(err) err = builder.SetMsgs(msg) + suite.Require().NoError(err) fees := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(msg.Fee()))) builder.SetFeeAmount(fees) builder.SetGasLimit(msg.GetGas()) diff --git a/x/evm/keeper/statedb.go b/x/evm/keeper/statedb.go index a4c157f0..2ea7f552 100644 --- a/x/evm/keeper/statedb.go +++ b/x/evm/keeper/statedb.go @@ -228,6 +228,9 @@ func (k *Keeper) GetCode(addr common.Address) []byte { // SetCode calls CommitStateDB.SetCode using the passed in context func (k *Keeper) SetCode(addr common.Address, code []byte) { + if bytes.Equal(code, types.EmptyCodeHash) { + k.Logger(k.ctx).Debug("passed in EmptyCodeHash, but expected empty code") + } hash := crypto.Keccak256Hash(code) // update account code hash @@ -269,9 +272,11 @@ func (k *Keeper) SetCode(addr common.Address, code []byte) { ) } -// GetCodeSize returns the code hash stored in the address account. +// GetCodeSize returns the size of the contract code associated with this object, +// or zero if none. func (k *Keeper) GetCodeSize(addr common.Address) int { - return len(k.GetCode(addr)) + code := k.GetCode(addr) + return len(code) } // ----------------------------------------------------------------------------