Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
### BUG FIXES

- [\#869](https://github.com/cosmos/evm/pull/869) Fix erc20 IBC callbacks to check for native token transfer before parsing recipient.
- [\#860](https://github.com/cosmos/evm/pull/860) Fix EIP-712 signature verification to use configured EVM chain ID instead of parsing cosmos chain ID string and replace legacytx.StdSignBytes with the aminojson sign mode handler.
- [\#794](https://github.com/cosmos/evm/pull/794) Fix mempool.max-txs flag not using desired default of 0
- [\#748](https://github.com/cosmos/evm/pull/748) Fix DynamicFeeChecker in Cosmos ante handler to respect NoBaseFee feemarkets' parameter.
- [\#690](https://github.com/cosmos/evm/pull/690) Fix Ledger hardware wallet support for coin type 60.
Expand Down
53 changes: 38 additions & 15 deletions ante/cosmos/eip712.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package cosmos

import (
"context"
"fmt"
"strconv"

ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
Expand All @@ -11,8 +11,12 @@ import (
anteinterfaces "github.com/cosmos/evm/ante/interfaces"
"github.com/cosmos/evm/crypto/ethsecp256k1"
"github.com/cosmos/evm/ethereum/eip712"
evmtypes "github.com/cosmos/evm/x/vm/types"

txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
errorsmod "cosmossdk.io/errors"
txsigning "cosmossdk.io/x/tx/signing"
"cosmossdk.io/x/tx/signing/aminojson"

"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
Expand All @@ -21,7 +25,6 @@ import (
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
)

Expand Down Expand Up @@ -136,6 +139,7 @@ func (svd LegacyEip712SigVerificationDecorator) AnteHandle(ctx sdk.Context,
ChainID: chainID,
AccountNumber: accNum,
Sequence: acc.GetSequence(),
Address: acc.GetAddress().String(),
}

if simulate {
Expand Down Expand Up @@ -177,22 +181,41 @@ func VerifySignature(
return errorsmod.Wrap(errortypes.ErrNoSignatures, "tx doesn't contain any msgs to verify signature")
}

txBytes := legacytx.StdSignBytes( //nolint:staticcheck // TODO: fix
signerData.ChainID,
signerData.AccountNumber,
signerData.Sequence,
tx.GetTimeoutHeight(),
legacytx.StdFee{
Amount: tx.GetFee(),
Gas: tx.GetGas(),
anyMsgs, err := eip712.ToAnyMsgs(msgs)
if err != nil {
return err
}
feeAmount := eip712.ToFeeAmount(tx.GetFee())
txData := txsigning.TxData{
Body: &txv1beta1.TxBody{
Messages: anyMsgs,
Memo: tx.GetMemo(),
TimeoutHeight: tx.GetTimeoutHeight(),
},
msgs, tx.GetMemo(),
)

signerChainID, err := strconv.ParseUint(signerData.ChainID, 10, 64)
AuthInfo: &txv1beta1.AuthInfo{
Fee: &txv1beta1.Fee{
Amount: feeAmount,
GasLimit: tx.GetGas(),
},
},
}
signModeHandler := aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{})
signer := txsigning.SignerData{
ChainID: signerData.ChainID,
AccountNumber: signerData.AccountNumber,
Sequence: signerData.Sequence,
Address: signerData.Address,
}
txBytes, err := signModeHandler.GetSignBytes(context.Background(), signer, txData)
if err != nil {
return errorsmod.Wrapf(err, "failed to parse chain-id: %s", signerData.ChainID)
return errorsmod.Wrap(err, "failed to get sign bytes using aminojson")
}

ethChainID := evmtypes.GetEthChainConfig().ChainID
if ethChainID == nil {
return errorsmod.Wrap(errortypes.ErrInvalidChainID, "eth chain ID not configured")
}
signerChainID := ethChainID.Uint64()

txWithExtensions, ok := tx.(authante.HasExtensionOptionsTx)
if !ok {
Expand Down
54 changes: 40 additions & 14 deletions ethereum/eip712/encoding.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package eip712

import (
"context"
"errors"
"fmt"

apitypes "github.com/ethereum/go-ethereum/signer/core/apitypes"

txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
errorsmod "cosmossdk.io/errors"
txsigning "cosmossdk.io/x/tx/signing"
"cosmossdk.io/x/tx/signing/aminojson"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
txTypes "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
Expand Down Expand Up @@ -159,22 +166,41 @@ func decodeProtobufSignDoc(signDocBytes []byte) (apitypes.TypedData, error) {
}

signerInfo := authInfo.SignerInfos[0]

stdFee := &legacytx.StdFee{
Amount: authInfo.Fee.Amount,
Gas: authInfo.Fee.GasLimit,
var pubKey cryptotypes.PubKey
err := protoCodec.UnpackAny(signerInfo.PublicKey, &pubKey)
if err != nil {
return apitypes.TypedData{}, errorsmod.Wrap(err, "failed to unpack signer public key")
}

// WrapTxToTypedData expects the payload as an Amino Sign Doc
signBytes := legacytx.StdSignBytes( //nolint:staticcheck // TODO: fix
signDoc.ChainId,
signDoc.AccountNumber,
signerInfo.Sequence,
body.TimeoutHeight,
*stdFee,
msgs,
body.Memo,
)
anyMsgs, err := ToAnyMsgs(msgs)
if err != nil {
return apitypes.TypedData{}, err
}
feeAmount := ToFeeAmount(authInfo.Fee.Amount)
txData := txsigning.TxData{
Body: &txv1beta1.TxBody{
Messages: anyMsgs,
Memo: body.Memo,
TimeoutHeight: body.TimeoutHeight,
},
AuthInfo: &txv1beta1.AuthInfo{
Fee: &txv1beta1.Fee{
Amount: feeAmount,
GasLimit: authInfo.Fee.GasLimit,
},
},
}
signModeHandler := aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{})
signer := txsigning.SignerData{
ChainID: signDoc.ChainId,
AccountNumber: signDoc.AccountNumber,
Sequence: signerInfo.Sequence,
Address: pubKey.Address().String(),
}
signBytes, err := signModeHandler.GetSignBytes(context.Background(), signer, txData)
if err != nil {
return apitypes.TypedData{}, errorsmod.Wrap(err, "failed to get sign bytes using aminojson")
}

typedData, err := WrapTxToTypedData(
eip155ChainID,
Expand Down
56 changes: 41 additions & 15 deletions ethereum/eip712/encoding_legacy.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package eip712

import (
"context"
"encoding/json"
"errors"
"fmt"

apitypes "github.com/ethereum/go-ethereum/signer/core/apitypes"

txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
errorsmod "cosmossdk.io/errors"
txsigning "cosmossdk.io/x/tx/signing"
"cosmossdk.io/x/tx/signing/aminojson"

cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
txTypes "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
Expand Down Expand Up @@ -157,14 +164,12 @@ func legacyDecodeProtobufSignDoc(signDocBytes []byte, eip155ChainID uint64) (api

// Use first message for fee payer and type inference
msg := msgs[0]

signerInfo := authInfo.SignerInfos[0]

stdFee := &legacytx.StdFee{
Amount: authInfo.Fee.Amount,
Gas: authInfo.Fee.GasLimit,
var pubKey cryptotypes.PubKey
err := protoCodec.UnpackAny(signerInfo.PublicKey, &pubKey)
if err != nil {
return apitypes.TypedData{}, errorsmod.Wrap(err, "failed to unpack signer public key")
}

signers, _, err := protoCodec.GetMsgV1Signers(msg)
if err != nil {
return apitypes.TypedData{}, err
Expand All @@ -175,15 +180,36 @@ func legacyDecodeProtobufSignDoc(signDocBytes []byte, eip155ChainID uint64) (api
}

// WrapTxToTypedData expects the payload as an Amino Sign Doc
signBytes := legacytx.StdSignBytes( //nolint:staticcheck // TODO: fix
signDoc.ChainId,
signDoc.AccountNumber,
signerInfo.Sequence,
body.TimeoutHeight,
*stdFee,
msgs,
body.Memo,
)
anyMsgs, err := ToAnyMsgs(msgs)
if err != nil {
return apitypes.TypedData{}, err
}
feeAmount := ToFeeAmount(authInfo.Fee.Amount)
txData := txsigning.TxData{
Body: &txv1beta1.TxBody{
Messages: anyMsgs,
Memo: body.Memo,
TimeoutHeight: body.TimeoutHeight,
},
AuthInfo: &txv1beta1.AuthInfo{
Fee: &txv1beta1.Fee{
Amount: feeAmount,
GasLimit: authInfo.Fee.GasLimit,
},
},
}

signModeHandler := aminojson.NewSignModeHandler(aminojson.SignModeHandlerOptions{})
signer := txsigning.SignerData{
ChainID: signDoc.ChainId,
AccountNumber: signDoc.AccountNumber,
Sequence: signerInfo.Sequence,
Address: pubKey.Address().String(),
}
signBytes, err := signModeHandler.GetSignBytes(context.Background(), signer, txData)
if err != nil {
return apitypes.TypedData{}, errorsmod.Wrap(err, "failed to get sign bytes using aminojson")
}

typedData, err := LegacyWrapTxToTypedData(
protoCodec,
Expand Down
26 changes: 26 additions & 0 deletions ethereum/eip712/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ import (
"github.com/tidwall/gjson"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"google.golang.org/protobuf/types/known/anypb"

basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
errorsmod "cosmossdk.io/errors"

"github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
)

Expand Down Expand Up @@ -387,3 +391,25 @@ func doRecover(err *error) {
*err = fmt.Errorf("%v", r)
}
}

// ToAnyMsgs helps to convert sdk.Msg slice to []*anypb.Any
func ToAnyMsgs(msgs []sdk.Msg) ([]*anypb.Any, error) {
anyMsgs := make([]*anypb.Any, len(msgs))
for i, msg := range msgs {
anyMsg, err := types.NewAnyWithValue(msg)
if err != nil {
return nil, errorsmod.Wrap(err, "failed to convert sdk.Msg to Any")
}
anyMsgs[i] = &anypb.Any{TypeUrl: anyMsg.TypeUrl, Value: anyMsg.Value}
}
return anyMsgs, nil
}

// ToFeeAmount helps to convert sdk.Coins to []*basev1beta1.Coin
func ToFeeAmount(coins sdk.Coins) []*basev1beta1.Coin {
feeAmount := make([]*basev1beta1.Coin, len(coins))
for i, coin := range coins {
feeAmount[i] = &basev1beta1.Coin{Denom: coin.Denom, Amount: coin.Amount.String()}
}
return feeAmount
}
Loading
Loading