paramstore refactor base
rm debug code fix lint fix hack.go
This commit is contained in:
parent
c4b243142d
commit
cc0e2c9523
|
@ -88,11 +88,11 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
|
|||
|
||||
// add handlers
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
||||
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams)
|
||||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.tkeyStake, app.bankKeeper, app.RegisterCodespace(stake.DefaultCodespace))
|
||||
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Getter(), app.RegisterCodespace(slashing.DefaultCodespace))
|
||||
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams)
|
||||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.tkeyStake, app.bankKeeper, app.paramsKeeper.Subspace(stake.DefaultParamSpace), app.RegisterCodespace(stake.DefaultCodespace))
|
||||
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamSpace), app.RegisterCodespace(slashing.DefaultCodespace))
|
||||
app.stakeKeeper = app.stakeKeeper.WithHooks(app.slashingKeeper.Hooks())
|
||||
app.govKeeper = gov.NewKeeper(app.cdc, app.keyGov, app.paramsKeeper.Setter(), app.bankKeeper, app.stakeKeeper, app.RegisterCodespace(gov.DefaultCodespace))
|
||||
app.govKeeper = gov.NewKeeper(app.cdc, app.keyGov, app.paramsKeeper, app.paramsKeeper.Subspace(gov.DefaultParamSpace), app.bankKeeper, app.stakeKeeper, app.RegisterCodespace(gov.DefaultCodespace))
|
||||
app.feeCollectionKeeper = auth.NewFeeCollectionKeeper(app.cdc, app.keyFeeCollection)
|
||||
|
||||
// register message routes
|
||||
|
@ -184,7 +184,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
|||
}
|
||||
|
||||
// load the address to pubkey map
|
||||
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.StakeData)
|
||||
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
|
||||
|
||||
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
||||
err = GaiaValidateGenesisState(genesisState)
|
||||
|
@ -193,6 +193,11 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
|||
panic(err)
|
||||
}
|
||||
|
||||
err = slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return abci.ResponseInitChain{
|
||||
Validators: validators,
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/libs/db"
|
||||
|
@ -21,8 +22,9 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error {
|
|||
}
|
||||
|
||||
genesisState := GenesisState{
|
||||
Accounts: genaccs,
|
||||
StakeData: stake.DefaultGenesisState(),
|
||||
Accounts: genaccs,
|
||||
StakeData: stake.DefaultGenesisState(),
|
||||
SlashingData: slashing.HubDefaultGenesisState(),
|
||||
}
|
||||
|
||||
stateBytes, err := codec.MarshalJSONIndent(gapp.cdc, genesisState)
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
|
||||
|
@ -32,9 +33,10 @@ var (
|
|||
|
||||
// State to Unmarshal
|
||||
type GenesisState struct {
|
||||
Accounts []GenesisAccount `json:"accounts"`
|
||||
StakeData stake.GenesisState `json:"stake"`
|
||||
GovData gov.GenesisState `json:"gov"`
|
||||
Accounts []GenesisAccount `json:"accounts"`
|
||||
StakeData stake.GenesisState `json:"stake"`
|
||||
GovData gov.GenesisState `json:"gov"`
|
||||
SlashingData slashing.GenesisState `json:"slashing"`
|
||||
}
|
||||
|
||||
// GenesisAccount doesn't need pubkey or sequence
|
||||
|
@ -170,6 +172,8 @@ func GaiaAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (genesisStat
|
|||
// start with the default staking genesis state
|
||||
stakeData := stake.DefaultGenesisState()
|
||||
|
||||
slashingData := slashing.HubDefaultGenesisState()
|
||||
|
||||
// get genesis flag account information
|
||||
genaccs := make([]GenesisAccount, len(appGenTxs))
|
||||
for i, appGenTx := range appGenTxs {
|
||||
|
@ -192,9 +196,10 @@ func GaiaAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (genesisStat
|
|||
|
||||
// create the final app state
|
||||
genesisState = GenesisState{
|
||||
Accounts: genaccs,
|
||||
StakeData: stakeData,
|
||||
GovData: gov.DefaultGenesisState(),
|
||||
Accounts: genaccs,
|
||||
StakeData: stakeData,
|
||||
GovData: gov.DefaultGenesisState(),
|
||||
SlashingData: slashingData,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation"
|
||||
stake "github.com/cosmos/cosmos-sdk/x/stake"
|
||||
stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation"
|
||||
|
@ -74,9 +75,10 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
|||
stakeGenesis.Params.InflationMax = sdk.NewDec(0)
|
||||
stakeGenesis.Params.InflationMin = sdk.NewDec(0)
|
||||
genesis := GenesisState{
|
||||
Accounts: genesisAccounts,
|
||||
StakeData: stakeGenesis,
|
||||
GovData: govGenesis,
|
||||
Accounts: genesisAccounts,
|
||||
StakeData: stakeGenesis,
|
||||
SlashingData: slashing.HubDefaultGenesisState(),
|
||||
GovData: govGenesis,
|
||||
}
|
||||
|
||||
// Marshal genesis
|
||||
|
|
|
@ -135,6 +135,7 @@ type GaiaApp struct {
|
|||
tkeyStake *sdk.TransientStoreKey
|
||||
keySlashing *sdk.KVStoreKey
|
||||
keyParams *sdk.KVStoreKey
|
||||
tkeyParams *sdk.TransientStoreKey
|
||||
|
||||
// Manage getting and setting accounts
|
||||
accountMapper auth.AccountMapper
|
||||
|
@ -161,6 +162,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.BaseAp
|
|||
tkeyStake: sdk.NewTransientStoreKey("transient_stake"),
|
||||
keySlashing: sdk.NewKVStoreKey("slashing"),
|
||||
keyParams: sdk.NewKVStoreKey("params"),
|
||||
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
|
||||
}
|
||||
|
||||
// define the accountMapper
|
||||
|
@ -172,9 +174,9 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.BaseAp
|
|||
|
||||
// add handlers
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountMapper)
|
||||
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams)
|
||||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.tkeyStake, app.bankKeeper, app.RegisterCodespace(stake.DefaultCodespace))
|
||||
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Getter(), app.RegisterCodespace(slashing.DefaultCodespace))
|
||||
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams, app.tkeyParams)
|
||||
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.tkeyStake, app.bankKeeper, app.paramsKeeper.Subspace(stake.DefaultParamSpace), app.RegisterCodespace(stake.DefaultCodespace))
|
||||
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamSpace), app.RegisterCodespace(slashing.DefaultCodespace))
|
||||
|
||||
// register message routes
|
||||
app.Router().
|
||||
|
@ -186,7 +188,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.BaseAp
|
|||
app.SetBeginBlocker(app.BeginBlocker)
|
||||
app.SetEndBlocker(app.EndBlocker)
|
||||
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper))
|
||||
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyStake, app.keySlashing)
|
||||
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyStake, app.keySlashing, app.keyParams)
|
||||
app.MountStore(app.tkeyParams, sdk.StoreTypeTransient)
|
||||
err := app.LoadLatestVersion(app.keyMain)
|
||||
if err != nil {
|
||||
cmn.Exit(err.Error())
|
||||
|
@ -252,6 +255,11 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
|||
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
}
|
||||
|
||||
err = slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return abci.ResponseInitChain{
|
||||
Validators: validators,
|
||||
}
|
||||
|
|
|
@ -13,13 +13,13 @@ import (
|
|||
func newGasKVStore() KVStore {
|
||||
meter := sdk.NewGasMeter(1000)
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
return NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
|
||||
return NewGasKVStore(meter, sdk.DefaultKVGasConfig(), mem)
|
||||
}
|
||||
|
||||
func TestGasKVStoreBasic(t *testing.T) {
|
||||
func TestKVGasKVStoreBasic(t *testing.T) {
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
meter := sdk.NewGasMeter(1000)
|
||||
st := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
|
||||
st := NewGasKVStore(meter, sdk.DefaultKVGasConfig(), mem)
|
||||
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
|
||||
st.Set(keyFmt(1), valFmt(1))
|
||||
require.Equal(t, valFmt(1), st.Get(keyFmt(1)))
|
||||
|
@ -28,10 +28,10 @@ func TestGasKVStoreBasic(t *testing.T) {
|
|||
require.Equal(t, meter.GasConsumed(), sdk.Gas(193))
|
||||
}
|
||||
|
||||
func TestGasKVStoreIterator(t *testing.T) {
|
||||
func TestKVGasKVStoreIterator(t *testing.T) {
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
meter := sdk.NewGasMeter(1000)
|
||||
st := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
|
||||
st := NewGasKVStore(meter, sdk.DefaultKVGasConfig(), mem)
|
||||
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
|
||||
require.Empty(t, st.Get(keyFmt(2)), "Expected `key2` to be empty")
|
||||
st.Set(keyFmt(1), valFmt(1))
|
||||
|
@ -52,24 +52,24 @@ func TestGasKVStoreIterator(t *testing.T) {
|
|||
require.Equal(t, meter.GasConsumed(), sdk.Gas(384))
|
||||
}
|
||||
|
||||
func TestGasKVStoreOutOfGasSet(t *testing.T) {
|
||||
func TestKVGasKVStoreOutOfGasSet(t *testing.T) {
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
meter := sdk.NewGasMeter(0)
|
||||
st := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
|
||||
st := NewGasKVStore(meter, sdk.DefaultKVGasConfig(), mem)
|
||||
require.Panics(t, func() { st.Set(keyFmt(1), valFmt(1)) }, "Expected out-of-gas")
|
||||
}
|
||||
|
||||
func TestGasKVStoreOutOfGasIterator(t *testing.T) {
|
||||
func TestKVGasKVStoreOutOfGasIterator(t *testing.T) {
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
meter := sdk.NewGasMeter(200)
|
||||
st := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
|
||||
st := NewGasKVStore(meter, sdk.DefaultKVGasConfig(), mem)
|
||||
st.Set(keyFmt(1), valFmt(1))
|
||||
iterator := st.Iterator(nil, nil)
|
||||
iterator.Next()
|
||||
require.Panics(t, func() { iterator.Value() }, "Expected out-of-gas")
|
||||
}
|
||||
|
||||
func testGasKVStoreWrap(t *testing.T, store KVStore) {
|
||||
func testKVGasKVStoreWrap(t *testing.T, store KVStore) {
|
||||
meter := sdk.NewGasMeter(10000)
|
||||
|
||||
store = store.Gas(meter, sdk.GasConfig{HasCost: 10})
|
||||
|
@ -84,22 +84,22 @@ func testGasKVStoreWrap(t *testing.T, store KVStore) {
|
|||
require.Equal(t, int64(40), meter.GasConsumed())
|
||||
}
|
||||
|
||||
func TestGasKVStoreWrap(t *testing.T) {
|
||||
func TestKVGasKVStoreWrap(t *testing.T) {
|
||||
db := dbm.NewMemDB()
|
||||
tree, _ := newTree(t, db)
|
||||
iavl := newIAVLStore(tree, numRecent, storeEvery)
|
||||
testGasKVStoreWrap(t, iavl)
|
||||
testKVGasKVStoreWrap(t, iavl)
|
||||
|
||||
st := NewCacheKVStore(iavl)
|
||||
testGasKVStoreWrap(t, st)
|
||||
testKVGasKVStoreWrap(t, st)
|
||||
|
||||
pref := st.Prefix([]byte("prefix"))
|
||||
testGasKVStoreWrap(t, pref)
|
||||
testKVGasKVStoreWrap(t, pref)
|
||||
|
||||
dsa := dbStoreAdapter{dbm.NewMemDB()}
|
||||
testGasKVStoreWrap(t, dsa)
|
||||
testKVGasKVStoreWrap(t, dsa)
|
||||
|
||||
ts := newTransientStore()
|
||||
testGasKVStoreWrap(t, ts)
|
||||
testKVGasKVStoreWrap(t, ts)
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,18 @@ type prefixStore struct {
|
|||
prefix []byte
|
||||
}
|
||||
|
||||
func clone(bz []byte) (res []byte) {
|
||||
res = make([]byte, len(bz))
|
||||
copy(res, bz)
|
||||
return
|
||||
}
|
||||
|
||||
func (s prefixStore) key(key []byte) (res []byte) {
|
||||
res = clone(s.prefix)
|
||||
res = append(res, key...)
|
||||
return
|
||||
}
|
||||
|
||||
// Implements Store
|
||||
func (s prefixStore) GetStoreType() StoreType {
|
||||
return s.parent.GetStoreType()
|
||||
|
@ -30,22 +42,23 @@ func (s prefixStore) CacheWrapWithTrace(w io.Writer, tc TraceContext) CacheWrap
|
|||
|
||||
// Implements KVStore
|
||||
func (s prefixStore) Get(key []byte) []byte {
|
||||
return s.parent.Get(append(s.prefix, key...))
|
||||
res := s.parent.Get(s.key(key))
|
||||
return res
|
||||
}
|
||||
|
||||
// Implements KVStore
|
||||
func (s prefixStore) Has(key []byte) bool {
|
||||
return s.parent.Has(append(s.prefix, key...))
|
||||
return s.parent.Has(s.key(key))
|
||||
}
|
||||
|
||||
// Implements KVStore
|
||||
func (s prefixStore) Set(key, value []byte) {
|
||||
s.parent.Set(append(s.prefix, key...), value)
|
||||
s.parent.Set(s.key(key), value)
|
||||
}
|
||||
|
||||
// Implements KVStore
|
||||
func (s prefixStore) Delete(key []byte) {
|
||||
s.parent.Delete(append(s.prefix, key...))
|
||||
s.parent.Delete(s.key(key))
|
||||
}
|
||||
|
||||
// Implements KVStore
|
||||
|
@ -60,27 +73,40 @@ func (s prefixStore) Gas(meter GasMeter, config GasConfig) KVStore {
|
|||
|
||||
// Implements KVStore
|
||||
func (s prefixStore) Iterator(start, end []byte) Iterator {
|
||||
newstart := clone(s.prefix)
|
||||
newstart = append(newstart, start...)
|
||||
|
||||
var newend []byte
|
||||
if end == nil {
|
||||
end = sdk.PrefixEndBytes(s.prefix)
|
||||
newend = sdk.PrefixEndBytes(s.prefix)
|
||||
} else {
|
||||
end = append(s.prefix, end...)
|
||||
newend = clone(s.prefix)
|
||||
newend = append(newend, end...)
|
||||
}
|
||||
|
||||
return prefixIterator{
|
||||
prefix: s.prefix,
|
||||
iter: s.parent.Iterator(append(s.prefix, start...), end),
|
||||
iter: s.parent.Iterator(newstart, newend),
|
||||
}
|
||||
}
|
||||
|
||||
// Implements KVStore
|
||||
func (s prefixStore) ReverseIterator(start, end []byte) Iterator {
|
||||
newstart := make([]byte, len(s.prefix), len(start))
|
||||
copy(newstart, s.prefix)
|
||||
newstart = append(newstart, start...)
|
||||
|
||||
newend := make([]byte, len(s.prefix)+len(end))
|
||||
if end == nil {
|
||||
end = sdk.PrefixEndBytes(s.prefix)
|
||||
newend = sdk.PrefixEndBytes(s.prefix)
|
||||
} else {
|
||||
end = append(s.prefix, end...)
|
||||
copy(newend, s.prefix)
|
||||
newend = append(newend, end...)
|
||||
}
|
||||
|
||||
return prefixIterator{
|
||||
prefix: s.prefix,
|
||||
iter: s.parent.ReverseIterator(start, end),
|
||||
iter: s.parent.ReverseIterator(newstart, newend),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ func TestCacheKVStorePrefix(t *testing.T) {
|
|||
func TestGasKVStorePrefix(t *testing.T) {
|
||||
meter := sdk.NewGasMeter(100000000)
|
||||
mem := dbStoreAdapter{dbm.NewMemDB()}
|
||||
gasStore := NewGasKVStore(meter, sdk.DefaultGasConfig(), mem)
|
||||
gasStore := NewGasKVStore(meter, sdk.DefaultKVGasConfig(), mem)
|
||||
|
||||
testPrefixStore(t, gasStore, []byte("test"))
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, logger log.Lo
|
|||
c = c.WithVoteInfos(nil)
|
||||
c = c.WithGasMeter(NewInfiniteGasMeter())
|
||||
c = c.WithMinimumFees(Coins{})
|
||||
c = c.WithKVGasConfig(KVGasConfig())
|
||||
c = c.WithTransientGasConfig(TransientGasConfig())
|
||||
return c
|
||||
}
|
||||
|
||||
|
@ -73,12 +75,12 @@ func (c Context) Value(key interface{}) interface{} {
|
|||
|
||||
// KVStore fetches a KVStore from the MultiStore.
|
||||
func (c Context) KVStore(key StoreKey) KVStore {
|
||||
return c.multiStore().GetKVStore(key).Gas(c.GasMeter(), cachedDefaultGasConfig)
|
||||
return c.multiStore().GetKVStore(key).Gas(c.GasMeter(), c.KVGasConfig())
|
||||
}
|
||||
|
||||
// TransientStore fetches a TransientStore from the MultiStore.
|
||||
func (c Context) TransientStore(key StoreKey) KVStore {
|
||||
return c.multiStore().GetKVStore(key).Gas(c.GasMeter(), cachedTransientGasConfig)
|
||||
return c.multiStore().GetKVStore(key).Gas(c.GasMeter(), c.TransientGasConfig())
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -141,6 +143,8 @@ const (
|
|||
contextKeyVoteInfos
|
||||
contextKeyGasMeter
|
||||
contextKeyMinimumFees
|
||||
contextKeyKVGasConfig
|
||||
contextKeyTransientGasConfig
|
||||
)
|
||||
|
||||
// NOTE: Do not expose MultiStore.
|
||||
|
@ -176,6 +180,12 @@ func (c Context) MinimumFees() Coins { return c.Value(contextKeyMinimumFees).(Co
|
|||
|
||||
func (c Context) WithMultiStore(ms MultiStore) Context { return c.withValue(contextKeyMultiStore, ms) }
|
||||
|
||||
func (c Context) KVGasConfig() GasConfig { return c.Value(contextKeyKVGasConfig).(GasConfig) }
|
||||
|
||||
func (c Context) TransientGasConfig() GasConfig {
|
||||
return c.Value(contextKeyTransientGasConfig).(GasConfig)
|
||||
}
|
||||
|
||||
func (c Context) WithBlockHeader(header abci.Header) Context {
|
||||
var _ proto.Message = &header // for cloning.
|
||||
return c.withValue(contextKeyBlockHeader, header)
|
||||
|
@ -212,6 +222,12 @@ func (c Context) WithIsCheckTx(isCheckTx bool) Context {
|
|||
func (c Context) WithMinimumFees(minFees Coins) Context {
|
||||
return c.withValue(contextKeyMinimumFees, minFees)
|
||||
}
|
||||
func (c Context) WithKVGasConfig(config GasConfig) Context {
|
||||
return c.withValue(contextKeyKVGasConfig, config)
|
||||
}
|
||||
func (c Context) WithTransientGasConfig(config GasConfig) Context {
|
||||
return c.withValue(contextKeyTransientGasConfig, config)
|
||||
}
|
||||
|
||||
// Cache the multistore and return a new cached context. The cached context is
|
||||
// written to the context when writeCache is called.
|
||||
|
|
|
@ -13,7 +13,7 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
cachedDefaultGasConfig = DefaultGasConfig()
|
||||
cachedKVGasConfig = KVGasConfig()
|
||||
cachedTransientGasConfig = TransientGasConfig()
|
||||
)
|
||||
|
||||
|
@ -86,8 +86,8 @@ type GasConfig struct {
|
|||
IterNextCostFlat Gas
|
||||
}
|
||||
|
||||
// DefaultGasConfig returns a default gas config for KVStores.
|
||||
func DefaultGasConfig() GasConfig {
|
||||
// KVGasConfig returns a default gas config for KVStores.
|
||||
func KVGasConfig() GasConfig {
|
||||
return GasConfig{
|
||||
HasCost: 10,
|
||||
DeleteCost: 10,
|
||||
|
@ -103,5 +103,5 @@ func DefaultGasConfig() GasConfig {
|
|||
// TransientGasConfig returns a default gas config for TransientStores.
|
||||
func TransientGasConfig() GasConfig {
|
||||
// TODO: define gasconfig for transient stores
|
||||
return DefaultGasConfig()
|
||||
return KVGasConfig()
|
||||
}
|
||||
|
|
|
@ -9,15 +9,28 @@ import (
|
|||
|
||||
// nolint
|
||||
const (
|
||||
ParamStoreKeyDepositProcedure = "gov/depositprocedure"
|
||||
ParamStoreKeyVotingProcedure = "gov/votingprocedure"
|
||||
ParamStoreKeyTallyingProcedure = "gov/tallyingprocedure"
|
||||
DefaultParamSpace = "gov"
|
||||
)
|
||||
|
||||
// nolint - Paramstore key constructor
|
||||
func ParamStoreKeyDepositProcedure() params.Key { return params.NewKey("depositprocedure") }
|
||||
func ParamStoreKeyVotingProcedure() params.Key { return params.NewKey("votingprocedure") }
|
||||
func ParamStoreKeyTallyingProcedure() params.Key { return params.NewKey("tallyingprocedure") }
|
||||
|
||||
// Cached parameter store keys
|
||||
var (
|
||||
paramStoreKeyDepositProcedure = ParamStoreKeyDepositProcedure()
|
||||
paramStoreKeyVotingProcedure = ParamStoreKeyVotingProcedure()
|
||||
paramStoreKeyTallyingProcedure = ParamStoreKeyTallyingProcedure()
|
||||
)
|
||||
|
||||
// Governance Keeper
|
||||
type Keeper struct {
|
||||
// The reference to the ParamSetter to get and set Global Params
|
||||
ps params.Setter
|
||||
// The reference to the Param Keeper to get and set Global Params
|
||||
pk params.Keeper
|
||||
|
||||
// The reference to the Paramstore to get and set gov specific params
|
||||
ps params.Space
|
||||
|
||||
// The reference to the CoinKeeper to modify balances
|
||||
ck bank.Keeper
|
||||
|
@ -43,9 +56,10 @@ type Keeper struct {
|
|||
// - depositing funds into proposals, and activating upon sufficient funds being deposited
|
||||
// - users voting on proposals, with weight proportional to stake in the system
|
||||
// - and tallying the result of the vote.
|
||||
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, ps params.Setter, ck bank.Keeper, ds sdk.DelegationSet, codespace sdk.CodespaceType) Keeper {
|
||||
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, pk params.Keeper, ps params.Space, ck bank.Keeper, ds sdk.DelegationSet, codespace sdk.CodespaceType) Keeper {
|
||||
return Keeper{
|
||||
storeKey: key,
|
||||
pk: pk,
|
||||
ps: ps,
|
||||
ck: ck,
|
||||
ds: ds,
|
||||
|
@ -210,7 +224,7 @@ func (keeper Keeper) activateVotingPeriod(ctx sdk.Context, proposal Proposal) {
|
|||
// nolint: errcheck
|
||||
func (keeper Keeper) GetDepositProcedure(ctx sdk.Context) DepositProcedure {
|
||||
var depositProcedure DepositProcedure
|
||||
keeper.ps.Get(ctx, ParamStoreKeyDepositProcedure, &depositProcedure)
|
||||
keeper.ps.Get(ctx, paramStoreKeyDepositProcedure, &depositProcedure)
|
||||
return depositProcedure
|
||||
}
|
||||
|
||||
|
@ -218,7 +232,7 @@ func (keeper Keeper) GetDepositProcedure(ctx sdk.Context) DepositProcedure {
|
|||
// nolint: errcheck
|
||||
func (keeper Keeper) GetVotingProcedure(ctx sdk.Context) VotingProcedure {
|
||||
var votingProcedure VotingProcedure
|
||||
keeper.ps.Get(ctx, ParamStoreKeyVotingProcedure, &votingProcedure)
|
||||
keeper.ps.Get(ctx, paramStoreKeyVotingProcedure, &votingProcedure)
|
||||
return votingProcedure
|
||||
}
|
||||
|
||||
|
@ -226,23 +240,23 @@ func (keeper Keeper) GetVotingProcedure(ctx sdk.Context) VotingProcedure {
|
|||
// nolint: errcheck
|
||||
func (keeper Keeper) GetTallyingProcedure(ctx sdk.Context) TallyingProcedure {
|
||||
var tallyingProcedure TallyingProcedure
|
||||
keeper.ps.Get(ctx, ParamStoreKeyTallyingProcedure, &tallyingProcedure)
|
||||
keeper.ps.Get(ctx, paramStoreKeyTallyingProcedure, &tallyingProcedure)
|
||||
return tallyingProcedure
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) setDepositProcedure(ctx sdk.Context, depositProcedure DepositProcedure) {
|
||||
keeper.ps.Set(ctx, ParamStoreKeyDepositProcedure, &depositProcedure)
|
||||
keeper.ps.Set(ctx, paramStoreKeyDepositProcedure, &depositProcedure)
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) setVotingProcedure(ctx sdk.Context, votingProcedure VotingProcedure) {
|
||||
keeper.ps.Set(ctx, ParamStoreKeyVotingProcedure, &votingProcedure)
|
||||
keeper.ps.Set(ctx, paramStoreKeyVotingProcedure, &votingProcedure)
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func (keeper Keeper) setTallyingProcedure(ctx sdk.Context, tallyingProcedure TallyingProcedure) {
|
||||
keeper.ps.Set(ctx, ParamStoreKeyTallyingProcedure, &tallyingProcedure)
|
||||
keeper.ps.Set(ctx, paramStoreKeyTallyingProcedure, &tallyingProcedure)
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
|
|
|
@ -28,16 +28,19 @@ func TestGovWithRandomMessages(t *testing.T) {
|
|||
stakeTKey := sdk.NewTransientStoreKey("transient_stake")
|
||||
stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, stakeTKey, bankKeeper, stake.DefaultCodespace)
|
||||
paramKey := sdk.NewKVStoreKey("params")
|
||||
paramKeeper := params.NewKeeper(mapp.Cdc, paramKey)
|
||||
paramTKey := sdk.NewTransientStoreKey("transient_params")
|
||||
paramKeeper := params.NewKeeper(mapp.Cdc, paramKey, paramTKey)
|
||||
stakeKey := sdk.NewKVStoreKey("stake")
|
||||
stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, coinKeeper, paramKeeper.Subspace(stake.DefaultParamSpace), stake.DefaultCodespace)
|
||||
govKey := sdk.NewKVStoreKey("gov")
|
||||
govKeeper := gov.NewKeeper(mapp.Cdc, govKey, paramKeeper.Setter(), bankKeeper, stakeKeeper, gov.DefaultCodespace)
|
||||
govKeeper := gov.NewKeeper(mapp.Cdc, govKey, paramKeeper, paramKeeper.Subspace(gov.DefaultParamSpace), bankKeeper, stakeKeeper, gov.DefaultCodespace)
|
||||
mapp.Router().AddRoute("gov", gov.NewHandler(govKeeper))
|
||||
mapp.SetEndBlocker(func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
gov.EndBlocker(ctx, govKeeper)
|
||||
return abci.ResponseEndBlock{}
|
||||
})
|
||||
|
||||
err := mapp.CompleteSetup(stakeKey, stakeTKey, paramKey, govKey)
|
||||
err := mapp.CompleteSetup(stakeKey, stakeTKey, paramKey, paramTKey, govKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -27,20 +27,22 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper,
|
|||
RegisterCodec(mapp.Cdc)
|
||||
|
||||
keyGlobalParams := sdk.NewKVStoreKey("params")
|
||||
tkeyGlobalParams := sdk.NewTransientStoreKey("transient_params")
|
||||
keyStake := sdk.NewKVStoreKey("stake")
|
||||
tkeyStake := sdk.NewTransientStoreKey("transient_stake")
|
||||
keyGov := sdk.NewKVStoreKey("gov")
|
||||
|
||||
pk := params.NewKeeper(mapp.Cdc, keyGlobalParams)
|
||||
pk := params.NewKeeper(mapp.Cdc, keyGlobalParams, tkeyGlobalParams)
|
||||
ck := bank.NewBaseKeeper(mapp.AccountMapper)
|
||||
sk := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, ck, mapp.RegisterCodespace(stake.DefaultCodespace))
|
||||
keeper := NewKeeper(mapp.Cdc, keyGov, pk.Setter(), ck, sk, DefaultCodespace)
|
||||
sk := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, ck, pk.Subspace(stake.DefaultParamSpace), mapp.RegisterCodespace(stake.DefaultCodespace))
|
||||
keeper := NewKeeper(mapp.Cdc, keyGov, pk, pk.Subspace("testgov"), ck, sk, DefaultCodespace)
|
||||
|
||||
mapp.Router().AddRoute("gov", NewHandler(keeper))
|
||||
|
||||
mapp.SetEndBlocker(getEndBlocker(keeper))
|
||||
mapp.SetInitChainer(getInitChainer(mapp, keeper, sk))
|
||||
|
||||
require.NoError(t, mapp.CompleteSetup(keyStake, keyGov, keyGlobalParams, tkeyStake))
|
||||
require.NoError(t, mapp.CompleteSetup(keyStake, tkeyStake, keyGov, keyGlobalParams, tkeyGlobalParams))
|
||||
|
||||
genAccs, addrs, pubKeys, privKeys := mock.CreateGenAccounts(numGenAccs, sdk.Coins{sdk.NewInt64Coin("steak", 42)})
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
// TODO: remove hardcoded storename
|
||||
const storeName = "params"
|
||||
|
||||
// Query parameters from node with CLIContext
|
||||
func QueryParams(cliCtx context.CLIContext, subStoreName string, ps params.ParamStruct) error {
|
||||
m := make(map[string][]byte)
|
||||
|
||||
for _, p := range ps.KeyFieldPairs() {
|
||||
key := p.Key.String()
|
||||
bz, err := cliCtx.QueryStore([]byte(subStoreName+"/"+key), storeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m[key] = bz
|
||||
}
|
||||
|
||||
return params.UnmarshalParamsFromMap(m, cliCtx.Codec, ps)
|
||||
}
|
|
@ -1,406 +1,53 @@
|
|||
package params
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/params/space"
|
||||
)
|
||||
|
||||
// Keeper manages global parameter store
|
||||
// Keeper of the global paramstore
|
||||
type Keeper struct {
|
||||
cdc *codec.Codec
|
||||
key sdk.StoreKey
|
||||
cdc *codec.Codec
|
||||
key sdk.StoreKey
|
||||
tkey sdk.StoreKey
|
||||
|
||||
spaces map[string]*Space
|
||||
}
|
||||
|
||||
// NewKeeper constructs a new Keeper
|
||||
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey) Keeper {
|
||||
return Keeper{
|
||||
cdc: cdc,
|
||||
key: key,
|
||||
}
|
||||
}
|
||||
// NewKeeper construct a params keeper
|
||||
func NewKeeper(cdc *codec.Codec, key *sdk.KVStoreKey, tkey *sdk.TransientStoreKey) (k Keeper) {
|
||||
k = Keeper{
|
||||
cdc: cdc,
|
||||
key: key,
|
||||
tkey: tkey,
|
||||
|
||||
// InitKeeper constructs a new Keeper with initial parameters
|
||||
// nolint: errcheck
|
||||
func InitKeeper(ctx sdk.Context, cdc *codec.Codec, key sdk.StoreKey, params ...interface{}) Keeper {
|
||||
if len(params)%2 != 0 {
|
||||
panic("Odd params list length for InitKeeper")
|
||||
}
|
||||
|
||||
k := NewKeeper(cdc, key)
|
||||
|
||||
for i := 0; i < len(params); i += 2 {
|
||||
k.set(ctx, params[i].(string), params[i+1])
|
||||
spaces: make(map[string]*Space),
|
||||
}
|
||||
|
||||
return k
|
||||
}
|
||||
|
||||
// get automatically unmarshalls parameter to pointer
|
||||
func (k Keeper) get(ctx sdk.Context, key string, ptr interface{}) error {
|
||||
store := ctx.KVStore(k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
return k.cdc.UnmarshalBinary(bz, ptr)
|
||||
}
|
||||
|
||||
// getRaw returns raw byte slice
|
||||
func (k Keeper) getRaw(ctx sdk.Context, key string) []byte {
|
||||
store := ctx.KVStore(k.key)
|
||||
return store.Get([]byte(key))
|
||||
}
|
||||
|
||||
// set automatically marshalls and type check parameter
|
||||
func (k Keeper) set(ctx sdk.Context, key string, param interface{}) error {
|
||||
store := ctx.KVStore(k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz != nil {
|
||||
ptrty := reflect.PtrTo(reflect.TypeOf(param))
|
||||
ptr := reflect.New(ptrty).Interface()
|
||||
|
||||
if k.cdc.UnmarshalBinary(bz, ptr) != nil {
|
||||
return fmt.Errorf("Type mismatch with stored param and provided param")
|
||||
}
|
||||
// Allocate substore used for keepers
|
||||
func (k Keeper) Subspace(space string) Space {
|
||||
_, ok := k.spaces[space]
|
||||
if ok {
|
||||
panic("subspace already occupied")
|
||||
}
|
||||
|
||||
bz, err := k.cdc.MarshalBinary(param)
|
||||
if err != nil {
|
||||
return err
|
||||
return k.UnsafeSubspace(space)
|
||||
}
|
||||
|
||||
// Get substore without checking existing allocation
|
||||
func (k Keeper) UnsafeSubspace(spacename string) Space {
|
||||
if spacename == "" {
|
||||
panic("cannot use empty string for subspace")
|
||||
}
|
||||
store.Set([]byte(key), bz)
|
||||
|
||||
return nil
|
||||
}
|
||||
space := space.NewSpace(k.cdc, k.key, k.tkey, spacename)
|
||||
|
||||
// setRaw sets raw byte slice
|
||||
func (k Keeper) setRaw(ctx sdk.Context, key string, param []byte) {
|
||||
store := ctx.KVStore(k.key)
|
||||
store.Set([]byte(key), param)
|
||||
}
|
||||
k.spaces[spacename] = &space
|
||||
|
||||
// Getter returns readonly struct
|
||||
func (k Keeper) Getter() Getter {
|
||||
return Getter{k}
|
||||
}
|
||||
|
||||
// Setter returns read/write struct
|
||||
func (k Keeper) Setter() Setter {
|
||||
return Setter{Getter{k}}
|
||||
}
|
||||
|
||||
// Getter exposes methods related with only getting params
|
||||
type Getter struct {
|
||||
k Keeper
|
||||
}
|
||||
|
||||
// Get exposes get
|
||||
func (k Getter) Get(ctx sdk.Context, key string, ptr interface{}) error {
|
||||
return k.k.get(ctx, key, ptr)
|
||||
}
|
||||
|
||||
// GetRaw exposes getRaw
|
||||
func (k Getter) GetRaw(ctx sdk.Context, key string) []byte {
|
||||
return k.k.getRaw(ctx, key)
|
||||
}
|
||||
|
||||
// GetString is helper function for string params
|
||||
func (k Getter) GetString(ctx sdk.Context, key string) (res string, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetBool is helper function for bool params
|
||||
func (k Getter) GetBool(ctx sdk.Context, key string) (res bool, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt16 is helper function for int16 params
|
||||
func (k Getter) GetInt16(ctx sdk.Context, key string) (res int16, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt32 is helper function for int32 params
|
||||
func (k Getter) GetInt32(ctx sdk.Context, key string) (res int32, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt64 is helper function for int64 params
|
||||
func (k Getter) GetInt64(ctx sdk.Context, key string) (res int64, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint16 is helper function for uint16 params
|
||||
func (k Getter) GetUint16(ctx sdk.Context, key string) (res uint16, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint32 is helper function for uint32 params
|
||||
func (k Getter) GetUint32(ctx sdk.Context, key string) (res uint32, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint64 is helper function for uint64 params
|
||||
func (k Getter) GetUint64(ctx sdk.Context, key string) (res uint64, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt is helper function for sdk.Int params
|
||||
func (k Getter) GetInt(ctx sdk.Context, key string) (res sdk.Int, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint is helper function for sdk.Uint params
|
||||
func (k Getter) GetUint(ctx sdk.Context, key string) (res sdk.Uint, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetDec is helper function for decimal params
|
||||
func (k Getter) GetDec(ctx sdk.Context, key string) (res sdk.Dec, err error) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
err = k.k.cdc.UnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetStringWithDefault is helper function for string params with default value
|
||||
func (k Getter) GetStringWithDefault(ctx sdk.Context, key string, def string) (res string) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetBoolWithDefault is helper function for bool params with default value
|
||||
func (k Getter) GetBoolWithDefault(ctx sdk.Context, key string, def bool) (res bool) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt16WithDefault is helper function for int16 params with default value
|
||||
func (k Getter) GetInt16WithDefault(ctx sdk.Context, key string, def int16) (res int16) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt32WithDefault is helper function for int32 params with default value
|
||||
func (k Getter) GetInt32WithDefault(ctx sdk.Context, key string, def int32) (res int32) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetInt64WithDefault is helper function for int64 params with default value
|
||||
func (k Getter) GetInt64WithDefault(ctx sdk.Context, key string, def int64) (res int64) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint16WithDefault is helper function for uint16 params with default value
|
||||
func (k Getter) GetUint16WithDefault(ctx sdk.Context, key string, def uint16) (res uint16) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint32WithDefault is helper function for uint32 params with default value
|
||||
func (k Getter) GetUint32WithDefault(ctx sdk.Context, key string, def uint32) (res uint32) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUint64WithDefault is helper function for uint64 params with default value
|
||||
func (k Getter) GetUint64WithDefault(ctx sdk.Context, key string, def uint64) (res uint64) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetIntWithDefault is helper function for sdk.Int params with default value
|
||||
func (k Getter) GetIntWithDefault(ctx sdk.Context, key string, def sdk.Int) (res sdk.Int) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetUintWithDefault is helper function for sdk.Uint params with default value
|
||||
func (k Getter) GetUintWithDefault(ctx sdk.Context, key string, def sdk.Uint) (res sdk.Uint) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetDecWithDefault is helper function for sdk.Dec params with default value
|
||||
func (k Getter) GetDecWithDefault(ctx sdk.Context, key string, def sdk.Dec) (res sdk.Dec) {
|
||||
store := ctx.KVStore(k.k.key)
|
||||
bz := store.Get([]byte(key))
|
||||
if bz == nil {
|
||||
return def
|
||||
}
|
||||
k.k.cdc.MustUnmarshalBinary(bz, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// Setter exposes all methods including Set
|
||||
type Setter struct {
|
||||
Getter
|
||||
}
|
||||
|
||||
// Set exposes set
|
||||
func (k Setter) Set(ctx sdk.Context, key string, param interface{}) error {
|
||||
return k.k.set(ctx, key, param)
|
||||
}
|
||||
|
||||
// SetRaw exposes setRaw
|
||||
func (k Setter) SetRaw(ctx sdk.Context, key string, param []byte) {
|
||||
k.k.setRaw(ctx, key, param)
|
||||
}
|
||||
|
||||
// SetString is helper function for string params
|
||||
func (k Setter) SetString(ctx sdk.Context, key string, param string) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetBool is helper function for bool params
|
||||
func (k Setter) SetBool(ctx sdk.Context, key string, param bool) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetInt16 is helper function for int16 params
|
||||
func (k Setter) SetInt16(ctx sdk.Context, key string, param int16) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetInt32 is helper function for int32 params
|
||||
func (k Setter) SetInt32(ctx sdk.Context, key string, param int32) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetInt64 is helper function for int64 params
|
||||
func (k Setter) SetInt64(ctx sdk.Context, key string, param int64) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetUint16 is helper function for uint16 params
|
||||
func (k Setter) SetUint16(ctx sdk.Context, key string, param uint16) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetUint32 is helper function for uint32 params
|
||||
func (k Setter) SetUint32(ctx sdk.Context, key string, param uint32) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetUint64 is helper function for uint64 params
|
||||
func (k Setter) SetUint64(ctx sdk.Context, key string, param uint64) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetInt is helper function for sdk.Int params
|
||||
func (k Setter) SetInt(ctx sdk.Context, key string, param sdk.Int) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetUint is helper function for sdk.Uint params
|
||||
func (k Setter) SetUint(ctx sdk.Context, key string, param sdk.Uint) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetDec is helper function for decimal params
|
||||
func (k Setter) SetDec(ctx sdk.Context, key string, param sdk.Dec) {
|
||||
if err := k.k.set(ctx, key, param); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return space
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package params
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
|
@ -14,267 +15,123 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func defaultContext(key sdk.StoreKey) sdk.Context {
|
||||
func defaultContext(key sdk.StoreKey, tkey sdk.StoreKey) sdk.Context {
|
||||
db := dbm.NewMemDB()
|
||||
cms := store.NewCommitMultiStore(db)
|
||||
cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
|
||||
cms.MountStoreWithDB(tkey, sdk.StoreTypeTransient, db)
|
||||
cms.LoadLatestVersion()
|
||||
ctx := sdk.NewContext(cms, abci.Header{}, false, log.NewNopLogger())
|
||||
return ctx
|
||||
}
|
||||
|
||||
type s struct{}
|
||||
|
||||
func createTestCodec() *codec.Codec {
|
||||
cdc := codec.NewCodec()
|
||||
sdk.RegisterWire(cdc)
|
||||
cdc.RegisterConcrete(s{}, "test/s", nil)
|
||||
return cdc
|
||||
}
|
||||
|
||||
func TestKeeper(t *testing.T) {
|
||||
kvs := []struct {
|
||||
key string
|
||||
key Key
|
||||
param int64
|
||||
}{
|
||||
{"key1", 10},
|
||||
{"key2", 55},
|
||||
{"key3", 182},
|
||||
{"key4", 17582},
|
||||
{"key5", 2768554},
|
||||
{NewKey("key1"), 10},
|
||||
{NewKey("key2"), 55},
|
||||
{NewKey("key3"), 182},
|
||||
{NewKey("key4"), 17582},
|
||||
{NewKey("key5"), 2768554},
|
||||
{NewKey("space1", "key1"), 1157279},
|
||||
{NewKey("space1", "key2"), 9058701},
|
||||
}
|
||||
|
||||
skey := sdk.NewKVStoreKey("test")
|
||||
ctx := defaultContext(skey)
|
||||
setter := NewKeeper(codec.New(), skey).Setter()
|
||||
tkey := sdk.NewTransientStoreKey("transient_test")
|
||||
ctx := defaultContext(skey, tkey)
|
||||
space := NewKeeper(codec.NewCodec(), skey, tkey).Subspace("test")
|
||||
|
||||
for _, kv := range kvs {
|
||||
err := setter.Set(ctx, kv.key, kv.param)
|
||||
assert.Nil(t, err)
|
||||
err := space.Set(ctx, kv.key, kv.param)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
for _, kv := range kvs {
|
||||
var param int64
|
||||
err := setter.Get(ctx, kv.key, ¶m)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kv.param, param)
|
||||
require.NotPanics(t, func() { space.Get(ctx, kv.key, ¶m) })
|
||||
require.Equal(t, kv.param, param)
|
||||
}
|
||||
|
||||
cdc := codec.New()
|
||||
for _, kv := range kvs {
|
||||
var param int64
|
||||
bz := setter.GetRaw(ctx, kv.key)
|
||||
err := cdc.UnmarshalBinary(bz, ¶m)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kv.param, param)
|
||||
bz := space.GetRaw(ctx, kv.key)
|
||||
err := cdc.UnmarshalJSON(bz, ¶m)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, kv.param, param)
|
||||
}
|
||||
|
||||
for _, kv := range kvs {
|
||||
var param bool
|
||||
err := setter.Get(ctx, kv.key, ¶m)
|
||||
assert.NotNil(t, err)
|
||||
require.Panics(t, func() { space.Get(ctx, kv.key, ¶m) })
|
||||
}
|
||||
|
||||
for _, kv := range kvs {
|
||||
err := setter.Set(ctx, kv.key, true)
|
||||
assert.NotNil(t, err)
|
||||
err := space.Set(ctx, kv.key, true)
|
||||
require.NotNil(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetter(t *testing.T) {
|
||||
func TestGet(t *testing.T) {
|
||||
key := sdk.NewKVStoreKey("test")
|
||||
ctx := defaultContext(key)
|
||||
keeper := NewKeeper(codec.New(), key)
|
||||
tkey := sdk.NewTransientStoreKey("transient_test")
|
||||
ctx := defaultContext(key, tkey)
|
||||
keeper := NewKeeper(createTestCodec(), key, tkey)
|
||||
|
||||
g := keeper.Getter()
|
||||
s := keeper.Setter()
|
||||
space := keeper.Subspace("test")
|
||||
|
||||
kvs := []struct {
|
||||
key string
|
||||
key Key
|
||||
param interface{}
|
||||
zero interface{}
|
||||
ptr interface{}
|
||||
}{
|
||||
{"string", "test"},
|
||||
{"bool", true},
|
||||
{"int16", int16(1)},
|
||||
{"int32", int32(1)},
|
||||
{"int64", int64(1)},
|
||||
{"uint16", uint16(1)},
|
||||
{"uint32", uint32(1)},
|
||||
{"uint64", uint64(1)},
|
||||
{"int", sdk.NewInt(1)},
|
||||
{"uint", sdk.NewUint(1)},
|
||||
{"rat", sdk.NewDec(1)},
|
||||
{NewKey("string"), "test", "", new(string)},
|
||||
{NewKey("bool"), true, false, new(bool)},
|
||||
{NewKey("int16"), int16(1), int16(0), new(int16)},
|
||||
{NewKey("int32"), int32(1), int32(0), new(int32)},
|
||||
{NewKey("int64"), int64(1), int64(0), new(int64)},
|
||||
{NewKey("uint16"), uint16(1), uint16(0), new(uint16)},
|
||||
{NewKey("uint32"), uint32(1), uint32(0), new(uint32)},
|
||||
{NewKey("uint64"), uint64(1), uint64(0), new(uint64)},
|
||||
/*
|
||||
{NewKey("int"), sdk.NewInt(1), *new(sdk.Int), new(sdk.Int)},
|
||||
{NewKey("uint"), sdk.NewUint(1), *new(sdk.Uint), new(sdk.Uint)},
|
||||
{NewKey("dec"), sdk.NewDec(1), *new(sdk.Dec), new(sdk.Dec)},
|
||||
*/
|
||||
}
|
||||
|
||||
assert.NotPanics(t, func() { s.SetString(ctx, kvs[0].key, "test") })
|
||||
assert.NotPanics(t, func() { s.SetBool(ctx, kvs[1].key, true) })
|
||||
assert.NotPanics(t, func() { s.SetInt16(ctx, kvs[2].key, int16(1)) })
|
||||
assert.NotPanics(t, func() { s.SetInt32(ctx, kvs[3].key, int32(1)) })
|
||||
assert.NotPanics(t, func() { s.SetInt64(ctx, kvs[4].key, int64(1)) })
|
||||
assert.NotPanics(t, func() { s.SetUint16(ctx, kvs[5].key, uint16(1)) })
|
||||
assert.NotPanics(t, func() { s.SetUint32(ctx, kvs[6].key, uint32(1)) })
|
||||
assert.NotPanics(t, func() { s.SetUint64(ctx, kvs[7].key, uint64(1)) })
|
||||
assert.NotPanics(t, func() { s.SetInt(ctx, kvs[8].key, sdk.NewInt(1)) })
|
||||
assert.NotPanics(t, func() { s.SetUint(ctx, kvs[9].key, sdk.NewUint(1)) })
|
||||
assert.NotPanics(t, func() { s.SetDec(ctx, kvs[10].key, sdk.NewDec(1)) })
|
||||
for _, kv := range kvs {
|
||||
require.NotPanics(t, func() { space.Set(ctx, kv.key, kv.param) })
|
||||
}
|
||||
|
||||
var res interface{}
|
||||
var err error
|
||||
for _, kv := range kvs {
|
||||
require.NotPanics(t, func() { space.GetIfExists(ctx, NewKey("invalid"), kv.ptr) })
|
||||
require.Equal(t, kv.zero, reflect.ValueOf(kv.ptr).Elem().Interface())
|
||||
require.Panics(t, func() { space.Get(ctx, NewKey("invalid"), kv.ptr) })
|
||||
require.Equal(t, kv.zero, reflect.ValueOf(kv.ptr).Elem().Interface())
|
||||
|
||||
// String
|
||||
def0 := "default"
|
||||
res, err = g.GetString(ctx, kvs[0].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[0].param, res)
|
||||
require.NotPanics(t, func() { space.GetIfExists(ctx, kv.key, kv.ptr) })
|
||||
require.Equal(t, kv.param, reflect.ValueOf(kv.ptr).Elem().Interface())
|
||||
require.NotPanics(t, func() { space.Get(ctx, kv.key, kv.ptr) })
|
||||
require.Equal(t, kv.param, reflect.ValueOf(kv.ptr).Elem().Interface())
|
||||
|
||||
_, err = g.GetString(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetStringWithDefault(ctx, kvs[0].key, def0)
|
||||
assert.Equal(t, kvs[0].param, res)
|
||||
|
||||
res = g.GetStringWithDefault(ctx, "invalid", def0)
|
||||
assert.Equal(t, def0, res)
|
||||
|
||||
// Bool
|
||||
def1 := false
|
||||
res, err = g.GetBool(ctx, kvs[1].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[1].param, res)
|
||||
|
||||
_, err = g.GetBool(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetBoolWithDefault(ctx, kvs[1].key, def1)
|
||||
assert.Equal(t, kvs[1].param, res)
|
||||
|
||||
res = g.GetBoolWithDefault(ctx, "invalid", def1)
|
||||
assert.Equal(t, def1, res)
|
||||
|
||||
// Int16
|
||||
def2 := int16(0)
|
||||
res, err = g.GetInt16(ctx, kvs[2].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[2].param, res)
|
||||
|
||||
_, err = g.GetInt16(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetInt16WithDefault(ctx, kvs[2].key, def2)
|
||||
assert.Equal(t, kvs[2].param, res)
|
||||
|
||||
res = g.GetInt16WithDefault(ctx, "invalid", def2)
|
||||
assert.Equal(t, def2, res)
|
||||
|
||||
// Int32
|
||||
def3 := int32(0)
|
||||
res, err = g.GetInt32(ctx, kvs[3].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[3].param, res)
|
||||
|
||||
_, err = g.GetInt32(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetInt32WithDefault(ctx, kvs[3].key, def3)
|
||||
assert.Equal(t, kvs[3].param, res)
|
||||
|
||||
res = g.GetInt32WithDefault(ctx, "invalid", def3)
|
||||
assert.Equal(t, def3, res)
|
||||
|
||||
// Int64
|
||||
def4 := int64(0)
|
||||
res, err = g.GetInt64(ctx, kvs[4].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[4].param, res)
|
||||
|
||||
_, err = g.GetInt64(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetInt64WithDefault(ctx, kvs[4].key, def4)
|
||||
assert.Equal(t, kvs[4].param, res)
|
||||
|
||||
res = g.GetInt64WithDefault(ctx, "invalid", def4)
|
||||
assert.Equal(t, def4, res)
|
||||
|
||||
// Uint16
|
||||
def5 := uint16(0)
|
||||
res, err = g.GetUint16(ctx, kvs[5].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[5].param, res)
|
||||
|
||||
_, err = g.GetUint16(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetUint16WithDefault(ctx, kvs[5].key, def5)
|
||||
assert.Equal(t, kvs[5].param, res)
|
||||
|
||||
res = g.GetUint16WithDefault(ctx, "invalid", def5)
|
||||
assert.Equal(t, def5, res)
|
||||
|
||||
// Uint32
|
||||
def6 := uint32(0)
|
||||
res, err = g.GetUint32(ctx, kvs[6].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[6].param, res)
|
||||
|
||||
_, err = g.GetUint32(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetUint32WithDefault(ctx, kvs[6].key, def6)
|
||||
assert.Equal(t, kvs[6].param, res)
|
||||
|
||||
res = g.GetUint32WithDefault(ctx, "invalid", def6)
|
||||
assert.Equal(t, def6, res)
|
||||
|
||||
// Uint64
|
||||
def7 := uint64(0)
|
||||
res, err = g.GetUint64(ctx, kvs[7].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[7].param, res)
|
||||
|
||||
_, err = g.GetUint64(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetUint64WithDefault(ctx, kvs[7].key, def7)
|
||||
assert.Equal(t, kvs[7].param, res)
|
||||
|
||||
res = g.GetUint64WithDefault(ctx, "invalid", def7)
|
||||
assert.Equal(t, def7, res)
|
||||
|
||||
// Int
|
||||
def8 := sdk.NewInt(0)
|
||||
res, err = g.GetInt(ctx, kvs[8].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[8].param, res)
|
||||
|
||||
_, err = g.GetInt(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetIntWithDefault(ctx, kvs[8].key, def8)
|
||||
assert.Equal(t, kvs[8].param, res)
|
||||
|
||||
res = g.GetIntWithDefault(ctx, "invalid", def8)
|
||||
assert.Equal(t, def8, res)
|
||||
|
||||
// Uint
|
||||
def9 := sdk.NewUint(0)
|
||||
res, err = g.GetUint(ctx, kvs[9].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[9].param, res)
|
||||
|
||||
_, err = g.GetUint(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetUintWithDefault(ctx, kvs[9].key, def9)
|
||||
assert.Equal(t, kvs[9].param, res)
|
||||
|
||||
res = g.GetUintWithDefault(ctx, "invalid", def9)
|
||||
assert.Equal(t, def9, res)
|
||||
|
||||
// Rat
|
||||
def10 := sdk.NewDec(0)
|
||||
res, err = g.GetDec(ctx, kvs[10].key)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, kvs[10].param, res)
|
||||
|
||||
_, err = g.GetDec(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
res = g.GetDecWithDefault(ctx, kvs[10].key, def10)
|
||||
assert.Equal(t, kvs[10].param, res)
|
||||
|
||||
res = g.GetDecWithDefault(ctx, "invalid", def10)
|
||||
assert.Equal(t, def10, res)
|
||||
require.Panics(t, func() { space.Get(ctx, NewKey("invalid"), kv.ptr) })
|
||||
require.Equal(t, kv.param, reflect.ValueOf(kv.ptr).Elem().Interface())
|
||||
|
||||
require.Panics(t, func() { space.Get(ctx, kv.key, nil) })
|
||||
require.Panics(t, func() { space.Get(ctx, kv.key, new(s)) })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package params
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// GenesisState defines initial activated msg types
|
||||
type GenesisState struct {
|
||||
ActivatedTypes []string `json:"activated-types"`
|
||||
}
|
||||
|
||||
// ActivatedParamKey - paramstore key for msg type activation
|
||||
func ActivatedParamKey(ty string) string {
|
||||
return "Activated/" + ty
|
||||
}
|
||||
|
||||
// InitGenesis stores activated type to param store
|
||||
// nolint: errcheck
|
||||
func InitGenesis(ctx sdk.Context, k Keeper, data GenesisState) {
|
||||
for _, ty := range data.ActivatedTypes {
|
||||
k.set(ctx, ActivatedParamKey(ty), true)
|
||||
}
|
||||
}
|
||||
|
||||
// NewAnteHandler returns an AnteHandler that checks
|
||||
// whether msg type is activate or not
|
||||
func NewAnteHandler(k Keeper) sdk.AnteHandler {
|
||||
return func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, sdk.Result, bool) {
|
||||
for _, msg := range tx.GetMsgs() {
|
||||
ok := k.Getter().GetBoolWithDefault(ctx, ActivatedParamKey(msg.Type()), false)
|
||||
if !ok {
|
||||
return ctx, sdk.ErrUnauthorized("deactivated msg type").Result(), true
|
||||
}
|
||||
}
|
||||
return ctx, sdk.Result{}, false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package params
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/x/params/space"
|
||||
)
|
||||
|
||||
// nolint - reexport
|
||||
type Space = space.Space
|
||||
type ReadOnlySpace = space.ReadOnlySpace
|
||||
type Key = space.Key
|
||||
type KeyFieldPair = space.KeyFieldPair
|
||||
type KeyFieldPairs = space.KeyFieldPairs
|
||||
type ParamStruct = space.ParamStruct
|
||||
|
||||
// nolint - reexport
|
||||
func NewKey(keys ...string) Key {
|
||||
return space.NewKey(keys...)
|
||||
}
|
||||
func UnmarshalParamsFromMap(m map[string][]byte, cdc *codec.Codec, ps space.ParamStruct) error {
|
||||
return space.UnmarshalParamsFromMap(m, cdc, ps)
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package space
|
||||
|
||||
import (
|
||||
tmlibs "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
)
|
||||
|
||||
// Wrapper for key string
|
||||
type Key struct {
|
||||
s string
|
||||
}
|
||||
|
||||
// Appending two keys with '/' as separator
|
||||
// Checks alpanumericity
|
||||
func (k Key) Append(keys ...string) (res Key) {
|
||||
res = k
|
||||
|
||||
for _, key := range keys {
|
||||
if !tmlibs.IsASCIIText(key) {
|
||||
panic("parameter key expressions can only contain alphanumeric characters")
|
||||
}
|
||||
res.s = res.s + "/" + key
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// NewKey constructs a key from a list of strings
|
||||
func NewKey(keys ...string) (res Key) {
|
||||
if len(keys) < 1 {
|
||||
panic("length of parameter keys must not be zero")
|
||||
}
|
||||
res = Key{keys[0]}
|
||||
|
||||
return res.Append(keys[1:]...)
|
||||
}
|
||||
|
||||
// KeyBytes make KVStore key bytes from Key
|
||||
func (k Key) Bytes() []byte {
|
||||
return []byte(k.s)
|
||||
}
|
||||
|
||||
// Human readable string
|
||||
func (k Key) String() string {
|
||||
return k.s
|
||||
}
|
||||
|
||||
// Used for associating paramstore key and field of param structs
|
||||
type KeyFieldPair struct {
|
||||
Key Key
|
||||
Field interface{}
|
||||
}
|
||||
|
||||
// Slice of KeyFieldPair
|
||||
type KeyFieldPairs []KeyFieldPair
|
||||
|
||||
// Interface for structs containing parameters for a module
|
||||
type ParamStruct interface {
|
||||
KeyFieldPairs() KeyFieldPairs
|
||||
}
|
||||
|
||||
// Takes a map from key string to byte slice and
|
||||
// unmarshalles it to ParamStruct
|
||||
func UnmarshalParamsFromMap(m map[string][]byte, cdc *codec.Codec, ps ParamStruct) error {
|
||||
for _, p := range ps.KeyFieldPairs() {
|
||||
err := cdc.UnmarshalJSON(m[p.Key.String()], p.Field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
package space
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
tmlibs "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Individual parameter store for each keeper
|
||||
type Space struct {
|
||||
cdc *codec.Codec
|
||||
key sdk.StoreKey
|
||||
tkey sdk.StoreKey
|
||||
|
||||
space []byte
|
||||
}
|
||||
|
||||
// NewSpace constructs a store with namespace
|
||||
func NewSpace(cdc *codec.Codec, key sdk.StoreKey, tkey sdk.StoreKey, space string) Space {
|
||||
if !tmlibs.IsASCIIText(space) {
|
||||
panic("paramstore space expressions can only contain alphanumeric characters")
|
||||
}
|
||||
|
||||
return Space{
|
||||
cdc: cdc,
|
||||
key: key,
|
||||
tkey: tkey,
|
||||
|
||||
space: []byte(space + "/"),
|
||||
}
|
||||
}
|
||||
|
||||
// Get parameter from store
|
||||
func (s Space) Get(ctx sdk.Context, key Key, ptr interface{}) {
|
||||
store := ctx.KVStore(s.key).Prefix(s.space)
|
||||
bz := store.Get(key.Bytes())
|
||||
err := s.cdc.UnmarshalJSON(bz, ptr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// GetIfExists do not modify ptr if the stored parameter is nil
|
||||
func (s Space) GetIfExists(ctx sdk.Context, key Key, ptr interface{}) {
|
||||
store := ctx.KVStore(s.key).Prefix(s.space)
|
||||
bz := store.Get(key.Bytes())
|
||||
if bz == nil {
|
||||
return
|
||||
}
|
||||
err := s.cdc.UnmarshalJSON(bz, ptr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Get raw bytes of parameter from store
|
||||
func (s Space) GetRaw(ctx sdk.Context, key Key) []byte {
|
||||
store := ctx.KVStore(s.key).Prefix(s.space)
|
||||
res := store.Get(key.Bytes())
|
||||
return res
|
||||
}
|
||||
|
||||
// Check if the parameter is set in the store
|
||||
func (s Space) Has(ctx sdk.Context, key Key) bool {
|
||||
store := ctx.KVStore(s.key).Prefix(s.space)
|
||||
return store.Has(key.Bytes())
|
||||
}
|
||||
|
||||
// Returns true if the parameter is set in the block
|
||||
func (s Space) Modified(ctx sdk.Context, key Key) bool {
|
||||
tstore := ctx.KVStore(s.tkey).Prefix(s.space)
|
||||
return tstore.Has(key.Bytes())
|
||||
}
|
||||
|
||||
// Set parameter, return error if stored parameter has different type from input
|
||||
func (s Space) Set(ctx sdk.Context, key Key, param interface{}) error {
|
||||
store := ctx.KVStore(s.key).Prefix(s.space)
|
||||
keybz := key.Bytes()
|
||||
|
||||
bz := store.Get(keybz)
|
||||
if bz != nil {
|
||||
ptrty := reflect.PtrTo(reflect.TypeOf(param))
|
||||
ptr := reflect.New(ptrty).Interface()
|
||||
|
||||
if s.cdc.UnmarshalJSON(bz, ptr) != nil {
|
||||
return fmt.Errorf("Type mismatch with stored param and provided param")
|
||||
}
|
||||
}
|
||||
|
||||
bz, err := s.cdc.MarshalJSON(param)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
store.Set(keybz, bz)
|
||||
|
||||
tstore := ctx.KVStore(s.tkey).Prefix(s.space)
|
||||
tstore.Set(keybz, []byte{})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set raw bytes of parameter
|
||||
func (s Space) SetRaw(ctx sdk.Context, key Key, param []byte) {
|
||||
keybz := key.Bytes()
|
||||
|
||||
store := ctx.KVStore(s.key).Prefix(s.space)
|
||||
store.Set(keybz, param)
|
||||
|
||||
tstore := ctx.KVStore(s.tkey).Prefix(s.space)
|
||||
tstore.Set(keybz, []byte{})
|
||||
}
|
||||
|
||||
// Returns a KVStore identical with the paramspace
|
||||
func (s Space) KVStore(ctx sdk.Context) sdk.KVStore {
|
||||
return ctx.KVStore(s.key).Prefix(s.space)
|
||||
}
|
||||
|
||||
// Wrapper of Space, provides immutable functions only
|
||||
type ReadOnlySpace struct {
|
||||
s Space
|
||||
}
|
||||
|
||||
// Exposes Get
|
||||
func (ros ReadOnlySpace) Get(ctx sdk.Context, key Key, ptr interface{}) {
|
||||
ros.s.Get(ctx, key, ptr)
|
||||
}
|
||||
|
||||
// Exposes GetRaw
|
||||
func (ros ReadOnlySpace) GetRaw(ctx sdk.Context, key Key) []byte {
|
||||
return ros.s.GetRaw(ctx, key)
|
||||
}
|
||||
|
||||
// Exposes Has
|
||||
func (ros ReadOnlySpace) Has(ctx sdk.Context, key Key) bool {
|
||||
return ros.s.Has(ctx, key)
|
||||
}
|
||||
|
||||
// Exposes Modified
|
||||
func (ros ReadOnlySpace) Modified(ctx sdk.Context, key Key) bool {
|
||||
return ros.s.Modified(ctx, key)
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package space
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Keys for parameter access
|
||||
const (
|
||||
TestParamSpace = "ParamsTest"
|
||||
)
|
||||
|
||||
// Returns components for testing
|
||||
func DefaultTestComponents(t *testing.T) (sdk.Context, Space, func() sdk.CommitID) {
|
||||
cdc := codec.New()
|
||||
key := sdk.NewKVStoreKey("params")
|
||||
tkey := sdk.NewTransientStoreKey("tparams")
|
||||
db := dbm.NewMemDB()
|
||||
ms := store.NewCommitMultiStore(db)
|
||||
ms.WithTracer(os.Stdout)
|
||||
ms.WithTracingContext(sdk.TraceContext{})
|
||||
ms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db)
|
||||
ms.MountStoreWithDB(tkey, sdk.StoreTypeTransient, db)
|
||||
err := ms.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewTMLogger(os.Stdout))
|
||||
store := NewSpace(cdc, key, tkey, TestParamSpace)
|
||||
|
||||
return ctx, store, ms.Commit
|
||||
}
|
|
@ -28,18 +28,20 @@ func getMockApp(t *testing.T) (*mock.App, stake.Keeper, Keeper) {
|
|||
keyStake := sdk.NewKVStoreKey("stake")
|
||||
tkeyStake := sdk.NewTransientStoreKey("transient_stake")
|
||||
keySlashing := sdk.NewKVStoreKey("slashing")
|
||||
keyParams := sdk.NewKVStoreKey("params")
|
||||
|
||||
tkeyParams := sdk.NewTransientStoreKey("transient_params")
|
||||
bankKeeper := bank.NewBaseKeeper(mapp.AccountMapper)
|
||||
paramsKeeper := params.NewKeeper(mapp.Cdc, keyParams)
|
||||
stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, bankKeeper, mapp.RegisterCodespace(stake.DefaultCodespace))
|
||||
stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, bankKeeper, paramstore, mapp.RegisterCodespace(stake.DefaultCodespace))
|
||||
keeper := NewKeeper(mapp.Cdc, keySlashing, stakeKeeper, paramstore, mapp.RegisterCodespace(DefaultCodespace))
|
||||
|
||||
keeper := NewKeeper(mapp.Cdc, keySlashing, stakeKeeper, paramsKeeper.Getter(), mapp.RegisterCodespace(DefaultCodespace))
|
||||
mapp.Router().AddRoute("stake", stake.NewHandler(stakeKeeper))
|
||||
mapp.Router().AddRoute("slashing", NewHandler(keeper))
|
||||
|
||||
mapp.SetEndBlocker(getEndBlocker(stakeKeeper))
|
||||
mapp.SetInitChainer(getInitChainer(mapp, stakeKeeper))
|
||||
require.NoError(t, mapp.CompleteSetup(keyStake, keySlashing, keyParams, tkeyStake))
|
||||
|
||||
require.NoError(t, mapp.CompleteSetup(keyStake, tkeyStake, keySlashing, keyParams, tkeyParams))
|
||||
|
||||
return mapp, stakeKeeper, keeper
|
||||
}
|
||||
|
|
|
@ -5,10 +5,32 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
)
|
||||
|
||||
// InitGenesis initializes the keeper's address to pubkey map.
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
||||
for _, validator := range data.Validators {
|
||||
keeper.addPubkey(ctx, validator.GetConsPubKey())
|
||||
}
|
||||
return
|
||||
// GenesisState - all slashing state that must be provided at genesis
|
||||
type GenesisState struct {
|
||||
Params Params
|
||||
}
|
||||
|
||||
// HubDefaultGenesisState - default GenesisState used by Cosmos Hub
|
||||
func HubDefaultGenesisState() GenesisState {
|
||||
return GenesisState{
|
||||
Params: HubDefaultParams(),
|
||||
}
|
||||
}
|
||||
|
||||
// InitGenesis initialize default parameters
|
||||
// and the keeper's address to pubkey map
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data GenesisState, sdata types.GenesisState) error {
|
||||
for _, validator := range sdata.Validators {
|
||||
keeper.addPubkey(ctx, validator.GetPubKey())
|
||||
}
|
||||
|
||||
p := data.Params
|
||||
keeper.paramstore.Set(ctx, maxEvidenceAgeKey, p.MaxEvidenceAge)
|
||||
keeper.paramstore.Set(ctx, signedBlocksWindowKey, p.SignedBlocksWindow)
|
||||
keeper.paramstore.Set(ctx, minSignedPerWindowKey, p.MinSignedPerWindow)
|
||||
keeper.paramstore.Set(ctx, doubleSignUnbondDurationKey, p.DoubleSignUnbondDuration)
|
||||
keeper.paramstore.Set(ctx, downtimeUnbondDurationKey, p.DowntimeUnbondDuration)
|
||||
keeper.paramstore.Set(ctx, slashFractionDoubleSignKey, p.SlashFractionDoubleSign)
|
||||
keeper.paramstore.Set(ctx, slashFractionDowntimeKey, p.SlashFractionDowntime)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
func TestCannotUnjailUnlessJailed(t *testing.T) {
|
||||
// initial setup
|
||||
ctx, ck, sk, _, keeper := createTestInput(t)
|
||||
ctx, ck, sk, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
slh := NewHandler(keeper)
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
|
@ -30,7 +30,7 @@ func TestCannotUnjailUnlessJailed(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestJailedValidatorDelegations(t *testing.T) {
|
||||
ctx, _, stakeKeeper, _, slashingKeeper := createTestInput(t)
|
||||
ctx, _, stakeKeeper, _, slashingKeeper := createTestInput(t, HubDefaultParams())
|
||||
|
||||
stakeParams := stakeKeeper.GetParams(ctx)
|
||||
stakeParams.UnbondingTime = 0
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func TestHookOnValidatorBonded(t *testing.T) {
|
||||
ctx, _, _, _, keeper := createTestInput(t)
|
||||
ctx, _, _, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
addr := sdk.ConsAddress(addrs[0])
|
||||
keeper.onValidatorBonded(ctx, addr)
|
||||
period := keeper.getValidatorSlashingPeriodForHeight(ctx, addr, ctx.BlockHeight())
|
||||
|
@ -17,7 +17,7 @@ func TestHookOnValidatorBonded(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestHookOnValidatorBeginUnbonding(t *testing.T) {
|
||||
ctx, _, _, _, keeper := createTestInput(t)
|
||||
ctx, _, _, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
addr := sdk.ConsAddress(addrs[0])
|
||||
keeper.onValidatorBonded(ctx, addr)
|
||||
keeper.onValidatorBeginUnbonding(ctx, addr)
|
||||
|
|
|
@ -18,18 +18,19 @@ type Keeper struct {
|
|||
storeKey sdk.StoreKey
|
||||
cdc *codec.Codec
|
||||
validatorSet sdk.ValidatorSet
|
||||
params params.Getter
|
||||
paramstore params.Space
|
||||
|
||||
// codespace
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
|
||||
// NewKeeper creates a slashing keeper
|
||||
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, vs sdk.ValidatorSet, params params.Getter, codespace sdk.CodespaceType) Keeper {
|
||||
func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, vs sdk.ValidatorSet, paramstore params.Space, codespace sdk.CodespaceType) Keeper {
|
||||
keeper := Keeper{
|
||||
storeKey: key,
|
||||
cdc: cdc,
|
||||
validatorSet: vs,
|
||||
params: params,
|
||||
paramstore: paramstore,
|
||||
codespace: codespace,
|
||||
}
|
||||
return keeper
|
||||
|
|
|
@ -12,10 +12,12 @@ import (
|
|||
|
||||
// Have to change these parameters for tests
|
||||
// lest the tests take forever
|
||||
func init() {
|
||||
defaultSignedBlocksWindow = 1000
|
||||
defaultDowntimeUnbondDuration = 60 * 60
|
||||
defaultDoubleSignUnbondDuration = 60 * 60
|
||||
func keeperTestParams() Params {
|
||||
params := HubDefaultParams()
|
||||
params.SignedBlocksWindow = 1000
|
||||
params.DowntimeUnbondDuration = 60 * 60
|
||||
params.DoubleSignUnbondDuration = 60 * 60
|
||||
return params
|
||||
}
|
||||
|
||||
// ______________________________________________________________
|
||||
|
@ -26,7 +28,7 @@ func init() {
|
|||
func TestHandleDoubleSign(t *testing.T) {
|
||||
|
||||
// initial setup
|
||||
ctx, ck, sk, _, keeper := createTestInput(t)
|
||||
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
|
||||
sk = sk.WithHooks(keeper.Hooks())
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
|
@ -68,7 +70,7 @@ func TestHandleDoubleSign(t *testing.T) {
|
|||
func TestSlashingPeriodCap(t *testing.T) {
|
||||
|
||||
// initial setup
|
||||
ctx, ck, sk, _, keeper := createTestInput(t)
|
||||
ctx, ck, sk, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
sk = sk.WithHooks(keeper.Hooks())
|
||||
amtInt := int64(100)
|
||||
addr, amt := addrs[0], sdk.NewInt(amtInt)
|
||||
|
@ -133,7 +135,7 @@ func TestSlashingPeriodCap(t *testing.T) {
|
|||
func TestHandleAbsentValidator(t *testing.T) {
|
||||
|
||||
// initial setup
|
||||
ctx, ck, sk, _, keeper := createTestInput(t)
|
||||
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
|
||||
sk = sk.WithHooks(keeper.Hooks())
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
|
@ -259,7 +261,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
|||
// and that they are not immediately jailed
|
||||
func TestHandleNewValidator(t *testing.T) {
|
||||
// initial setup
|
||||
ctx, ck, sk, _, keeper := createTestInput(t)
|
||||
ctx, ck, sk, _, keeper := createTestInput(t, keeperTestParams())
|
||||
addr, val, amt := addrs[0], pks[0], int64(100)
|
||||
sh := stake.NewHandler(sk)
|
||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, sdk.NewInt(amt)))
|
||||
|
@ -296,7 +298,7 @@ func TestHandleNewValidator(t *testing.T) {
|
|||
func TestHandleAlreadyJailed(t *testing.T) {
|
||||
|
||||
// initial setup
|
||||
ctx, _, sk, _, keeper := createTestInput(t)
|
||||
ctx, _, sk, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
sh := stake.NewHandler(sk)
|
||||
|
|
|
@ -4,77 +4,111 @@ import (
|
|||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
// nolint
|
||||
// Default parameter namespace
|
||||
const (
|
||||
MaxEvidenceAgeKey = "slashing/MaxEvidenceAge"
|
||||
SignedBlocksWindowKey = "slashing/SignedBlocksWindow"
|
||||
MinSignedPerWindowKey = "slashing/MinSignedPerWindow"
|
||||
DoubleSignUnbondDurationKey = "slashing/DoubleSignUnbondDuration"
|
||||
DowntimeUnbondDurationKey = "slashing/DowntimeUnbondDuration"
|
||||
SlashFractionDoubleSignKey = "slashing/SlashFractionDoubleSign"
|
||||
SlashFractionDowntimeKey = "slashing/SlashFractionDowntime"
|
||||
DefaultParamSpace = "slashing"
|
||||
)
|
||||
|
||||
// nolint - Key generators for parameter access
|
||||
func MaxEvidenceAgeKey() params.Key { return params.NewKey("MaxEvidenceAge") }
|
||||
func SignedBlocksWindowKey() params.Key { return params.NewKey("SignedBlocksWindow") }
|
||||
func MinSignedPerWindowKey() params.Key { return params.NewKey("MinSignedPerWindow") }
|
||||
func DoubleSignUnbondDurationKey() params.Key { return params.NewKey("DoubleSignUnbondDuration") }
|
||||
func DowntimeUnbondDurationKey() params.Key { return params.NewKey("DowntimeUnbondDuration") }
|
||||
func SlashFractionDoubleSignKey() params.Key { return params.NewKey("SlashFractionDoubleSign") }
|
||||
func SlashFractionDowntimeKey() params.Key { return params.NewKey("SlashFractionDowntime") }
|
||||
|
||||
// Cached parameter keys
|
||||
var (
|
||||
maxEvidenceAgeKey = MaxEvidenceAgeKey()
|
||||
signedBlocksWindowKey = SignedBlocksWindowKey()
|
||||
minSignedPerWindowKey = MinSignedPerWindowKey()
|
||||
doubleSignUnbondDurationKey = DoubleSignUnbondDurationKey()
|
||||
downtimeUnbondDurationKey = DowntimeUnbondDurationKey()
|
||||
slashFractionDoubleSignKey = SlashFractionDoubleSignKey()
|
||||
slashFractionDowntimeKey = SlashFractionDowntimeKey()
|
||||
)
|
||||
|
||||
// Params - used for initializing default parameter for slashing at genesis
|
||||
type Params struct {
|
||||
MaxEvidenceAge time.Duration `json:"max-evidence-age"`
|
||||
SignedBlocksWindow int64 `json:"signed-blocks-window"`
|
||||
MinSignedPerWindow sdk.Dec `json:"min-signed-per-window"`
|
||||
DoubleSignUnbondDuration time.Duration `json:"doublesign-unbond-duration"`
|
||||
DowntimeUnbondDuration time.Duration `json:"downtime-unbond-duration"`
|
||||
SlashFractionDoubleSign sdk.Dec `json:"slash-fraction-doublesign"`
|
||||
SlashFractionDowntime sdk.Dec `json:"slash-fraction-downtime"`
|
||||
}
|
||||
|
||||
// Default parameters used by Cosmos Hub
|
||||
func HubDefaultParams() Params {
|
||||
return Params{
|
||||
// defaultMaxEvidenceAge = 60 * 60 * 24 * 7 * 3
|
||||
// TODO Temporarily set to 2 minutes for testnets.
|
||||
MaxEvidenceAge: 60 * 2 * time.Second,
|
||||
|
||||
// TODO Temporarily set to five minutes for testnets
|
||||
DoubleSignUnbondDuration: 60 * 5 * time.Second,
|
||||
|
||||
// TODO Temporarily set to 100 blocks for testnets
|
||||
SignedBlocksWindow: 100,
|
||||
|
||||
// TODO Temporarily set to 10 minutes for testnets
|
||||
DowntimeUnbondDuration: 60 * 10 * time.Second,
|
||||
|
||||
MinSignedPerWindow: sdk.NewDecWithPrec(5, 1),
|
||||
|
||||
SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(20)),
|
||||
|
||||
SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(100)),
|
||||
}
|
||||
}
|
||||
|
||||
// MaxEvidenceAge - Max age for evidence - 21 days (3 weeks)
|
||||
// MaxEvidenceAge = 60 * 60 * 24 * 7 * 3
|
||||
func (k Keeper) MaxEvidenceAge(ctx sdk.Context) time.Duration {
|
||||
return time.Duration(k.params.GetInt64WithDefault(ctx, MaxEvidenceAgeKey, defaultMaxEvidenceAge)) * time.Second
|
||||
func (k Keeper) MaxEvidenceAge(ctx sdk.Context) (res time.Duration) {
|
||||
k.paramstore.Get(ctx, maxEvidenceAgeKey, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// SignedBlocksWindow - sliding window for downtime slashing
|
||||
func (k Keeper) SignedBlocksWindow(ctx sdk.Context) int64 {
|
||||
return k.params.GetInt64WithDefault(ctx, SignedBlocksWindowKey, defaultSignedBlocksWindow)
|
||||
func (k Keeper) SignedBlocksWindow(ctx sdk.Context) (res int64) {
|
||||
k.paramstore.Get(ctx, signedBlocksWindowKey, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// Downtime slashing thershold - default 50%
|
||||
// Downtime slashing thershold - default 50% of the SignedBlocksWindow
|
||||
func (k Keeper) MinSignedPerWindow(ctx sdk.Context) int64 {
|
||||
minSignedPerWindow := k.params.GetDecWithDefault(ctx, MinSignedPerWindowKey, defaultMinSignedPerWindow)
|
||||
var minSignedPerWindow sdk.Dec
|
||||
k.paramstore.Get(ctx, minSignedPerWindowKey, &minSignedPerWindow)
|
||||
signedBlocksWindow := k.SignedBlocksWindow(ctx)
|
||||
return sdk.NewDec(signedBlocksWindow).Mul(minSignedPerWindow).RoundInt64()
|
||||
}
|
||||
|
||||
// Double-sign unbond duration
|
||||
func (k Keeper) DoubleSignUnbondDuration(ctx sdk.Context) time.Duration {
|
||||
return time.Duration(k.params.GetInt64WithDefault(ctx, DoubleSignUnbondDurationKey, defaultDoubleSignUnbondDuration)) * time.Second
|
||||
func (k Keeper) DoubleSignUnbondDuration(ctx sdk.Context) (res time.Duration) {
|
||||
k.paramstore.Get(ctx, doubleSignUnbondDurationKey, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// Downtime unbond duration
|
||||
func (k Keeper) DowntimeUnbondDuration(ctx sdk.Context) time.Duration {
|
||||
return time.Duration(k.params.GetInt64WithDefault(ctx, DowntimeUnbondDurationKey, defaultDowntimeUnbondDuration)) * time.Second
|
||||
func (k Keeper) DowntimeUnbondDuration(ctx sdk.Context) (res time.Duration) {
|
||||
k.paramstore.Get(ctx, downtimeUnbondDurationKey, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// SlashFractionDoubleSign - currently default 5%
|
||||
func (k Keeper) SlashFractionDoubleSign(ctx sdk.Context) sdk.Dec {
|
||||
return k.params.GetDecWithDefault(ctx, SlashFractionDoubleSignKey, defaultSlashFractionDoubleSign)
|
||||
func (k Keeper) SlashFractionDoubleSign(ctx sdk.Context) (res sdk.Dec) {
|
||||
k.paramstore.Get(ctx, slashFractionDoubleSignKey, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// SlashFractionDowntime - currently default 1%
|
||||
func (k Keeper) SlashFractionDowntime(ctx sdk.Context) sdk.Dec {
|
||||
return k.params.GetDecWithDefault(ctx, SlashFractionDowntimeKey, defaultSlashFractionDowntime)
|
||||
func (k Keeper) SlashFractionDowntime(ctx sdk.Context) (res sdk.Dec) {
|
||||
k.paramstore.Get(ctx, slashFractionDowntimeKey, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// declared as var because of keeper_test.go
|
||||
// TODO: make it const or parameter of NewKeeper
|
||||
|
||||
var (
|
||||
// defaultMaxEvidenceAge = 60 * 60 * 24 * 7 * 3
|
||||
// TODO Temporarily set to 2 minutes for testnets.
|
||||
defaultMaxEvidenceAge int64 = 60 * 2
|
||||
|
||||
// TODO Temporarily set to five minutes for testnets
|
||||
defaultDoubleSignUnbondDuration int64 = 60 * 5
|
||||
|
||||
// TODO Temporarily set to 10000 blocks for testnets
|
||||
defaultSignedBlocksWindow int64 = 10000
|
||||
|
||||
// TODO Temporarily set to 10 minutes for testnets
|
||||
defaultDowntimeUnbondDuration int64 = 60 * 10
|
||||
|
||||
defaultMinSignedPerWindow = sdk.NewDecWithPrec(5, 1)
|
||||
|
||||
defaultSlashFractionDoubleSign = sdk.NewDec(1).Quo(sdk.NewDec(20))
|
||||
|
||||
defaultSlashFractionDowntime = sdk.NewDec(1).Quo(sdk.NewDec(100))
|
||||
)
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
func TestGetSetValidatorSigningInfo(t *testing.T) {
|
||||
ctx, _, _, _, keeper := createTestInput(t)
|
||||
ctx, _, _, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
info, found := keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(addrs[0]))
|
||||
require.False(t, found)
|
||||
newInfo := ValidatorSigningInfo{
|
||||
|
@ -29,7 +29,7 @@ func TestGetSetValidatorSigningInfo(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetSetValidatorSigningBitArray(t *testing.T) {
|
||||
ctx, _, _, _, keeper := createTestInput(t)
|
||||
ctx, _, _, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
signed := keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0)
|
||||
require.False(t, signed) // treat empty key as unsigned
|
||||
keeper.setValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0, true)
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func TestGetSetValidatorSlashingPeriod(t *testing.T) {
|
||||
ctx, _, _, _, keeper := createTestInput(t)
|
||||
ctx, _, _, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
addr := sdk.ConsAddress(addrs[0])
|
||||
height := int64(5)
|
||||
require.Panics(t, func() { keeper.getValidatorSlashingPeriodForHeight(ctx, addr, height) })
|
||||
|
@ -60,7 +60,7 @@ func TestGetSetValidatorSlashingPeriod(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestValidatorSlashingPeriodCap(t *testing.T) {
|
||||
ctx, _, _, _, keeper := createTestInput(t)
|
||||
ctx, _, _, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
addr := sdk.ConsAddress(addrs[0])
|
||||
height := int64(5)
|
||||
newPeriod := ValidatorSlashingPeriod{
|
||||
|
|
|
@ -49,12 +49,13 @@ func createTestCodec() *codec.Codec {
|
|||
return cdc
|
||||
}
|
||||
|
||||
func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, params.Setter, Keeper) {
|
||||
func createTestInput(t *testing.T, defaults Params) (sdk.Context, bank.Keeper, stake.Keeper, params.Space, Keeper) {
|
||||
keyAcc := sdk.NewKVStoreKey("acc")
|
||||
keyStake := sdk.NewKVStoreKey("stake")
|
||||
tkeyStake := sdk.NewTransientStoreKey("transient_stake")
|
||||
keySlashing := sdk.NewKVStoreKey("slashing")
|
||||
keyParams := sdk.NewKVStoreKey("params")
|
||||
tkeyParams := sdk.NewTransientStoreKey("transient_params")
|
||||
db := dbm.NewMemDB()
|
||||
ms := store.NewCommitMultiStore(db)
|
||||
ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
|
||||
|
@ -62,14 +63,16 @@ func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, para
|
|||
ms.MountStoreWithDB(keyStake, sdk.StoreTypeIAVL, db)
|
||||
ms.MountStoreWithDB(keySlashing, sdk.StoreTypeIAVL, db)
|
||||
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
|
||||
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
|
||||
err := ms.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
ctx := sdk.NewContext(ms, abci.Header{Time: time.Unix(0, 0)}, false, log.NewTMLogger(os.Stdout))
|
||||
cdc := createTestCodec()
|
||||
accountMapper := auth.NewAccountMapper(cdc, keyAcc, auth.ProtoBaseAccount)
|
||||
|
||||
ck := bank.NewBaseKeeper(accountMapper)
|
||||
params := params.NewKeeper(cdc, keyParams)
|
||||
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, stake.DefaultCodespace)
|
||||
paramstore := params.NewKeeper(cdc, keyParams, tkeyParams).Subspace(DefaultParamSpace)
|
||||
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, paramstore, stake.DefaultCodespace)
|
||||
genesis := stake.DefaultGenesisState()
|
||||
|
||||
genesis.Pool.LooseTokens = sdk.NewDec(initCoins.MulRaw(int64(len(addrs))).Int64())
|
||||
|
@ -83,8 +86,12 @@ func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, para
|
|||
})
|
||||
}
|
||||
require.Nil(t, err)
|
||||
keeper := NewKeeper(cdc, keySlashing, sk, params.Getter(), DefaultCodespace)
|
||||
return ctx, ck, sk, params.Setter(), keeper
|
||||
keeper := NewKeeper(cdc, keySlashing, sk, paramstore, DefaultCodespace)
|
||||
|
||||
err = InitGenesis(ctx, keeper, GenesisState{defaults}, genesis)
|
||||
require.Nil(t, err)
|
||||
|
||||
return ctx, ck, sk, paramstore, keeper
|
||||
}
|
||||
|
||||
func newPubKey(pk string) (res crypto.PubKey) {
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
func TestBeginBlocker(t *testing.T) {
|
||||
ctx, ck, sk, _, keeper := createTestInput(t)
|
||||
ctx, ck, sk, _, keeper := createTestInput(t, HubDefaultParams())
|
||||
addr, pk, amt := addrs[2], pks[2], sdk.NewInt(100)
|
||||
|
||||
// bond the validator
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
|
@ -36,15 +37,20 @@ func getMockApp(t *testing.T) (*mock.App, Keeper) {
|
|||
RegisterCodec(mApp.Cdc)
|
||||
|
||||
keyStake := sdk.NewKVStoreKey("stake")
|
||||
|
||||
tkeyStake := sdk.NewTransientStoreKey("transient_stake")
|
||||
keyParams := sdk.NewKVStoreKey("params")
|
||||
tkeyParams := sdk.NewTransientStoreKey("transient_params")
|
||||
|
||||
bankKeeper := bank.NewBaseKeeper(mApp.AccountMapper)
|
||||
keeper := NewKeeper(mApp.Cdc, keyStake, tkeyStake, bankKeeper, mApp.RegisterCodespace(DefaultCodespace))
|
||||
pk := params.NewKeeper(mApp.Cdc, keyParams, tkeyParams)
|
||||
keeper := NewKeeper(mApp.Cdc, keyStake, tkeyStake, coinKeeper, pk.Subspace("stake"), mApp.RegisterCodespace(DefaultCodespace))
|
||||
|
||||
mApp.Router().AddRoute("stake", NewHandler(keeper))
|
||||
mApp.SetEndBlocker(getEndBlocker(keeper))
|
||||
mApp.SetInitChainer(getInitChainer(mApp, keeper))
|
||||
|
||||
require.NoError(t, mApp.CompleteSetup(keyStake, tkeyStake))
|
||||
require.NoError(t, mApp.CompleteSetup(keyStake, tkeyStake, keyParams, tkeyParams))
|
||||
return mApp, keeper
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
paramutils "github.com/cosmos/cosmos-sdk/x/params/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
)
|
||||
|
@ -464,16 +465,14 @@ func GetCmdQueryParams(storeName string, cdc *codec.Codec) *cobra.Command {
|
|||
Short: "Query the current staking parameters information",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
key := stake.ParamKey
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
res, err := cliCtx.QueryStore(key, storeName)
|
||||
var params types.Params
|
||||
err := paramutils.QueryParams(cliCtx, storeName, ¶ms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params := types.MustUnmarshalParams(cdc, res)
|
||||
|
||||
switch viper.Get(cli.OutputFlag) {
|
||||
case "text":
|
||||
human := params.HumanReadableString()
|
||||
|
|
|
@ -335,7 +335,7 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA
|
|||
//______________________________________________________________________________________________________
|
||||
|
||||
// get info for begin functions: MinTime and CreationHeight
|
||||
func (k Keeper) getBeginInfo(ctx sdk.Context, params types.Params, valSrcAddr sdk.ValAddress) (
|
||||
func (k Keeper) getBeginInfo(ctx sdk.Context, valSrcAddr sdk.ValAddress) (
|
||||
minTime time.Time, height int64, completeNow bool) {
|
||||
|
||||
validator, found := k.GetValidator(ctx, valSrcAddr)
|
||||
|
@ -343,7 +343,7 @@ func (k Keeper) getBeginInfo(ctx sdk.Context, params types.Params, valSrcAddr sd
|
|||
case !found || validator.Status == sdk.Bonded:
|
||||
|
||||
// the longest wait - just unbonding period from now
|
||||
minTime = ctx.BlockHeader().Time.Add(params.UnbondingTime)
|
||||
minTime = ctx.BlockHeader().Time.Add(k.UnbondingTime(ctx))
|
||||
height = ctx.BlockHeader().Height
|
||||
return minTime, height, false
|
||||
|
||||
|
@ -376,9 +376,8 @@ func (k Keeper) BeginUnbonding(ctx sdk.Context,
|
|||
}
|
||||
|
||||
// create the unbonding delegation
|
||||
params := k.GetParams(ctx)
|
||||
minTime, height, completeNow := k.getBeginInfo(ctx, params, valAddr)
|
||||
balance := sdk.NewCoin(params.BondDenom, returnAmount.RoundInt())
|
||||
minTime, height, completeNow := k.getBeginInfo(ctx, valAddr)
|
||||
balance := sdk.Coin{k.BondDenom(ctx), returnAmount.RoundInt()}
|
||||
|
||||
// no need to create the ubd object just complete now
|
||||
if completeNow {
|
||||
|
@ -437,8 +436,7 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress,
|
|||
return err
|
||||
}
|
||||
|
||||
params := k.GetParams(ctx)
|
||||
returnCoin := sdk.NewCoin(params.BondDenom, returnAmount.RoundInt())
|
||||
returnCoin := sdk.Coin{k.BondDenom(ctx), returnAmount.RoundInt()}
|
||||
dstValidator, found := k.GetValidator(ctx, valDstAddr)
|
||||
if !found {
|
||||
return types.ErrBadRedelegationDst(k.Codespace())
|
||||
|
@ -449,7 +447,7 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress,
|
|||
}
|
||||
|
||||
// create the unbonding delegation
|
||||
minTime, height, completeNow := k.getBeginInfo(ctx, params, valSrcAddr)
|
||||
minTime, height, completeNow := k.getBeginInfo(ctx, valSrcAddr)
|
||||
|
||||
if completeNow { // no need to create the redelegation object
|
||||
return nil
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
)
|
||||
|
||||
|
@ -15,17 +16,19 @@ type Keeper struct {
|
|||
cdc *codec.Codec
|
||||
bankKeeper bank.Keeper
|
||||
hooks sdk.StakingHooks
|
||||
paramstore params.Space
|
||||
|
||||
// codespace
|
||||
codespace sdk.CodespaceType
|
||||
}
|
||||
|
||||
func NewKeeper(cdc *codec.Codec, key, tkey sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
|
||||
func NewKeeper(cdc *codec.Codec, key, tkey sdk.StoreKey, ck bank.Keeper, paramstore params.Space, codespace sdk.CodespaceType) Keeper {
|
||||
keeper := Keeper{
|
||||
storeKey: key,
|
||||
storeTKey: tkey,
|
||||
cdc: cdc,
|
||||
bankKeeper: ck,
|
||||
paramstore: paramstore,
|
||||
hooks: nil,
|
||||
codespace: codespace,
|
||||
}
|
||||
|
@ -48,29 +51,6 @@ func (k Keeper) Codespace() sdk.CodespaceType {
|
|||
return k.codespace
|
||||
}
|
||||
|
||||
//_________________________________________________________________________
|
||||
// some generic reads/writes that don't need their own files
|
||||
|
||||
// load/save the global staking params
|
||||
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
b := store.Get(ParamKey)
|
||||
if b == nil {
|
||||
panic("Stored params should not have been nil")
|
||||
}
|
||||
|
||||
k.cdc.MustUnmarshalBinary(b, ¶ms)
|
||||
return
|
||||
}
|
||||
|
||||
// set the params
|
||||
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
b := k.cdc.MustMarshalBinary(params)
|
||||
store.Set(ParamKey, b)
|
||||
}
|
||||
|
||||
//_______________________________________________________________________
|
||||
|
||||
// load/save the pool
|
||||
|
|
|
@ -12,7 +12,8 @@ import (
|
|||
//nolint
|
||||
var (
|
||||
// Keys for store prefixes
|
||||
ParamKey = []byte{0x00} // key for parameters relating to staking
|
||||
// TODO DEPRECATED: delete in next release and reorder keys
|
||||
// ParamKey = []byte{0x00} // key for parameters relating to staking
|
||||
PoolKey = []byte{0x01} // key for the staking pools
|
||||
ValidatorsKey = []byte{0x02} // prefix for each key to a validator
|
||||
ValidatorsByConsAddrKey = []byte{0x03} // prefix for each key to a validator index, by pubkey
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package keeper
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
)
|
||||
|
||||
// Default parameter namespace
|
||||
const (
|
||||
DefaultParamSpace = "stake"
|
||||
)
|
||||
|
||||
// Cached parameter keys
|
||||
var (
|
||||
keyInflationRateChange = types.KeyInflationRateChange()
|
||||
keyInflationMax = types.KeyInflationMax()
|
||||
keyInflationMin = types.KeyInflationMin()
|
||||
keyGoalBonded = types.KeyGoalBonded()
|
||||
keyUnbondingTime = types.KeyUnbondingTime()
|
||||
keyMaxValidators = types.KeyMaxValidators()
|
||||
keyBondDenom = types.KeyBondDenom()
|
||||
)
|
||||
|
||||
// InflationRateChange - Maximum annual change in inflation rate
|
||||
func (k Keeper) InflationRateChange(ctx sdk.Context) (res sdk.Dec) {
|
||||
k.paramstore.Get(ctx, keyInflationRateChange, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// InflationMax - Maximum inflation rate
|
||||
func (k Keeper) InflationMax(ctx sdk.Context) (res sdk.Dec) {
|
||||
k.paramstore.Get(ctx, keyInflationMax, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// InflationMin - Minimum inflation rate
|
||||
func (k Keeper) InflationMin(ctx sdk.Context) (res sdk.Dec) {
|
||||
k.paramstore.Get(ctx, keyInflationMin, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GoalBonded - Goal of percent bonded atoms
|
||||
func (k Keeper) GoalBonded(ctx sdk.Context) (res sdk.Dec) {
|
||||
k.paramstore.Get(ctx, keyGoalBonded, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// UnbondingTime
|
||||
func (k Keeper) UnbondingTime(ctx sdk.Context) (res time.Duration) {
|
||||
k.paramstore.Get(ctx, keyUnbondingTime, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// MaxValidators - Maximum number of validators
|
||||
func (k Keeper) MaxValidators(ctx sdk.Context) (res uint16) {
|
||||
k.paramstore.Get(ctx, keyMaxValidators, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// BondDenom - Bondable coin denomination
|
||||
func (k Keeper) BondDenom(ctx sdk.Context) (res string) {
|
||||
k.paramstore.Get(ctx, keyBondDenom, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// Get all parameteras as types.Params
|
||||
func (k Keeper) GetParams(ctx sdk.Context) (res types.Params) {
|
||||
res.InflationRateChange = k.InflationRateChange(ctx)
|
||||
res.InflationMax = k.InflationMax(ctx)
|
||||
res.InflationMin = k.InflationMin(ctx)
|
||||
res.GoalBonded = k.GoalBonded(ctx)
|
||||
res.UnbondingTime = k.UnbondingTime(ctx)
|
||||
res.MaxValidators = k.MaxValidators(ctx)
|
||||
res.BondDenom = k.BondDenom(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
// Need a distinct function because setParams depends on an existing previous
|
||||
// record of params to exist (to check if maxValidators has changed) - and we
|
||||
// panic on retrieval if it doesn't exist - hence if we use setParams for the very
|
||||
// first params set it will panic.
|
||||
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
|
||||
if k.MaxValidators(ctx) != params.MaxValidators {
|
||||
k.UpdateBondedValidatorsFull(ctx)
|
||||
}
|
||||
k.SetNewParams(ctx, params)
|
||||
}
|
||||
|
||||
// set the params without updating validator set
|
||||
func (k Keeper) SetNewParams(ctx sdk.Context, params types.Params) {
|
||||
k.paramstore.Set(ctx, keyInflationRateChange, params.InflationRateChange)
|
||||
k.paramstore.Set(ctx, keyInflationMax, params.InflationMax)
|
||||
k.paramstore.Set(ctx, keyInflationMin, params.InflationMin)
|
||||
k.paramstore.Set(ctx, keyGoalBonded, params.GoalBonded)
|
||||
k.paramstore.Set(ctx, keyUnbondingTime, params.UnbondingTime)
|
||||
k.paramstore.Set(ctx, keyMaxValidators, params.MaxValidators)
|
||||
k.paramstore.Set(ctx, keyBondDenom, params.BondDenom)
|
||||
}
|
|
@ -19,6 +19,7 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
)
|
||||
|
||||
|
@ -92,12 +93,16 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
|
|||
keyStake := sdk.NewKVStoreKey("stake")
|
||||
tkeyStake := sdk.NewTransientStoreKey("transient_stake")
|
||||
keyAcc := sdk.NewKVStoreKey("acc")
|
||||
keyParams := sdk.NewKVStoreKey("params")
|
||||
tkeyParams := sdk.NewTransientStoreKey("transient_params")
|
||||
|
||||
db := dbm.NewMemDB()
|
||||
ms := store.NewCommitMultiStore(db)
|
||||
ms.MountStoreWithDB(tkeyStake, sdk.StoreTypeTransient, nil)
|
||||
ms.MountStoreWithDB(keyStake, sdk.StoreTypeIAVL, db)
|
||||
ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
|
||||
ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
|
||||
ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
|
||||
err := ms.LoadLatestVersion()
|
||||
require.Nil(t, err)
|
||||
|
||||
|
@ -108,8 +113,11 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
|
|||
keyAcc, // target store
|
||||
auth.ProtoBaseAccount, // prototype
|
||||
)
|
||||
|
||||
ck := bank.NewBaseKeeper(accountMapper)
|
||||
keeper := NewKeeper(cdc, keyStake, tkeyStake, ck, types.DefaultCodespace)
|
||||
|
||||
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
|
||||
keeper := NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Subspace("stake"), types.DefaultCodespace)
|
||||
keeper.SetPool(ctx, types.InitialPool())
|
||||
keeper.SetParams(ctx, types.DefaultParams())
|
||||
keeper.InitIntraTxCounter(ctx)
|
||||
|
@ -118,7 +126,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
|
|||
for _, addr := range Addrs {
|
||||
pool := keeper.GetPool(ctx)
|
||||
_, _, err := ck.AddCoins(ctx, addr, sdk.Coins{
|
||||
{keeper.GetParams(ctx).BondDenom, sdk.NewInt(initCoins)},
|
||||
{keeper.BondDenom(ctx), sdk.NewInt(initCoins)},
|
||||
})
|
||||
require.Nil(t, err)
|
||||
pool.LooseTokens = pool.LooseTokens.Add(sdk.NewDec(initCoins))
|
||||
|
|
|
@ -238,7 +238,7 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validat
|
|||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
// add the actual validator power sorted store
|
||||
maxValidators := k.GetParams(ctx).MaxValidators
|
||||
maxValidators := k.MaxValidators(ctx)
|
||||
validators = make([]types.Validator, maxValidators)
|
||||
|
||||
iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey)
|
||||
|
@ -263,7 +263,7 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validat
|
|||
// get the group of bonded validators sorted by power-rank
|
||||
func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
maxValidators := k.GetParams(ctx).MaxValidators
|
||||
maxValidators := k.MaxValidators(ctx)
|
||||
validators := make([]types.Validator, maxValidators)
|
||||
|
||||
iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey)
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
||||
"github.com/cosmos/cosmos-sdk/x/mock/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
)
|
||||
|
||||
|
@ -23,7 +24,11 @@ func TestStakeWithRandomMessages(t *testing.T) {
|
|||
bankKeeper := bank.NewBaseKeeper(mapper)
|
||||
stakeKey := sdk.NewKVStoreKey("stake")
|
||||
stakeTKey := sdk.NewTransientStoreKey("transient_stake")
|
||||
stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, stakeTKey, bankKeeper, stake.DefaultCodespace)
|
||||
paramsKey := sdk.NewKVStoreKey("params")
|
||||
paramsTKey := sdk.NewTransientStoreKey("transient_params")
|
||||
|
||||
paramstore := params.NewKeeper(mapp.Cdc, paramsKey, paramsTKey).Subspace(stake.DefaultParamSpace)
|
||||
stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, stakeTKey, bankKeeper, paramstore, stake.DefaultCodespace)
|
||||
mapp.Router().AddRoute("stake", stake.NewHandler(stakeKeeper))
|
||||
mapp.SetEndBlocker(func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
validatorUpdates := stake.EndBlocker(ctx, stakeKeeper)
|
||||
|
@ -32,7 +37,7 @@ func TestStakeWithRandomMessages(t *testing.T) {
|
|||
}
|
||||
})
|
||||
|
||||
err := mapp.CompleteSetup(stakeKey, stakeTKey)
|
||||
err := mapp.CompleteSetup(stakeKey, stakeTKey, paramsKey, paramsTKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ var (
|
|||
GetValidatorsByPowerIndexKey = keeper.GetValidatorsByPowerIndexKey
|
||||
GetDelegationKey = keeper.GetDelegationKey
|
||||
GetDelegationsKey = keeper.GetDelegationsKey
|
||||
ParamKey = keeper.ParamKey
|
||||
PoolKey = keeper.PoolKey
|
||||
ValidatorsKey = keeper.ValidatorsKey
|
||||
ValidatorsByConsAddrKey = keeper.ValidatorsByConsAddrKey
|
||||
|
@ -60,6 +59,14 @@ var (
|
|||
GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey
|
||||
GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey
|
||||
|
||||
DefaultParamSpace = keeper.DefaultParamSpace
|
||||
KeyInflationRateChange = types.KeyInflationRateChange
|
||||
KeyInflationMax = types.KeyInflationMax
|
||||
KeyGoalBonded = types.KeyGoalBonded
|
||||
KeyUnbondingTime = types.KeyUnbondingTime
|
||||
KeyMaxValidators = types.KeyMaxValidators
|
||||
KeyBondDenom = types.KeyBondDenom
|
||||
|
||||
DefaultParams = types.DefaultParams
|
||||
InitialPool = types.InitialPool
|
||||
NewValidator = types.NewValidator
|
||||
|
|
|
@ -7,12 +7,22 @@ import (
|
|||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
// defaultUnbondingTime reflects three weeks in seconds as the default
|
||||
// unbonding time.
|
||||
const defaultUnbondingTime time.Duration = 60 * 60 * 24 * 3 * time.Second
|
||||
|
||||
// nolint - Key generators for parameter access
|
||||
func KeyInflationRateChange() params.Key { return params.NewKey("InflationRateChange") }
|
||||
func KeyInflationMax() params.Key { return params.NewKey("InflationMax") }
|
||||
func KeyInflationMin() params.Key { return params.NewKey("InflationMin") }
|
||||
func KeyGoalBonded() params.Key { return params.NewKey("GoalBonded") }
|
||||
func KeyUnbondingTime() params.Key { return params.NewKey("UnbondingTime") }
|
||||
func KeyMaxValidators() params.Key { return params.NewKey("MaxValidators") }
|
||||
func KeyBondDenom() params.Key { return params.NewKey("BondDenom") }
|
||||
|
||||
// Params defines the high level settings for staking
|
||||
type Params struct {
|
||||
InflationRateChange sdk.Dec `json:"inflation_rate_change"` // maximum annual change in inflation rate
|
||||
|
@ -26,6 +36,19 @@ type Params struct {
|
|||
BondDenom string `json:"bond_denom"` // bondable coin denomination
|
||||
}
|
||||
|
||||
// Implements params.ParamStruct
|
||||
func (p *Params) KeyFieldPairs() params.KeyFieldPairs {
|
||||
return params.KeyFieldPairs{
|
||||
{KeyInflationRateChange(), &p.InflationRateChange},
|
||||
{KeyInflationMax(), &p.InflationMax},
|
||||
{KeyInflationMin(), &p.InflationMin},
|
||||
{KeyGoalBonded(), &p.GoalBonded},
|
||||
{KeyUnbondingTime(), &p.UnbondingTime},
|
||||
{KeyMaxValidators(), &p.MaxValidators},
|
||||
{KeyBondDenom(), &p.BondDenom},
|
||||
}
|
||||
}
|
||||
|
||||
// Equal returns a boolean determining if two Param types are identical.
|
||||
func (p Params) Equal(p2 Params) bool {
|
||||
bz1 := MsgCdc.MustMarshalBinary(&p)
|
||||
|
|
Loading…
Reference in New Issue