/
ante.go
144 lines (123 loc) · 4.43 KB
/
ante.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
132
133
134
135
136
137
138
139
140
141
142
143
144
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"
ibcante "github.com/cosmos/ibc-go/v3/modules/core/ante"
ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types"
)
// HandlerOptions extends the SDK's AnteHandler options by requiring the IBC
// channel keeper.
type HandlerOptions struct {
ante.HandlerOptions
IBCKeeper *ibckeeper.Keeper
TxCounterStoreKey sdk.StoreKey
WasmConfig wasmTypes.WasmConfig
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)
}
// NewAnteHandler returns an AnteHandler that checks and increments sequence
// numbers, checks signatures & account numbers, and deducts fees from the first
// signer.
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
if options.AccountKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for ante builder")
}
if options.BankKeeper == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for ante builder")
}
if options.SignModeHandler == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder")
}
sigGasConsumer := options.SigGasConsumer
if sigGasConsumer == nil {
sigGasConsumer = ante.DefaultSigVerificationGasConsumer
}
anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
NewMinCommissionDecorator(options.Cdc),
wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit),
wasmkeeper.NewCountTXDecorator(options.TxCounterStoreKey),
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.IBCKeeper),
}
return sdk.ChainAnteDecorators(anteDecorators...), nil
}