Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
Add EIP-712 encoding support type for any array (#1430)
Browse files Browse the repository at this point in the history
* Add EIP-712 encoding support type for any array

* Refactor implementation + add tests

* Refactor unpacking implementation; refactor test case

* Fix lint issue

* Add MsgExec test case

* Update comment for clarity

* Add changelog entry

* Refactor `sdkerrors` to `errorsmod`

Co-authored-by: Freddy Caceres <facs95@gmail.com>
  • Loading branch information
austinchandra and facs95 authored Nov 16, 2022
1 parent 71e51aa commit 5f418c7
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (deps) [#1168](https://github.com/evmos/ethermint/pull/1168) Upgrade Cosmos SDK to `v0.46`.
* (feemarket) [#1194](https://github.com/evmos/ethermint/pull/1194) Apply feemarket to native cosmos tx.
* (eth) [#1346](https://github.com/evmos/ethermint/pull/1346) Added support for `sdk.Dec` and `ed25519` type on eip712.
* (eth) [#1430](https://github.com/evmos/ethermint/pull/1430) Added support for array of type `Any` on eip712. 
* (ante) [1460](https://github.com/evmos/ethermint/pull/1460) Add KV Gas config on ethereum Txs.
* (geth) [#1413](https://github.com/evmos/ethermint/pull/1413) Update geth version to v1.10.25.

Expand Down
24 changes: 23 additions & 1 deletion app/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,29 @@ func (suite AnteTestSuite) TestAnteHandler() {
coinAmount := sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20))
amount := sdk.NewCoins(coinAmount)
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712MsgEditValidator(from, privKey, "ethermint_9000-1", gas, amount)
txBuilder := suite.CreateTestEIP712MsgSubmitEvidence(from, privKey, "ethermint_9000-1", gas, amount)
return txBuilder.GetTx()
}, false, false, true,
},
{
"success- DeliverTx EIP712 submit proposal v1",
func() sdk.Tx {
from := acc.GetAddress()
coinAmount := sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20))
amount := sdk.NewCoins(coinAmount)
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712SubmitProposalV1(from, privKey, "ethermint_9000-1", gas, amount)
return txBuilder.GetTx()
}, false, false, true,
},
{
"success- DeliverTx EIP712 MsgExec",
func() sdk.Tx {
from := acc.GetAddress()
coinAmount := sdk.NewCoin(evmtypes.DefaultEVMDenom, sdk.NewInt(20))
amount := sdk.NewCoins(coinAmount)
gas := uint64(200000)
txBuilder := suite.CreateTestEIP712MsgExec(from, privKey, "ethermint_9000-1", gas, amount)
return txBuilder.GetTx()
}, false, false, true,
},
Expand Down
48 changes: 48 additions & 0 deletions app/ante/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ import (
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
authz "github.com/cosmos/cosmos-sdk/x/authz"
cryptocodec "github.com/evmos/ethermint/crypto/codec"
"github.com/evmos/ethermint/crypto/ethsecp256k1"

"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
evtypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
"github.com/cosmos/cosmos-sdk/x/feegrant"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
types5 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
"github.com/evmos/ethermint/app"
ante "github.com/evmos/ethermint/app/ante"
Expand Down Expand Up @@ -344,6 +346,52 @@ func (suite *AnteTestSuite) CreateTestEIP712MsgSubmitEvidence(from sdk.AccAddres
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgEvidence)
}

func (suite *AnteTestSuite) CreateTestEIP712SubmitProposalV1(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
// Build V1 proposal messages. Must all be same-type, since EIP-712
// does not support arrays of variable type.
authAcc := suite.app.GovKeeper.GetGovernanceAccount(suite.ctx)

proposal1, ok := types5.ContentFromProposalType("My proposal 1", "My description 1", types5.ProposalTypeText)
suite.Require().True(ok)
content1, err := govtypes.NewLegacyContent(
proposal1,
sdk.MustBech32ifyAddressBytes(sdk.GetConfig().GetBech32AccountAddrPrefix(), authAcc.GetAddress().Bytes()),
)
suite.Require().NoError(err)

proposal2, ok := types5.ContentFromProposalType("My proposal 2", "My description 2", types5.ProposalTypeText)
suite.Require().True(ok)
content2, err := govtypes.NewLegacyContent(
proposal2,
sdk.MustBech32ifyAddressBytes(sdk.GetConfig().GetBech32AccountAddrPrefix(), authAcc.GetAddress().Bytes()),
)
suite.Require().NoError(err)

proposalMsgs := []sdk.Msg{
content1,
content2,
}

// Build V1 proposal
msgProposal, err := govtypes.NewMsgSubmitProposal(
proposalMsgs,
sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdkmath.NewInt(100))),
sdk.MustBech32ifyAddressBytes(sdk.GetConfig().GetBech32AccountAddrPrefix(), from.Bytes()),
"Metadata",
)

suite.Require().NoError(err)

return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, msgProposal)
}

func (suite *AnteTestSuite) CreateTestEIP712MsgExec(from sdk.AccAddress, priv cryptotypes.PrivKey, chainId string, gas uint64, gasAmount sdk.Coins) client.TxBuilder {
recipient := sdk.AccAddress(common.Address{}.Bytes())
msgSend := types2.NewMsgSend(from, recipient, sdk.NewCoins(sdk.NewCoin(evmtypes.DefaultEVMDenom, sdkmath.NewInt(1))))
msgExec := authz.NewMsgExec(from, []sdk.Msg{msgSend})
return suite.CreateTestEIP712CosmosTxBuilder(from, priv, chainId, gas, gasAmount, &msgExec)
}

// StdSignBytes returns the bytes to sign for a transaction.
func StdSignBytes(cdc *codec.LegacyAmino, chainID string, accnum uint64, sequence uint64, timeout uint64, fee legacytx.StdFee, msgs []sdk.Msg, memo string, tip *txtypes.Tip) []byte {
msgsBytes := make([]json.RawMessage, 0, len(msgs))
Expand Down
52 changes: 35 additions & 17 deletions ethereum/eip712/eip712.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ func traverseFields(
}

for i := 0; i < n; i++ {
var field reflect.Value
var (
field reflect.Value
err error
)

if v.IsValid() {
field = v.Field(i)
}
Expand All @@ -197,23 +201,10 @@ func traverseFields(
fieldName := jsonNameFromTag(t.Field(i).Tag)

if fieldType == cosmosAnyType {
any, ok := field.Interface().(*codectypes.Any)
if !ok {
return errorsmod.Wrapf(errortypes.ErrPackAny, "%T", field.Interface())
}

anyWrapper := &cosmosAnyWrapper{
Type: any.TypeUrl,
}

if err := cdc.UnpackAny(any, &anyWrapper.Value); err != nil {
return errorsmod.Wrap(err, "failed to unpack Any in msg struct")
// Unpack field, value as Any
if fieldType, field, err = unpackAny(cdc, field); err != nil {
return err
}

fieldType = reflect.TypeOf(anyWrapper)
field = reflect.ValueOf(anyWrapper)

// then continue as normal
}

// If its a nil pointer, do not include in types
Expand Down Expand Up @@ -255,6 +246,12 @@ func traverseFields(
fieldType = fieldType.Elem()
field = field.Index(0)
isCollection = true

if fieldType == cosmosAnyType {
if fieldType, field, err = unpackAny(cdc, field); err != nil {
return err
}
}
}

for {
Expand Down Expand Up @@ -345,6 +342,27 @@ func jsonNameFromTag(tag reflect.StructTag) string {
return parts[0]
}

// Unpack the given Any value with Type/Value deconstruction
func unpackAny(cdc codectypes.AnyUnpacker, field reflect.Value) (reflect.Type, reflect.Value, error) {
any, ok := field.Interface().(*codectypes.Any)
if !ok {
return nil, reflect.Value{}, errorsmod.Wrapf(errortypes.ErrPackAny, "%T", field.Interface())
}

anyWrapper := &cosmosAnyWrapper{
Type: any.TypeUrl,
}

if err := cdc.UnpackAny(any, &anyWrapper.Value); err != nil {
return nil, reflect.Value{}, errorsmod.Wrap(err, "failed to unpack Any in msg struct")
}

fieldType := reflect.TypeOf(anyWrapper)
field = reflect.ValueOf(anyWrapper)

return fieldType, field, nil
}

// _.foo_bar.baz -> TypeFooBarBaz
//
// this is needed for Geth's own signing code which doesn't
Expand Down

0 comments on commit 5f418c7

Please sign in to comment.