-
Notifications
You must be signed in to change notification settings - Fork 201
/
msg_server.go
127 lines (102 loc) · 3.5 KB
/
msg_server.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
package keeper
import (
"context"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/NibiruChain/collections"
"github.com/NibiruChain/nibiru/x/common/set"
sudotypes "github.com/NibiruChain/nibiru/x/sudo/types"
)
type MsgServer struct {
keeper Keeper
}
func NewMsgServer(keeper Keeper) *MsgServer {
return &MsgServer{keeper: keeper}
}
// Ensure the interface is properly implemented at compile time
var _ sudotypes.MsgServer = MsgServer{}
// EditSudoers adds or removes sudo contracts from state.
func (m MsgServer) EditSudoers(
goCtx context.Context, msg *sudotypes.MsgEditSudoers,
) (*sudotypes.MsgEditSudoersResponse, error) {
switch msg.RootAction() {
case sudotypes.AddContracts:
return m.keeper.AddContracts(goCtx, msg)
case sudotypes.RemoveContracts:
return m.keeper.RemoveContracts(goCtx, msg)
default:
return nil, fmt.Errorf("invalid action type specified on msg: %s", msg)
}
}
func (m MsgServer) ChangeRoot(ctx context.Context, msg *sudotypes.MsgChangeRoot) (*sudotypes.MsgChangeRootResponse, error) {
sdkContext := sdk.UnwrapSDKContext(ctx)
pbSudoers, err := m.keeper.Sudoers.Get(sdkContext)
if err != nil {
return nil, fmt.Errorf("failed to get sudoers: %w", err)
}
err = m.validateRootPermissions(pbSudoers, msg)
if err != nil {
return nil, err
}
pbSudoers.Root = msg.NewRoot
m.keeper.Sudoers.Set(sdkContext, pbSudoers)
return &sudotypes.MsgChangeRootResponse{}, nil
}
func (m MsgServer) validateRootPermissions(pbSudoers sudotypes.Sudoers, msg *sudotypes.MsgChangeRoot) error {
root, err := sdk.AccAddressFromBech32(pbSudoers.Root)
if err != nil {
return fmt.Errorf("failed to parse root address: %w", err)
}
sender, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return fmt.Errorf("failed to parse sender address: %w", err)
}
if !root.Equals(sender) {
return sudotypes.ErrUnauthorized
}
return nil
}
// ————————————————————————————————————————————————————————————————————————————
// Encoder for the Sudoers type
// ————————————————————————————————————————————————————————————————————————————
func SudoersValueEncoder(cdc codec.BinaryCodec) collections.ValueEncoder[sudotypes.Sudoers] {
return collections.ProtoValueEncoder[sudotypes.Sudoers](cdc)
}
type Sudoers struct {
Root string `json:"root"`
Contracts set.Set[string] `json:"contracts"`
}
func (sudo Sudoers) String() string {
return sudo.ToPb().String()
}
func (sudo Sudoers) ToPb() sudotypes.Sudoers {
return sudotypes.Sudoers{
Root: sudo.Root,
Contracts: sudo.Contracts.ToSlice(),
}
}
func SudoersFromPb(pbSudoers sudotypes.Sudoers) Sudoers {
return Sudoers{
Root: pbSudoers.Root,
Contracts: set.New[string](pbSudoers.Contracts...),
}
}
// AddContracts adds contract addresses to the sudoer set.
func (sudo *Sudoers) AddContracts(
contracts []string,
) (out set.Set[string], err error) {
for _, contractStr := range contracts {
contract, err := sdk.AccAddressFromBech32(contractStr)
if err != nil {
return out, err
}
sudo.Contracts.Add(contract.String())
}
return sudo.Contracts, err
}
func (sudo *Sudoers) RemoveContracts(contracts []string) {
for _, contract := range contracts {
sudo.Contracts.Remove(contract)
}
}