-
Notifications
You must be signed in to change notification settings - Fork 16
/
msg_server_buy_storage.go
105 lines (83 loc) · 2.64 KB
/
msg_server_buy_storage.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
package keeper
import (
"context"
"fmt"
"strconv"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerr "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/jackalLabs/canine-chain/v3/x/storage/types"
)
func (k msgServer) BuyStorage(goCtx context.Context, msg *types.MsgBuyStorage) (*types.MsgBuyStorageResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
_, err := sdk.AccAddressFromBech32(msg.ForAddress)
if err != nil {
return nil, err
}
duration, err := time.ParseDuration(msg.Duration)
if err != nil {
return nil, fmt.Errorf("duration can't be parsed: %s", err.Error())
}
timeMonth := time.Hour * 24 * 30
if duration.Truncate(timeMonth) <= 0 {
return nil, fmt.Errorf("duration can't be less than 1 month")
}
bytes, err := strconv.ParseInt(msg.Bytes, 10, 64)
if err != nil {
return nil, fmt.Errorf("bytes can't be parsed: %s", err.Error())
}
denom := msg.PaymentDenom
if denom != "ujkl" {
return nil, sdkerr.Wrap(sdkerr.ErrInvalidCoins, "cannot pay with anything other than ujkl")
}
const gb int64 = 1000000000
gbs := bytes / gb
if gbs <= 0 {
return nil, fmt.Errorf("cannot buy less than a gb")
}
hours := sdk.NewDec(duration.Milliseconds()).Quo(sdk.NewDec(60 * 60 * 1000))
priceTokens := sdk.NewCoin(denom, k.GetStorageCost(ctx, gbs, hours.TruncateInt().Int64()))
add, err := sdk.AccAddressFromBech32(msg.Creator)
if err != nil {
return nil, err
}
err = k.bankkeeper.SendCoinsFromAccountToModule(ctx, add, types.ModuleName, sdk.NewCoins(priceTokens))
if err != nil {
return nil, err
}
deposit, err := sdk.AccAddressFromBech32(k.GetParams(ctx).DepositAccount)
if err != nil {
return nil, err
}
var spi types.StoragePaymentInfo
payInfo, found := k.GetStoragePaymentInfo(ctx, msg.ForAddress)
if found {
if payInfo.SpaceUsed > bytes {
return nil, fmt.Errorf("cannot buy less than your current gb usage")
}
if payInfo.End.After(ctx.BlockTime()) {
return nil, fmt.Errorf("please use MsgUpgradeStorage if you want to upgrade/downgrade")
}
spi = types.StoragePaymentInfo{
Start: ctx.BlockTime(),
End: ctx.BlockTime().Add(duration),
SpaceAvailable: bytes,
SpaceUsed: payInfo.SpaceUsed,
Address: msg.ForAddress,
}
} else {
spi = types.StoragePaymentInfo{
Start: ctx.BlockTime(),
End: ctx.BlockTime().Add(duration),
SpaceAvailable: bytes,
SpaceUsed: 0,
Address: msg.ForAddress,
}
}
k.SetStoragePaymentInfo(ctx, spi)
err = k.bankkeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, deposit, sdk.NewCoins(priceTokens))
if err != nil {
return nil, err
}
return &types.MsgBuyStorageResponse{}, nil
}