diff --git a/app/app.go b/app/app.go index 02b7899c88..153d35e76a 100644 --- a/app/app.go +++ b/app/app.go @@ -539,7 +539,7 @@ func New( evmS, func(ctx sdk.Context, stateDB vm.StateDB) []precompiles.StatefulPrecompiledContract { return []precompiles.StatefulPrecompiledContract{ - cronosprecompiles.NewRelayerContract(ctx, app.IBCKeeper, stateDB.(precompiles.ExtStateDB)), + cronosprecompiles.NewRelayerContract(app.IBCKeeper, appCodec), } }, keys, diff --git a/x/cronos/keeper/precompiles/relayer.go b/x/cronos/keeper/precompiles/relayer.go index acb7ab5b52..7c50aafcfc 100644 --- a/x/cronos/keeper/precompiles/relayer.go +++ b/x/cronos/keeper/precompiles/relayer.go @@ -9,6 +9,7 @@ import ( "math/big" "strings" + "github.com/cosmos/cosmos-sdk/codec" "github.com/crypto-org-chain/cronos/v2/bindings/cosmos/lib" generated "github.com/crypto-org-chain/cronos/v2/bindings/cosmos/precompile/relayer" "github.com/ethereum/go-ethereum/common" @@ -16,33 +17,29 @@ import ( "github.com/evmos/ethermint/x/evm/keeper/precompiles" "github.com/gogo/protobuf/proto" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" chantypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - tmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" ) type RelayerContract struct { BaseContract - ctx sdk.Context + cdc codec.Codec ibcKeeper *ibckeeper.Keeper - stateDB precompiles.ExtStateDB } -func NewRelayerContract(ctx sdk.Context, ibcKeeper *ibckeeper.Keeper, stateDB precompiles.ExtStateDB) precompiles.StatefulPrecompiledContract { +func NewRelayerContract(ibcKeeper *ibckeeper.Keeper, cdc codec.Codec) precompiles.StatefulPrecompiledContract { return &RelayerContract{ BaseContract: NewBaseContract( generated.RelayerModuleMetaData.ABI, common.BytesToAddress([]byte{101}), ), - ctx: ctx, ibcKeeper: ibcKeeper, - stateDB: stateDB, + cdc: cdc, } } @@ -177,111 +174,25 @@ func convertAddress(addrString string) (*common.Address, error) { return &to, nil } -func unmarshalAndExec[T MsgType, U any]( +func unmarshalAndExec[T codec.ProtoMarshaler, U any]( bc *RelayerContract, + stateDB precompiles.ExtStateDB, input []byte, msg T, - callback func(context.Context, T) (U, error), -) error { - if err := proto.Unmarshal(input, msg); err != nil { - return fmt.Errorf("fail to Unmarshal %T", msg) + action func(context.Context, T) (*U, error), +) (*U, error) { + if err := bc.cdc.Unmarshal(input, msg); err != nil { + return nil, fmt.Errorf("fail to Unmarshal %T", msg) } - switch clientMsg := any(msg).(type) { - case *clienttypes.MsgCreateClient: - clientState := new(tmtypes.ClientState) - if err := proto.Unmarshal(clientMsg.ClientState.Value, clientState); err != nil { - return errors.New("fail to Unmarshal ClientState") - } - value, err := codectypes.NewAnyWithValue(clientState) - if err != nil { - return err - } - clientMsg.ClientState = value - - consensusState := new(tmtypes.ConsensusState) - if err := proto.Unmarshal(clientMsg.ConsensusState.Value, consensusState); err != nil { - return errors.New("fail to Unmarshal ConsensusState") - } - value, err = codectypes.NewAnyWithValue(consensusState) - if err != nil { - return err - } - clientMsg.ConsensusState = value - - case *clienttypes.MsgUpgradeClient: - clientState := new(tmtypes.ClientState) - if err := proto.Unmarshal(clientMsg.ClientState.Value, clientState); err != nil { - return errors.New("fail to Unmarshal ClientState") - } - value, err := codectypes.NewAnyWithValue(clientState) - if err != nil { - return err - } - clientMsg.ClientState = value - - consensusState := new(tmtypes.ConsensusState) - if err := proto.Unmarshal(clientMsg.ConsensusState.Value, consensusState); err != nil { - return errors.New("fail to Unmarshal ConsensusState") - } - value, err = codectypes.NewAnyWithValue(consensusState) - if err != nil { - return err - } - clientMsg.ConsensusState = value - - case *conntypes.MsgConnectionOpenTry: - clientState := new(tmtypes.ClientState) - if err := proto.Unmarshal(clientMsg.ClientState.Value, clientState); err != nil { - return errors.New("fail to Unmarshal ClientState") - } - value, err := codectypes.NewAnyWithValue(clientState) - if err != nil { - return err - } - clientMsg.ClientState = value - - case *conntypes.MsgConnectionOpenAck: - clientState := new(tmtypes.ClientState) - if err := proto.Unmarshal(clientMsg.ClientState.Value, clientState); err != nil { - return errors.New("fail to Unmarshal ClientState") - } - value, err := codectypes.NewAnyWithValue(clientState) - if err != nil { - return err - } - clientMsg.ClientState = value - - case *clienttypes.MsgUpdateClient: - header := new(tmtypes.Header) - if err := proto.Unmarshal(clientMsg.ClientMessage.Value, header); err != nil { - return errors.New("fail to Unmarshal Header") - } - value, err := codectypes.NewAnyWithValue(header) - if err != nil { - return err - } - clientMsg.ClientMessage = value - - case *clienttypes.MsgSubmitMisbehaviour: - misbehaviour := new(tmtypes.Misbehaviour) - if err := proto.Unmarshal(clientMsg.Misbehaviour.Value, misbehaviour); err != nil { - return errors.New("fail to Unmarshal Misbehaviour") - } - value, err := codectypes.NewAnyWithValue(misbehaviour) - if err != nil { - return err - } - clientMsg.Misbehaviour = value - } - - return bc.stateDB.ExecuteNativeAction(func(ctx sdk.Context) error { - startEventIdx := len(ctx.EventManager().Events()) - _, err := callback(ctx, msg) + var res *U + if err := stateDB.ExecuteNativeAction(func(ctx sdk.Context) error { + var err error + res, err = action(ctx, msg) events := ctx.EventManager().Events() - if len(events) > startEventIdx { + if len(events) > 0 { f := NewFactory([]Registrable{bc}) - for _, evt := range events[startEventIdx:] { + for _, evt := range events { event := evt if event.Type == sdk.EventTypeMessage { continue @@ -294,12 +205,16 @@ func unmarshalAndExec[T MsgType, U any]( return err } if log != nil { - bc.stateDB.AddLog(log) + stateDB.AddLog(log) } } } return err - }) + }); err != nil { + return nil, err + } + + return res, nil } func (bc *RelayerContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([]byte, error) { @@ -312,40 +227,41 @@ func (bc *RelayerContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool } prefix := int(binary.LittleEndian.Uint32(contract.Input[:prefixSize4Bytes])) input := contract.Input[prefixSize4Bytes:] + stateDB := evm.StateDB.(precompiles.ExtStateDB) var err error switch prefix { case prefixCreateClient: - err = unmarshalAndExec(bc, input, new(clienttypes.MsgCreateClient), bc.ibcKeeper.CreateClient) + _, err = unmarshalAndExec(bc, stateDB, input, new(clienttypes.MsgCreateClient), bc.ibcKeeper.CreateClient) case prefixUpdateClient: - err = unmarshalAndExec(bc, input, new(clienttypes.MsgUpdateClient), bc.ibcKeeper.UpdateClient) + _, err = unmarshalAndExec(bc, stateDB, input, new(clienttypes.MsgUpdateClient), bc.ibcKeeper.UpdateClient) case prefixUpgradeClient: - err = unmarshalAndExec(bc, input, new(clienttypes.MsgUpgradeClient), bc.ibcKeeper.UpgradeClient) + _, err = unmarshalAndExec(bc, stateDB, input, new(clienttypes.MsgUpgradeClient), bc.ibcKeeper.UpgradeClient) case prefixSubmitMisbehaviour: - err = unmarshalAndExec(bc, input, new(clienttypes.MsgSubmitMisbehaviour), bc.ibcKeeper.SubmitMisbehaviour) + _, err = unmarshalAndExec(bc, stateDB, input, new(clienttypes.MsgSubmitMisbehaviour), bc.ibcKeeper.SubmitMisbehaviour) case prefixConnectionOpenInit: - err = unmarshalAndExec(bc, input, new(conntypes.MsgConnectionOpenInit), bc.ibcKeeper.ConnectionOpenInit) + _, err = unmarshalAndExec(bc, stateDB, input, new(conntypes.MsgConnectionOpenInit), bc.ibcKeeper.ConnectionOpenInit) case prefixConnectionOpenTry: - err = unmarshalAndExec(bc, input, new(conntypes.MsgConnectionOpenTry), bc.ibcKeeper.ConnectionOpenTry) + _, err = unmarshalAndExec(bc, stateDB, input, new(conntypes.MsgConnectionOpenTry), bc.ibcKeeper.ConnectionOpenTry) case prefixConnectionOpenAck: - err = unmarshalAndExec(bc, input, new(conntypes.MsgConnectionOpenAck), bc.ibcKeeper.ConnectionOpenAck) + _, err = unmarshalAndExec(bc, stateDB, input, new(conntypes.MsgConnectionOpenAck), bc.ibcKeeper.ConnectionOpenAck) case prefixConnectionOpenConfirm: - err = unmarshalAndExec(bc, input, new(conntypes.MsgConnectionOpenConfirm), bc.ibcKeeper.ConnectionOpenConfirm) + _, err = unmarshalAndExec(bc, stateDB, input, new(conntypes.MsgConnectionOpenConfirm), bc.ibcKeeper.ConnectionOpenConfirm) case prefixChannelOpenInit: - err = unmarshalAndExec(bc, input, new(chantypes.MsgChannelOpenInit), bc.ibcKeeper.ChannelOpenInit) + _, err = unmarshalAndExec(bc, stateDB, input, new(chantypes.MsgChannelOpenInit), bc.ibcKeeper.ChannelOpenInit) case prefixChannelOpenTry: - err = unmarshalAndExec(bc, input, new(chantypes.MsgChannelOpenTry), bc.ibcKeeper.ChannelOpenTry) + _, err = unmarshalAndExec(bc, stateDB, input, new(chantypes.MsgChannelOpenTry), bc.ibcKeeper.ChannelOpenTry) case prefixChannelOpenAck: - err = unmarshalAndExec(bc, input, new(chantypes.MsgChannelOpenAck), bc.ibcKeeper.ChannelOpenAck) + _, err = unmarshalAndExec(bc, stateDB, input, new(chantypes.MsgChannelOpenAck), bc.ibcKeeper.ChannelOpenAck) case prefixChannelOpenConfirm: - err = unmarshalAndExec(bc, input, new(chantypes.MsgChannelOpenConfirm), bc.ibcKeeper.ChannelOpenConfirm) + _, err = unmarshalAndExec(bc, stateDB, input, new(chantypes.MsgChannelOpenConfirm), bc.ibcKeeper.ChannelOpenConfirm) case prefixRecvPacket: - err = unmarshalAndExec(bc, input, new(chantypes.MsgRecvPacket), bc.ibcKeeper.RecvPacket) + _, err = unmarshalAndExec(bc, stateDB, input, new(chantypes.MsgRecvPacket), bc.ibcKeeper.RecvPacket) case prefixAcknowledgement: - err = unmarshalAndExec(bc, input, new(chantypes.MsgAcknowledgement), bc.ibcKeeper.Acknowledgement) + _, err = unmarshalAndExec(bc, stateDB, input, new(chantypes.MsgAcknowledgement), bc.ibcKeeper.Acknowledgement) case prefixTimeout: - err = unmarshalAndExec(bc, input, new(chantypes.MsgTimeout), bc.ibcKeeper.Timeout) + _, err = unmarshalAndExec(bc, stateDB, input, new(chantypes.MsgTimeout), bc.ibcKeeper.Timeout) case prefixTimeoutOnClose: - err = unmarshalAndExec(bc, input, new(chantypes.MsgTimeoutOnClose), bc.ibcKeeper.TimeoutOnClose) + _, err = unmarshalAndExec(bc, stateDB, input, new(chantypes.MsgTimeoutOnClose), bc.ibcKeeper.TimeoutOnClose) default: return nil, errors.New("unknown method") }