This repository has been archived by the owner on Nov 28, 2023. It is now read-only.
/
keeper.go
123 lines (106 loc) · 3.59 KB
/
keeper.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
package keeper
import (
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/modules/incubator/faucet/internal/types"
"github.com/tendermint/tendermint/libs/log"
"time"
)
const FaucetStoreKey = "DefaultFaucetStoreKey"
// Keeper maintains the link to storage and exposes getter/setter methods for the various parts of the state machine
type Keeper struct {
SupplyKeeper types.SupplyKeeper
StakingKeeper types.StakingKeeper
amount int64 // set default amount for each mint.
Limit time.Duration // rate limiting for mint, etc 24 * time.Hours
storeKey sdk.StoreKey // Unexposed key to access store from sdk.Context
cdc *codec.Codec // The wire codec for binary encoding/decoding.
}
// NewKeeper creates new instances of the Faucet Keeper
func NewKeeper(
supplyKeeper types.SupplyKeeper,
stakingKeeper types.StakingKeeper,
amount int64,
rateLimit time.Duration,
storeKey sdk.StoreKey,
cdc *codec.Codec) Keeper {
return Keeper{
SupplyKeeper: supplyKeeper,
StakingKeeper: stakingKeeper,
amount: amount,
Limit: rateLimit,
storeKey: storeKey,
cdc: cdc,
}
}
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
}
// MintAndSend mint coins and send to minter.
func (k Keeper) MintAndSend(ctx sdk.Context, minter sdk.AccAddress, mintTime int64) error {
mining := k.getMining(ctx, minter)
// refuse mint in 24 hours
if k.isPresent(ctx, minter) &&
time.Unix(mining.LastTime, 0).Add(k.Limit).UTC().After(time.Unix(mintTime, 0)) {
return types.ErrWithdrawTooOften
}
denom := k.StakingKeeper.BondDenom(ctx)
newCoin := sdk.NewCoin(denom, sdk.NewInt(k.amount))
mining.Total = mining.Total.Add(newCoin)
mining.LastTime = mintTime
k.setMining(ctx, minter, mining)
k.Logger(ctx).Info("Mint coin: %s", newCoin)
err := k.SupplyKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(newCoin))
if err != nil {
return err
}
err = k.SupplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, minter, sdk.NewCoins(newCoin))
if err != nil {
return err
}
return nil
}
func (k Keeper) getMining(ctx sdk.Context, minter sdk.AccAddress) types.Mining {
store := ctx.KVStore(k.storeKey)
if !k.isPresent(ctx, minter) {
denom := k.StakingKeeper.BondDenom(ctx)
return types.NewMining(minter, sdk.NewCoin(denom, sdk.NewInt(0)))
}
bz := store.Get(minter.Bytes())
var mining types.Mining
k.cdc.MustUnmarshalBinaryBare(bz, &mining)
return mining
}
func (k Keeper) setMining(ctx sdk.Context, minter sdk.AccAddress, mining types.Mining) {
if mining.Minter.Empty() {
return
}
if !mining.Total.IsPositive() {
return
}
store := ctx.KVStore(k.storeKey)
store.Set(minter.Bytes(), k.cdc.MustMarshalBinaryBare(mining))
}
// IsPresent check if the name is present in the store or not
func (k Keeper) isPresent(ctx sdk.Context, minter sdk.AccAddress) bool {
store := ctx.KVStore(k.storeKey)
return store.Has(minter.Bytes())
}
func (k Keeper) GetFaucetKey(ctx sdk.Context) types.FaucetKey {
store := ctx.KVStore(k.storeKey)
bz := store.Get([]byte(FaucetStoreKey))
var faucet types.FaucetKey
k.cdc.MustUnmarshalBinaryBare(bz, &faucet)
return faucet
}
func (k Keeper) SetFaucetKey(ctx sdk.Context, armor string) {
store := ctx.KVStore(k.storeKey)
faucet := types.NewFaucetKey(armor)
store.Set([]byte(FaucetStoreKey), k.cdc.MustMarshalBinaryBare(faucet))
}
func (k Keeper) HasFaucetKey(ctx sdk.Context) bool {
store := ctx.KVStore(k.storeKey)
return store.Has([]byte(FaucetStoreKey))
}