forked from osmosis-labs/osmosis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sendblock.go
83 lines (71 loc) · 2.15 KB
/
sendblock.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
package ante
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/spf13/cast"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
)
type SendBlockOptions struct {
PermittedOnlySendTo map[string]string
}
func NewSendBlockOptions(appOpts servertypes.AppOptions) SendBlockOptions {
return SendBlockOptions{
PermittedOnlySendTo: parsePermittedOnlySendTo(appOpts),
}
}
func parsePermittedOnlySendTo(opts servertypes.AppOptions) map[string]string {
valueInterface := opts.Get("permitted-only-send-to")
if valueInterface == nil {
return make(map[string]string)
}
return cast.ToStringMapString(valueInterface) // equal with viper.GetStringMapString
}
type SendBlockDecorator struct {
Options SendBlockOptions
}
func NewSendBlockDecorator(options SendBlockOptions) *SendBlockDecorator {
return &SendBlockDecorator{
Options: options, // TODO: hydrate from configuration
}
}
func (decorator *SendBlockDecorator) AnteHandle(
ctx sdk.Context,
tx sdk.Tx,
simulate bool,
next sdk.AnteHandler,
) (newCtx sdk.Context, err error) {
if ctx.IsReCheckTx() {
return next(ctx, tx, simulate)
}
if ctx.IsCheckTx() && !simulate {
if err := decorator.CheckIfBlocked(tx.GetMsgs()); err != nil {
return ctx, err
}
}
return next(ctx, tx, simulate)
}
// CheckIfBlocked returns error if following are true:
// 1. decorator.permittedOnlySendTo has msg.GetSigners() has its key, and
// 2-1. msg is not a SendMsg, or
// 2-2. msg is SendMsg and the destination is not decorator.permittedOnlySendTo[msg.Sender]
func (decorator *SendBlockDecorator) CheckIfBlocked(msgs []sdk.Msg) error {
if len(decorator.Options.PermittedOnlySendTo) == 0 {
return nil
}
for _, msg := range msgs {
signers := msg.GetSigners()
for _, signer := range signers {
if permittedTo, ok := decorator.Options.PermittedOnlySendTo[signer.String()]; ok {
sendmsg, ok := msg.(*bank.MsgSend)
if !ok {
return fmt.Errorf("signer is not allowed to send transactions: %s", signer)
}
if sendmsg.ToAddress != permittedTo {
return fmt.Errorf("signer is not allowed to send tokens: %s", signer)
}
}
}
}
return nil
}