/
msg_send_request.go
94 lines (78 loc) · 2.59 KB
/
msg_send_request.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
package keeper
import (
"context"
sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
ignterrors "github.com/ignite/modules/pkg/errors"
"github.com/tendermint/spn/x/launch/types"
profiletypes "github.com/tendermint/spn/x/profile/types"
)
func (k msgServer) SendRequest(
goCtx context.Context,
msg *types.MsgSendRequest,
) (*types.MsgSendRequestResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
chain, found := k.GetChain(ctx, msg.LaunchID)
if !found {
return nil, sdkerrors.Wrapf(types.ErrChainNotFound, "%d", msg.LaunchID)
}
// check if request is valid for mainnet
err := msg.Content.IsValidForMainnet()
if err != nil && chain.IsMainnet {
return nil, sdkerrors.Wrap(types.ErrInvalidRequestForMainnet, err.Error())
}
// no request can be sent if the launch of the chain is triggered
if chain.LaunchTriggered {
return nil, sdkerrors.Wrapf(types.ErrTriggeredLaunch, "%d", msg.LaunchID)
}
coord, found := k.profileKeeper.GetCoordinator(ctx, chain.CoordinatorID)
if !found {
return nil, sdkerrors.Wrapf(types.ErrChainInactive,
"the chain %d coordinator not found", chain.LaunchID)
}
// only chain with active coordinator can receive a request
if !coord.Active {
return nil, sdkerrors.Wrapf(profiletypes.ErrCoordInactive,
"the chain %d coordinator is inactive", chain.LaunchID)
}
// create the request from the content
request := types.Request{
LaunchID: msg.LaunchID,
Creator: msg.Creator,
CreatedAt: ctx.BlockTime().Unix(),
Content: msg.Content,
Status: types.Request_PENDING,
}
var requestID uint64
approved := false
if msg.Creator == coord.Address {
err := ApplyRequest(ctx, k.Keeper, chain, request, coord)
if err != nil {
return nil, sdkerrors.Wrap(types.ErrRequestApplicationFailure, err.Error())
}
approved = true
request.Status = types.Request_APPROVED
}
// deduct request fee if set
requestFee := k.RequestFee(ctx)
if !requestFee.Empty() {
sender, err := sdk.AccAddressFromBech32(msg.Creator)
if err != nil {
return nil, ignterrors.Criticalf("invalid sender bech32 address %s", err.Error())
}
if err = k.distrKeeper.FundCommunityPool(ctx, requestFee, sender); err != nil {
return nil, sdkerrors.Wrap(types.ErrFundCommunityPool, err.Error())
}
}
requestID = k.AppendRequest(ctx, request)
err = ctx.EventManager().EmitTypedEvent(&types.EventRequestCreated{
Creator: msg.Creator,
Request: request,
})
// call request created hook
k.RequestCreated(ctx, msg.Creator, msg.LaunchID, requestID, msg.Content)
return &types.MsgSendRequestResponse{
RequestID: requestID,
AutoApproved: approved,
}, err
}