2018-01-11 21:30:39 -08:00
|
|
|
package stake
|
|
|
|
|
|
|
|
import (
|
|
|
|
crypto "github.com/tendermint/go-crypto"
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/wire"
|
2018-01-11 21:30:39 -08:00
|
|
|
)
|
|
|
|
|
2018-02-28 08:27:07 -08:00
|
|
|
//nolint
|
2018-01-11 21:30:39 -08:00
|
|
|
var (
|
|
|
|
// Keys for store prefixes
|
|
|
|
CandidatesPubKeysKey = []byte{0x01} // key for all candidates' pubkeys
|
|
|
|
ParamKey = []byte{0x02} // key for global parameters relating to staking
|
|
|
|
GlobalStateKey = []byte{0x03} // key for global parameters relating to staking
|
|
|
|
|
|
|
|
// Key prefixes
|
2018-01-31 18:56:46 -08:00
|
|
|
CandidateKeyPrefix = []byte{0x04} // prefix for each key to a candidate
|
|
|
|
ValidatorKeyPrefix = []byte{0x05} // prefix for each key to a candidate
|
|
|
|
ValidatorUpdatesKeyPrefix = []byte{0x06} // prefix for each key to a candidate
|
|
|
|
DelegatorBondKeyPrefix = []byte{0x07} // prefix for each key to a delegator's bond
|
|
|
|
DelegatorBondsKeyPrefix = []byte{0x08} // prefix for each key to a delegator's bond
|
2018-01-11 21:30:39 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
// GetCandidateKey - get the key for the candidate with pubKey
|
|
|
|
func GetCandidateKey(pubKey crypto.PubKey) []byte {
|
|
|
|
return append(CandidateKeyPrefix, pubKey.Bytes()...)
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:06:25 -08:00
|
|
|
// GetValidatorKey - get the key for the validator used in the power-store
|
2018-03-13 11:27:52 -07:00
|
|
|
func GetValidatorKey(pubKey crypto.PubKey, power sdk.Rational) []byte {
|
2018-01-31 18:56:46 -08:00
|
|
|
b, _ := cdc.MarshalJSON(power) // TODO need to handle error here?
|
2018-01-25 01:06:25 -08:00
|
|
|
return append(ValidatorKeyPrefix, append(b, pubKey.Bytes()...)...) // TODO does this need prefix if its in its own store
|
|
|
|
}
|
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
// GetValidatorUpdatesKey - get the key for the validator used in the power-store
|
|
|
|
func GetValidatorUpdatesKey(pubKey crypto.PubKey) []byte {
|
|
|
|
return append(ValidatorUpdatesKeyPrefix, pubKey.Bytes()...) // TODO does this need prefix if its in its own store
|
|
|
|
}
|
|
|
|
|
2018-01-11 21:30:39 -08:00
|
|
|
// GetDelegatorBondKey - get the key for delegator bond with candidate
|
2018-01-18 00:39:16 -08:00
|
|
|
func GetDelegatorBondKey(delegator crypto.Address, candidate crypto.PubKey) []byte {
|
2018-01-11 21:30:39 -08:00
|
|
|
return append(GetDelegatorBondKeyPrefix(delegator), candidate.Bytes()...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetDelegatorBondKeyPrefix - get the prefix for a delegator for all candidates
|
2018-01-18 00:39:16 -08:00
|
|
|
func GetDelegatorBondKeyPrefix(delegator crypto.Address) []byte {
|
2018-01-31 18:56:46 -08:00
|
|
|
res, err := cdc.MarshalJSON(&delegator)
|
2018-01-18 00:39:16 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return append(DelegatorBondKeyPrefix, res...)
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetDelegatorBondsKey - get the key for list of all the delegator's bonds
|
2018-01-18 00:39:16 -08:00
|
|
|
func GetDelegatorBondsKey(delegator crypto.Address) []byte {
|
2018-01-31 18:56:46 -08:00
|
|
|
res, err := cdc.MarshalJSON(&delegator)
|
2018-01-18 00:39:16 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return append(DelegatorBondsKeyPrefix, res...)
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
|
2018-02-28 08:27:07 -08:00
|
|
|
//___________________________________________________________________________
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
// mapper of the staking store
|
|
|
|
type Mapper struct {
|
|
|
|
store sdk.KVStore
|
2018-02-28 08:27:07 -08:00
|
|
|
cdc *wire.Codec
|
|
|
|
}
|
2018-01-11 21:30:39 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func NewMapper(ctx sdk.Context, key sdk.StoreKey) Mapper {
|
2018-02-28 08:27:07 -08:00
|
|
|
cdc := wire.NewCodec()
|
2018-03-13 11:27:52 -07:00
|
|
|
cdc.RegisterInterface((*sdk.Rational)(nil), nil) // XXX make like crypto.RegisterWire()
|
|
|
|
cdc.RegisterConcrete(sdk.Rat{}, "rat", nil)
|
2018-02-28 08:27:07 -08:00
|
|
|
crypto.RegisterWire(cdc)
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
return StakeMapper{
|
|
|
|
store: ctx.KVStore(m.key),
|
2018-02-28 08:27:07 -08:00
|
|
|
cdc: cdc,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) loadCandidate(pubKey crypto.PubKey) *Candidate {
|
|
|
|
b := m.store.Get(GetCandidateKey(pubKey))
|
2018-01-11 21:30:39 -08:00
|
|
|
if b == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
candidate := new(Candidate)
|
2018-01-31 18:56:46 -08:00
|
|
|
err := cdc.UnmarshalJSON(b, candidate)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
2018-01-25 01:06:25 -08:00
|
|
|
panic(err) // This error should never occur big problem if does
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
return candidate
|
|
|
|
}
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) saveCandidate(candidate *Candidate) {
|
2018-01-11 21:30:39 -08:00
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
// XXX should only remove validator if we know candidate is a validator
|
2018-03-13 11:27:52 -07:00
|
|
|
removeValidator(m.store, candidate.PubKey)
|
2018-01-25 01:06:25 -08:00
|
|
|
validator := &Validator{candidate.PubKey, candidate.VotingPower}
|
2018-03-13 11:27:52 -07:00
|
|
|
updateValidator(m.store, validator)
|
2018-01-11 21:30:39 -08:00
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
b, err := cdc.MarshalJSON(*candidate)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(GetCandidateKey(candidate.PubKey), b)
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) removeCandidate(pubKey crypto.PubKey) {
|
2018-01-31 18:56:46 -08:00
|
|
|
|
|
|
|
// XXX should only remove validator if we know candidate is a validator
|
2018-03-13 11:27:52 -07:00
|
|
|
removeValidator(m.store, pubKey)
|
|
|
|
m.store.Delete(GetCandidateKey(pubKey))
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
|
2018-02-28 08:27:07 -08:00
|
|
|
//___________________________________________________________________________
|
2018-01-11 21:30:39 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
//func loadValidator(m.store sdk.KVStore, pubKey crypto.PubKey, votingPower sdk.Rational) *Validator {
|
|
|
|
//b := m.store.Get(GetValidatorKey(pubKey, votingPower))
|
2018-01-31 18:56:46 -08:00
|
|
|
//if b == nil {
|
|
|
|
//return nil
|
|
|
|
//}
|
|
|
|
//validator := new(Validator)
|
|
|
|
//err := cdc.UnmarshalJSON(b, validator)
|
|
|
|
//if err != nil {
|
|
|
|
//panic(err) // This error should never occur big problem if does
|
|
|
|
//}
|
|
|
|
//return validator
|
|
|
|
//}
|
|
|
|
|
|
|
|
// updateValidator - update a validator and create accumulate any changes
|
|
|
|
// in the changed validator substore
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) updateValidator(validator *Validator) {
|
2018-01-25 01:06:25 -08:00
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
b, err := cdc.MarshalJSON(*validator)
|
2018-01-23 01:04:36 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-01-31 18:56:46 -08:00
|
|
|
|
|
|
|
// add to the validators to update list if necessary
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(GetValidatorUpdatesKey(validator.PubKey), b)
|
2018-01-31 18:56:46 -08:00
|
|
|
|
|
|
|
// update the list ordered by voting power
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(GetValidatorKey(validator.PubKey, validator.VotingPower), b)
|
2018-01-23 01:04:36 -08:00
|
|
|
}
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) removeValidator(pubKey crypto.PubKey) {
|
2018-01-31 18:56:46 -08:00
|
|
|
|
|
|
|
//add validator with zero power to the validator updates
|
2018-03-13 11:27:52 -07:00
|
|
|
b, err := cdc.MarshalJSON(Validator{pubKey, sdk.ZeroRat})
|
2018-01-31 18:56:46 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(GetValidatorUpdatesKey(pubKey), b)
|
2018-01-25 01:06:25 -08:00
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
// now actually delete from the validator set
|
2018-03-13 11:27:52 -07:00
|
|
|
candidate := loadCandidate(m.store, pubKey)
|
2018-01-25 01:06:25 -08:00
|
|
|
if candidate != nil {
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Delete(GetValidatorKey(pubKey, candidate.VotingPower))
|
2018-01-23 01:04:36 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
// 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
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) getValidators(maxVal int) (validators []Validator) {
|
2018-01-23 01:04:36 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
iterator := m.store.Iterator(subspace(ValidatorKeyPrefix)) //smallest to largest
|
2018-01-23 01:04:36 -08:00
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
validators = make([]Validator, maxVal)
|
2018-01-23 01:04:36 -08:00
|
|
|
for i := 0; ; i++ {
|
|
|
|
if !iterator.Valid() || i > maxVal {
|
|
|
|
iterator.Close()
|
|
|
|
break
|
|
|
|
}
|
2018-01-25 01:06:25 -08:00
|
|
|
valBytes := iterator.Value()
|
|
|
|
var val Validator
|
2018-01-31 18:56:46 -08:00
|
|
|
err := cdc.UnmarshalJSON(valBytes, &val)
|
2018-01-23 01:04:36 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-01-25 01:06:25 -08:00
|
|
|
validators[i] = val
|
2018-01-23 01:04:36 -08:00
|
|
|
iterator.Next()
|
|
|
|
}
|
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-02-28 08:27:07 -08:00
|
|
|
//_________________________________________________________________________
|
2018-01-31 18:56:46 -08:00
|
|
|
|
|
|
|
// get the most updated validators
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) getValidatorUpdates() (updates []Validator) {
|
2018-01-31 18:56:46 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
iterator := m.store.Iterator(subspace(ValidatorUpdatesKeyPrefix)) //smallest to largest
|
2018-01-31 18:56:46 -08:00
|
|
|
|
|
|
|
for ; iterator.Valid(); iterator.Next() {
|
|
|
|
valBytes := iterator.Value()
|
|
|
|
var val Validator
|
|
|
|
err := cdc.UnmarshalJSON(valBytes, &val)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
updates = append(updates, val)
|
|
|
|
}
|
|
|
|
|
|
|
|
iterator.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove all validator update entries
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) clearValidatorUpdates(maxVal int) {
|
|
|
|
iterator := m.store.Iterator(subspace(ValidatorUpdatesKeyPrefix))
|
2018-01-31 18:56:46 -08:00
|
|
|
for ; iterator.Valid(); iterator.Next() {
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Delete(iterator.Key()) // XXX write test for this, may need to be in a second loop
|
2018-01-31 18:56:46 -08:00
|
|
|
}
|
|
|
|
iterator.Close()
|
2018-01-23 01:04:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
2018-01-25 01:06:25 -08:00
|
|
|
// loadCandidates - get the active list of all candidates TODO replace with multistore
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) loadCandidates() (candidates Candidates) {
|
2018-01-25 01:06:25 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
iterator := m.store.Iterator(subspace(CandidateKeyPrefix))
|
|
|
|
//iterator := m.store.Iterator(CandidateKeyPrefix, []byte(nil))
|
|
|
|
//iterator := m.store.Iterator([]byte{}, []byte(nil))
|
2018-01-25 01:06:25 -08:00
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
for ; iterator.Valid(); iterator.Next() {
|
2018-01-25 01:06:25 -08:00
|
|
|
candidateBytes := iterator.Value()
|
|
|
|
var candidate Candidate
|
2018-01-31 18:56:46 -08:00
|
|
|
err := cdc.UnmarshalJSON(candidateBytes, &candidate)
|
2018-01-25 01:06:25 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-01-31 18:56:46 -08:00
|
|
|
candidates = append(candidates, &candidate)
|
2018-01-25 01:06:25 -08:00
|
|
|
}
|
2018-01-31 18:56:46 -08:00
|
|
|
iterator.Close()
|
2018-01-25 01:06:25 -08:00
|
|
|
return candidates
|
|
|
|
}
|
|
|
|
|
2018-02-28 08:27:07 -08:00
|
|
|
//_____________________________________________________________________
|
2018-01-25 01:06:25 -08:00
|
|
|
|
2018-01-11 21:30:39 -08:00
|
|
|
// load the pubkeys of all candidates a delegator is delegated too
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) loadDelegatorCandidates(delegator crypto.Address) (candidates []crypto.PubKey) {
|
2018-01-11 21:30:39 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
candidateBytes := m.store.Get(GetDelegatorBondsKey(delegator))
|
2018-01-11 21:30:39 -08:00
|
|
|
if candidateBytes == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
err := cdc.UnmarshalJSON(candidateBytes, &candidates)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-02-28 08:27:07 -08:00
|
|
|
//_____________________________________________________________________
|
2018-01-11 21:30:39 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) loadDelegatorBond(delegator crypto.Address,
|
2018-02-28 08:27:07 -08:00
|
|
|
candidate crypto.PubKey) *DelegatorBond {
|
2018-01-11 21:30:39 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
delegatorBytes := m.store.Get(GetDelegatorBondKey(delegator, candidate))
|
2018-01-11 21:30:39 -08:00
|
|
|
if delegatorBytes == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
bond := new(DelegatorBond)
|
2018-01-31 18:56:46 -08:00
|
|
|
err := cdc.UnmarshalJSON(delegatorBytes, bond)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return bond
|
|
|
|
}
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) saveDelegatorBond(delegator crypto.Address,
|
2018-02-28 08:27:07 -08:00
|
|
|
bond *DelegatorBond) {
|
2018-01-11 21:30:39 -08:00
|
|
|
|
|
|
|
// if a new bond add to the list of bonds
|
2018-03-13 11:27:52 -07:00
|
|
|
if loadDelegatorBond(m.store, delegator, bond.PubKey) == nil {
|
|
|
|
pks := loadDelegatorCandidates(m.store, delegator)
|
2018-01-11 21:30:39 -08:00
|
|
|
pks = append(pks, (*bond).PubKey)
|
2018-01-31 18:56:46 -08:00
|
|
|
b, err := cdc.MarshalJSON(pks)
|
2018-01-18 00:39:16 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(GetDelegatorBondsKey(delegator), b)
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// now actually save the bond
|
2018-01-31 18:56:46 -08:00
|
|
|
b, err := cdc.MarshalJSON(*bond)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(GetDelegatorBondKey(delegator, bond.PubKey), b)
|
2018-01-11 21:30:39 -08:00
|
|
|
//updateDelegatorBonds(store, delegator)
|
|
|
|
}
|
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) removeDelegatorBond(delegator crypto.Address, candidate crypto.PubKey) {
|
2018-01-11 21:30:39 -08:00
|
|
|
// TODO use list queries on multistore to remove iterations here!
|
|
|
|
// first remove from the list of bonds
|
2018-03-13 11:27:52 -07:00
|
|
|
pks := loadDelegatorCandidates(m.store, delegator)
|
2018-01-11 21:30:39 -08:00
|
|
|
for i, pk := range pks {
|
|
|
|
if candidate.Equals(pk) {
|
|
|
|
pks = append(pks[:i], pks[i+1:]...)
|
|
|
|
}
|
|
|
|
}
|
2018-01-31 18:56:46 -08:00
|
|
|
b, err := cdc.MarshalJSON(pks)
|
2018-01-18 00:39:16 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(GetDelegatorBondsKey(delegator), b)
|
2018-01-11 21:30:39 -08:00
|
|
|
|
|
|
|
// now remove the actual bond
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Delete(GetDelegatorBondKey(delegator, candidate))
|
2018-01-11 21:30:39 -08:00
|
|
|
//updateDelegatorBonds(store, delegator)
|
|
|
|
}
|
|
|
|
|
|
|
|
//_______________________________________________________________________
|
|
|
|
|
|
|
|
// load/save the global staking params
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) loadParams() (params Params) {
|
|
|
|
b := m.store.Get(ParamKey)
|
2018-01-11 21:30:39 -08:00
|
|
|
if b == nil {
|
|
|
|
return defaultParams()
|
|
|
|
}
|
|
|
|
|
2018-01-31 18:56:46 -08:00
|
|
|
err := cdc.UnmarshalJSON(b, ¶ms)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
2018-01-25 01:06:25 -08:00
|
|
|
panic(err) // This error should never occur big problem if does
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) saveParams(params Params) {
|
2018-01-31 18:56:46 -08:00
|
|
|
b, err := cdc.MarshalJSON(params)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(ParamKey, b)
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
//_______________________________________________________________________
|
|
|
|
|
|
|
|
// load/save the global staking state
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) loadGlobalState() (gs *GlobalState) {
|
|
|
|
b := m.store.Get(GlobalStateKey)
|
2018-01-11 21:30:39 -08:00
|
|
|
if b == nil {
|
|
|
|
return initialGlobalState()
|
|
|
|
}
|
|
|
|
gs = new(GlobalState)
|
2018-01-31 18:56:46 -08:00
|
|
|
err := cdc.UnmarshalJSON(b, gs)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
2018-01-25 01:06:25 -08:00
|
|
|
panic(err) // This error should never occur big problem if does
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2018-02-28 08:27:07 -08:00
|
|
|
|
2018-03-13 11:27:52 -07:00
|
|
|
func (m Mapper) saveGlobalState(gs *GlobalState) {
|
2018-01-31 18:56:46 -08:00
|
|
|
b, err := cdc.MarshalJSON(*gs)
|
2018-01-11 21:30:39 -08:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-03-13 11:27:52 -07:00
|
|
|
m.store.Set(GlobalStateKey, b)
|
2018-01-11 21:30:39 -08:00
|
|
|
}
|