apply requests in progress

This commit is contained in:
mossid 2018-10-07 00:32:41 +09:00
parent 7d49675600
commit 7a68b376bd
21 changed files with 163 additions and 73 deletions

View File

@ -97,14 +97,14 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
app.stakeKeeper = stake.NewKeeper(
app.cdc,
app.keyStake, app.tkeyStake,
app.bankKeeper, app.paramsKeeper.Substore(stake.DefaultParamspace),
app.bankKeeper, app.paramsKeeper.Substore(stake.DefaultParamspace, stake.ParamTable()),
app.RegisterCodespace(stake.DefaultCodespace),
)
app.slashingKeeper = slashing.NewKeeper(
app.cdc,
app.keySlashing,
app.stakeKeeper, app.paramsKeeper.Substore(slashing.DefaultParamspace),
app.stakeKeeper, app.paramsKeeper.Substore(slashing.DefaultParamspace, slashing.ParamTable()),
app.RegisterCodespace(slashing.DefaultCodespace),
)
@ -115,7 +115,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
app.govKeeper = gov.NewKeeper(
app.cdc,
app.keyGov,
app.paramsKeeper, app.paramsKeeper.Substore(gov.DefaultParamspace), app.bankKeeper, app.stakeKeeper,
app.paramsKeeper, app.paramsKeeper.Substore(gov.DefaultParamspace, gov.ParamTable()), app.bankKeeper, app.stakeKeeper,
app.RegisterCodespace(gov.DefaultCodespace),
)

View File

@ -175,8 +175,8 @@ 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.tkeyParams)
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.tkeyStake, app.bankKeeper, app.paramsKeeper.Substore(stake.DefaultParamspace), app.RegisterCodespace(stake.DefaultCodespace))
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Substore(slashing.DefaultParamspace), app.RegisterCodespace(slashing.DefaultCodespace))
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.tkeyStake, app.bankKeeper, app.paramsKeeper.Substore(stake.DefaultParamspace, stake.ParamTable()), app.RegisterCodespace(stake.DefaultCodespace))
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Substore(slashing.DefaultParamspace, slashing.ParamTable()), app.RegisterCodespace(slashing.DefaultCodespace))
// register message routes
app.Router().

View File

@ -47,8 +47,6 @@ 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
}
@ -74,12 +72,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(), c.KVGasConfig())
return c.multiStore().GetKVStore(key).Gas(c.GasMeter(), cachedKVGasConfig)
}
// TransientStore fetches a TransientStore from the MultiStore.
func (c Context) TransientStore(key StoreKey) KVStore {
return c.multiStore().GetKVStore(key).Gas(c.GasMeter(), c.TransientGasConfig())
return c.multiStore().GetKVStore(key).Gas(c.GasMeter(), cachedTransientGasConfig)
}
//----------------------------------------
@ -142,8 +140,6 @@ const (
contextKeyVoteInfos
contextKeyGasMeter
contextKeyMinimumFees
contextKeyKVGasConfig
contextKeyTransientGasConfig
)
// NOTE: Do not expose MultiStore.
@ -179,12 +175,6 @@ 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)
@ -222,14 +212,6 @@ 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.
func (c Context) CacheContext() (cc Context, writeCache func()) {

View File

@ -19,6 +19,14 @@ var (
ParamStoreKeyTallyingProcedure = []byte("tallyingprocedure")
)
func ParamTable() params.Table {
return params.NewTable(
ParamStoreKeyDepositProcedure, DepositProcedure{},
ParamStoreKeyVotingProcedure, VotingProcedure{},
ParamStoreKeyTallyingProcedure, TallyingProcedure{},
)
}
// Governance Keeper
type Keeper struct {
// The reference to the Param Keeper to get and set Global Params

View File

@ -30,9 +30,9 @@ func TestGovWithRandomMessages(t *testing.T) {
paramKey := sdk.NewKVStoreKey("params")
paramTKey := sdk.NewTransientStoreKey("transient_params")
paramKeeper := params.NewKeeper(mapp.Cdc, paramKey, paramTKey)
stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, stakeTKey, bankKeeper, paramKeeper.Substore(stake.DefaultParamspace), stake.DefaultCodespace)
stakeKeeper := stake.NewKeeper(mapp.Cdc, stakeKey, stakeTKey, bankKeeper, paramKeeper.Substore(stake.DefaultParamspace, stake.ParamTable()), stake.DefaultCodespace)
govKey := sdk.NewKVStoreKey("gov")
govKeeper := gov.NewKeeper(mapp.Cdc, govKey, paramKeeper, paramKeeper.Substore(gov.DefaultParamspace), bankKeeper, stakeKeeper, gov.DefaultCodespace)
govKeeper := gov.NewKeeper(mapp.Cdc, govKey, paramKeeper, paramKeeper.Substore(gov.DefaultParamspace, gov.ParamTable()), 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)

View File

@ -34,8 +34,8 @@ func getMockApp(t *testing.T, numGenAccs int) (*mock.App, Keeper, stake.Keeper,
pk := params.NewKeeper(mapp.Cdc, keyGlobalParams, tkeyGlobalParams)
ck := bank.NewBaseKeeper(mapp.AccountMapper)
sk := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, ck, pk.Substore(stake.DefaultParamspace), mapp.RegisterCodespace(stake.DefaultCodespace))
keeper := NewKeeper(mapp.Cdc, keyGov, pk, pk.Substore("testgov"), ck, sk, DefaultCodespace)
sk := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, ck, pk.Substore(stake.DefaultParamspace, stake.ParamTable()), mapp.RegisterCodespace(stake.DefaultCodespace))
keeper := NewKeeper(mapp.Cdc, keyGov, pk, pk.Substore("testgov", ParamTable()), ck, sk, DefaultCodespace)
mapp.Router().AddRoute("gov", NewHandler(keeper))

View File

@ -30,7 +30,7 @@ func NewKeeper(cdc *codec.Codec, key *sdk.KVStoreKey, tkey *sdk.TransientStoreKe
}
// Allocate substore used for keepers
func (k Keeper) Substore(storename string) Store {
func (k Keeper) Substore(storename string, table Table) Store {
_, ok := k.stores[storename]
if ok {
panic("substore already occupied")
@ -40,7 +40,7 @@ func (k Keeper) Substore(storename string) Store {
panic("cannot use empty string for substore")
}
store := store.NewStore(k.cdc, k.key, k.tkey, storename)
store := store.NewStore(k.cdc, k.key, k.tkey, storename, table)
k.stores[storename] = &store

View File

@ -49,14 +49,26 @@ func TestKeeper(t *testing.T) {
{"key3", 182},
{"key4", 17582},
{"key5", 2768554},
{"store1/key1", 1157279},
{"store1/key2", 9058701},
{"key6", 1157279},
{"key7", 9058701},
}
table := NewTable(
[]byte("key1"), int64(0),
[]byte("key2"), int64(0),
[]byte("key3"), int64(0),
[]byte("key4"), int64(0),
[]byte("key5"), int64(0),
[]byte("key6"), int64(0),
[]byte("key7"), int64(0),
[]byte("extra1"), bool(false),
[]byte("extra2"), string(""),
)
skey := sdk.NewKVStoreKey("test")
tkey := sdk.NewTransientStoreKey("transient_test")
ctx := defaultContext(skey, tkey)
store := NewKeeper(codec.New(), skey, tkey).Substore("test")
store := NewKeeper(codec.New(), skey, tkey).Substore("test", table)
for i, kv := range kvs {
require.NotPanics(t, func() { store.Set(ctx, []byte(kv.key), kv.param) }, "store.Set panics, tc #%d", i)
@ -93,8 +105,6 @@ func TestGet(t *testing.T) {
ctx := defaultContext(key, tkey)
keeper := NewKeeper(createTestCodec(), key, tkey)
store := keeper.Substore("test")
kvs := []struct {
key string
param interface{}
@ -115,6 +125,23 @@ func TestGet(t *testing.T) {
{"struct", s{1}, s{0}, new(s)},
}
table := NewTable(
[]byte("string"), string(""),
[]byte("bool"), bool(false),
[]byte("int16"), int16(0),
[]byte("int32"), int32(0),
[]byte("int64"), int64(0),
[]byte("uint16"), uint16(0),
[]byte("uint32"), uint32(0),
[]byte("uint64"), uint64(0),
[]byte("int"), sdk.Int{},
[]byte("uint"), sdk.Uint{},
[]byte("dec"), sdk.Dec{},
[]byte("struct"), s{},
)
store := keeper.Substore("test", table)
for i, kv := range kvs {
require.False(t, store.Modified(ctx, []byte(kv.key)), "store.Modified returns true before setting, tc #%d", i)
require.NotPanics(t, func() { store.Set(ctx, []byte(kv.key), kv.param) }, "store.Set panics, tc #%d", i)

View File

@ -10,4 +10,10 @@ type (
ReadOnlyStore = store.ReadOnlyStore
ParamStruct = store.ParamStruct
KeyValuePairs = store.KeyValuePairs
Table = store.Table
)
// re-export functions from store
func NewTable(keytypes ...interface{}) Table {
return store.NewTable(keytypes...)
}

View File

@ -1,13 +1,13 @@
package store
// Used for associating paramstore key and field of param structs
type KeyFieldPair struct {
type KeyValuePair struct {
Key []byte
Field interface{}
Value interface{}
}
// Slice of KeyFieldPair
type KeyValuePairs []KeyFieldPair
type KeyValuePairs []KeyValuePair
// Interface for structs containing parameters for a module
type ParamStruct interface {

View File

@ -21,14 +21,18 @@ type Store struct {
tkey sdk.StoreKey // []byte -> bool, stores parameter change
space []byte
table Table
}
// NewStore constructs a store with namestore
func NewStore(cdc *codec.Codec, key sdk.StoreKey, tkey sdk.StoreKey, space string) (res Store) {
func NewStore(cdc *codec.Codec, key sdk.StoreKey, tkey sdk.StoreKey, space string, table Table) (res Store) {
res = Store{
cdc: cdc,
key: key,
tkey: tkey,
table: table,
}
spacebz := []byte(space)
@ -77,8 +81,7 @@ func (s Store) GetIfExists(ctx sdk.Context, key []byte, ptr interface{}) {
// Get raw bytes of parameter from store
func (s Store) GetRaw(ctx sdk.Context, key []byte) []byte {
store := s.kvStore(ctx)
res := store.Get(key)
return res
return store.Get(key)
}
// Check if the parameter is set in the store
@ -98,18 +101,19 @@ func (s Store) Modified(ctx sdk.Context, key []byte) bool {
func (s Store) Set(ctx sdk.Context, key []byte, param interface{}) {
store := s.kvStore(ctx)
bz := store.Get(key)
ty, ok := s.table.m[string(key)]
if !ok {
fmt.Println(string(key), ty, param, reflect.TypeOf(param))
panic("Parameter not registered")
}
// To prevent invalid parameter set, we check the type of the stored parameter
// and try to match it with the provided parameter. It continues only if they matches.
// It is possible because parameter set happens rarely.
if bz != nil {
ptrType := reflect.PtrTo(reflect.TypeOf(param))
ptr := reflect.New(ptrType).Interface()
pty := reflect.TypeOf(param)
if pty.Kind() == reflect.Ptr {
pty = pty.Elem()
}
if s.cdc.UnmarshalJSON(bz, ptr) != nil {
panic(fmt.Errorf("Type mismatch with stored param and provided param"))
}
if pty != ty {
panic("Type mismatch with registered table")
}
bz, err := s.cdc.MarshalJSON(param)
@ -122,20 +126,10 @@ func (s Store) Set(ctx sdk.Context, key []byte, param interface{}) {
tstore.Set(key, []byte{})
}
// Set raw bytes of parameter
// Also set to the transient store to record change
func (s Store) SetRaw(ctx sdk.Context, key []byte, param []byte) {
store := s.kvStore(ctx)
store.Set(key, param)
tstore := s.transientStore(ctx)
tstore.Set(key, []byte{})
}
// Get to ParamStruct
func (s Store) GetStruct(ctx sdk.Context, ps ParamStruct) {
for _, pair := range ps.KeyValuePairs() {
s.Get(ctx, pair.Key, pair.Field)
s.Get(ctx, pair.Key, pair.Value)
}
}
@ -146,7 +140,7 @@ func (s Store) SetStruct(ctx sdk.Context, ps ParamStruct) {
// go-amino automatically handles it but just for sure,
// since SetStruct is meant to be used in InitGenesis
// so this method will not be called frequently
v := reflect.Indirect(reflect.ValueOf(pair.Field)).Interface()
v := reflect.Indirect(reflect.ValueOf(pair.Value)).Interface()
s.Set(ctx, pair.Key, v)
}
}

56
x/params/store/table.go Normal file
View File

@ -0,0 +1,56 @@
package store
import (
"reflect"
)
type Table struct {
m map[string]reflect.Type
sealed bool
}
func NewTable(keytypes ...interface{}) (res Table) {
if len(keytypes)%2 != 0 {
panic("odd number arguments in NewTypeTable")
}
res = Table{
m: make(map[string]reflect.Type),
sealed: false,
}
for i := 0; i < len(keytypes); i += 2 {
res = res.RegisterType(keytypes[i].([]byte), keytypes[i+1])
}
return
}
func (t Table) RegisterType(key []byte, ty interface{}) Table {
if t.sealed {
panic("RegisterType() on sealed Table")
}
keystr := string(key)
if _, ok := t.m[keystr]; ok {
panic("duplicate parameter key")
}
rty := reflect.TypeOf(ty)
// Indirect rty if it is ptr
if rty.Kind() == reflect.Ptr {
rty = rty.Elem()
}
t.m[keystr] = rty
return t
}
func (t Table) RegisterParamStruct(ps ParamStruct) Table {
for _, kvp := range ps.KeyValuePairs() {
t = t.RegisterType(kvp.Key, kvp.Value)
}
return t
}

View File

@ -21,7 +21,7 @@ const (
)
// Returns components for testing
func DefaultTestComponents(t *testing.T) (sdk.Context, Store, func() sdk.CommitID) {
func DefaultTestComponents(t *testing.T, table Table) (sdk.Context, Store, func() sdk.CommitID) {
cdc := codec.New()
key := sdk.NewKVStoreKey("params")
tkey := sdk.NewTransientStoreKey("tparams")
@ -34,7 +34,7 @@ func DefaultTestComponents(t *testing.T) (sdk.Context, Store, func() sdk.CommitI
err := ms.LoadLatestVersion()
require.Nil(t, err)
ctx := sdk.NewContext(ms, abci.Header{}, false, log.NewTMLogger(os.Stdout))
store := NewStore(cdc, key, tkey, TestParamStore)
store := NewStore(cdc, key, tkey, TestParamStore, table)
return ctx, store, ms.Commit
}

View File

@ -34,8 +34,8 @@ func getMockApp(t *testing.T) (*mock.App, stake.Keeper, Keeper) {
bankKeeper := bank.NewBaseKeeper(mapp.AccountMapper)
paramsKeeper := params.NewKeeper(mapp.Cdc, keyParams, tkeyParams)
stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, bankKeeper, paramsKeeper.Substore(stake.DefaultParamspace), mapp.RegisterCodespace(stake.DefaultCodespace))
keeper := NewKeeper(mapp.Cdc, keySlashing, stakeKeeper, paramsKeeper.Substore(DefaultParamspace), mapp.RegisterCodespace(DefaultCodespace))
stakeKeeper := stake.NewKeeper(mapp.Cdc, keyStake, tkeyStake, bankKeeper, paramsKeeper.Substore(stake.DefaultParamspace, stake.ParamTable()), mapp.RegisterCodespace(stake.DefaultCodespace))
keeper := NewKeeper(mapp.Cdc, keySlashing, stakeKeeper, paramsKeeper.Substore(DefaultParamspace, ParamTable()), mapp.RegisterCodespace(DefaultCodespace))
mapp.Router().AddRoute("stake", stake.NewHandler(stakeKeeper))
mapp.Router().AddRoute("slashing", NewHandler(keeper))

View File

@ -23,6 +23,10 @@ var (
KeySlashFractionDowntime = []byte("SlashFractionDowntime")
)
func ParamTable() params.Table {
return params.NewTable().RegisterParamStruct(&Params{})
}
// Params - used for initializing default parameter for slashing at genesis
type Params struct {
MaxEvidenceAge time.Duration `json:"max-evidence-age"`

View File

@ -71,8 +71,8 @@ func createTestInput(t *testing.T, defaults Params) (sdk.Context, bank.Keeper, s
accountMapper := auth.NewAccountMapper(cdc, keyAcc, auth.ProtoBaseAccount)
ck := bank.NewBaseKeeper(accountMapper)
paramstore := params.NewKeeper(cdc, keyParams, tkeyParams).Substore(DefaultParamspace)
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, paramstore, stake.DefaultCodespace)
paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams)
sk := stake.NewKeeper(cdc, keyStake, tkeyStake, ck, paramsKeeper.Substore(stake.DefaultParamspace, stake.ParamTable()), stake.DefaultCodespace)
genesis := stake.DefaultGenesisState()
genesis.Pool.LooseTokens = sdk.NewDec(initCoins.MulRaw(int64(len(addrs))).Int64())
@ -86,6 +86,7 @@ func createTestInput(t *testing.T, defaults Params) (sdk.Context, bank.Keeper, s
})
}
require.Nil(t, err)
paramstore := paramsKeeper.Substore(DefaultParamspace, ParamTable())
keeper := NewKeeper(cdc, keySlashing, sk, paramstore, DefaultCodespace)
require.NotPanics(t, func() {

View File

@ -45,7 +45,7 @@ func getMockApp(t *testing.T) (*mock.App, Keeper) {
bankKeeper := bank.NewBaseKeeper(mApp.AccountMapper)
pk := params.NewKeeper(mApp.Cdc, keyParams, tkeyParams)
keeper := NewKeeper(mApp.Cdc, keyStake, tkeyStake, bankKeeper, pk.Substore(DefaultParamspace), mApp.RegisterCodespace(DefaultCodespace))
keeper := NewKeeper(mApp.Cdc, keyStake, tkeyStake, bankKeeper, pk.Substore(DefaultParamspace, ParamTable()), mApp.RegisterCodespace(DefaultCodespace))
mApp.Router().AddRoute("stake", NewHandler(keeper))
mApp.SetEndBlocker(getEndBlocker(keeper))

View File

@ -4,6 +4,7 @@ import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/stake/types"
)
@ -12,6 +13,10 @@ const (
DefaultParamspace = "stake"
)
func ParamTable() params.Table {
return params.NewTable().RegisterParamStruct(&types.Params{})
}
// InflationRateChange - Maximum annual change in inflation rate
func (k Keeper) InflationRateChange(ctx sdk.Context) (res sdk.Dec) {
k.paramstore.Get(ctx, types.KeyInflationRateChange, &res)

View File

@ -117,7 +117,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context
ck := bank.NewBaseKeeper(accountMapper)
pk := params.NewKeeper(cdc, keyParams, tkeyParams)
keeper := NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Substore("stake"), types.DefaultCodespace)
keeper := NewKeeper(cdc, keyStake, tkeyStake, ck, pk.Substore("stake", ParamTable()), types.DefaultCodespace)
keeper.SetPool(ctx, types.InitialPool())
keeper.SetParams(ctx, types.DefaultParams())
keeper.InitIntraTxCounter(ctx)

View File

@ -27,7 +27,7 @@ func TestStakeWithRandomMessages(t *testing.T) {
paramsKey := sdk.NewKVStoreKey("params")
paramsTKey := sdk.NewTransientStoreKey("transient_params")
paramstore := params.NewKeeper(mapp.Cdc, paramsKey, paramsTKey).Substore(stake.DefaultParamspace)
paramstore := params.NewKeeper(mapp.Cdc, paramsKey, paramsTKey).Substore(stake.DefaultParamspace, stake.ParamTable())
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 {

View File

@ -2,6 +2,8 @@
package stake
import (
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/stake/keeper"
"github.com/cosmos/cosmos-sdk/x/stake/querier"
"github.com/cosmos/cosmos-sdk/x/stake/tags"
@ -162,3 +164,8 @@ var (
TagMoniker = tags.Moniker
TagIdentity = tags.Identity
)
// nolint - reexport
func ParamTable() params.Table {
return keeper.ParamTable()
}