-
Notifications
You must be signed in to change notification settings - Fork 20
/
ante_handler.go
131 lines (113 loc) · 3.9 KB
/
ante_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package app
import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/authz"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
channelkeeper "github.com/cosmos/ibc-go/v2/modules/core/04-channel/keeper"
ibcante "github.com/cosmos/ibc-go/v2/modules/core/ante"
)
// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC
// channel keeper.
type HandlerOptions struct {
ante.HandlerOptions
IBCChannelkeeper channelkeeper.Keeper
Cdc codec.BinaryCodec
}
type MinCommissionDecorator struct {
cdc codec.BinaryCodec
}
func NewMinCommissionDecorator(cdc codec.BinaryCodec) MinCommissionDecorator {
return MinCommissionDecorator{cdc}
}
func (min MinCommissionDecorator) AnteHandle(
ctx sdk.Context, tx sdk.Tx,
simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
msgs := tx.GetMsgs()
minCommissionRate := sdk.NewDecWithPrec(5, 2)
validMsg := func(m sdk.Msg) error {
switch msg := m.(type) {
case *stakingtypes.MsgCreateValidator:
// prevent new validators joining the set with
// commission set below 5%
c := msg.Commission
if c.Rate.LT(minCommissionRate) {
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%")
}
case *stakingtypes.MsgEditValidator:
// if commission rate is nil, it means only
// other fields are affected - skip
if msg.CommissionRate == nil {
break
}
if msg.CommissionRate.LT(minCommissionRate) {
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "commission can't be lower than 5%")
}
}
return nil
}
validAuthz := func(execMsg *authz.MsgExec) error {
for _, v := range execMsg.Msgs {
var innerMsg sdk.Msg
err := min.cdc.UnpackAny(v, &innerMsg)
if err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "cannot unmarshal authz exec msgs")
}
err = validMsg(innerMsg)
if err != nil {
return err
}
}
return nil
}
for _, m := range msgs {
if msg, ok := m.(*authz.MsgExec); ok {
if err := validAuthz(msg); err != nil {
return ctx, err
}
continue
}
// validate normal msgs
err = validMsg(m)
if err != nil {
return ctx, err
}
}
return next(ctx, tx, simulate)
}
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
if options.AccountKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler")
}
if options.BankKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler")
}
if options.SignModeHandler == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
}
var sigGasConsumer = options.SigGasConsumer
if sigGasConsumer == nil {
sigGasConsumer = ante.DefaultSigVerificationGasConsumer
}
anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(),
NewMinCommissionDecorator(options.Cdc),
ante.NewRejectExtensionOptionsDecorator(),
ante.NewMempoolFeeDecorator(),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper),
// SetPubKeyDecorator must be called before all signature verification decorators
ante.NewSetPubKeyDecorator(options.AccountKeeper),
ante.NewValidateSigCountDecorator(options.AccountKeeper),
ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer),
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler),
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
ibcante.NewAnteDecorator(options.IBCChannelkeeper),
}
return sdk.ChainAnteDecorators(anteDecorators...), nil
}