diff --git a/app/ante/ante.go b/app/ante/ante.go new file mode 100644 index 000000000..130dbfe1c --- /dev/null +++ b/app/ante/ante.go @@ -0,0 +1,38 @@ +package ante + +import ( + ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + + "github.com/cosmos/cosmos-sdk/codec" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + sdk "github.com/cosmos/cosmos-sdk/types" + ante "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/cosmos/cosmos-sdk/x/auth/signing" +) + +// Link to default ante handler used by cosmos sdk: +// https://github.com/cosmos/cosmos-sdk/blob/v0.43.0/x/auth/ante/ante.go#L41 +func NewAnteHandler( + appOpts servertypes.AppOptions, + ak ante.AccountKeeper, + sigGasConsumer ante.SignatureVerificationGasConsumer, + signModeHandler signing.SignModeHandler, + channelKeeper *ibckeeper.Keeper, + codec codec.BinaryCodec, +) sdk.AnteHandler { + return sdk.ChainAnteDecorators( + ante.NewSetUpContextDecorator(), // // outermost AnteDecorator. SetUpContext must be called first + ante.NewValidateBasicDecorator(), + ante.NewTxTimeoutHeightDecorator(), + ante.NewValidateMemoDecorator(ak), + ante.NewConsumeGasForTxSizeDecorator(ak), + NewIBCPermissionDecorator(codec), + ante.NewSetPubKeyDecorator(ak), // SetPubKeyDecorator must be called before all signature verification decorators + ante.NewValidateSigCountDecorator(ak), + ante.NewSigGasConsumeDecorator(ak, sigGasConsumer), + ante.NewSigVerificationDecorator(ak, signModeHandler), + ante.NewIncrementSequenceDecorator(ak), + ibcante.NewRedundantRelayDecorator(channelKeeper), + ) +} diff --git a/app/ante/ibc_ante.go b/app/ante/ibc_ante.go new file mode 100644 index 000000000..c5d9e05e5 --- /dev/null +++ b/app/ante/ibc_ante.go @@ -0,0 +1,89 @@ +package ante + +import ( + "fmt" + + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/cosmos-sdk/x/authz" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" +) + +var ( + allowedRelayAddress = map[string]bool{ + "centauri1eqv3xl0vk0md74qukfghfff4z3axsp29rr9c85": true, + "centauri1av6x9sll0yx4anske424jtgxejnrgqv6j6tjjt": true, + } +) + +type IBCPermissionDecorator struct { + cdc codec.BinaryCodec +} + +func NewIBCPermissionDecorator(cdc codec.BinaryCodec) IBCPermissionDecorator { + return IBCPermissionDecorator{ + cdc: cdc, + } +} + +func (g IBCPermissionDecorator) AnteHandle( + ctx sdk.Context, tx sdk.Tx, + simulate bool, next sdk.AnteHandler, +) (newCtx sdk.Context, err error) { + // run checks only on CheckTx or simulate + if !ctx.IsCheckTx() || simulate { + return next(ctx, tx, simulate) + } + + msgs := tx.GetMsgs() + if err = g.ValidateIBCUpdateClientMsg(ctx, msgs); err != nil { + return ctx, err + } + + return next(ctx, tx, simulate) +} + +// ValidateIBCUpdateClientMsg validate +func (g IBCPermissionDecorator) ValidateIBCUpdateClientMsg(ctx sdk.Context, msgs []sdk.Msg) error { + for _, m := range msgs { + if msg, ok := m.(*authz.MsgExec); ok { + if err := g.validAuthz(msg); err != nil { + return err + } + continue + } + + // validate normal msgs + if err := g.validMsg(m); err != nil { + return err + } + } + return nil +} + +func (g IBCPermissionDecorator) validMsg(m sdk.Msg) error { + if msg, ok := m.(*clienttypes.MsgUpdateClient); ok { + if !allowedRelayAddress[msg.Signer] { + return fmt.Errorf("permission denied, address %s don't have relay permission", msg.Signer) + } + // prevent messages with insufficient initial deposit amount + } + + return nil +} + +func (g IBCPermissionDecorator) validAuthz(execMsg *authz.MsgExec) error { + for _, v := range execMsg.Msgs { + var innerMsg sdk.Msg + if err := g.cdc.UnpackAny(v, &innerMsg); err != nil { + return errorsmod.Wrap(err, "cannot unmarshal authz exec msgs") + } + if err := g.validMsg(innerMsg); err != nil { + return err + } + } + + return nil +} diff --git a/app/app.go b/app/app.go index 5bd729f73..e09002ddc 100644 --- a/app/app.go +++ b/app/app.go @@ -6,6 +6,7 @@ import ( "path/filepath" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" + authante "github.com/cosmos/cosmos-sdk/x/auth/ante" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" "github.com/cosmos/cosmos-sdk/x/consensus" porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" @@ -24,7 +25,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/ante" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -107,6 +107,7 @@ import ( alliancemodulekeeper "github.com/terra-money/alliance/x/alliance/keeper" alliancemoduletypes "github.com/terra-money/alliance/x/alliance/types" + "github.com/notional-labs/centauri/v3/app/ante" transfermiddleware "github.com/notional-labs/centauri/v3/x/transfermiddleware" transfermiddlewarekeeper "github.com/notional-labs/centauri/v3/x/transfermiddleware/keeper" transfermiddlewaretypes "github.com/notional-labs/centauri/v3/x/transfermiddleware/types" @@ -659,20 +660,14 @@ func NewCentauriApp( app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) - anteHandler, err := ante.NewAnteHandler( - ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), - FeegrantKeeper: app.FeeGrantKeeper, - SigGasConsumer: ante.DefaultSigVerificationGasConsumer, - }, - ) - if err != nil { - panic(err) - } - - app.SetAnteHandler(anteHandler) + app.SetAnteHandler(ante.NewAnteHandler( + appOpts, + app.AccountKeeper, + authante.DefaultSigVerificationGasConsumer, + encodingConfig.TxConfig.SignModeHandler(), + app.IBCKeeper, + appCodec, + )) app.SetEndBlocker(app.EndBlocker) if loadLatest {