cleanup, move simplestaking to democoin

This commit is contained in:
rigelrozanski
2018-04-26 22:59:30 -04:00
parent 2021ee1c77
commit 260ab69e4f
23 changed files with 155 additions and 181 deletions
+12
View File
@@ -0,0 +1,12 @@
package auth
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
)
// Register concrete types on wire codec for default AppAccount
func RegisterWire(cdc *wire.Codec) {
cdc.RegisterInterface((*sdk.Account)(nil), nil)
cdc.RegisterConcrete(&BaseAccount{}, "auth/Account", nil)
}
-96
View File
@@ -1,96 +0,0 @@
package cli
import (
"encoding/hex"
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
crypto "github.com/tendermint/go-crypto"
"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/cosmos/cosmos-sdk/x/simplestake"
)
const (
flagStake = "stake"
flagValidator = "validator"
)
// simple bond tx
func BondTxCmd(cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "bond",
Short: "Bond to a validator",
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.NewCoreContextFromViper()
from, err := ctx.GetFromAddress()
if err != nil {
return err
}
stakeString := viper.GetString(flagStake)
if len(stakeString) == 0 {
return fmt.Errorf("specify coins to bond with --stake")
}
valString := viper.GetString(flagValidator)
if len(valString) == 0 {
return fmt.Errorf("specify pubkey to bond to with --validator")
}
stake, err := sdk.ParseCoin(stakeString)
if err != nil {
return err
}
// TODO: bech32 ...
rawPubKey, err := hex.DecodeString(valString)
if err != nil {
return err
}
var pubKeyEd crypto.PubKeyEd25519
copy(pubKeyEd[:], rawPubKey)
msg := simplestake.NewMsgBond(from, stake, pubKeyEd)
return sendMsg(cdc, msg)
},
}
cmd.Flags().String(flagStake, "", "Amount of coins to stake")
cmd.Flags().String(flagValidator, "", "Validator address to stake")
return cmd
}
// simple unbond tx
func UnbondTxCmd(cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unbond",
Short: "Unbond from a validator",
RunE: func(cmd *cobra.Command, args []string) error {
from, err := context.NewCoreContextFromViper().GetFromAddress()
if err != nil {
return err
}
msg := simplestake.NewMsgUnbond(from)
return sendMsg(cdc, msg)
},
}
return cmd
}
func sendMsg(cdc *wire.Codec, msg sdk.Msg) error {
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc)
if err != nil {
return err
}
fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String())
return nil
}
-37
View File
@@ -1,37 +0,0 @@
package simplestake
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// simple stake errors reserve 300 ~ 399.
const (
DefaultCodespace sdk.CodespaceType = 4
// simplestake errors reserve 300 - 399.
CodeEmptyValidator sdk.CodeType = 300
CodeInvalidUnbond sdk.CodeType = 301
CodeEmptyStake sdk.CodeType = 302
CodeIncorrectStakingToken sdk.CodeType = 303
)
// nolint
func ErrIncorrectStakingToken(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeIncorrectStakingToken, "")
}
func ErrEmptyValidator(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeEmptyValidator, "")
}
func ErrInvalidUnbond(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeInvalidUnbond, "")
}
func ErrEmptyStake(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeEmptyStake, "")
}
// -----------------------------
// Helpers
func newError(codespace sdk.CodespaceType, code sdk.CodeType, msg string) sdk.Error {
return sdk.NewError(codespace, code, msg)
}
-55
View File
@@ -1,55 +0,0 @@
package simplestake
import (
abci "github.com/tendermint/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// NewHandler returns a handler for "simplestake" type messages.
func NewHandler(k Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
switch msg := msg.(type) {
case MsgBond:
return handleMsgBond(ctx, k, msg)
case MsgUnbond:
return handleMsgUnbond(ctx, k, msg)
default:
return sdk.ErrUnknownRequest("No match for message type.").Result()
}
}
}
func handleMsgBond(ctx sdk.Context, k Keeper, msg MsgBond) sdk.Result {
power, err := k.Bond(ctx, msg.Address, msg.PubKey, msg.Stake)
if err != nil {
return err.Result()
}
valSet := abci.Validator{
PubKey: msg.PubKey.Bytes(),
Power: power,
}
return sdk.Result{
Code: sdk.ABCICodeOK,
ValidatorUpdates: abci.Validators{valSet},
}
}
func handleMsgUnbond(ctx sdk.Context, k Keeper, msg MsgUnbond) sdk.Result {
pubKey, _, err := k.Unbond(ctx, msg.Address)
if err != nil {
return err.Result()
}
valSet := abci.Validator{
PubKey: pubKey.Bytes(),
Power: int64(0),
}
return sdk.Result{
Code: sdk.ABCICodeOK,
ValidatorUpdates: abci.Validators{valSet},
}
}
-135
View File
@@ -1,135 +0,0 @@
package simplestake
import (
crypto "github.com/tendermint/go-crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/bank"
)
const stakingToken = "steak"
const moduleName = "simplestake"
// simple stake keeper
type Keeper struct {
ck bank.Keeper
key sdk.StoreKey
cdc *wire.Codec
codespace sdk.CodespaceType
}
func NewKeeper(key sdk.StoreKey, coinKeeper bank.Keeper, codespace sdk.CodespaceType) Keeper {
cdc := wire.NewCodec()
wire.RegisterCrypto(cdc)
return Keeper{
key: key,
cdc: cdc,
ck: coinKeeper,
codespace: codespace,
}
}
func (k Keeper) getBondInfo(ctx sdk.Context, addr sdk.Address) bondInfo {
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
}
func (k Keeper) setBondInfo(ctx sdk.Context, addr sdk.Address, bi bondInfo) {
store := ctx.KVStore(k.key)
bz, err := k.cdc.MarshalBinary(bi)
if err != nil {
panic(err)
}
store.Set(addr, bz)
}
func (k Keeper) deleteBondInfo(ctx sdk.Context, addr sdk.Address) {
store := ctx.KVStore(k.key)
store.Delete(addr)
}
// register a bond with the keeper
func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) {
if stake.Denom != stakingToken {
return 0, ErrIncorrectStakingToken(k.codespace)
}
_, err := k.ck.SubtractCoins(ctx, addr, []sdk.Coin{stake})
if err != nil {
return 0, err
}
bi := k.getBondInfo(ctx, addr)
if bi.isEmpty() {
bi = bondInfo{
PubKey: pubKey,
Power: 0,
}
}
bi.Power = bi.Power + stake.Amount
k.setBondInfo(ctx, addr, bi)
return bi.Power, nil
}
// register an unbond with the keeper
func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) {
bi := k.getBondInfo(ctx, addr)
if bi.isEmpty() {
return nil, 0, ErrInvalidUnbond(k.codespace)
}
k.deleteBondInfo(ctx, addr)
returnedBond := sdk.Coin{stakingToken, bi.Power}
_, err := k.ck.AddCoins(ctx, addr, []sdk.Coin{returnedBond})
if err != nil {
return bi.PubKey, bi.Power, err
}
return bi.PubKey, bi.Power, nil
}
// FOR TESTING PURPOSES -------------------------------------------------
func (k Keeper) bondWithoutCoins(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) {
if stake.Denom != stakingToken {
return 0, ErrIncorrectStakingToken(k.codespace)
}
bi := k.getBondInfo(ctx, addr)
if bi.isEmpty() {
bi = bondInfo{
PubKey: pubKey,
Power: 0,
}
}
bi.Power = bi.Power + stake.Amount
k.setBondInfo(ctx, addr, bi)
return bi.Power, nil
}
func (k Keeper) unbondWithoutCoins(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) {
bi := k.getBondInfo(ctx, addr)
if bi.isEmpty() {
return nil, 0, ErrInvalidUnbond(k.codespace)
}
k.deleteBondInfo(ctx, addr)
return bi.PubKey, bi.Power, nil
}
-86
View File
@@ -1,86 +0,0 @@
package simplestake
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
dbm "github.com/tendermint/tmlibs/db"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
)
func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) {
db := dbm.NewMemDB()
authKey := sdk.NewKVStoreKey("authkey")
capKey := sdk.NewKVStoreKey("capkey")
ms := store.NewCommitMultiStore(db)
ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(authKey, sdk.StoreTypeIAVL, db)
ms.LoadLatestVersion()
return ms, authKey, capKey
}
func TestKeeperGetSet(t *testing.T) {
ms, _, capKey := setupMultiStore()
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
stakeKeeper := NewKeeper(capKey, bank.NewKeeper(nil), DefaultCodespace)
addr := sdk.Address([]byte("some-address"))
bi := stakeKeeper.getBondInfo(ctx, addr)
assert.Equal(t, bi, bondInfo{})
privKey := crypto.GenPrivKeyEd25519()
bi = bondInfo{
PubKey: privKey.PubKey(),
Power: int64(10),
}
fmt.Printf("Pubkey: %v\n", privKey.PubKey())
stakeKeeper.setBondInfo(ctx, addr, bi)
savedBi := stakeKeeper.getBondInfo(ctx, addr)
assert.NotNil(t, savedBi)
fmt.Printf("Bond Info: %v\n", savedBi)
assert.Equal(t, int64(10), savedBi.Power)
}
func TestBonding(t *testing.T) {
ms, authKey, capKey := setupMultiStore()
cdc := wire.NewCodec()
auth.RegisterBaseAccount(cdc)
ctx := sdk.NewContext(ms, abci.Header{}, false, nil)
accountMapper := auth.NewAccountMapper(cdc, authKey, &auth.BaseAccount{})
coinKeeper := bank.NewKeeper(accountMapper)
stakeKeeper := NewKeeper(capKey, coinKeeper, DefaultCodespace)
addr := sdk.Address([]byte("some-address"))
privKey := crypto.GenPrivKeyEd25519()
pubKey := privKey.PubKey()
_, _, err := stakeKeeper.unbondWithoutCoins(ctx, addr)
assert.Equal(t, err, ErrInvalidUnbond(DefaultCodespace))
_, err = stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.Coin{"steak", 10})
assert.Nil(t, err)
power, err := stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.Coin{"steak", 10})
assert.Equal(t, int64(20), power)
pk, _, err := stakeKeeper.unbondWithoutCoins(ctx, addr)
assert.Nil(t, err)
assert.Equal(t, pubKey, pk)
_, _, err = stakeKeeper.unbondWithoutCoins(ctx, addr)
assert.Equal(t, err, ErrInvalidUnbond(DefaultCodespace))
}
-81
View File
@@ -1,81 +0,0 @@
package simplestake
import (
"encoding/json"
crypto "github.com/tendermint/go-crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
//_________________________________________________________----
// simple bond message
type MsgBond struct {
Address sdk.Address `json:"address"`
Stake sdk.Coin `json:"coins"`
PubKey crypto.PubKey `json:"pub_key"`
}
func NewMsgBond(addr sdk.Address, stake sdk.Coin, pubKey crypto.PubKey) MsgBond {
return MsgBond{
Address: addr,
Stake: stake,
PubKey: pubKey,
}
}
//nolint
func (msg MsgBond) Type() string { return moduleName } //TODO update "stake/declarecandidacy"
func (msg MsgBond) Get(key interface{}) (value interface{}) { return nil }
func (msg MsgBond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} }
// basic validation of the bond message
func (msg MsgBond) ValidateBasic() sdk.Error {
if msg.Stake.IsZero() {
return ErrEmptyStake(DefaultCodespace)
}
if msg.PubKey == nil {
return sdk.ErrInvalidPubKey("MsgBond.PubKey must not be empty")
}
return nil
}
// get bond message sign bytes
func (msg MsgBond) GetSignBytes() []byte {
bz, err := json.Marshal(msg)
if err != nil {
panic(err)
}
return bz
}
//_______________________________________________________________
// simple unbond message
type MsgUnbond struct {
Address sdk.Address `json:"address"`
}
func NewMsgUnbond(addr sdk.Address) MsgUnbond {
return MsgUnbond{
Address: addr,
}
}
//nolint
func (msg MsgUnbond) Type() string { return moduleName } //TODO update "stake/declarecandidacy"
func (msg MsgUnbond) Get(key interface{}) (value interface{}) { return nil }
func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} }
func (msg MsgUnbond) ValidateBasic() sdk.Error { return nil }
// get unbond message sign bytes
func (msg MsgUnbond) GetSignBytes() []byte {
bz, err := json.Marshal(msg)
if err != nil {
panic(err)
}
return bz
}
-31
View File
@@ -1,31 +0,0 @@
package simplestake
import (
"testing"
"github.com/stretchr/testify/assert"
crypto "github.com/tendermint/go-crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func TestBondMsgValidation(t *testing.T) {
privKey := crypto.GenPrivKeyEd25519()
cases := []struct {
valid bool
msgBond MsgBond
}{
{true, NewMsgBond(sdk.Address{}, sdk.Coin{"mycoin", 5}, privKey.PubKey())},
{false, NewMsgBond(sdk.Address{}, sdk.Coin{"mycoin", 0}, privKey.PubKey())},
}
for i, tc := range cases {
err := tc.msgBond.ValidateBasic()
if tc.valid {
assert.Nil(t, err, "%d: %+v", i, err)
} else {
assert.NotNil(t, err, "%d", i)
}
}
}
-15
View File
@@ -1,15 +0,0 @@
package simplestake
import crypto "github.com/tendermint/go-crypto"
type bondInfo struct {
PubKey crypto.PubKey
Power int64
}
func (bi bondInfo) isEmpty() bool {
if bi == (bondInfo{}) {
return true
}
return false
}
+9
View File
@@ -0,0 +1,9 @@
package stake
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
func FeeHandler(ctx sdk.Context, tx sdk.Tx, fee sdk.Coins) {
}