/
msg_server.go
183 lines (139 loc) · 5.39 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package keeper
import (
"context"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/percosis-labs/percosis/v16/x/protorev/types"
)
type MsgServer struct {
k Keeper
}
// NewMsgServer returns an implementation of the MsgServer interface for the provided Keeper.
func NewMsgServer(keeper Keeper) types.MsgServer {
return MsgServer{k: keeper}
}
var _ types.MsgServer = MsgServer{}
// SetHotRoutes sets the hot routes for ProtoRev
func (m MsgServer) SetHotRoutes(c context.Context, msg *types.MsgSetHotRoutes) (*types.MsgSetHotRoutesResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
// Ensure the account has the admin role and can make the tx
if err := m.AdminCheck(ctx, msg.Admin); err != nil {
return nil, err
}
// Delete all previously set hot routes
m.k.DeleteAllTokenPairArbRoutes(ctx)
// Set the new hot routes
for _, tokenPairArbRoutes := range msg.HotRoutes {
if err := m.k.SetTokenPairArbRoutes(ctx, tokenPairArbRoutes.TokenIn, tokenPairArbRoutes.TokenOut, tokenPairArbRoutes); err != nil {
return nil, err
}
}
return &types.MsgSetHotRoutesResponse{}, nil
}
// SetDeveloperAccount sets the developer account that will receive fees
func (m MsgServer) SetDeveloperAccount(c context.Context, msg *types.MsgSetDeveloperAccount) (*types.MsgSetDeveloperAccountResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
// Ensure the account has the admin role and can make the tx
if err := m.AdminCheck(ctx, msg.Admin); err != nil {
return nil, err
}
// Set the developer account
developer, err := sdk.AccAddressFromBech32(msg.DeveloperAccount)
if err != nil {
return nil, err
}
m.k.SetDeveloperAccount(ctx, developer)
return &types.MsgSetDeveloperAccountResponse{}, nil
}
// SetMaxPoolPointsPerTx sets the maximum number of pool points that can be consumed per tx
func (m MsgServer) SetMaxPoolPointsPerTx(c context.Context, msg *types.MsgSetMaxPoolPointsPerTx) (*types.MsgSetMaxPoolPointsPerTxResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
// Ensure the account has the admin role and can make the tx
if err := m.AdminCheck(ctx, msg.Admin); err != nil {
return nil, err
}
maxPointsPerBlock, err := m.k.GetMaxPointsPerBlock(ctx)
if err != nil {
return nil, err
}
if msg.MaxPoolPointsPerTx > maxPointsPerBlock {
return nil, fmt.Errorf("max pool points per tx cannot be greater than max pool points per block")
}
// Set the max pool points per tx
if err := m.k.SetMaxPointsPerTx(ctx, msg.MaxPoolPointsPerTx); err != nil {
return nil, err
}
return &types.MsgSetMaxPoolPointsPerTxResponse{}, nil
}
// SetMaxPoolPointsPerBlock sets the maximum number of pool points that can be consumed per block
func (m MsgServer) SetMaxPoolPointsPerBlock(c context.Context, msg *types.MsgSetMaxPoolPointsPerBlock) (*types.MsgSetMaxPoolPointsPerBlockResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
// Ensure the account has the admin role and can make the tx
if err := m.AdminCheck(ctx, msg.Admin); err != nil {
return nil, err
}
maxPointsPerTx, err := m.k.GetMaxPointsPerTx(ctx)
if err != nil {
return nil, err
}
if msg.MaxPoolPointsPerBlock < maxPointsPerTx {
return nil, fmt.Errorf("max pool points per block cannot be less than max pool points per tx")
}
// Set the max pool points per block
if err := m.k.SetMaxPointsPerBlock(ctx, msg.MaxPoolPointsPerBlock); err != nil {
return nil, err
}
return &types.MsgSetMaxPoolPointsPerBlockResponse{}, nil
}
// SetPoolWeights sets the weights corresponding to each pool type. This distinction is necessary because the
// pool types have different execution times. Each weight roughly corresponds to the amount of time (in ms) it takes
// to simulate and execute a trade.
func (m MsgServer) SetPoolWeights(c context.Context, msg *types.MsgSetPoolWeights) (*types.MsgSetPoolWeightsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
// Ensure the account has the admin role and can make the tx
if err := m.AdminCheck(ctx, msg.Admin); err != nil {
return nil, err
}
m.k.SetPoolWeights(ctx, msg.PoolWeights)
return &types.MsgSetPoolWeightsResponse{}, nil
}
// SetBaseDenoms sets the base denoms that will be used to generate cyclic arbitrage routes
func (m MsgServer) SetBaseDenoms(c context.Context, msg *types.MsgSetBaseDenoms) (*types.MsgSetBaseDenomsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
// Ensure the account has the admin role and can make the tx
if err := m.AdminCheck(ctx, msg.Admin); err != nil {
return nil, err
}
// Get the old base denoms
baseDenoms, err := m.k.GetAllBaseDenoms(ctx)
if err != nil {
return nil, err
}
// Delete all pools associated with the base denoms
for _, baseDenom := range baseDenoms {
m.k.DeleteAllPoolsForBaseDenom(ctx, baseDenom.Denom)
}
// Delete the old base denoms
m.k.DeleteBaseDenoms(ctx)
if err := m.k.SetBaseDenoms(ctx, msg.BaseDenoms); err != nil {
return nil, err
}
// Update all of the pools
if err := m.k.UpdatePools(ctx); err != nil {
return nil, err
}
return &types.MsgSetBaseDenomsResponse{}, nil
}
// AdminCheck ensures that the sender is the admin account.
func (m MsgServer) AdminCheck(ctx sdk.Context, admin string) error {
sender, err := sdk.AccAddressFromBech32(admin)
if err != nil {
return err
}
adminAccount := m.k.GetAdminAccount(ctx)
// Ensure the admin and sender are the same
if !adminAccount.Equals(sender) {
return fmt.Errorf("sender account %s is not authorized. sender must be %s", sender.String(), adminAccount.String())
}
return nil
}