parent
59b10d33c1
commit
292e156872
55
glide.yaml
55
glide.yaml
|
@ -1,55 +0,0 @@
|
|||
package: github.com/cosmos/cosmos-sdk
|
||||
import:
|
||||
- package: github.com/golang/protobuf
|
||||
version: ^1.0.0
|
||||
subpackages:
|
||||
- proto
|
||||
- package: github.com/bgentry/speakeasy
|
||||
version: ^0.1.0
|
||||
- package: github.com/mattn/go-isatty
|
||||
version: ~0.0.3
|
||||
- package: github.com/pkg/errors
|
||||
version: ^0.8.0
|
||||
- package: github.com/rigelrozanski/common
|
||||
- package: github.com/tendermint/abci
|
||||
version: develop
|
||||
subpackages:
|
||||
- server
|
||||
- types
|
||||
- package: github.com/tendermint/go-crypto
|
||||
version: develop
|
||||
- package: github.com/tendermint/go-wire
|
||||
version: develop
|
||||
- package: github.com/tendermint/iavl
|
||||
version: develop
|
||||
- package: github.com/tendermint/tmlibs
|
||||
version: develop
|
||||
subpackages:
|
||||
- common
|
||||
- db
|
||||
- log
|
||||
- logger
|
||||
- merkle
|
||||
- package: github.com/tendermint/tendermint
|
||||
version: breaking/wire-sdk2
|
||||
subpackages:
|
||||
- cmd/tendermint/commands
|
||||
- config
|
||||
- lite
|
||||
- rpc/client
|
||||
- types
|
||||
- package: golang.org/x/crypto
|
||||
subpackages:
|
||||
- ripemd160
|
||||
- package: github.com/spf13/pflag
|
||||
version: v1.0.0
|
||||
- package: github.com/spf13/cobra
|
||||
version: v0.0.1
|
||||
- package: github.com/spf13/viper
|
||||
version: ^1.0.0
|
||||
testImport:
|
||||
- package: github.com/stretchr/testify
|
||||
version: ^1.2.1
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
|
@ -2,23 +2,11 @@ package types
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
wire "github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
var ratCdc = RegisterWire(wire.NewCodec())
|
||||
|
||||
// add rational codec elements to provided codec
|
||||
func RegisterWire(cdc *wire.Codec) *wire.Codec {
|
||||
cdc.RegisterInterface((*Rational)(nil), nil)
|
||||
cdc.RegisterConcrete(Rat{}, "rat", nil)
|
||||
return cdc
|
||||
}
|
||||
|
||||
// "that's one big rat!"
|
||||
// ______
|
||||
// / / /\ \____oo
|
||||
|
@ -175,32 +163,44 @@ func (r Rat) Round(precisionFactor int64) Rational {
|
|||
|
||||
//___________________________________________________________________________________
|
||||
|
||||
//var ratCdc = RegisterWire(wire.NewCodec())
|
||||
//// add rational codec elements to provided codec
|
||||
//func RegisterWire(cdc *wire.Codec) *wire.Codec {
|
||||
//cdc.RegisterInterface((*Rational)(nil), nil)
|
||||
//cdc.RegisterConcrete(Rat{}, "rat", nil)
|
||||
//return cdc
|
||||
//}
|
||||
|
||||
//TODO there has got to be a better way using native MarshalText and UnmarshalText
|
||||
|
||||
// RatMarshal - Marshable Rat Struct
|
||||
type RatMarshal struct {
|
||||
Numerator int64 `json:"numerator"`
|
||||
Denominator int64 `json:"denominator"`
|
||||
}
|
||||
//type RatMarshal struct {
|
||||
//Numerator int64 `json:"numerator"`
|
||||
//Denominator int64 `json:"denominator"`
|
||||
//}
|
||||
|
||||
// MarshalJSON - custom implementation of JSON Marshal
|
||||
func (r Rat) MarshalJSON() ([]byte, error) {
|
||||
return ratCdc.MarshalJSON(RatMarshal{r.Num(), r.Denom()})
|
||||
}
|
||||
//// MarshalJSON - custom implementation of JSON Marshal
|
||||
//func (r Rat) MarshalJSON() ([]byte, error) {
|
||||
//return ratCdc.MarshalJSON(RatMarshal{r.Num(), r.Denom()})
|
||||
//}
|
||||
|
||||
// UnmarshalJSON - custom implementation of JSON Unmarshal
|
||||
func (r *Rat) UnmarshalJSON(data []byte) (err error) {
|
||||
defer func() {
|
||||
if rcv := recover(); rcv != nil {
|
||||
err = fmt.Errorf("Panic during UnmarshalJSON: %v", rcv)
|
||||
}
|
||||
}()
|
||||
//// UnmarshalJSON - custom implementation of JSON Unmarshal
|
||||
//func (r *Rat) UnmarshalJSON(data []byte) (err error) {
|
||||
//defer func() {
|
||||
//if rcv := recover(); rcv != nil {
|
||||
//err = fmt.Errorf("Panic during UnmarshalJSON: %v", rcv)
|
||||
//}
|
||||
//}()
|
||||
|
||||
ratMar := new(RatMarshal)
|
||||
if err := ratCdc.UnmarshalJSON(data, ratMar); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Rat = big.NewRat(ratMar.Numerator, ratMar.Denominator)
|
||||
//ratMar := new(RatMarshal)
|
||||
//if err := ratCdc.UnmarshalJSON(data, ratMar); err != nil {
|
||||
//return err
|
||||
//}
|
||||
//r.Rat = big.NewRat(ratMar.Numerator, ratMar.Denominator)
|
||||
|
||||
return nil
|
||||
}
|
||||
//return nil
|
||||
//}
|
||||
|
||||
//nolint
|
||||
func (r Rat) MarshalJSON() ([]byte, error) { return r.MarshalText() }
|
||||
func (r *Rat) UnmarshalJSON(data []byte) (err error) { return r.UnmarshalText(data) }
|
||||
|
|
|
@ -14,9 +14,9 @@ import (
|
|||
)
|
||||
|
||||
// separated for testing
|
||||
func InitState(ctx sdk.Context, key, value string) error {
|
||||
func InitState(ctx sdk.Context, mapper Mapper, key, value string) error {
|
||||
|
||||
params := loadParams(store)
|
||||
params := mapper.loadParams()
|
||||
switch key {
|
||||
case "allowed_bond_denom":
|
||||
params.AllowedBondDenom = value
|
||||
|
@ -39,74 +39,57 @@ func InitState(ctx sdk.Context, key, value string) error {
|
|||
params.GasUnbond = int64(i)
|
||||
}
|
||||
default:
|
||||
return sdk.ErrUnknownKey(key)
|
||||
return sdk.ErrUnknownRequest(key)
|
||||
}
|
||||
|
||||
saveParams(store, params)
|
||||
mapper.saveParams(params)
|
||||
return nil
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
func NewHandler(stakeKey sdk.StoreKey, ck bank.CoinKeeper) sdk.Handler {
|
||||
func NewHandler(mapper Mapper, ck bank.CoinKeeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
|
||||
res := sdk.Result{}
|
||||
params := mapper.loadParams()
|
||||
|
||||
err := msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return res, err
|
||||
res := msg.ValidateBasic().Result()
|
||||
if res.Code != sdk.CodeOK {
|
||||
return res
|
||||
}
|
||||
|
||||
// return the fee for each tx type
|
||||
if ctx.IsCheckTx() {
|
||||
// XXX: add some tags so we can search it!
|
||||
switch txInner := tx.Unwrap().(type) {
|
||||
case TxDeclareCandidacy:
|
||||
return sdk.NewCheck(params.GasDeclareCandidacy, "")
|
||||
case TxEditCandidacy:
|
||||
return sdk.NewCheck(params.GasEditCandidacy, "")
|
||||
case TxDelegate:
|
||||
return sdk.NewCheck(params.GasDelegate, "")
|
||||
case TxUnbond:
|
||||
return sdk.NewCheck(params.GasUnbond, "")
|
||||
default:
|
||||
return sdk.ErrUnknownTxType(tx)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove redundancy
|
||||
// also we don't need to check the res - gas is already deducted in sdk
|
||||
_, err = h.CheckTx(ctx, store, tx, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sender, err := getTxSender(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
keeper := NewKeeper(ctx, stakeKey)
|
||||
transact := NewTransact(ctx, ck)
|
||||
|
||||
// Run the transaction
|
||||
switch _tx := tx.Unwrap().(type) {
|
||||
case TxDeclareCandidacy:
|
||||
res.GasUsed = params.GasDeclareCandidacy
|
||||
if !ctx.IsCheckTx() {
|
||||
res.GasUsed = params.GasDeclareCandidacy
|
||||
}
|
||||
return res, transact.declareCandidacy(_tx)
|
||||
case TxEditCandidacy:
|
||||
res.GasUsed = params.GasEditCandidacy
|
||||
if !ctx.IsCheckTx() {
|
||||
res.GasUsed = params.GasEditCandidacy
|
||||
}
|
||||
return res, transact.editCandidacy(_tx)
|
||||
case TxDelegate:
|
||||
res.GasUsed = params.GasDelegate
|
||||
if !ctx.IsCheckTx() {
|
||||
res.GasUsed = params.GasDelegate
|
||||
}
|
||||
return res, transact.delegate(_tx)
|
||||
case TxUnbond:
|
||||
//context with hold account permissions
|
||||
params := loadParams(store)
|
||||
res.GasUsed = params.GasUnbond
|
||||
//ctx2 := ctx.WithPermissions(params.HoldBonded) //TODO remove this line if non-permissioned ctx works
|
||||
if !ctx.IsCheckTx() {
|
||||
params := loadParams(store)
|
||||
res.GasUsed = params.GasUnbond
|
||||
}
|
||||
return res, transact.unbond(_tx)
|
||||
default:
|
||||
return sdk.ErrUnknownTxType(msgType)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -126,20 +109,21 @@ func getTxSender(ctx sdk.Context) (sender crypto.Address, err error) {
|
|||
// common fields to all transactions
|
||||
type transact struct {
|
||||
sender crypto.Address
|
||||
keeper Keeper
|
||||
mapper Mapper
|
||||
coinKeeper bank.CoinKeeper
|
||||
params Params
|
||||
gs *GlobalState
|
||||
isCheckTx sdk.Context
|
||||
}
|
||||
|
||||
// XXX move keeper creation to application?
|
||||
func newTransact(ctx sdk.Context, keeper Keeper, ck bank.CoinKeeper) transact {
|
||||
func newTransact(ctx sdk.Context, sender sdk.Address, mapper Mapper, ck bank.CoinKeeper) transact {
|
||||
return transact{
|
||||
sender: sender,
|
||||
keeper: keeper,
|
||||
mapper: mapper,
|
||||
coinKeeper: ck,
|
||||
params: keeper.loadParams(),
|
||||
gs: keeper.loadGlobalState(),
|
||||
params: mapper.loadParams(),
|
||||
gs: mapper.loadGlobalState(),
|
||||
isCheckTx: ctx.IsCheckTx(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,8 +156,8 @@ func (tr transact) unbondedToBondedPool(candidate *Candidate) error {
|
|||
}
|
||||
|
||||
// return an error if the bonds coins are incorrect
|
||||
func checkDenom(keeper Keeper, tx BondUpdate) error {
|
||||
if tx.Bond.Denom != keeper.loadParams().AllowedBondDenom {
|
||||
func checkDenom(mapper Mapper, tx BondUpdate) error {
|
||||
if tx.Bond.Denom != mapper.loadParams().AllowedBondDenom {
|
||||
return fmt.Errorf("Invalid coin denomination")
|
||||
}
|
||||
return nil
|
||||
|
@ -186,25 +170,26 @@ func checkDenom(keeper Keeper, tx BondUpdate) error {
|
|||
func (tr transact) declareCandidacy(tx TxDeclareCandidacy) error {
|
||||
|
||||
// check to see if the pubkey or sender has been registered before
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate != nil {
|
||||
if tr.mapper.loadCandidate(tx.PubKey) != nil {
|
||||
return fmt.Errorf("cannot bond to pubkey which is already declared candidacy"+
|
||||
" PubKey %v already registered with %v candidate address",
|
||||
candidate.PubKey, candidate.Owner)
|
||||
}
|
||||
err := checkDenom(tx.BondUpdate, tr.keeper)
|
||||
err := checkDenom(tx.BondUpdate, tr.mapper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// XXX end of old check tx
|
||||
if tr.IsCheckTx {
|
||||
return nil
|
||||
}
|
||||
|
||||
// create and save the empty candidate
|
||||
bond := tr.keeper.loadCandidate(tx.PubKey)
|
||||
bond := tr.mapper.loadCandidate(tx.PubKey)
|
||||
if bond != nil {
|
||||
return ErrCandidateExistsAddr()
|
||||
}
|
||||
candidate := NewCandidate(tx.PubKey, tr.sender, tx.Description)
|
||||
tr.keeper.saveCandidate(candidate)
|
||||
tr.mapper.saveCandidate(candidate)
|
||||
|
||||
// move coins from the tr.sender account to a (self-bond) delegator account
|
||||
// the candidate account and global shares are updated within here
|
||||
|
@ -215,14 +200,15 @@ func (tr transact) declareCandidacy(tx TxDeclareCandidacy) error {
|
|||
func (tr transact) editCandidacy(tx TxEditCandidacy) error {
|
||||
|
||||
// candidate must already be registered
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil { // does PubKey exist
|
||||
if tr.mapper.loadCandidate(tx.PubKey) == nil { // does PubKey exist
|
||||
return fmt.Errorf("cannot delegate to non-existant PubKey %v", tx.PubKey)
|
||||
}
|
||||
// XXX end of old check tx
|
||||
if tr.IsCheckTx {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the pubKey bond account
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
candidate := tr.mapper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil {
|
||||
return ErrBondNotNominated()
|
||||
}
|
||||
|
@ -244,24 +230,25 @@ func (tr transact) editCandidacy(tx TxEditCandidacy) error {
|
|||
candidate.Description.Details = tx.Description.Details
|
||||
}
|
||||
|
||||
tr.keeper.saveCandidate(candidate)
|
||||
tr.mapper.saveCandidate(candidate)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tr transact) delegate(tx TxDelegate) error {
|
||||
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil { // does PubKey exist
|
||||
if tr.mapper.loadCandidate(tx.PubKey) == nil { // does PubKey exist
|
||||
return fmt.Errorf("cannot delegate to non-existant PubKey %v", tx.PubKey)
|
||||
}
|
||||
err := checkDenom(tx.BondUpdate, tr.keeper)
|
||||
err := checkDenom(tx.BondUpdate, tr.mapper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// end of old check tx
|
||||
if tr.IsCheckTx {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the pubKey bond account
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
candidate := tr.mapper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil {
|
||||
return ErrBondNotNominated()
|
||||
}
|
||||
|
@ -289,7 +276,7 @@ func (tr transact) delegateWithCandidate(tx TxDelegate, candidate *Candidate) er
|
|||
}
|
||||
|
||||
// Get or create the delegator bond
|
||||
bond := tr.keeper.loadDelegatorBond(tr.sender, tx.PubKey)
|
||||
bond := tr.mapper.loadDelegatorBond(tr.sender, tx.PubKey)
|
||||
if bond == nil {
|
||||
bond = &DelegatorBond{
|
||||
PubKey: tx.PubKey,
|
||||
|
@ -299,19 +286,19 @@ func (tr transact) delegateWithCandidate(tx TxDelegate, candidate *Candidate) er
|
|||
|
||||
// Account new shares, save
|
||||
bond.Shares = bond.Shares.Add(candidate.addTokens(tx.Bond.Amount, tr.gs))
|
||||
tr.keeper.saveCandidate(candidate)
|
||||
tr.keeper.saveDelegatorBond(tr.sender, bond)
|
||||
tr.keeper.saveGlobalState(tr.gs)
|
||||
tr.mapper.saveCandidate(candidate)
|
||||
tr.mapper.saveDelegatorBond(tr.sender, bond)
|
||||
tr.mapper.saveGlobalState(tr.gs)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tr transact) unbond(tx TxUnbond) error {
|
||||
|
||||
// check if bond has any shares in it unbond
|
||||
bond := tr.keeper.loadDelegatorBond(tr.sender, tx.PubKey)
|
||||
existingBond := tr.mapper.loadDelegatorBond(tr.sender, tx.PubKey)
|
||||
sharesStr := viper.GetString(tx.Shares)
|
||||
if bond.Shares.LT(sdk.ZeroRat) { // bond shares < tx shares
|
||||
return fmt.Errorf("no shares in account to unbond")
|
||||
if existingBond.Shares.LT(sdk.ZeroRat) { // bond shares < tx shares
|
||||
return errors.New("no shares in account to unbond")
|
||||
}
|
||||
|
||||
// if shares set to special case Max then we're good
|
||||
|
@ -331,7 +318,7 @@ func (tr transact) unbond(tx TxUnbond) error {
|
|||
// XXX end of old checkTx
|
||||
|
||||
// get delegator bond
|
||||
bond := tr.keeper.loadDelegatorBond(tr.sender, tx.PubKey)
|
||||
bond := tr.mapper.loadDelegatorBond(tr.sender, tx.PubKey)
|
||||
if bond == nil {
|
||||
return ErrNoDelegatorForAddress()
|
||||
}
|
||||
|
@ -355,7 +342,7 @@ func (tr transact) unbond(tx TxUnbond) error {
|
|||
bond.Shares = bond.Shares.Sub(shares)
|
||||
|
||||
// get pubKey candidate
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
candidate := tr.mapper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil {
|
||||
return ErrNoCandidateForAddress()
|
||||
}
|
||||
|
@ -371,9 +358,9 @@ func (tr transact) unbond(tx TxUnbond) error {
|
|||
}
|
||||
|
||||
// remove the bond
|
||||
tr.keeper.removeDelegatorBond(tr.sender, tx.PubKey)
|
||||
tr.mapper.removeDelegatorBond(tr.sender, tx.PubKey)
|
||||
} else {
|
||||
tr.keeper.saveDelegatorBond(tr.sender, bond)
|
||||
tr.mapper.saveDelegatorBond(tr.sender, bond)
|
||||
}
|
||||
|
||||
// transfer coins back to account
|
||||
|
@ -408,11 +395,11 @@ func (tr transact) unbond(tx TxUnbond) error {
|
|||
|
||||
// deduct shares from the candidate and save
|
||||
if candidate.Liabilities.IsZero() {
|
||||
tr.keeper.removeCandidate(tx.PubKey)
|
||||
tr.mapper.removeCandidate(tx.PubKey)
|
||||
} else {
|
||||
tr.keeper.saveCandidate(candidate)
|
||||
tr.mapper.saveCandidate(candidate)
|
||||
}
|
||||
|
||||
tr.keeper.saveGlobalState(tr.gs)
|
||||
tr.mapper.saveGlobalState(tr.gs)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/tmlibs/rational"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
coin "github.com/cosmos/cosmos-sdk/x/bank" // XXX fix
|
||||
|
@ -16,23 +15,7 @@ import (
|
|||
|
||||
//______________________________________________________________________
|
||||
|
||||
// dummy transfer functions, represents store operations on account balances
|
||||
|
||||
type testCoinSender struct {
|
||||
store map[string]int64
|
||||
}
|
||||
|
||||
var _ coinSend = testCoinSender{} // enforce interface at compile time
|
||||
|
||||
func (c testCoinSender) transferFn(sender, receiver sdk.Actor, coins coin.Coins) error {
|
||||
c.store[string(sender.Address)] -= coins[0].Amount
|
||||
c.store[string(receiver.Address)] += coins[0].Amount
|
||||
return nil
|
||||
}
|
||||
|
||||
//______________________________________________________________________
|
||||
|
||||
func initAccounts(n int, amount int64) ([]sdk.Actor, map[string]int64) {
|
||||
func initAccounts(n int, amount int64) ([]sdk.Address, map[string]int64) {
|
||||
accStore := map[string]int64{}
|
||||
senders := newActors(n)
|
||||
for _, sender := range senders {
|
||||
|
@ -69,10 +52,10 @@ func paramsNoInflation() Params {
|
|||
return Params{
|
||||
HoldBonded: sdk.NewActor(stakingModuleName, []byte("77777777777777777777777777777777")),
|
||||
HoldUnbonded: sdk.NewActor(stakingModuleName, []byte("88888888888888888888888888888888")),
|
||||
InflationRateChange: rational.Zero,
|
||||
InflationMax: rational.Zero,
|
||||
InflationMin: rational.Zero,
|
||||
GoalBonded: rational.New(67, 100),
|
||||
InflationRateChange: sdk.Zero,
|
||||
InflationMax: sdk.Zero,
|
||||
InflationMin: sdk.Zero,
|
||||
GoalBonded: sdk.New(67, 100),
|
||||
MaxVals: 100,
|
||||
AllowedBondDenom: "fermion",
|
||||
GasDeclareCandidacy: 20,
|
||||
|
@ -82,17 +65,11 @@ func paramsNoInflation() Params {
|
|||
}
|
||||
}
|
||||
|
||||
func newDeliver(t, sender sdk.Actor, accStore map[string]int64) deliver {
|
||||
store := initTestStore()
|
||||
func newTestTransact(t, sender sdk.Address, isCheckTx bool) transact {
|
||||
store, mapper, coinKeeper := createTestInput(t, isCheckTx)
|
||||
params := paramsNoInflation()
|
||||
saveParams(store, params)
|
||||
return deliver{
|
||||
store: store,
|
||||
sender: sender,
|
||||
params: params,
|
||||
gs: loadGlobalState(store),
|
||||
transfer: testCoinSender{accStore}.transferFn,
|
||||
}
|
||||
mapper.saveParams(params)
|
||||
newTransact(ctx, sender, mapper, coinKeeper)
|
||||
}
|
||||
|
||||
func TestDuplicatesTxDeclareCandidacy(t *testing.T) {
|
||||
|
|
|
@ -2,9 +2,9 @@ package stake
|
|||
|
||||
import (
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
)
|
||||
|
||||
//nolint
|
||||
|
@ -28,7 +28,7 @@ func GetCandidateKey(pubKey crypto.PubKey) []byte {
|
|||
}
|
||||
|
||||
// GetValidatorKey - get the key for the validator used in the power-store
|
||||
func GetValidatorKey(pubKey crypto.PubKey, power types.Rational) []byte {
|
||||
func GetValidatorKey(pubKey crypto.PubKey, power sdk.Rational) []byte {
|
||||
b, _ := cdc.MarshalJSON(power) // TODO need to handle error here?
|
||||
return append(ValidatorKeyPrefix, append(b, pubKey.Bytes()...)...) // TODO does this need prefix if its in its own store
|
||||
}
|
||||
|
@ -63,26 +63,26 @@ func GetDelegatorBondsKey(delegator crypto.Address) []byte {
|
|||
|
||||
//___________________________________________________________________________
|
||||
|
||||
// keeper of the staking store
|
||||
type Keeper struct {
|
||||
store types.KVStore
|
||||
// mapper of the staking store
|
||||
type Mapper struct {
|
||||
store sdk.KVStore
|
||||
cdc *wire.Codec
|
||||
}
|
||||
|
||||
func NewKeeper(ctx sdk.Context, key sdk.StoreKey) Keeper {
|
||||
func NewMapper(ctx sdk.Context, key sdk.StoreKey) Mapper {
|
||||
cdc := wire.NewCodec()
|
||||
cdc.RegisterInterface((*types.Rational)(nil), nil) // XXX make like crypto.RegisterWire()
|
||||
cdc.RegisterConcrete(types.Rat{}, "rat", nil)
|
||||
cdc.RegisterInterface((*sdk.Rational)(nil), nil) // XXX make like crypto.RegisterWire()
|
||||
cdc.RegisterConcrete(sdk.Rat{}, "rat", nil)
|
||||
crypto.RegisterWire(cdc)
|
||||
|
||||
return StakeKeeper{
|
||||
store: ctx.KVStore(k.key),
|
||||
return StakeMapper{
|
||||
store: ctx.KVStore(m.key),
|
||||
cdc: cdc,
|
||||
}
|
||||
}
|
||||
|
||||
func (k Keeper) loadCandidate(pubKey crypto.PubKey) *Candidate {
|
||||
b := k.store.Get(GetCandidateKey(pubKey))
|
||||
func (m Mapper) loadCandidate(pubKey crypto.PubKey) *Candidate {
|
||||
b := m.store.Get(GetCandidateKey(pubKey))
|
||||
if b == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -94,31 +94,31 @@ func (k Keeper) loadCandidate(pubKey crypto.PubKey) *Candidate {
|
|||
return candidate
|
||||
}
|
||||
|
||||
func (k Keeper) saveCandidate(candidate *Candidate) {
|
||||
func (m Mapper) saveCandidate(candidate *Candidate) {
|
||||
|
||||
// XXX should only remove validator if we know candidate is a validator
|
||||
removeValidator(k.store, candidate.PubKey)
|
||||
removeValidator(m.store, candidate.PubKey)
|
||||
validator := &Validator{candidate.PubKey, candidate.VotingPower}
|
||||
updateValidator(k.store, validator)
|
||||
updateValidator(m.store, validator)
|
||||
|
||||
b, err := cdc.MarshalJSON(*candidate)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.store.Set(GetCandidateKey(candidate.PubKey), b)
|
||||
m.store.Set(GetCandidateKey(candidate.PubKey), b)
|
||||
}
|
||||
|
||||
func (k Keeper) removeCandidate(pubKey crypto.PubKey) {
|
||||
func (m Mapper) removeCandidate(pubKey crypto.PubKey) {
|
||||
|
||||
// XXX should only remove validator if we know candidate is a validator
|
||||
removeValidator(k.store, pubKey)
|
||||
k.store.Delete(GetCandidateKey(pubKey))
|
||||
removeValidator(m.store, pubKey)
|
||||
m.store.Delete(GetCandidateKey(pubKey))
|
||||
}
|
||||
|
||||
//___________________________________________________________________________
|
||||
|
||||
//func loadValidator(k.store types.KVStore, pubKey crypto.PubKey, votingPower types.Rational) *Validator {
|
||||
//b := k.store.Get(GetValidatorKey(pubKey, votingPower))
|
||||
//func loadValidator(m.store sdk.KVStore, pubKey crypto.PubKey, votingPower sdk.Rational) *Validator {
|
||||
//b := m.store.Get(GetValidatorKey(pubKey, votingPower))
|
||||
//if b == nil {
|
||||
//return nil
|
||||
//}
|
||||
|
@ -132,7 +132,7 @@ func (k Keeper) removeCandidate(pubKey crypto.PubKey) {
|
|||
|
||||
// updateValidator - update a validator and create accumulate any changes
|
||||
// in the changed validator substore
|
||||
func (k Keeper) updateValidator(validator *Validator) {
|
||||
func (m Mapper) updateValidator(validator *Validator) {
|
||||
|
||||
b, err := cdc.MarshalJSON(*validator)
|
||||
if err != nil {
|
||||
|
@ -140,34 +140,34 @@ func (k Keeper) updateValidator(validator *Validator) {
|
|||
}
|
||||
|
||||
// add to the validators to update list if necessary
|
||||
k.store.Set(GetValidatorUpdatesKey(validator.PubKey), b)
|
||||
m.store.Set(GetValidatorUpdatesKey(validator.PubKey), b)
|
||||
|
||||
// update the list ordered by voting power
|
||||
k.store.Set(GetValidatorKey(validator.PubKey, validator.VotingPower), b)
|
||||
m.store.Set(GetValidatorKey(validator.PubKey, validator.VotingPower), b)
|
||||
}
|
||||
|
||||
func (k Keeper) removeValidator(pubKey crypto.PubKey) {
|
||||
func (m Mapper) removeValidator(pubKey crypto.PubKey) {
|
||||
|
||||
//add validator with zero power to the validator updates
|
||||
b, err := cdc.MarshalJSON(Validator{pubKey, types.ZeroRat})
|
||||
b, err := cdc.MarshalJSON(Validator{pubKey, sdk.ZeroRat})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.store.Set(GetValidatorUpdatesKey(pubKey), b)
|
||||
m.store.Set(GetValidatorUpdatesKey(pubKey), b)
|
||||
|
||||
// now actually delete from the validator set
|
||||
candidate := loadCandidate(k.store, pubKey)
|
||||
candidate := loadCandidate(m.store, pubKey)
|
||||
if candidate != nil {
|
||||
k.store.Delete(GetValidatorKey(pubKey, candidate.VotingPower))
|
||||
m.store.Delete(GetValidatorKey(pubKey, candidate.VotingPower))
|
||||
}
|
||||
}
|
||||
|
||||
// get the most recent updated validator set from the Candidates. These bonds
|
||||
// are already sorted by VotingPower from the UpdateVotingPower function which
|
||||
// is the only function which is to modify the VotingPower
|
||||
func (k Keeper) getValidators(maxVal int) (validators []Validator) {
|
||||
func (m Mapper) getValidators(maxVal int) (validators []Validator) {
|
||||
|
||||
iterator := k.store.Iterator(subspace(ValidatorKeyPrefix)) //smallest to largest
|
||||
iterator := m.store.Iterator(subspace(ValidatorKeyPrefix)) //smallest to largest
|
||||
|
||||
validators = make([]Validator, maxVal)
|
||||
for i := 0; ; i++ {
|
||||
|
@ -191,9 +191,9 @@ func (k Keeper) getValidators(maxVal int) (validators []Validator) {
|
|||
//_________________________________________________________________________
|
||||
|
||||
// get the most updated validators
|
||||
func (k Keeper) getValidatorUpdates() (updates []Validator) {
|
||||
func (m Mapper) getValidatorUpdates() (updates []Validator) {
|
||||
|
||||
iterator := k.store.Iterator(subspace(ValidatorUpdatesKeyPrefix)) //smallest to largest
|
||||
iterator := m.store.Iterator(subspace(ValidatorUpdatesKeyPrefix)) //smallest to largest
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
valBytes := iterator.Value()
|
||||
|
@ -210,10 +210,10 @@ func (k Keeper) getValidatorUpdates() (updates []Validator) {
|
|||
}
|
||||
|
||||
// remove all validator update entries
|
||||
func (k Keeper) clearValidatorUpdates(maxVal int) {
|
||||
iterator := k.store.Iterator(subspace(ValidatorUpdatesKeyPrefix))
|
||||
func (m Mapper) clearValidatorUpdates(maxVal int) {
|
||||
iterator := m.store.Iterator(subspace(ValidatorUpdatesKeyPrefix))
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
k.store.Delete(iterator.Key()) // XXX write test for this, may need to be in a second loop
|
||||
m.store.Delete(iterator.Key()) // XXX write test for this, may need to be in a second loop
|
||||
}
|
||||
iterator.Close()
|
||||
}
|
||||
|
@ -221,11 +221,11 @@ func (k Keeper) clearValidatorUpdates(maxVal int) {
|
|||
//---------------------------------------------------------------------
|
||||
|
||||
// loadCandidates - get the active list of all candidates TODO replace with multistore
|
||||
func (k Keeper) loadCandidates() (candidates Candidates) {
|
||||
func (m Mapper) loadCandidates() (candidates Candidates) {
|
||||
|
||||
iterator := k.store.Iterator(subspace(CandidateKeyPrefix))
|
||||
//iterator := k.store.Iterator(CandidateKeyPrefix, []byte(nil))
|
||||
//iterator := k.store.Iterator([]byte{}, []byte(nil))
|
||||
iterator := m.store.Iterator(subspace(CandidateKeyPrefix))
|
||||
//iterator := m.store.Iterator(CandidateKeyPrefix, []byte(nil))
|
||||
//iterator := m.store.Iterator([]byte{}, []byte(nil))
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
candidateBytes := iterator.Value()
|
||||
|
@ -243,9 +243,9 @@ func (k Keeper) loadCandidates() (candidates Candidates) {
|
|||
//_____________________________________________________________________
|
||||
|
||||
// load the pubkeys of all candidates a delegator is delegated too
|
||||
func (k Keeper) loadDelegatorCandidates(delegator crypto.Address) (candidates []crypto.PubKey) {
|
||||
func (m Mapper) loadDelegatorCandidates(delegator crypto.Address) (candidates []crypto.PubKey) {
|
||||
|
||||
candidateBytes := k.store.Get(GetDelegatorBondsKey(delegator))
|
||||
candidateBytes := m.store.Get(GetDelegatorBondsKey(delegator))
|
||||
if candidateBytes == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -259,10 +259,10 @@ func (k Keeper) loadDelegatorCandidates(delegator crypto.Address) (candidates []
|
|||
|
||||
//_____________________________________________________________________
|
||||
|
||||
func (k Keeper) loadDelegatorBond(delegator crypto.Address,
|
||||
func (m Mapper) loadDelegatorBond(delegator crypto.Address,
|
||||
candidate crypto.PubKey) *DelegatorBond {
|
||||
|
||||
delegatorBytes := k.store.Get(GetDelegatorBondKey(delegator, candidate))
|
||||
delegatorBytes := m.store.Get(GetDelegatorBondKey(delegator, candidate))
|
||||
if delegatorBytes == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -275,18 +275,18 @@ func (k Keeper) loadDelegatorBond(delegator crypto.Address,
|
|||
return bond
|
||||
}
|
||||
|
||||
func (k Keeper) saveDelegatorBond(delegator crypto.Address,
|
||||
func (m Mapper) saveDelegatorBond(delegator crypto.Address,
|
||||
bond *DelegatorBond) {
|
||||
|
||||
// if a new bond add to the list of bonds
|
||||
if loadDelegatorBond(k.store, delegator, bond.PubKey) == nil {
|
||||
pks := loadDelegatorCandidates(k.store, delegator)
|
||||
if loadDelegatorBond(m.store, delegator, bond.PubKey) == nil {
|
||||
pks := loadDelegatorCandidates(m.store, delegator)
|
||||
pks = append(pks, (*bond).PubKey)
|
||||
b, err := cdc.MarshalJSON(pks)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.store.Set(GetDelegatorBondsKey(delegator), b)
|
||||
m.store.Set(GetDelegatorBondsKey(delegator), b)
|
||||
}
|
||||
|
||||
// now actually save the bond
|
||||
|
@ -294,14 +294,14 @@ func (k Keeper) saveDelegatorBond(delegator crypto.Address,
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.store.Set(GetDelegatorBondKey(delegator, bond.PubKey), b)
|
||||
m.store.Set(GetDelegatorBondKey(delegator, bond.PubKey), b)
|
||||
//updateDelegatorBonds(store, delegator)
|
||||
}
|
||||
|
||||
func (k Keeper) removeDelegatorBond(delegator crypto.Address, candidate crypto.PubKey) {
|
||||
func (m Mapper) removeDelegatorBond(delegator crypto.Address, candidate crypto.PubKey) {
|
||||
// TODO use list queries on multistore to remove iterations here!
|
||||
// first remove from the list of bonds
|
||||
pks := loadDelegatorCandidates(k.store, delegator)
|
||||
pks := loadDelegatorCandidates(m.store, delegator)
|
||||
for i, pk := range pks {
|
||||
if candidate.Equals(pk) {
|
||||
pks = append(pks[:i], pks[i+1:]...)
|
||||
|
@ -311,18 +311,18 @@ func (k Keeper) removeDelegatorBond(delegator crypto.Address, candidate crypto.P
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.store.Set(GetDelegatorBondsKey(delegator), b)
|
||||
m.store.Set(GetDelegatorBondsKey(delegator), b)
|
||||
|
||||
// now remove the actual bond
|
||||
k.store.Delete(GetDelegatorBondKey(delegator, candidate))
|
||||
m.store.Delete(GetDelegatorBondKey(delegator, candidate))
|
||||
//updateDelegatorBonds(store, delegator)
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// load/save the global staking params
|
||||
func (k Keeper) loadParams() (params Params) {
|
||||
b := k.store.Get(ParamKey)
|
||||
func (m Mapper) loadParams() (params Params) {
|
||||
b := m.store.Get(ParamKey)
|
||||
if b == nil {
|
||||
return defaultParams()
|
||||
}
|
||||
|
@ -333,19 +333,19 @@ func (k Keeper) loadParams() (params Params) {
|
|||
}
|
||||
return
|
||||
}
|
||||
func (k Keeper) saveParams(params Params) {
|
||||
func (m Mapper) saveParams(params Params) {
|
||||
b, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.store.Set(ParamKey, b)
|
||||
m.store.Set(ParamKey, b)
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// load/save the global staking state
|
||||
func (k Keeper) loadGlobalState() (gs *GlobalState) {
|
||||
b := k.store.Get(GlobalStateKey)
|
||||
func (m Mapper) loadGlobalState() (gs *GlobalState) {
|
||||
b := m.store.Get(GlobalStateKey)
|
||||
if b == nil {
|
||||
return initialGlobalState()
|
||||
}
|
||||
|
@ -357,10 +357,10 @@ func (k Keeper) loadGlobalState() (gs *GlobalState) {
|
|||
return
|
||||
}
|
||||
|
||||
func (k Keeper) saveGlobalState(gs *GlobalState) {
|
||||
func (m Mapper) saveGlobalState(gs *GlobalState) {
|
||||
b, err := cdc.MarshalJSON(*gs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.store.Set(GlobalStateKey, b)
|
||||
m.store.Set(GlobalStateKey, b)
|
||||
}
|
|
@ -161,7 +161,7 @@ import (
|
|||
//}
|
||||
|
||||
func TestState(t *testing.T) {
|
||||
store := initTestStore(t)
|
||||
store := createTestInput(t)
|
||||
|
||||
//delegator := crypto.Address{[]byte("addressdelegator")}
|
||||
//validator := crypto.Address{[]byte("addressvalidator")}
|
||||
|
@ -260,7 +260,7 @@ func TestState(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetValidators(t *testing.T) {
|
||||
store := initTestStore(t)
|
||||
store, ctx, key := createTestInput(t, false)
|
||||
N := 5
|
||||
addrs := newAddrs(N)
|
||||
candidatesFromActors(store, addrs, []int64{400, 200, 0, 0, 0})
|
|
@ -7,10 +7,10 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
|
@ -21,16 +21,18 @@ func subspace(prefix []byte) (start, end []byte) {
|
|||
return prefix, end
|
||||
}
|
||||
|
||||
func initTestStore(t *testing.T) sdk.KVStore {
|
||||
// Capabilities key to access the main KVStore.
|
||||
//db, err := dbm.NewGoLevelDB("stake", "data")
|
||||
func createTestInput(t *testing.T, isCheckTx bool) (store sdk.KVStore, ctx sdk.Context, key sdk.StoreKey) {
|
||||
db := dbm.NewMemDB()
|
||||
stakeStoreKey := sdk.NewKVStoreKey("stake")
|
||||
key = sdk.NewKVStoreKey("stake")
|
||||
|
||||
ms := store.NewCommitMultiStore(db)
|
||||
ms.MountStoreWithDB(stakeStoreKey, sdk.StoreTypeIAVL, db)
|
||||
ms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
|
||||
err := ms.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
return ms.GetKVStore(stakeStoreKey)
|
||||
|
||||
ctx = sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, nil)
|
||||
store = ms.GetKVStore(key)
|
||||
return
|
||||
}
|
||||
|
||||
func newAddrs(n int) (addrs []crypto.Address) {
|
||||
|
|
|
@ -2,13 +2,11 @@ package stake
|
|||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/tmlibs/rational"
|
||||
)
|
||||
|
||||
// Tick - called at the end of every block
|
||||
func Tick(ctx sdk.Context, store types.KVStore) (change []*abci.Validator, err error) {
|
||||
func Tick(ctx sdk.Context, store sdk.KVStore) (change []*abci.Validator, err error) {
|
||||
|
||||
// retrieve params
|
||||
params := loadParams(store)
|
||||
|
@ -25,10 +23,10 @@ func Tick(ctx sdk.Context, store types.KVStore) (change []*abci.Validator, err e
|
|||
return UpdateValidatorSet(store, gs, params)
|
||||
}
|
||||
|
||||
var hrsPerYr = rational.New(8766) // as defined by a julian year of 365.25 days
|
||||
var hrsPerYr = sdk.NewRat(8766) // as defined by a julian year of 365.25 days
|
||||
|
||||
// process provisions for an hour period
|
||||
func processProvisions(store types.KVStore, gs *GlobalState, params Params) {
|
||||
func processProvisions(store sdk.KVStore, gs *GlobalState, params Params) {
|
||||
|
||||
gs.Inflation = nextInflation(gs, params).Round(1000000000)
|
||||
|
||||
|
@ -36,7 +34,7 @@ func processProvisions(store types.KVStore, gs *GlobalState, params Params) {
|
|||
// more bonded tokens are added proportionally to all validators the only term
|
||||
// which needs to be updated is the `BondedPool`. So for each previsions cycle:
|
||||
|
||||
provisions := gs.Inflation.Mul(rational.New(gs.TotalSupply)).Quo(hrsPerYr).Evaluate()
|
||||
provisions := gs.Inflation.Mul(sdk.New(gs.TotalSupply)).Quo(hrsPerYr).Evaluate()
|
||||
gs.BondedPool += provisions
|
||||
gs.TotalSupply += provisions
|
||||
|
||||
|
@ -49,7 +47,7 @@ func processProvisions(store types.KVStore, gs *GlobalState, params Params) {
|
|||
}
|
||||
|
||||
// get the next inflation rate for the hour
|
||||
func nextInflation(gs *GlobalState, params Params) (inflation rational.Rat) {
|
||||
func nextInflation(gs *GlobalState, params Params) (inflation sdk.Rat) {
|
||||
|
||||
// The target annual inflation rate is recalculated for each previsions cycle. The
|
||||
// inflation is also subject to a rate change (positive of negative) depending or
|
||||
|
@ -58,7 +56,7 @@ func nextInflation(gs *GlobalState, params Params) (inflation rational.Rat) {
|
|||
// 7% and 20%.
|
||||
|
||||
// (1 - bondedRatio/GoalBonded) * InflationRateChange
|
||||
inflationRateChangePerYear := rational.One.Sub(gs.bondedRatio().Quo(params.GoalBonded)).Mul(params.InflationRateChange)
|
||||
inflationRateChangePerYear := sdk.One.Sub(gs.bondedRatio().Quo(params.GoalBonded)).Mul(params.InflationRateChange)
|
||||
inflationRateChange := inflationRateChangePerYear.Quo(hrsPerYr)
|
||||
|
||||
// increase the new annual inflation for this next cycle
|
||||
|
|
|
@ -3,12 +3,12 @@ package stake
|
|||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tendermint/tmlibs/rational"
|
||||
)
|
||||
|
||||
func TestGetInflation(t *testing.T) {
|
||||
store := initTestStore(t)
|
||||
store, ctx, key := createTestInput(t, false)
|
||||
params := loadParams(store)
|
||||
gs := loadGlobalState(store)
|
||||
|
||||
|
@ -18,27 +18,27 @@ func TestGetInflation(t *testing.T) {
|
|||
|
||||
tests := []struct {
|
||||
setBondedPool, setTotalSupply int64
|
||||
setInflation, expectedChange rational.Rat
|
||||
setInflation, expectedChange sdk.Rat
|
||||
}{
|
||||
// with 0% bonded atom supply the inflation should increase by InflationRateChange
|
||||
{0, 0, rational.New(7, 100), params.InflationRateChange.Quo(hrsPerYr)},
|
||||
{0, 0, sdk.New(7, 100), params.InflationRateChange.Quo(hrsPerYr)},
|
||||
|
||||
// 100% bonded, starting at 20% inflation and being reduced
|
||||
{1, 1, rational.New(20, 100), rational.One.Sub(rational.One.Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYr)},
|
||||
{1, 1, sdk.New(20, 100), sdk.One.Sub(sdk.One.Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYr)},
|
||||
|
||||
// 50% bonded, starting at 10% inflation and being increased
|
||||
{1, 2, rational.New(10, 100), rational.One.Sub(rational.New(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYr)},
|
||||
{1, 2, sdk.New(10, 100), sdk.One.Sub(sdk.New(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYr)},
|
||||
|
||||
// test 7% minimum stop (testing with 100% bonded)
|
||||
{1, 1, rational.New(7, 100), rational.Zero},
|
||||
{1, 1, rational.New(70001, 1000000), rational.New(-1, 1000000)},
|
||||
{1, 1, sdk.New(7, 100), sdk.Zero},
|
||||
{1, 1, sdk.New(70001, 1000000), sdk.New(-1, 1000000)},
|
||||
|
||||
// test 20% maximum stop (testing with 0% bonded)
|
||||
{0, 0, rational.New(20, 100), rational.Zero},
|
||||
{0, 0, rational.New(199999, 1000000), rational.New(1, 1000000)},
|
||||
{0, 0, sdk.New(20, 100), sdk.Zero},
|
||||
{0, 0, sdk.New(199999, 1000000), sdk.New(1, 1000000)},
|
||||
|
||||
// perfect balance shouldn't change inflation
|
||||
{67, 100, rational.New(15, 100), rational.Zero},
|
||||
{67, 100, sdk.New(15, 100), sdk.Zero},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
gs.BondedPool, gs.TotalSupply = tc.setBondedPool, tc.setTotalSupply
|
||||
|
@ -53,7 +53,7 @@ func TestGetInflation(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestProcessProvisions(t *testing.T) {
|
||||
store := initTestStore(t)
|
||||
store, ctx, key := createTestInput(t, false)
|
||||
params := loadParams(store)
|
||||
gs := loadGlobalState(store)
|
||||
|
||||
|
@ -75,7 +75,7 @@ func TestProcessProvisions(t *testing.T) {
|
|||
var unbondedShares int64 = 400000000
|
||||
|
||||
// initial bonded ratio ~ 27%
|
||||
assert.True(t, gs.bondedRatio().Equal(rational.New(bondedShares, totalSupply)), "%v", gs.bondedRatio())
|
||||
assert.True(t, gs.bondedRatio().Equal(sdk.New(bondedShares, totalSupply)), "%v", gs.bondedRatio())
|
||||
|
||||
// Supplies
|
||||
assert.Equal(t, totalSupply, gs.TotalSupply)
|
||||
|
@ -83,7 +83,7 @@ func TestProcessProvisions(t *testing.T) {
|
|||
assert.Equal(t, unbondedShares, gs.UnbondedPool)
|
||||
|
||||
// test the value of candidate shares
|
||||
assert.True(t, gs.bondedShareExRate().Equal(rational.One), "%v", gs.bondedShareExRate())
|
||||
assert.True(t, gs.bondedShareExRate().Equal(sdk.One), "%v", gs.bondedShareExRate())
|
||||
|
||||
initialSupply := gs.TotalSupply
|
||||
initialUnbonded := gs.TotalSupply - gs.BondedPool
|
||||
|
@ -91,7 +91,7 @@ func TestProcessProvisions(t *testing.T) {
|
|||
// process the provisions a year
|
||||
for hr := 0; hr < 8766; hr++ {
|
||||
expInflation := nextInflation(gs, params).Round(1000000000)
|
||||
expProvisions := (expInflation.Mul(rational.New(gs.TotalSupply)).Quo(hrsPerYr)).Evaluate()
|
||||
expProvisions := (expInflation.Mul(sdk.New(gs.TotalSupply)).Quo(hrsPerYr)).Evaluate()
|
||||
startBondedPool := gs.BondedPool
|
||||
startTotalSupply := gs.TotalSupply
|
||||
processProvisions(store, gs, params)
|
||||
|
@ -103,7 +103,7 @@ func TestProcessProvisions(t *testing.T) {
|
|||
//panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", gs.TotalSupply, gs.BondedPool, gs.TotalSupply-gs.BondedPool))
|
||||
|
||||
// initial bonded ratio ~ 35% ~ 30% increase for bonded holders
|
||||
assert.True(t, gs.bondedRatio().Equal(rational.New(105906511, 305906511)), "%v", gs.bondedRatio())
|
||||
assert.True(t, gs.bondedRatio().Equal(sdk.New(105906511, 305906511)), "%v", gs.bondedRatio())
|
||||
|
||||
// global supply
|
||||
assert.Equal(t, int64(611813022), gs.TotalSupply)
|
||||
|
@ -111,6 +111,6 @@ func TestProcessProvisions(t *testing.T) {
|
|||
assert.Equal(t, unbondedShares, gs.UnbondedPool)
|
||||
|
||||
// test the value of candidate shares
|
||||
assert.True(t, gs.bondedShareExRate().Mul(rational.New(bondedShares)).Equal(rational.New(211813022)), "%v", gs.bondedShareExRate())
|
||||
assert.True(t, gs.bondedShareExRate().Mul(sdk.New(bondedShares)).Equal(sdk.New(211813022)), "%v", gs.bondedShareExRate())
|
||||
|
||||
}
|
||||
|
|
|
@ -18,10 +18,11 @@ const (
|
|||
ByteTxEditCandidacy = 0x56
|
||||
ByteTxDelegate = 0x57
|
||||
ByteTxUnbond = 0x58
|
||||
TypeTxDeclareCandidacy = stakingModuleName + "/declareCandidacy"
|
||||
TypeTxEditCandidacy = stakingModuleName + "/editCandidacy"
|
||||
TypeTxDelegate = stakingModuleName + "/delegate"
|
||||
TypeTxUnbond = stakingModuleName + "/unbond"
|
||||
|
||||
TypeTxDeclareCandidacy = "staking/declareCandidacy"
|
||||
TypeTxEditCandidacy = "staking/editCandidacy"
|
||||
TypeTxDelegate = "staking/delegate"
|
||||
TypeTxUnbond = "staking/unbond"
|
||||
)
|
||||
|
||||
//func init() {
|
||||
|
|
|
@ -13,8 +13,8 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
validator = sdk.Actor{"testChain", "testapp", []byte("addressvalidator1")}
|
||||
empty sdk.Actor
|
||||
validator = []byte("addressvalidator1")
|
||||
empty sdk.Address
|
||||
|
||||
coinPos = sdk.Coin{"fermion", 1000}
|
||||
coinZero = sdk.Coin{"fermion", 0}
|
||||
|
|
|
@ -139,6 +139,8 @@ const (
|
|||
// bond shares is based on the amount of coins delegated divided by the current
|
||||
// exchange rate. Voting power can be calculated as total bonds multiplied by
|
||||
// exchange rate.
|
||||
|
||||
// XXX update to use Address as the main key NOT the pubkey
|
||||
type Candidate struct {
|
||||
Status CandidateStatus `json:"status"` // Bonded status
|
||||
PubKey crypto.PubKey `json:"pub_key"` // Pubkey of candidate
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package stake
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
)
|
||||
|
||||
// XXX complete
|
||||
|
|
Loading…
Reference in New Issue