ante: check that sender is a EOA (#125)
* ante: check that sender is a EOA * fix: GetCodeSize handles nil case and comments * docs: add TODO comment * fix: use EmptyCodeHash check * lint: evmtypes instead of types * lint: fix suite error * test: set code to act not as EOA * undo comment on GetCodeSize * keeper: fix input checks * Apply suggestions from code review Co-authored-by: Akash Khosla <me@akashkhosla.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
d3c5df9dda
commit
d7da045fc4
@ -28,6 +28,7 @@ type EVMKeeper interface {
|
|||||||
WithContext(ctx sdk.Context)
|
WithContext(ctx sdk.Context)
|
||||||
ResetRefundTransient(ctx sdk.Context)
|
ResetRefundTransient(ctx sdk.Context)
|
||||||
NewEVM(msg core.Message, config *params.ChainConfig) *vm.EVM
|
NewEVM(msg core.Message, config *params.ChainConfig) *vm.EVM
|
||||||
|
GetCodeHash(addr common.Address) common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthSigVerificationDecorator validates an ethereum signatures
|
// 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
|
// get and set account must be called with an infinite gas meter in order to prevent
|
||||||
// additional gas from being deducted.
|
// additional gas from being deducted.
|
||||||
infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
infCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
|
||||||
|
avd.evmKeeper.WithContext(infCtx)
|
||||||
evmDenom := avd.evmKeeper.GetParams(infCtx).EvmDenom
|
evmDenom := avd.evmKeeper.GetParams(infCtx).EvmDenom
|
||||||
|
|
||||||
for i, msg := range tx.GetMsgs() {
|
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)
|
acc := avd.ak.GetAccount(infCtx, from)
|
||||||
if acc == nil {
|
if acc == nil {
|
||||||
acc = avd.ak.NewAccountWithAddress(infCtx, from)
|
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(),
|
"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)
|
return next(ctx, tx, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,10 +86,23 @@ func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
|||||||
true,
|
true,
|
||||||
false,
|
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",
|
"not enough balance to cover tx cost",
|
||||||
tx,
|
tx,
|
||||||
func() {},
|
func() {
|
||||||
|
// reset back to EOA
|
||||||
|
suite.app.EvmKeeper.SetCode(addr, nil)
|
||||||
|
},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
@ -86,6 +86,7 @@ func (suite *AnteTestSuite) CreateTestTx(
|
|||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
err = builder.SetMsgs(msg)
|
err = builder.SetMsgs(msg)
|
||||||
|
suite.Require().NoError(err)
|
||||||
fees := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(msg.Fee())))
|
fees := sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewIntFromBigInt(msg.Fee())))
|
||||||
builder.SetFeeAmount(fees)
|
builder.SetFeeAmount(fees)
|
||||||
builder.SetGasLimit(msg.GetGas())
|
builder.SetGasLimit(msg.GetGas())
|
||||||
|
@ -228,6 +228,9 @@ func (k *Keeper) GetCode(addr common.Address) []byte {
|
|||||||
|
|
||||||
// SetCode calls CommitStateDB.SetCode using the passed in context
|
// SetCode calls CommitStateDB.SetCode using the passed in context
|
||||||
func (k *Keeper) SetCode(addr common.Address, code []byte) {
|
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)
|
hash := crypto.Keccak256Hash(code)
|
||||||
|
|
||||||
// update account code hash
|
// 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 {
|
func (k *Keeper) GetCodeSize(addr common.Address) int {
|
||||||
return len(k.GetCode(addr))
|
code := k.GetCode(addr)
|
||||||
|
return len(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user