porting handler, refactoring mapper/types
This commit is contained in:
parent
e8cea08978
commit
59b10d33c1
|
@ -13,24 +13,8 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
)
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// DelegatedProofOfStake - interface to enforce delegation stake
|
||||
type delegatedProofOfStake interface {
|
||||
declareCandidacy(TxDeclareCandidacy) error
|
||||
editCandidacy(TxEditCandidacy) error
|
||||
delegate(TxDelegate) error
|
||||
unbond(TxUnbond) error
|
||||
}
|
||||
|
||||
type coinSend interface {
|
||||
transferFn(sender, receiver crypto.Address, coins sdk.Coins) error
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// separated for testing
|
||||
func InitState(key, value string, store sdk.KVStore) error {
|
||||
func InitState(ctx sdk.Context, key, value string) error {
|
||||
|
||||
params := loadParams(store)
|
||||
switch key {
|
||||
|
@ -64,22 +48,19 @@ func InitState(key, value string, store sdk.KVStore) error {
|
|||
|
||||
//_______________________________________________________________________
|
||||
|
||||
func NewHandler(ck bank.CoinKeeper) sdk.Handler {
|
||||
func NewHandler(stakeKey sdk.StoreKey, ck bank.CoinKeeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
|
||||
params := loadParams(store)
|
||||
params := loadGlobalState(store)
|
||||
res := sdk.Result{}
|
||||
|
||||
if ctx.IsCheckTx() {
|
||||
|
||||
err = tx.ValidateBasic()
|
||||
err := msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res := sdk.Result{}
|
||||
|
||||
// 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, "")
|
||||
|
@ -89,11 +70,9 @@ func NewHandler(ck bank.CoinKeeper) sdk.Handler {
|
|||
return sdk.NewCheck(params.GasDelegate, "")
|
||||
case TxUnbond:
|
||||
return sdk.NewCheck(params.GasUnbond, "")
|
||||
}
|
||||
|
||||
// TODO: add some tags so we can search it!
|
||||
default:
|
||||
return sdk.ErrUnknownTxType(tx)
|
||||
//return sdk.Result{} // TODO
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove redundancy
|
||||
|
@ -108,32 +87,26 @@ func NewHandler(ck bank.CoinKeeper) sdk.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
params := loadParams(store)
|
||||
deliverer := deliver{
|
||||
store: store,
|
||||
sender: sender,
|
||||
params: params,
|
||||
ck: ck,
|
||||
gs: gs,
|
||||
}
|
||||
keeper := NewKeeper(ctx, stakeKey)
|
||||
transact := NewTransact(ctx, ck)
|
||||
|
||||
// Run the transaction
|
||||
switch _tx := tx.Unwrap().(type) {
|
||||
case TxDeclareCandidacy:
|
||||
res.GasUsed = params.GasDeclareCandidacy
|
||||
return res, deliverer.declareCandidacy(_tx)
|
||||
return res, transact.declareCandidacy(_tx)
|
||||
case TxEditCandidacy:
|
||||
res.GasUsed = params.GasEditCandidacy
|
||||
return res, deliverer.editCandidacy(_tx)
|
||||
return res, transact.editCandidacy(_tx)
|
||||
case TxDelegate:
|
||||
res.GasUsed = params.GasDelegate
|
||||
return res, deliverer.delegate(_tx)
|
||||
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
|
||||
return res, deliverer.unbond(_tx)
|
||||
return res, transact.unbond(_tx)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -150,47 +123,57 @@ func getTxSender(ctx sdk.Context) (sender crypto.Address, err error) {
|
|||
|
||||
//_____________________________________________________________________
|
||||
|
||||
type deliver struct {
|
||||
store sdk.KVStore
|
||||
// common fields to all transactions
|
||||
type transact struct {
|
||||
sender crypto.Address
|
||||
keeper Keeper
|
||||
coinKeeper bank.CoinKeeper
|
||||
params Params
|
||||
ck bank.CoinKeeper
|
||||
gs *GlobalState
|
||||
}
|
||||
|
||||
var _ delegatedProofOfStake = deliver{} // enforce interface at compile time
|
||||
// XXX move keeper creation to application?
|
||||
func newTransact(ctx sdk.Context, keeper Keeper, ck bank.CoinKeeper) transact {
|
||||
return transact{
|
||||
sender: sender,
|
||||
keeper: keeper,
|
||||
coinKeeper: ck,
|
||||
params: keeper.loadParams(),
|
||||
gs: keeper.loadGlobalState(),
|
||||
}
|
||||
}
|
||||
|
||||
//_____________________________________________________________________
|
||||
// helper functions
|
||||
// TODO move from deliver with new SDK should only be dependant on store to send coins in NEW SDK
|
||||
|
||||
// move a candidates asset pool from bonded to unbonded pool
|
||||
func (d deliver) bondedToUnbondedPool(candidate *Candidate) error {
|
||||
func (tr transact) bondedToUnbondedPool(candidate *Candidate) error {
|
||||
|
||||
// replace bonded shares with unbonded shares
|
||||
tokens := d.gs.removeSharesBonded(candidate.Assets)
|
||||
candidate.Assets = d.gs.addTokensUnbonded(tokens)
|
||||
tokens := tr.gs.removeSharesBonded(candidate.Assets)
|
||||
candidate.Assets = tr.gs.addTokensUnbonded(tokens)
|
||||
candidate.Status = Unbonded
|
||||
|
||||
return d.transfer(d.params.HoldBonded, d.params.HoldUnbonded,
|
||||
sdk.Coins{{d.params.AllowedBondDenom, tokens}})
|
||||
return tr.transfer(tr.params.HoldBonded, tr.params.HoldUnbonded,
|
||||
sdk.Coins{{tr.params.AllowedBondDenom, tokens}})
|
||||
}
|
||||
|
||||
// move a candidates asset pool from unbonded to bonded pool
|
||||
func (d deliver) unbondedToBondedPool(candidate *Candidate) error {
|
||||
func (tr transact) unbondedToBondedPool(candidate *Candidate) error {
|
||||
|
||||
// replace bonded shares with unbonded shares
|
||||
tokens := d.gs.removeSharesUnbonded(candidate.Assets)
|
||||
candidate.Assets = d.gs.addTokensBonded(tokens)
|
||||
tokens := tr.gs.removeSharesUnbonded(candidate.Assets)
|
||||
candidate.Assets = tr.gs.addTokensBonded(tokens)
|
||||
candidate.Status = Bonded
|
||||
|
||||
return d.transfer(d.params.HoldUnbonded, d.params.HoldBonded,
|
||||
sdk.Coins{{d.params.AllowedBondDenom, tokens}})
|
||||
return tr.transfer(tr.params.HoldUnbonded, tr.params.HoldBonded,
|
||||
sdk.Coins{{tr.params.AllowedBondDenom, tokens}})
|
||||
}
|
||||
|
||||
// return an error if the bonds coins are incorrect
|
||||
func checkDenom(tx BondUpdate, store sdk.KVStore) error {
|
||||
if tx.Bond.Denom != loadParams(store).AllowedBondDenom {
|
||||
func checkDenom(keeper Keeper, tx BondUpdate) error {
|
||||
if tx.Bond.Denom != keeper.loadParams().AllowedBondDenom {
|
||||
return fmt.Errorf("Invalid coin denomination")
|
||||
}
|
||||
return nil
|
||||
|
@ -200,46 +183,46 @@ func checkDenom(tx BondUpdate, store sdk.KVStore) error {
|
|||
|
||||
// These functions assume everything has been authenticated,
|
||||
// now we just perform action and save
|
||||
func (d deliver) declareCandidacy(tx TxDeclareCandidacy) error {
|
||||
func (tr transact) declareCandidacy(tx TxDeclareCandidacy) error {
|
||||
|
||||
// check to see if the pubkey or sender has been registered before
|
||||
candidate := loadCandidate(d.store, tx.PubKey)
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate != 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, d.store)
|
||||
err := checkDenom(tx.BondUpdate, tr.keeper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// XXX end of old check tx
|
||||
|
||||
// create and save the empty candidate
|
||||
bond := loadCandidate(d.store, tx.PubKey)
|
||||
bond := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if bond != nil {
|
||||
return ErrCandidateExistsAddr()
|
||||
}
|
||||
candidate := NewCandidate(tx.PubKey, d.sender, tx.Description)
|
||||
saveCandidate(d.store, candidate)
|
||||
candidate := NewCandidate(tx.PubKey, tr.sender, tx.Description)
|
||||
tr.keeper.saveCandidate(candidate)
|
||||
|
||||
// move coins from the d.sender account to a (self-bond) delegator account
|
||||
// move coins from the tr.sender account to a (self-bond) delegator account
|
||||
// the candidate account and global shares are updated within here
|
||||
txDelegate := TxDelegate{tx.BondUpdate}
|
||||
return d.delegateWithCandidate(txDelegate, candidate)
|
||||
return tr.delegateWithCandidate(txDelegate, candidate)
|
||||
}
|
||||
|
||||
func (d deliver) editCandidacy(tx TxEditCandidacy) error {
|
||||
func (tr transact) editCandidacy(tx TxEditCandidacy) error {
|
||||
|
||||
// candidate must already be registered
|
||||
candidate := loadCandidate(d.store, tx.PubKey)
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil { // does PubKey exist
|
||||
return fmt.Errorf("cannot delegate to non-existant PubKey %v", tx.PubKey)
|
||||
}
|
||||
// XXX end of old check tx
|
||||
|
||||
// Get the pubKey bond account
|
||||
candidate := loadCandidate(d.store, tx.PubKey)
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil {
|
||||
return ErrBondNotNominated()
|
||||
}
|
||||
|
@ -261,31 +244,31 @@ func (d deliver) editCandidacy(tx TxEditCandidacy) error {
|
|||
candidate.Description.Details = tx.Description.Details
|
||||
}
|
||||
|
||||
saveCandidate(d.store, candidate)
|
||||
tr.keeper.saveCandidate(candidate)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d deliver) delegate(tx TxDelegate) error {
|
||||
func (tr transact) delegate(tx TxDelegate) error {
|
||||
|
||||
candidate := loadCandidate(c.store, tx.PubKey)
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil { // does PubKey exist
|
||||
return fmt.Errorf("cannot delegate to non-existant PubKey %v", tx.PubKey)
|
||||
}
|
||||
err := checkDenom(tx.BondUpdate, c.store)
|
||||
err := checkDenom(tx.BondUpdate, tr.keeper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// end of old check tx
|
||||
|
||||
// Get the pubKey bond account
|
||||
candidate := loadCandidate(d.store, tx.PubKey)
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil {
|
||||
return ErrBondNotNominated()
|
||||
}
|
||||
return d.delegateWithCandidate(tx, candidate)
|
||||
return tr.delegateWithCandidate(tx, candidate)
|
||||
}
|
||||
|
||||
func (d deliver) delegateWithCandidate(tx TxDelegate, candidate *Candidate) error {
|
||||
func (tr transact) delegateWithCandidate(tx TxDelegate, candidate *Candidate) error {
|
||||
|
||||
if candidate.Status == Revoked { //candidate has been withdrawn
|
||||
return ErrBondNotNominated()
|
||||
|
@ -293,20 +276,20 @@ func (d deliver) delegateWithCandidate(tx TxDelegate, candidate *Candidate) erro
|
|||
|
||||
var poolAccount crypto.Address
|
||||
if candidate.Status == Bonded {
|
||||
poolAccount = d.params.HoldBonded
|
||||
poolAccount = tr.params.HoldBonded
|
||||
} else {
|
||||
poolAccount = d.params.HoldUnbonded
|
||||
poolAccount = tr.params.HoldUnbonded
|
||||
}
|
||||
|
||||
// TODO maybe refactor into GlobalState.addBondedTokens(), maybe with new SDK
|
||||
// XXX refactor all steps like this into GlobalState.addBondedTokens()
|
||||
// Move coins from the delegator account to the bonded pool account
|
||||
err := d.transfer(d.sender, poolAccount, sdk.Coins{tx.Bond})
|
||||
err := tr.transfer(tr.sender, poolAccount, sdk.Coins{tx.Bond})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get or create the delegator bond
|
||||
bond := loadDelegatorBond(d.store, d.sender, tx.PubKey)
|
||||
bond := tr.keeper.loadDelegatorBond(tr.sender, tx.PubKey)
|
||||
if bond == nil {
|
||||
bond = &DelegatorBond{
|
||||
PubKey: tx.PubKey,
|
||||
|
@ -315,17 +298,17 @@ func (d deliver) delegateWithCandidate(tx TxDelegate, candidate *Candidate) erro
|
|||
}
|
||||
|
||||
// Account new shares, save
|
||||
bond.Shares = bond.Shares.Add(candidate.addTokens(tx.Bond.Amount, d.gs))
|
||||
saveCandidate(d.store, candidate)
|
||||
saveDelegatorBond(d.store, d.sender, bond)
|
||||
saveGlobalState(d.store, d.gs)
|
||||
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)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d deliver) unbond(tx TxUnbond) error {
|
||||
func (tr transact) unbond(tx TxUnbond) error {
|
||||
|
||||
// check if bond has any shares in it unbond
|
||||
bond := loadDelegatorBond(d.store, d.sender, tx.PubKey)
|
||||
bond := tr.keeper.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")
|
||||
|
@ -348,7 +331,7 @@ func (d deliver) unbond(tx TxUnbond) error {
|
|||
// XXX end of old checkTx
|
||||
|
||||
// get delegator bond
|
||||
bond := loadDelegatorBond(d.store, d.sender, tx.PubKey)
|
||||
bond := tr.keeper.loadDelegatorBond(tr.sender, tx.PubKey)
|
||||
if bond == nil {
|
||||
return ErrNoDelegatorForAddress()
|
||||
}
|
||||
|
@ -372,7 +355,7 @@ func (d deliver) unbond(tx TxUnbond) error {
|
|||
bond.Shares = bond.Shares.Sub(shares)
|
||||
|
||||
// get pubKey candidate
|
||||
candidate := loadCandidate(d.store, tx.PubKey)
|
||||
candidate := tr.keeper.loadCandidate(tx.PubKey)
|
||||
if candidate == nil {
|
||||
return ErrNoCandidateForAddress()
|
||||
}
|
||||
|
@ -382,28 +365,28 @@ func (d deliver) unbond(tx TxUnbond) error {
|
|||
|
||||
// if the bond is the owner of the candidate then
|
||||
// trigger a revoke candidacy
|
||||
if d.sender.Equals(candidate.Owner) &&
|
||||
if tr.sender.Equals(candidate.Owner) &&
|
||||
candidate.Status != Revoked {
|
||||
revokeCandidacy = true
|
||||
}
|
||||
|
||||
// remove the bond
|
||||
removeDelegatorBond(d.store, d.sender, tx.PubKey)
|
||||
tr.keeper.removeDelegatorBond(tr.sender, tx.PubKey)
|
||||
} else {
|
||||
saveDelegatorBond(d.store, d.sender, bond)
|
||||
tr.keeper.saveDelegatorBond(tr.sender, bond)
|
||||
}
|
||||
|
||||
// transfer coins back to account
|
||||
var poolAccount crypto.Address
|
||||
if candidate.Status == Bonded {
|
||||
poolAccount = d.params.HoldBonded
|
||||
poolAccount = tr.params.HoldBonded
|
||||
} else {
|
||||
poolAccount = d.params.HoldUnbonded
|
||||
poolAccount = tr.params.HoldUnbonded
|
||||
}
|
||||
|
||||
returnCoins := candidate.removeShares(shares, d.gs)
|
||||
err := d.transfer(poolAccount, d.sender,
|
||||
sdk.Coins{{d.params.AllowedBondDenom, returnCoins}})
|
||||
returnCoins := candidate.removeShares(shares, tr.gs)
|
||||
err := tr.transfer(poolAccount, tr.sender,
|
||||
sdk.Coins{{tr.params.AllowedBondDenom, returnCoins}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -413,7 +396,7 @@ func (d deliver) unbond(tx TxUnbond) error {
|
|||
|
||||
// change the share types to unbonded if they were not already
|
||||
if candidate.Status == Bonded {
|
||||
err = d.bondedToUnbondedPool(candidate)
|
||||
err = tr.bondedToUnbondedPool(candidate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -425,11 +408,11 @@ func (d deliver) unbond(tx TxUnbond) error {
|
|||
|
||||
// deduct shares from the candidate and save
|
||||
if candidate.Liabilities.IsZero() {
|
||||
removeCandidate(d.store, tx.PubKey)
|
||||
tr.keeper.removeCandidate(tx.PubKey)
|
||||
} else {
|
||||
saveCandidate(d.store, candidate)
|
||||
tr.keeper.saveCandidate(candidate)
|
||||
}
|
||||
|
||||
saveGlobalState(d.store, d.gs)
|
||||
tr.keeper.saveGlobalState(tr.gs)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -9,10 +9,6 @@ import (
|
|||
|
||||
//nolint
|
||||
var (
|
||||
|
||||
// internal wire codec
|
||||
cdc *wire.Codec
|
||||
|
||||
// Keys for store prefixes
|
||||
CandidatesPubKeysKey = []byte{0x01} // key for all candidates' pubkeys
|
||||
ParamKey = []byte{0x02} // key for global parameters relating to staking
|
||||
|
@ -26,13 +22,6 @@ var (
|
|||
DelegatorBondsKeyPrefix = []byte{0x08} // prefix for each key to a delegator's bond
|
||||
)
|
||||
|
||||
func init() {
|
||||
cdc = wire.NewCodec()
|
||||
cdc.RegisterInterface((*types.Rational)(nil), nil) // XXX make like crypto.RegisterWire()
|
||||
cdc.RegisterConcrete(types.Rat{}, "rat", nil)
|
||||
crypto.RegisterWire(cdc)
|
||||
}
|
||||
|
||||
// GetCandidateKey - get the key for the candidate with pubKey
|
||||
func GetCandidateKey(pubKey crypto.PubKey) []byte {
|
||||
return append(CandidateKeyPrefix, pubKey.Bytes()...)
|
||||
|
@ -72,10 +61,28 @@ func GetDelegatorBondsKey(delegator crypto.Address) []byte {
|
|||
return append(DelegatorBondsKeyPrefix, res...)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//___________________________________________________________________________
|
||||
|
||||
func loadCandidate(store types.KVStore, pubKey crypto.PubKey) *Candidate {
|
||||
b := store.Get(GetCandidateKey(pubKey))
|
||||
// keeper of the staking store
|
||||
type Keeper struct {
|
||||
store types.KVStore
|
||||
cdc *wire.Codec
|
||||
}
|
||||
|
||||
func NewKeeper(ctx sdk.Context, key sdk.StoreKey) Keeper {
|
||||
cdc := wire.NewCodec()
|
||||
cdc.RegisterInterface((*types.Rational)(nil), nil) // XXX make like crypto.RegisterWire()
|
||||
cdc.RegisterConcrete(types.Rat{}, "rat", nil)
|
||||
crypto.RegisterWire(cdc)
|
||||
|
||||
return StakeKeeper{
|
||||
store: ctx.KVStore(k.key),
|
||||
cdc: cdc,
|
||||
}
|
||||
}
|
||||
|
||||
func (k Keeper) loadCandidate(pubKey crypto.PubKey) *Candidate {
|
||||
b := k.store.Get(GetCandidateKey(pubKey))
|
||||
if b == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -87,31 +94,31 @@ func loadCandidate(store types.KVStore, pubKey crypto.PubKey) *Candidate {
|
|||
return candidate
|
||||
}
|
||||
|
||||
func saveCandidate(store types.KVStore, candidate *Candidate) {
|
||||
func (k Keeper) saveCandidate(candidate *Candidate) {
|
||||
|
||||
// XXX should only remove validator if we know candidate is a validator
|
||||
removeValidator(store, candidate.PubKey)
|
||||
removeValidator(k.store, candidate.PubKey)
|
||||
validator := &Validator{candidate.PubKey, candidate.VotingPower}
|
||||
updateValidator(store, validator)
|
||||
updateValidator(k.store, validator)
|
||||
|
||||
b, err := cdc.MarshalJSON(*candidate)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store.Set(GetCandidateKey(candidate.PubKey), b)
|
||||
k.store.Set(GetCandidateKey(candidate.PubKey), b)
|
||||
}
|
||||
|
||||
func removeCandidate(store types.KVStore, pubKey crypto.PubKey) {
|
||||
func (k Keeper) removeCandidate(pubKey crypto.PubKey) {
|
||||
|
||||
// XXX should only remove validator if we know candidate is a validator
|
||||
removeValidator(store, pubKey)
|
||||
store.Delete(GetCandidateKey(pubKey))
|
||||
removeValidator(k.store, pubKey)
|
||||
k.store.Delete(GetCandidateKey(pubKey))
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//___________________________________________________________________________
|
||||
|
||||
//func loadValidator(store types.KVStore, pubKey crypto.PubKey, votingPower types.Rational) *Validator {
|
||||
//b := store.Get(GetValidatorKey(pubKey, votingPower))
|
||||
//func loadValidator(k.store types.KVStore, pubKey crypto.PubKey, votingPower types.Rational) *Validator {
|
||||
//b := k.store.Get(GetValidatorKey(pubKey, votingPower))
|
||||
//if b == nil {
|
||||
//return nil
|
||||
//}
|
||||
|
@ -125,7 +132,7 @@ func removeCandidate(store types.KVStore, pubKey crypto.PubKey) {
|
|||
|
||||
// updateValidator - update a validator and create accumulate any changes
|
||||
// in the changed validator substore
|
||||
func updateValidator(store types.KVStore, validator *Validator) {
|
||||
func (k Keeper) updateValidator(validator *Validator) {
|
||||
|
||||
b, err := cdc.MarshalJSON(*validator)
|
||||
if err != nil {
|
||||
|
@ -133,34 +140,34 @@ func updateValidator(store types.KVStore, validator *Validator) {
|
|||
}
|
||||
|
||||
// add to the validators to update list if necessary
|
||||
store.Set(GetValidatorUpdatesKey(validator.PubKey), b)
|
||||
k.store.Set(GetValidatorUpdatesKey(validator.PubKey), b)
|
||||
|
||||
// update the list ordered by voting power
|
||||
store.Set(GetValidatorKey(validator.PubKey, validator.VotingPower), b)
|
||||
k.store.Set(GetValidatorKey(validator.PubKey, validator.VotingPower), b)
|
||||
}
|
||||
|
||||
func removeValidator(store types.KVStore, pubKey crypto.PubKey) {
|
||||
func (k Keeper) removeValidator(pubKey crypto.PubKey) {
|
||||
|
||||
//add validator with zero power to the validator updates
|
||||
b, err := cdc.MarshalJSON(Validator{pubKey, types.ZeroRat})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store.Set(GetValidatorUpdatesKey(pubKey), b)
|
||||
k.store.Set(GetValidatorUpdatesKey(pubKey), b)
|
||||
|
||||
// now actually delete from the validator set
|
||||
candidate := loadCandidate(store, pubKey)
|
||||
candidate := loadCandidate(k.store, pubKey)
|
||||
if candidate != nil {
|
||||
store.Delete(GetValidatorKey(pubKey, candidate.VotingPower))
|
||||
k.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 getValidators(store types.KVStore, maxVal int) (validators []Validator) {
|
||||
func (k Keeper) getValidators(maxVal int) (validators []Validator) {
|
||||
|
||||
iterator := store.Iterator(subspace(ValidatorKeyPrefix)) //smallest to largest
|
||||
iterator := k.store.Iterator(subspace(ValidatorKeyPrefix)) //smallest to largest
|
||||
|
||||
validators = make([]Validator, maxVal)
|
||||
for i := 0; ; i++ {
|
||||
|
@ -181,12 +188,12 @@ func getValidators(store types.KVStore, maxVal int) (validators []Validator) {
|
|||
return
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//_________________________________________________________________________
|
||||
|
||||
// get the most updated validators
|
||||
func getValidatorUpdates(store types.KVStore) (updates []Validator) {
|
||||
func (k Keeper) getValidatorUpdates() (updates []Validator) {
|
||||
|
||||
iterator := store.Iterator(subspace(ValidatorUpdatesKeyPrefix)) //smallest to largest
|
||||
iterator := k.store.Iterator(subspace(ValidatorUpdatesKeyPrefix)) //smallest to largest
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
valBytes := iterator.Value()
|
||||
|
@ -203,10 +210,10 @@ func getValidatorUpdates(store types.KVStore) (updates []Validator) {
|
|||
}
|
||||
|
||||
// remove all validator update entries
|
||||
func clearValidatorUpdates(store types.KVStore, maxVal int) {
|
||||
iterator := store.Iterator(subspace(ValidatorUpdatesKeyPrefix))
|
||||
func (k Keeper) clearValidatorUpdates(maxVal int) {
|
||||
iterator := k.store.Iterator(subspace(ValidatorUpdatesKeyPrefix))
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
store.Delete(iterator.Key()) // XXX write test for this, may need to be in a second loop
|
||||
k.store.Delete(iterator.Key()) // XXX write test for this, may need to be in a second loop
|
||||
}
|
||||
iterator.Close()
|
||||
}
|
||||
|
@ -214,11 +221,11 @@ func clearValidatorUpdates(store types.KVStore, maxVal int) {
|
|||
//---------------------------------------------------------------------
|
||||
|
||||
// loadCandidates - get the active list of all candidates TODO replace with multistore
|
||||
func loadCandidates(store types.KVStore) (candidates Candidates) {
|
||||
func (k Keeper) loadCandidates() (candidates Candidates) {
|
||||
|
||||
iterator := store.Iterator(subspace(CandidateKeyPrefix))
|
||||
//iterator := store.Iterator(CandidateKeyPrefix, []byte(nil))
|
||||
//iterator := store.Iterator([]byte{}, []byte(nil))
|
||||
iterator := k.store.Iterator(subspace(CandidateKeyPrefix))
|
||||
//iterator := k.store.Iterator(CandidateKeyPrefix, []byte(nil))
|
||||
//iterator := k.store.Iterator([]byte{}, []byte(nil))
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
candidateBytes := iterator.Value()
|
||||
|
@ -233,13 +240,12 @@ func loadCandidates(store types.KVStore) (candidates Candidates) {
|
|||
return candidates
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//_____________________________________________________________________
|
||||
|
||||
// load the pubkeys of all candidates a delegator is delegated too
|
||||
func loadDelegatorCandidates(store types.KVStore,
|
||||
delegator crypto.Address) (candidates []crypto.PubKey) {
|
||||
func (k Keeper) loadDelegatorCandidates(delegator crypto.Address) (candidates []crypto.PubKey) {
|
||||
|
||||
candidateBytes := store.Get(GetDelegatorBondsKey(delegator))
|
||||
candidateBytes := k.store.Get(GetDelegatorBondsKey(delegator))
|
||||
if candidateBytes == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -251,12 +257,12 @@ func loadDelegatorCandidates(store types.KVStore,
|
|||
return
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//_____________________________________________________________________
|
||||
|
||||
func loadDelegatorBond(store types.KVStore,
|
||||
delegator crypto.Address, candidate crypto.PubKey) *DelegatorBond {
|
||||
func (k Keeper) loadDelegatorBond(delegator crypto.Address,
|
||||
candidate crypto.PubKey) *DelegatorBond {
|
||||
|
||||
delegatorBytes := store.Get(GetDelegatorBondKey(delegator, candidate))
|
||||
delegatorBytes := k.store.Get(GetDelegatorBondKey(delegator, candidate))
|
||||
if delegatorBytes == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -269,17 +275,18 @@ func loadDelegatorBond(store types.KVStore,
|
|||
return bond
|
||||
}
|
||||
|
||||
func saveDelegatorBond(store types.KVStore, delegator crypto.Address, bond *DelegatorBond) {
|
||||
func (k Keeper) saveDelegatorBond(delegator crypto.Address,
|
||||
bond *DelegatorBond) {
|
||||
|
||||
// if a new bond add to the list of bonds
|
||||
if loadDelegatorBond(store, delegator, bond.PubKey) == nil {
|
||||
pks := loadDelegatorCandidates(store, delegator)
|
||||
if loadDelegatorBond(k.store, delegator, bond.PubKey) == nil {
|
||||
pks := loadDelegatorCandidates(k.store, delegator)
|
||||
pks = append(pks, (*bond).PubKey)
|
||||
b, err := cdc.MarshalJSON(pks)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store.Set(GetDelegatorBondsKey(delegator), b)
|
||||
k.store.Set(GetDelegatorBondsKey(delegator), b)
|
||||
}
|
||||
|
||||
// now actually save the bond
|
||||
|
@ -287,14 +294,14 @@ func saveDelegatorBond(store types.KVStore, delegator crypto.Address, bond *Dele
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store.Set(GetDelegatorBondKey(delegator, bond.PubKey), b)
|
||||
k.store.Set(GetDelegatorBondKey(delegator, bond.PubKey), b)
|
||||
//updateDelegatorBonds(store, delegator)
|
||||
}
|
||||
|
||||
func removeDelegatorBond(store types.KVStore, delegator crypto.Address, candidate crypto.PubKey) {
|
||||
func (k Keeper) 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(store, delegator)
|
||||
pks := loadDelegatorCandidates(k.store, delegator)
|
||||
for i, pk := range pks {
|
||||
if candidate.Equals(pk) {
|
||||
pks = append(pks[:i], pks[i+1:]...)
|
||||
|
@ -304,18 +311,18 @@ func removeDelegatorBond(store types.KVStore, delegator crypto.Address, candidat
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store.Set(GetDelegatorBondsKey(delegator), b)
|
||||
k.store.Set(GetDelegatorBondsKey(delegator), b)
|
||||
|
||||
// now remove the actual bond
|
||||
store.Delete(GetDelegatorBondKey(delegator, candidate))
|
||||
k.store.Delete(GetDelegatorBondKey(delegator, candidate))
|
||||
//updateDelegatorBonds(store, delegator)
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// load/save the global staking params
|
||||
func loadParams(store types.KVStore) (params Params) {
|
||||
b := store.Get(ParamKey)
|
||||
func (k Keeper) loadParams() (params Params) {
|
||||
b := k.store.Get(ParamKey)
|
||||
if b == nil {
|
||||
return defaultParams()
|
||||
}
|
||||
|
@ -324,22 +331,21 @@ func loadParams(store types.KVStore) (params Params) {
|
|||
if err != nil {
|
||||
panic(err) // This error should never occur big problem if does
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
func saveParams(store types.KVStore, params Params) {
|
||||
func (k Keeper) saveParams(params Params) {
|
||||
b, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store.Set(ParamKey, b)
|
||||
k.store.Set(ParamKey, b)
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// load/save the global staking state
|
||||
func loadGlobalState(store types.KVStore) (gs *GlobalState) {
|
||||
b := store.Get(GlobalStateKey)
|
||||
func (k Keeper) loadGlobalState() (gs *GlobalState) {
|
||||
b := k.store.Get(GlobalStateKey)
|
||||
if b == nil {
|
||||
return initialGlobalState()
|
||||
}
|
||||
|
@ -350,10 +356,11 @@ func loadGlobalState(store types.KVStore) (gs *GlobalState) {
|
|||
}
|
||||
return
|
||||
}
|
||||
func saveGlobalState(store types.KVStore, gs *GlobalState) {
|
||||
|
||||
func (k Keeper) saveGlobalState(gs *GlobalState) {
|
||||
b, err := cdc.MarshalJSON(*gs)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
store.Set(GlobalStateKey, b)
|
||||
k.store.Set(GlobalStateKey, b)
|
||||
}
|
|
@ -8,9 +8,6 @@ import (
|
|||
|
||||
// Params defines the high level settings for staking
|
||||
type Params struct {
|
||||
HoldBonded crypto.Address `json:"hold_bonded"` // account where all bonded coins are held
|
||||
HoldUnbonded crypto.Address `json:"hold_unbonded"` // account where all delegated but unbonded coins are held
|
||||
|
||||
InflationRateChange sdk.Rational `json:"inflation_rate_change"` // maximum annual change in inflation rate
|
||||
InflationMax sdk.Rational `json:"inflation_max"` // maximum inflation rate
|
||||
InflationMin sdk.Rational `json:"inflation_min"` // minimum inflation rate
|
||||
|
@ -28,8 +25,6 @@ type Params struct {
|
|||
|
||||
func defaultParams() Params {
|
||||
return Params{
|
||||
HoldBonded: []byte("77777777777777777777777777777777"),
|
||||
HoldUnbonded: []byte("88888888888888888888888888888888"),
|
||||
InflationRateChange: sdk.NewRat(13, 100),
|
||||
InflationMax: sdk.NewRat(20, 100),
|
||||
InflationMin: sdk.NewRat(7, 100),
|
||||
|
@ -94,6 +89,9 @@ func (gs *GlobalState) unbondedShareExRate() sdk.Rational {
|
|||
return gs.UnbondedShares.Inv().Mul(sdk.NewRat(gs.UnbondedPool))
|
||||
}
|
||||
|
||||
// XXX XXX XXX
|
||||
// expand to include the function of actually transfering the tokens
|
||||
|
||||
func (gs *GlobalState) addTokensBonded(amount int64) (issuedShares sdk.Rational) {
|
||||
issuedShares = gs.bondedShareExRate().Inv().Mul(sdk.NewRat(amount)) // (tokens/shares)^-1 * tokens
|
||||
gs.BondedPool += amount
|
||||
|
|
Loading…
Reference in New Issue