2018-03-28 21:40:06 -07:00
|
|
|
package simplestake
|
2018-03-21 15:21:46 -07:00
|
|
|
|
|
|
|
import (
|
2018-06-28 17:54:47 -07:00
|
|
|
"github.com/tendermint/tendermint/crypto"
|
2018-03-21 15:21:46 -07:00
|
|
|
|
2018-09-13 11:17:32 -07:00
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
2018-03-21 15:21:46 -07:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
|
|
|
)
|
|
|
|
|
|
|
|
const stakingToken = "steak"
|
|
|
|
|
2018-03-28 21:33:45 -07:00
|
|
|
const moduleName = "simplestake"
|
|
|
|
|
2018-04-18 21:49:24 -07:00
|
|
|
// simple stake keeper
|
2018-03-21 15:21:46 -07:00
|
|
|
type Keeper struct {
|
2018-04-18 21:49:24 -07:00
|
|
|
ck bank.Keeper
|
2018-03-21 15:21:46 -07:00
|
|
|
|
2018-04-17 19:16:21 -07:00
|
|
|
key sdk.StoreKey
|
2018-09-13 11:17:32 -07:00
|
|
|
cdc *codec.Codec
|
2018-04-17 19:16:21 -07:00
|
|
|
codespace sdk.CodespaceType
|
2018-03-21 15:21:46 -07:00
|
|
|
}
|
|
|
|
|
2018-09-07 22:34:32 -07:00
|
|
|
func NewKeeper(key sdk.StoreKey, bankKeeper bank.Keeper, codespace sdk.CodespaceType) Keeper {
|
2018-09-13 11:17:32 -07:00
|
|
|
cdc := codec.New()
|
|
|
|
codec.RegisterCrypto(cdc)
|
2018-03-21 15:21:46 -07:00
|
|
|
return Keeper{
|
2018-04-17 19:16:21 -07:00
|
|
|
key: key,
|
|
|
|
cdc: cdc,
|
2018-09-07 22:34:32 -07:00
|
|
|
ck: bankKeeper,
|
2018-04-17 19:16:21 -07:00
|
|
|
codespace: codespace,
|
2018-03-21 15:21:46 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-06 00:06:53 -07:00
|
|
|
func (k Keeper) getBondInfo(ctx sdk.Context, addr sdk.AccAddress) bondInfo {
|
2018-03-21 15:21:46 -07:00
|
|
|
store := ctx.KVStore(k.key)
|
|
|
|
bz := store.Get(addr)
|
|
|
|
if bz == nil {
|
|
|
|
return bondInfo{}
|
|
|
|
}
|
|
|
|
var bi bondInfo
|
|
|
|
err := k.cdc.UnmarshalBinary(bz, &bi)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return bi
|
|
|
|
}
|
|
|
|
|
2018-07-06 00:06:53 -07:00
|
|
|
func (k Keeper) setBondInfo(ctx sdk.Context, addr sdk.AccAddress, bi bondInfo) {
|
2018-03-21 15:21:46 -07:00
|
|
|
store := ctx.KVStore(k.key)
|
|
|
|
bz, err := k.cdc.MarshalBinary(bi)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
store.Set(addr, bz)
|
|
|
|
}
|
|
|
|
|
2018-07-06 00:06:53 -07:00
|
|
|
func (k Keeper) deleteBondInfo(ctx sdk.Context, addr sdk.AccAddress) {
|
2018-03-21 15:21:46 -07:00
|
|
|
store := ctx.KVStore(k.key)
|
|
|
|
store.Delete(addr)
|
|
|
|
}
|
|
|
|
|
2018-04-18 21:49:24 -07:00
|
|
|
// register a bond with the keeper
|
2018-07-06 00:06:53 -07:00
|
|
|
func (k Keeper) Bond(ctx sdk.Context, addr sdk.AccAddress, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) {
|
2018-03-21 15:21:46 -07:00
|
|
|
if stake.Denom != stakingToken {
|
2018-04-17 19:16:21 -07:00
|
|
|
return 0, ErrIncorrectStakingToken(k.codespace)
|
2018-03-21 15:21:46 -07:00
|
|
|
}
|
|
|
|
|
2018-04-26 07:14:51 -07:00
|
|
|
_, _, err := k.ck.SubtractCoins(ctx, addr, []sdk.Coin{stake})
|
2018-03-21 15:21:46 -07:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
bi := k.getBondInfo(ctx, addr)
|
|
|
|
if bi.isEmpty() {
|
|
|
|
bi = bondInfo{
|
|
|
|
PubKey: pubKey,
|
|
|
|
Power: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-15 14:16:45 -07:00
|
|
|
bi.Power = bi.Power + stake.Amount.Int64()
|
2018-03-21 15:21:46 -07:00
|
|
|
|
|
|
|
k.setBondInfo(ctx, addr, bi)
|
|
|
|
return bi.Power, nil
|
|
|
|
}
|
|
|
|
|
2018-04-18 21:49:24 -07:00
|
|
|
// register an unbond with the keeper
|
2018-07-06 00:06:53 -07:00
|
|
|
func (k Keeper) Unbond(ctx sdk.Context, addr sdk.AccAddress) (crypto.PubKey, int64, sdk.Error) {
|
2018-03-21 15:21:46 -07:00
|
|
|
bi := k.getBondInfo(ctx, addr)
|
|
|
|
if bi.isEmpty() {
|
2018-04-17 19:16:21 -07:00
|
|
|
return nil, 0, ErrInvalidUnbond(k.codespace)
|
2018-03-21 15:21:46 -07:00
|
|
|
}
|
|
|
|
k.deleteBondInfo(ctx, addr)
|
2018-03-24 16:27:23 -07:00
|
|
|
|
2018-07-30 17:09:50 -07:00
|
|
|
returnedBond := sdk.NewInt64Coin(stakingToken, bi.Power)
|
2018-03-24 16:27:23 -07:00
|
|
|
|
2018-04-26 07:14:51 -07:00
|
|
|
_, _, err := k.ck.AddCoins(ctx, addr, []sdk.Coin{returnedBond})
|
2018-03-24 16:27:23 -07:00
|
|
|
if err != nil {
|
|
|
|
return bi.PubKey, bi.Power, err
|
|
|
|
}
|
|
|
|
|
2018-03-21 15:21:46 -07:00
|
|
|
return bi.PubKey, bi.Power, nil
|
|
|
|
}
|
2018-03-24 17:12:44 -07:00
|
|
|
|
|
|
|
// FOR TESTING PURPOSES -------------------------------------------------
|
|
|
|
|
2018-07-06 00:06:53 -07:00
|
|
|
func (k Keeper) bondWithoutCoins(ctx sdk.Context, addr sdk.AccAddress, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) {
|
2018-03-24 17:12:44 -07:00
|
|
|
if stake.Denom != stakingToken {
|
2018-04-17 19:16:21 -07:00
|
|
|
return 0, ErrIncorrectStakingToken(k.codespace)
|
2018-03-24 17:12:44 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
bi := k.getBondInfo(ctx, addr)
|
|
|
|
if bi.isEmpty() {
|
|
|
|
bi = bondInfo{
|
|
|
|
PubKey: pubKey,
|
|
|
|
Power: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-15 14:16:45 -07:00
|
|
|
bi.Power = bi.Power + stake.Amount.Int64()
|
2018-03-24 17:12:44 -07:00
|
|
|
|
|
|
|
k.setBondInfo(ctx, addr, bi)
|
|
|
|
return bi.Power, nil
|
|
|
|
}
|
|
|
|
|
2018-07-06 00:06:53 -07:00
|
|
|
func (k Keeper) unbondWithoutCoins(ctx sdk.Context, addr sdk.AccAddress) (crypto.PubKey, int64, sdk.Error) {
|
2018-03-24 17:12:44 -07:00
|
|
|
bi := k.getBondInfo(ctx, addr)
|
|
|
|
if bi.isEmpty() {
|
2018-04-17 19:16:21 -07:00
|
|
|
return nil, 0, ErrInvalidUnbond(k.codespace)
|
2018-03-24 17:12:44 -07:00
|
|
|
}
|
|
|
|
k.deleteBondInfo(ctx, addr)
|
|
|
|
|
|
|
|
return bi.PubKey, bi.Power, nil
|
|
|
|
}
|