/
msg_set_reward.go
122 lines (110 loc) · 3.59 KB
/
msg_set_reward.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
package keeper
import (
"context"
sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
ignterrors "github.com/ignite/modules/pkg/errors"
launchtypes "github.com/tendermint/spn/x/launch/types"
"github.com/tendermint/spn/x/reward/types"
)
func (k msgServer) SetRewards(goCtx context.Context, msg *types.MsgSetRewards) (*types.MsgSetRewardsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// determine if the chain exists
chain, chainFound := k.launchKeeper.GetChain(ctx, msg.LaunchID)
if !chainFound {
return nil, sdkerrors.Wrapf(launchtypes.ErrChainNotFound, "%d", msg.LaunchID)
}
// check coordinator
coordID, err := k.profileKeeper.CoordinatorIDFromAddress(ctx, msg.Provider)
if err != nil {
return nil, err
}
if chain.CoordinatorID != coordID {
return nil, sdkerrors.Wrapf(types.ErrInvalidCoordinatorID, "%d", coordID)
}
// reward can't be changed once launch is triggered
if chain.LaunchTriggered {
return nil, sdkerrors.Wrapf(launchtypes.ErrTriggeredLaunch, "%d", msg.LaunchID)
}
provider, err := sdk.AccAddressFromBech32(msg.Provider)
if err != nil {
return nil, ignterrors.Criticalf("can't parse provider address %s", err.Error())
}
var (
previousCoins sdk.Coins
previousLastRewardHeight int64
)
rewardPool, poolFound := k.GetRewardPool(ctx, msg.LaunchID)
if !poolFound {
// create the reward pool and transfer tokens if not created yet
if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, provider, types.ModuleName, msg.Coins); err != nil {
return nil, sdkerrors.Wrap(types.ErrInsufficientFunds, err.Error())
}
rewardPool = types.NewRewardPool(msg.LaunchID, 0)
} else {
previousCoins = rewardPool.RemainingCoins
previousLastRewardHeight = rewardPool.LastRewardHeight
if err := SetBalance(ctx, k.bankKeeper, provider, msg.Coins, rewardPool.RemainingCoins); err != nil {
return nil, err
}
}
if msg.Coins.Empty() || msg.LastRewardHeight == 0 {
rewardPool.InitialCoins = sdk.NewCoins()
rewardPool.RemainingCoins = sdk.NewCoins()
rewardPool.LastRewardHeight = 0
k.RemoveRewardPool(ctx, msg.LaunchID)
err = ctx.EventManager().EmitTypedEvent(&types.EventRewardPoolRemoved{LaunchID: msg.LaunchID})
} else {
rewardPool.InitialCoins = msg.Coins
rewardPool.RemainingCoins = msg.Coins
rewardPool.Provider = msg.Provider
rewardPool.LastRewardHeight = msg.LastRewardHeight
k.SetRewardPool(ctx, rewardPool)
if !poolFound {
err = ctx.EventManager().EmitTypedEvent(&types.EventRewardPoolCreated{
LaunchID: rewardPool.LaunchID,
Provider: rewardPool.Provider,
})
}
}
return &types.MsgSetRewardsResponse{
PreviousCoins: previousCoins,
PreviousLastRewardHeight: previousLastRewardHeight,
NewCoins: rewardPool.InitialCoins,
NewLastRewardHeight: rewardPool.LastRewardHeight,
}, err
}
// SetBalance set balance to Coins on the module account
// calling the transfer depending on the balance difference
func SetBalance(
ctx sdk.Context,
bankKeeper types.BankKeeper,
provider sdk.AccAddress,
coins sdk.Coins,
poolCoins sdk.Coins,
) error {
if coins.DenomsSubsetOf(poolCoins) && coins.IsEqual(poolCoins) {
return nil
}
if poolCoins != nil && !poolCoins.IsZero() {
if err := bankKeeper.SendCoinsFromModuleToAccount(
ctx,
types.ModuleName,
provider,
poolCoins,
); err != nil {
return ignterrors.Critical(err.Error())
}
}
if coins != nil && !coins.IsZero() {
if err := bankKeeper.SendCoinsFromAccountToModule(
ctx,
provider,
types.ModuleName,
coins,
); err != nil {
return sdkerrors.Wrap(types.ErrInsufficientFunds, err.Error())
}
}
return nil
}