cosmos-sdk/x/params/subspace/subspace.go

301 lines
7.5 KiB
Go
Raw Normal View History

package subspace
import (
Merge PR #4206: Param Change Proposal * Add params error types * Update param module keeper to take a codespace * Update imports * Implement SetRaw and SetRawWithSubkey * Implement ParamChange and update aliases * Add types codec * Implement ParameterChangeProposal * Implement TestParameterChangeProposal * Fix linting errors * Update tags * Implement content * Updata params aliases * Finish params handler and proposal types * Move deposit and vote logic to types package * Move proposal type to types package * Move errors to types package * Update proposal * Move gov messages to types package * Minor updates to naming * Move keys to types package * Move codec to types package * Move proposal types to types package * Update aliases * Add governance alias types * Implement governance router * Update gov aliases * Update gov keeper * Update private functions needed for the keeper * Update godocs * Update the gov message handler * Update Gaia app * Make updates to auth * Update the message codec in the keeper * Update gov end blocker * Update types tests * Minor tweaks * Add legacy genesis logic * Update gov aliases * Move gov keys to types package * Revertt to using gov/types in params * Implement params handler test * Update governance tests * Fix endblocker tests * Fix governance querier tests * Add seal support to gov router * Update simulationCreateMsgSubmitProposal * Disable software upgrade proposals * Move params keys to types package * Implement param module proposal client logic * Update gov client logic * Update gaia app client hooks * Fix linting errors * Fix ValidateBasic * Remove legacy files * Update paramchange to use strings * Update paramchange cli cmd * Update ValidateBasic and errors * Use PostCommands when adding child cmds * Fix codec logic * Update params client and handler * Update IsValidProposalType * Update SubmitProposal to test exec * Implement TestGaiaCLISubmitParamChangeProposal * Implement TestSubmitParamChangeProposal * Update swagger.yaml * Update gaiacli.md * Update gov spec docs * Fix linting errors * Fix unit tests * Add pending log entries * Update docs * Update docs * Update client/lcd/swagger-ui/swagger.yaml Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update cmd/gaia/cli_test/test_helpers.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update client/lcd/test_helpers.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update x/gov/types/proposal.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Address PR comments * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update gov docs to include quorum notes * Add logs to handleParameterChangeProposal * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Support and use new StatusFailed when proposal passes but fails exec * Add docs/notes warning on param validity * Update docs * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Minor doc update * Update x/gov/client/cli/tx.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Fix usage of fromAddr * Rige code style suggestion * Update x/params/types/proposal.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Fix CI lint errors * Update NewModuleClient godoc * Add godoc to rtr.Seal() call * Rename files * Rename NewProposalHandler
2019-04-30 09:31:38 -07:00
"errors"
"reflect"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
2019-02-01 17:03:09 -08:00
"github.com/cosmos/cosmos-sdk/store/prefix"
)
const (
// StoreKey is the string store key for the param store
StoreKey = "params"
// TStoreKey is the string store key for the param transient store
TStoreKey = "transient_params"
)
// Individual parameter store for each keeper
2018-09-27 11:12:52 -07:00
// Transient store persists for a block, so we use it for
// recording whether the parameter has been changed or not
type Subspace struct {
cdc *codec.Codec
2018-09-27 11:12:52 -07:00
key sdk.StoreKey // []byte -> []byte, stores parameter
tkey sdk.StoreKey // []byte -> bool, stores parameter change
name []byte
2018-10-06 08:32:41 -07:00
2019-02-04 18:13:04 -08:00
table KeyTable
}
// NewSubspace constructs a store with namestore
func NewSubspace(cdc *codec.Codec, key sdk.StoreKey, tkey sdk.StoreKey, name string) (res Subspace) {
res = Subspace{
cdc: cdc,
key: key,
tkey: tkey,
name: []byte(name),
2019-02-04 18:13:04 -08:00
table: KeyTable{
m: make(map[string]attribute),
},
}
return
}
2018-10-06 08:32:41 -07:00
2019-02-04 18:13:04 -08:00
// WithKeyTable initializes KeyTable and returns modified Subspace
func (s Subspace) WithKeyTable(table KeyTable) Subspace {
if table.m == nil {
2019-02-04 18:13:04 -08:00
panic("SetKeyTable() called with nil KeyTable")
}
if len(s.table.m) != 0 {
2019-02-04 18:13:04 -08:00
panic("SetKeyTable() called on already initialized Subspace")
}
for k, v := range table.m {
s.table.m[k] = v
}
2018-10-06 06:50:58 -07:00
// Allocate additional capicity for Subspace.name
// So we don't have to allocate extra space each time appending to the key
name := s.name
s.name = make([]byte, len(name), len(name)+table.maxKeyLength())
copy(s.name, name)
return s
}
2018-10-06 06:50:58 -07:00
// Returns a KVStore identical with ctx.KVStore(s.key).Prefix()
func (s Subspace) kvStore(ctx sdk.Context) sdk.KVStore {
2018-10-06 06:50:58 -07:00
// append here is safe, appends within a function won't cause
// weird side effects when its singlethreaded
2019-02-01 17:03:09 -08:00
return prefix.NewStore(ctx.KVStore(s.key), append(s.name, '/'))
2018-09-18 10:16:51 -07:00
}
2019-02-04 18:13:04 -08:00
// Returns a transient store for modification
func (s Subspace) transientStore(ctx sdk.Context) sdk.KVStore {
2018-10-06 06:50:58 -07:00
// append here is safe, appends within a function won't cause
// weird side effects when its singlethreaded
2019-02-01 17:03:09 -08:00
return prefix.NewStore(ctx.TransientStore(s.tkey), append(s.name, '/'))
2018-09-18 10:16:51 -07:00
}
2019-02-04 18:13:04 -08:00
func concatKeys(key, subkey []byte) (res []byte) {
res = make([]byte, len(key)+1+len(subkey))
copy(res, key)
res[len(key)] = '/'
copy(res[len(key)+1:], subkey)
return
}
// Get parameter from store
func (s Subspace) Get(ctx sdk.Context, key []byte, ptr interface{}) {
2018-09-18 10:16:51 -07:00
store := s.kvStore(ctx)
2018-09-27 11:52:29 -07:00
bz := store.Get(key)
err := s.cdc.UnmarshalJSON(bz, ptr)
if err != nil {
panic(err)
}
}
// GetIfExists do not modify ptr if the stored parameter is nil
func (s Subspace) GetIfExists(ctx sdk.Context, key []byte, ptr interface{}) {
2018-09-18 10:16:51 -07:00
store := s.kvStore(ctx)
2018-09-27 11:52:29 -07:00
bz := store.Get(key)
if bz == nil {
return
}
err := s.cdc.UnmarshalJSON(bz, ptr)
if err != nil {
panic(err)
}
}
2019-02-04 18:13:04 -08:00
// GetWithSubkey returns a parameter with a given key and a subkey.
func (s Subspace) GetWithSubkey(ctx sdk.Context, key, subkey []byte, ptr interface{}) {
s.Get(ctx, concatKeys(key, subkey), ptr)
2019-02-04 18:13:04 -08:00
}
// GetWithSubkeyIfExists returns a parameter with a given key and a subkey but does not
// modify ptr if the stored parameter is nil.
func (s Subspace) GetWithSubkeyIfExists(ctx sdk.Context, key, subkey []byte, ptr interface{}) {
s.GetIfExists(ctx, concatKeys(key, subkey), ptr)
2019-02-04 18:13:04 -08:00
}
// Get raw bytes of parameter from store
func (s Subspace) GetRaw(ctx sdk.Context, key []byte) []byte {
2018-09-18 10:16:51 -07:00
store := s.kvStore(ctx)
2018-10-06 08:32:41 -07:00
return store.Get(key)
}
// Check if the parameter is set in the store
func (s Subspace) Has(ctx sdk.Context, key []byte) bool {
2018-09-18 10:16:51 -07:00
store := s.kvStore(ctx)
2018-09-27 11:52:29 -07:00
return store.Has(key)
}
// Returns true if the parameter is set in the block
func (s Subspace) Modified(ctx sdk.Context, key []byte) bool {
2018-09-18 10:16:51 -07:00
tstore := s.transientStore(ctx)
2018-09-27 11:52:29 -07:00
return tstore.Has(key)
}
func (s Subspace) checkType(store sdk.KVStore, key []byte, param interface{}) {
2019-02-04 18:13:04 -08:00
attr, ok := s.table.m[string(key)]
2018-10-06 08:32:41 -07:00
if !ok {
panic("Parameter not registered")
2018-10-06 08:32:41 -07:00
}
2018-09-26 11:30:57 -07:00
2019-02-04 18:13:04 -08:00
ty := attr.ty
2018-10-06 08:32:41 -07:00
pty := reflect.TypeOf(param)
if pty.Kind() == reflect.Ptr {
pty = pty.Elem()
}
2018-10-06 08:32:41 -07:00
if pty != ty {
panic("Type mismatch with registered table")
}
2019-02-04 18:13:04 -08:00
}
// Set stores the parameter. It returns error if stored parameter has different type from input.
// It also set to the transient store to record change.
func (s Subspace) Set(ctx sdk.Context, key []byte, param interface{}) {
2019-02-04 18:13:04 -08:00
store := s.kvStore(ctx)
s.checkType(store, key, param)
bz, err := s.cdc.MarshalJSON(param)
if err != nil {
panic(err)
}
2018-09-27 11:52:29 -07:00
store.Set(key, bz)
2018-09-18 10:16:51 -07:00
tstore := s.transientStore(ctx)
2018-09-27 11:52:29 -07:00
tstore.Set(key, []byte{})
}
Merge PR #4206: Param Change Proposal * Add params error types * Update param module keeper to take a codespace * Update imports * Implement SetRaw and SetRawWithSubkey * Implement ParamChange and update aliases * Add types codec * Implement ParameterChangeProposal * Implement TestParameterChangeProposal * Fix linting errors * Update tags * Implement content * Updata params aliases * Finish params handler and proposal types * Move deposit and vote logic to types package * Move proposal type to types package * Move errors to types package * Update proposal * Move gov messages to types package * Minor updates to naming * Move keys to types package * Move codec to types package * Move proposal types to types package * Update aliases * Add governance alias types * Implement governance router * Update gov aliases * Update gov keeper * Update private functions needed for the keeper * Update godocs * Update the gov message handler * Update Gaia app * Make updates to auth * Update the message codec in the keeper * Update gov end blocker * Update types tests * Minor tweaks * Add legacy genesis logic * Update gov aliases * Move gov keys to types package * Revertt to using gov/types in params * Implement params handler test * Update governance tests * Fix endblocker tests * Fix governance querier tests * Add seal support to gov router * Update simulationCreateMsgSubmitProposal * Disable software upgrade proposals * Move params keys to types package * Implement param module proposal client logic * Update gov client logic * Update gaia app client hooks * Fix linting errors * Fix ValidateBasic * Remove legacy files * Update paramchange to use strings * Update paramchange cli cmd * Update ValidateBasic and errors * Use PostCommands when adding child cmds * Fix codec logic * Update params client and handler * Update IsValidProposalType * Update SubmitProposal to test exec * Implement TestGaiaCLISubmitParamChangeProposal * Implement TestSubmitParamChangeProposal * Update swagger.yaml * Update gaiacli.md * Update gov spec docs * Fix linting errors * Fix unit tests * Add pending log entries * Update docs * Update docs * Update client/lcd/swagger-ui/swagger.yaml Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update cmd/gaia/cli_test/test_helpers.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update client/lcd/test_helpers.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update x/gov/types/proposal.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Address PR comments * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update gov docs to include quorum notes * Add logs to handleParameterChangeProposal * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Support and use new StatusFailed when proposal passes but fails exec * Add docs/notes warning on param validity * Update docs * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Minor doc update * Update x/gov/client/cli/tx.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Fix usage of fromAddr * Rige code style suggestion * Update x/params/types/proposal.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Fix CI lint errors * Update NewModuleClient godoc * Add godoc to rtr.Seal() call * Rename files * Rename NewProposalHandler
2019-04-30 09:31:38 -07:00
// SetRaw stores raw parameter bytes. It returns error if the stored parameter
// has a different type from the input. It also sets to the transient store to
// record change.
func (s Subspace) SetRaw(ctx sdk.Context, key []byte, param []byte) error {
attr, ok := s.table.m[string(key)]
if !ok {
panic("Parameter not registered")
}
ty := attr.ty
dest := reflect.New(ty).Interface()
err := s.cdc.UnmarshalJSON(param, dest)
if err != nil {
return err
}
store := s.kvStore(ctx)
store.Set(key, param)
tStore := s.transientStore(ctx)
tStore.Set(key, []byte{})
return nil
}
2019-02-04 18:13:04 -08:00
// SetWithSubkey set a parameter with a key and subkey
// Checks parameter type only over the key
func (s Subspace) SetWithSubkey(ctx sdk.Context, key []byte, subkey []byte, param interface{}) {
2019-02-04 18:13:04 -08:00
store := s.kvStore(ctx)
s.checkType(store, key, param)
2019-02-04 18:13:04 -08:00
newkey := concatKeys(key, subkey)
bz, err := s.cdc.MarshalJSON(param)
if err != nil {
panic(err)
2019-02-04 18:13:04 -08:00
}
store.Set(newkey, bz)
tstore := s.transientStore(ctx)
tstore.Set(newkey, []byte{})
}
Merge PR #4206: Param Change Proposal * Add params error types * Update param module keeper to take a codespace * Update imports * Implement SetRaw and SetRawWithSubkey * Implement ParamChange and update aliases * Add types codec * Implement ParameterChangeProposal * Implement TestParameterChangeProposal * Fix linting errors * Update tags * Implement content * Updata params aliases * Finish params handler and proposal types * Move deposit and vote logic to types package * Move proposal type to types package * Move errors to types package * Update proposal * Move gov messages to types package * Minor updates to naming * Move keys to types package * Move codec to types package * Move proposal types to types package * Update aliases * Add governance alias types * Implement governance router * Update gov aliases * Update gov keeper * Update private functions needed for the keeper * Update godocs * Update the gov message handler * Update Gaia app * Make updates to auth * Update the message codec in the keeper * Update gov end blocker * Update types tests * Minor tweaks * Add legacy genesis logic * Update gov aliases * Move gov keys to types package * Revertt to using gov/types in params * Implement params handler test * Update governance tests * Fix endblocker tests * Fix governance querier tests * Add seal support to gov router * Update simulationCreateMsgSubmitProposal * Disable software upgrade proposals * Move params keys to types package * Implement param module proposal client logic * Update gov client logic * Update gaia app client hooks * Fix linting errors * Fix ValidateBasic * Remove legacy files * Update paramchange to use strings * Update paramchange cli cmd * Update ValidateBasic and errors * Use PostCommands when adding child cmds * Fix codec logic * Update params client and handler * Update IsValidProposalType * Update SubmitProposal to test exec * Implement TestGaiaCLISubmitParamChangeProposal * Implement TestSubmitParamChangeProposal * Update swagger.yaml * Update gaiacli.md * Update gov spec docs * Fix linting errors * Fix unit tests * Add pending log entries * Update docs * Update docs * Update client/lcd/swagger-ui/swagger.yaml Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update cmd/gaia/cli_test/test_helpers.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update client/lcd/test_helpers.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update x/gov/types/proposal.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Address PR comments * Update docs/cosmos-hub/gaiacli.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update gov docs to include quorum notes * Add logs to handleParameterChangeProposal * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Support and use new StatusFailed when proposal passes but fails exec * Add docs/notes warning on param validity * Update docs * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Update docs/spec/governance/02_state.md Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Minor doc update * Update x/gov/client/cli/tx.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Fix usage of fromAddr * Rige code style suggestion * Update x/params/types/proposal.go Co-Authored-By: alexanderbez <alexanderbez@users.noreply.github.com> * Fix CI lint errors * Update NewModuleClient godoc * Add godoc to rtr.Seal() call * Rename files * Rename NewProposalHandler
2019-04-30 09:31:38 -07:00
// SetRawWithSubkey stores raw parameter bytes with a key and subkey. It checks
// the parameter type only over the key.
func (s Subspace) SetRawWithSubkey(ctx sdk.Context, key []byte, subkey []byte, param []byte) error {
concatkey := concatKeys(key, subkey)
attr, ok := s.table.m[string(concatkey)]
if !ok {
return errors.New("parameter not registered")
}
ty := attr.ty
dest := reflect.New(ty).Interface()
err := s.cdc.UnmarshalJSON(param, &dest)
if err != nil {
return err
}
store := s.kvStore(ctx)
store.Set(concatkey, param)
tStore := s.transientStore(ctx)
tStore.Set(concatkey, []byte{})
return nil
}
// Get to ParamSet
func (s Subspace) GetParamSet(ctx sdk.Context, ps ParamSet) {
2019-02-04 18:13:04 -08:00
for _, pair := range ps.ParamSetPairs() {
s.Get(ctx, pair.Key, pair.Value)
2018-09-18 09:27:54 -07:00
}
}
// Set from ParamSet
func (s Subspace) SetParamSet(ctx sdk.Context, ps ParamSet) {
2019-02-04 18:13:04 -08:00
for _, pair := range ps.ParamSetPairs() {
2018-09-18 10:16:51 -07:00
// pair.Field is a pointer to the field, so indirecting the ptr.
// 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
2018-10-06 08:32:41 -07:00
v := reflect.Indirect(reflect.ValueOf(pair.Value)).Interface()
s.Set(ctx, pair.Key, v)
2018-09-17 08:28:13 -07:00
}
}
// Returns name of Subspace
func (s Subspace) Name() string {
return string(s.name)
}
// Wrapper of Subspace, provides immutable functions only
type ReadOnlySubspace struct {
s Subspace
}
// Exposes Get
func (ros ReadOnlySubspace) Get(ctx sdk.Context, key []byte, ptr interface{}) {
ros.s.Get(ctx, key, ptr)
}
// Exposes GetRaw
func (ros ReadOnlySubspace) GetRaw(ctx sdk.Context, key []byte) []byte {
return ros.s.GetRaw(ctx, key)
}
// Exposes Has
func (ros ReadOnlySubspace) Has(ctx sdk.Context, key []byte) bool {
return ros.s.Has(ctx, key)
}
// Exposes Modified
func (ros ReadOnlySubspace) Modified(ctx sdk.Context, key []byte) bool {
return ros.s.Modified(ctx, key)
}
2018-09-18 10:16:51 -07:00
// Exposes Space
func (ros ReadOnlySubspace) Name() string {
return ros.s.Name()
2018-09-18 10:16:51 -07:00
}