diff --git a/app/ante.go b/app/ante.go index 3e31e6c09..0ccb6cd3c 100644 --- a/app/ante.go +++ b/app/ante.go @@ -103,6 +103,7 @@ func NewAnteHandlerAndDepGenerator(options HandlerOptions) (sdk.AnteHandler, sdk sdk.CustomDepWrappedAnteDecorator(ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), depdecorators.SignerDepDecorator{ReadOnly: true}), sdk.CustomDepWrappedAnteDecorator(sequentialVerifyDecorator, depdecorators.SignerDepDecorator{ReadOnly: true}), sdk.CustomDepWrappedAnteDecorator(ante.NewIncrementSequenceDecorator(options.AccountKeeper), depdecorators.SignerDepDecorator{ReadOnly: false}), + sdk.DefaultWrappedAnteDecorator(evmante.NewEVMAddressDecorator(options.EVMKeeper, options.EVMKeeper.AccountKeeper())), sdk.DefaultWrappedAnteDecorator(ibcante.NewAnteDecorator(options.IBCKeeper)), sdk.DefaultWrappedAnteDecorator(dex.NewTickSizeMultipleDecorator(*options.DexKeeper)), dex.NewCheckDexGasDecorator(*options.DexKeeper, options.CheckTxMemState), diff --git a/precompiles/wasmd/wasmd_test.go b/precompiles/wasmd/wasmd_test.go index 68adf3913..caa097587 100644 --- a/precompiles/wasmd/wasmd_test.go +++ b/precompiles/wasmd/wasmd_test.go @@ -70,7 +70,7 @@ func TestInstantiate(t *testing.T) { require.Equal(t, 2, len(outputs)) require.Equal(t, "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", outputs[0].(string)) require.Empty(t, outputs[1].([]byte)) - require.Equal(t, uint64(902900), g) + require.Equal(t, uint64(902898), g) // non-existent code ID args, _ = instantiateMethod.Inputs.Pack( @@ -138,7 +138,7 @@ func TestExecute(t *testing.T) { require.Nil(t, err) require.Equal(t, 1, len(outputs)) require.Equal(t, fmt.Sprintf("received test msg from %s with 1000usei", mockAddr.String()), string(outputs[0].([]byte))) - require.Equal(t, uint64(906042), g) + require.Equal(t, uint64(906041), g) require.Equal(t, int64(1000), testApp.BankKeeper.GetBalance(statedb.Ctx(), contractAddr, "usei").Amount.Int64()) // allowed delegatecall @@ -199,7 +199,7 @@ func TestQuery(t *testing.T) { require.Nil(t, err) require.Equal(t, 1, len(outputs)) require.Equal(t, "{\"message\":\"query test\"}", string(outputs[0].([]byte))) - require.Equal(t, uint64(930368), g) + require.Equal(t, uint64(930367), g) // bad contract address args, _ = queryMethod.Inputs.Pack(mockAddr.String(), []byte("{\"info\":{}}")) diff --git a/x/evm/ante/preprocess.go b/x/evm/ante/preprocess.go index 0ec06d14c..995c225c9 100644 --- a/x/evm/ante/preprocess.go +++ b/x/evm/ante/preprocess.go @@ -3,6 +3,7 @@ package ante import ( "encoding/hex" "errors" + "fmt" "math/big" "github.com/btcsuite/btcd/btcec" @@ -12,6 +13,7 @@ import ( sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" accountkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/ethereum/go-ethereum/common" @@ -305,3 +307,43 @@ func GetVersion(ctx sdk.Context, ethCfg *params.ChainConfig) derived.SignerVersi return derived.London } } + +type EVMAddressDecorator struct { + evmKeeper *evmkeeper.Keeper + accountKeeper *accountkeeper.AccountKeeper +} + +func NewEVMAddressDecorator(evmKeeper *evmkeeper.Keeper, accountKeeper *accountkeeper.AccountKeeper) *EVMAddressDecorator { + return &EVMAddressDecorator{evmKeeper: evmKeeper, accountKeeper: accountKeeper} +} + +//nolint:revive +func (p *EVMAddressDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + sigTx, ok := tx.(authsigning.SigVerifiableTx) + if !ok { + return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid tx type") + } + signers := sigTx.GetSigners() + for _, signer := range signers { + if _, associated := p.evmKeeper.GetEVMAddress(ctx, signer); associated { + continue + } + acc := p.accountKeeper.GetAccount(ctx, signer) + if acc.GetPubKey() == nil { + ctx.Logger().Error(fmt.Sprintf("missing pubkey for %s", signer.String())) + continue + } + pk, err := btcec.ParsePubKey(acc.GetPubKey().Bytes(), btcec.S256()) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("failed to parse pubkey for %s", err)) + continue + } + evmAddr, err := pubkeyToEVMAddress(pk.SerializeUncompressed()) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("failed to get EVM address from pubkey due to %s", err)) + continue + } + p.evmKeeper.SetAddressMapping(ctx, signer, evmAddr) + } + return next(ctx, tx, simulate) +} diff --git a/x/evm/ante/preprocess_test.go b/x/evm/ante/preprocess_test.go index abf70ddbc..4078f0044 100644 --- a/x/evm/ante/preprocess_test.go +++ b/x/evm/ante/preprocess_test.go @@ -10,6 +10,8 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -154,3 +156,20 @@ func TestAnteDeps(t *testing.T) { require.Nil(t, err) require.Equal(t, 12, len(deps)) } + +func TestEVMAddressDecorator(t *testing.T) { + k, ctx := testkeeper.MockEVMKeeper() + privKey := testkeeper.MockPrivateKey() + sender, evmAddr := testkeeper.PrivateKeyToAddresses(privKey) + recipient, _ := testkeeper.MockAddressPair() + handler := ante.NewEVMAddressDecorator(k, k.AccountKeeper()) + msg := banktypes.NewMsgSend(sender, recipient, sdk.NewCoins(sdk.NewCoin("usei", sdk.OneInt()))) + k.AccountKeeper().SetAccount(ctx, authtypes.NewBaseAccount(sender, privKey.PubKey(), 1, 1)) + ctx, err := handler.AnteHandle(ctx, mockTx{msgs: []sdk.Msg{msg}, signers: []sdk.AccAddress{sender}}, false, func(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) { + return ctx, nil + }) + require.Nil(t, err) + associatedEvmAddr, associated := k.GetEVMAddress(ctx, sender) + require.True(t, associated) + require.Equal(t, evmAddr, associatedEvmAddr) +} diff --git a/x/evm/ante/router_test.go b/x/evm/ante/router_test.go index a31c57404..86e16cca9 100644 --- a/x/evm/ante/router_test.go +++ b/x/evm/ante/router_test.go @@ -3,8 +3,10 @@ package ante_test import ( "testing" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" + "github.com/cosmos/cosmos-sdk/types/tx/signing" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/sei-protocol/sei-chain/x/evm/ante" "github.com/sei-protocol/sei-chain/x/evm/types" @@ -37,11 +39,15 @@ func (m *mockAnteState) evmAnteDepGenerator(txDeps []sdkacltypes.AccessOperation } type mockTx struct { - msgs []sdk.Msg + msgs []sdk.Msg + signers []sdk.AccAddress } -func (tx mockTx) GetMsgs() []sdk.Msg { return tx.msgs } -func (tx mockTx) ValidateBasic() error { return nil } +func (tx mockTx) GetMsgs() []sdk.Msg { return tx.msgs } +func (tx mockTx) ValidateBasic() error { return nil } +func (tx mockTx) GetSigners() []sdk.AccAddress { return tx.signers } +func (tx mockTx) GetPubKeys() ([]cryptotypes.PubKey, error) { return nil, nil } +func (tx mockTx) GetSignaturesV2() ([]signing.SignatureV2, error) { return nil, nil } func TestRouter(t *testing.T) { bankMsg := &banktypes.MsgSend{}