cosmos-sdk/examples/democoin/x/pow/keeper.go

120 lines
3.1 KiB
Go
Raw Normal View History

2018-03-24 13:41:26 -07:00
package pow
import (
"fmt"
"strconv"
sdk "github.com/cosmos/cosmos-sdk/types"
bank "github.com/cosmos/cosmos-sdk/x/bank"
)
// module users must specify coin denomination and reward (constant) per PoW solution
2018-04-18 21:49:24 -07:00
type Config struct {
2018-03-24 13:41:26 -07:00
Denomination string
Reward int64
}
2018-04-05 06:16:54 -07:00
// genesis info must specify starting difficulty and starting count
2018-04-18 21:49:24 -07:00
type Genesis struct {
2018-04-05 06:16:54 -07:00
Difficulty uint64 `json:"difficulty"`
Count uint64 `json:"count"`
2018-03-24 13:41:26 -07:00
}
2018-04-18 21:49:24 -07:00
// POW Keeper
2018-03-24 13:41:26 -07:00
type Keeper struct {
key sdk.StoreKey
2018-04-18 21:49:24 -07:00
config Config
ck bank.Keeper
codespace sdk.CodespaceType
2018-03-24 13:41:26 -07:00
}
2018-04-18 21:49:24 -07:00
func NewConfig(denomination string, reward int64) Config {
return Config{denomination, reward}
2018-04-05 06:16:54 -07:00
}
2018-04-18 21:49:24 -07:00
func NewKeeper(key sdk.StoreKey, config Config, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
return Keeper{key, config, ck, codespace}
2018-03-24 13:41:26 -07:00
}
2018-04-18 21:49:24 -07:00
// Init Genessis for the POW module
func (k Keeper) InitGenesis(ctx sdk.Context, genesis Genesis) error {
k.SetLastDifficulty(ctx, genesis.Difficulty)
k.SetLastCount(ctx, genesis.Count)
2018-04-05 06:16:54 -07:00
return nil
}
2018-03-24 13:41:26 -07:00
var lastDifficultyKey = []byte("lastDifficultyKey")
2018-04-18 21:49:24 -07:00
// get the last mining difficulty
func (k Keeper) GetLastDifficulty(ctx sdk.Context) (uint64, error) {
store := ctx.KVStore(k.key)
2018-03-24 13:41:26 -07:00
stored := store.Get(lastDifficultyKey)
if stored == nil {
2018-04-05 06:16:54 -07:00
panic("no stored difficulty")
2018-03-24 13:41:26 -07:00
} else {
return strconv.ParseUint(string(stored), 0, 64)
}
}
2018-04-18 21:49:24 -07:00
// set the last mining difficulty
func (k Keeper) SetLastDifficulty(ctx sdk.Context, diff uint64) {
store := ctx.KVStore(k.key)
2018-03-24 13:41:26 -07:00
store.Set(lastDifficultyKey, []byte(strconv.FormatUint(diff, 16)))
}
var countKey = []byte("count")
2018-04-18 21:49:24 -07:00
// get the last count
func (k Keeper) GetLastCount(ctx sdk.Context) (uint64, error) {
store := ctx.KVStore(k.key)
2018-03-24 13:41:26 -07:00
stored := store.Get(countKey)
if stored == nil {
2018-04-05 06:16:54 -07:00
panic("no stored count")
2018-03-24 13:41:26 -07:00
} else {
return strconv.ParseUint(string(stored), 0, 64)
}
}
2018-04-18 21:49:24 -07:00
// set the last count
func (k Keeper) SetLastCount(ctx sdk.Context, count uint64) {
store := ctx.KVStore(k.key)
2018-03-24 13:41:26 -07:00
store.Set(countKey, []byte(strconv.FormatUint(count, 16)))
}
2018-04-18 21:49:24 -07:00
// Is the keeper state valid?
func (k Keeper) CheckValid(ctx sdk.Context, difficulty uint64, count uint64) (uint64, uint64, sdk.Error) {
2018-03-24 13:41:26 -07:00
2018-04-18 21:49:24 -07:00
lastDifficulty, err := k.GetLastDifficulty(ctx)
2018-03-24 13:41:26 -07:00
if err != nil {
2018-04-18 21:49:24 -07:00
return 0, 0, ErrNonexistentDifficulty(k.codespace)
2018-03-24 13:41:26 -07:00
}
newDifficulty := lastDifficulty + 1
2018-04-18 21:49:24 -07:00
lastCount, err := k.GetLastCount(ctx)
2018-03-24 13:41:26 -07:00
if err != nil {
2018-04-18 21:49:24 -07:00
return 0, 0, ErrNonexistentCount(k.codespace)
2018-03-24 13:41:26 -07:00
}
newCount := lastCount + 1
if count != newCount {
2018-04-18 21:49:24 -07:00
return 0, 0, ErrInvalidCount(k.codespace, fmt.Sprintf("invalid count: was %d, should have been %d", count, newCount))
2018-03-24 13:41:26 -07:00
}
if difficulty != newDifficulty {
2018-04-18 21:49:24 -07:00
return 0, 0, ErrInvalidDifficulty(k.codespace, fmt.Sprintf("invalid difficulty: was %d, should have been %d", difficulty, newDifficulty))
2018-03-24 13:41:26 -07:00
}
return newDifficulty, newCount, nil
}
2018-04-18 21:49:24 -07:00
// Add some coins for a POW well done
func (k Keeper) ApplyValid(ctx sdk.Context, sender sdk.Address, newDifficulty uint64, newCount uint64) sdk.Error {
_, ckErr := k.ck.AddCoins(ctx, sender, []sdk.Coin{sdk.Coin{k.config.Denomination, k.config.Reward}})
2018-03-24 13:41:26 -07:00
if ckErr != nil {
return ckErr
}
2018-04-18 21:49:24 -07:00
k.SetLastDifficulty(ctx, newDifficulty)
k.SetLastCount(ctx, newCount)
2018-03-24 13:41:26 -07:00
return nil
}