mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +00:00
improve permission types
This commit is contained in:
parent
c50f6bc9fa
commit
77553ed299
@ -38,6 +38,7 @@ var (
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
GetKeyFromID = types.GetKeyFromID
|
||||
GetVoteKey = types.GetVoteKey
|
||||
NewCommittee = types.NewCommittee
|
||||
NewCommitteeChangeProposal = types.NewCommitteeChangeProposal
|
||||
NewCommitteeDeleteProposal = types.NewCommitteeDeleteProposal
|
||||
NewGenesisState = types.NewGenesisState
|
||||
@ -46,7 +47,9 @@ var (
|
||||
NewQueryCommitteeParams = types.NewQueryCommitteeParams
|
||||
NewQueryProposalParams = types.NewQueryProposalParams
|
||||
NewQueryVoteParams = types.NewQueryVoteParams
|
||||
RegisterCodec = types.RegisterCodec
|
||||
RegisterAppCodec = types.RegisterAppCodec
|
||||
RegisterModuleCodec = types.RegisterModuleCodec
|
||||
RegisterProposalTypeCodec = types.RegisterProposalTypeCodec
|
||||
Uint64FromBytes = types.Uint64FromBytes
|
||||
|
||||
// variable aliases
|
||||
@ -61,22 +64,23 @@ var (
|
||||
)
|
||||
|
||||
type (
|
||||
Keeper = keeper.Keeper
|
||||
Committee = types.Committee
|
||||
CommitteeChangeProposal = types.CommitteeChangeProposal
|
||||
CommitteeDeleteProposal = types.CommitteeDeleteProposal
|
||||
GeneralShutdownPermission = types.GeneralShutdownPermission
|
||||
GenesisState = types.GenesisState
|
||||
GodPermission = types.GodPermission
|
||||
InflationRateChangePermission = types.InflationRateChangePermission
|
||||
MsgSubmitProposal = types.MsgSubmitProposal
|
||||
MsgVote = types.MsgVote
|
||||
Permission = types.Permission
|
||||
Proposal = types.Proposal
|
||||
PubProposal = types.PubProposal
|
||||
QueryCommitteeParams = types.QueryCommitteeParams
|
||||
QueryProposalParams = types.QueryProposalParams
|
||||
QueryVoteParams = types.QueryVoteParams
|
||||
ShutdownCDPDepsitPermission = types.ShutdownCDPDepsitPermission
|
||||
Vote = types.Vote
|
||||
Keeper = keeper.Keeper
|
||||
AllowedParam = types.AllowedParam
|
||||
AllowedParams = types.AllowedParams
|
||||
Committee = types.Committee
|
||||
CommitteeChangeProposal = types.CommitteeChangeProposal
|
||||
CommitteeDeleteProposal = types.CommitteeDeleteProposal
|
||||
GenesisState = types.GenesisState
|
||||
GodPermission = types.GodPermission
|
||||
MsgSubmitProposal = types.MsgSubmitProposal
|
||||
MsgVote = types.MsgVote
|
||||
ParamChangePermission = types.ParamChangePermission
|
||||
Permission = types.Permission
|
||||
Proposal = types.Proposal
|
||||
PubProposal = types.PubProposal
|
||||
QueryCommitteeParams = types.QueryCommitteeParams
|
||||
QueryProposalParams = types.QueryProposalParams
|
||||
QueryVoteParams = types.QueryVoteParams
|
||||
ShutdownPermission = types.ShutdownPermission
|
||||
Vote = types.Vote
|
||||
)
|
||||
|
@ -32,7 +32,7 @@ func (AppModuleBasic) Name() string {
|
||||
|
||||
// RegisterCodec register module codec
|
||||
func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
|
||||
RegisterCodec(cdc)
|
||||
RegisterAppCodec(cdc)
|
||||
}
|
||||
|
||||
// DefaultGenesis default genesis state
|
||||
|
@ -12,32 +12,47 @@ var ModuleCdc *codec.Codec
|
||||
|
||||
func init() {
|
||||
cdc := codec.New()
|
||||
RegisterModuleCodec(cdc)
|
||||
ModuleCdc = cdc.Seal()
|
||||
}
|
||||
|
||||
// TODO decide if not using gov's Content type would be better
|
||||
|
||||
func RegisterModuleCodec(cdc *codec.Codec) {
|
||||
cdc.RegisterInterface((*gov.Content)(nil), nil) // registering the Content interface on the ModuleCdc will not conflict with gov.
|
||||
// TODO ideally dist and params would register their proposals on here at their init. However can't change them so:
|
||||
// Ideally dist and params would register their proposals on here at their init. However can't change them so:
|
||||
cdc.RegisterConcrete(distribution.CommunityPoolSpendProposal{}, "cosmos-sdk/CommunityPoolSpendProposal", nil)
|
||||
cdc.RegisterConcrete(params.ParameterChangeProposal{}, "cosmos-sdk/ParameterChangeProposal", nil)
|
||||
cdc.RegisterConcrete(gov.TextProposal{}, "cosmos-sdk/TextProposal", nil)
|
||||
cdc.RegisterConcrete(gov.SoftwareUpgradeProposal{}, "cosmos-sdk/SoftwareUpgradeProposal", nil)
|
||||
|
||||
RegisterCodec(cdc)
|
||||
ModuleCdc = cdc.Seal()
|
||||
RegisterAppCodec(cdc)
|
||||
}
|
||||
|
||||
// RegisterCodec registers the necessary types for the module
|
||||
func RegisterCodec(cdc *codec.Codec) {
|
||||
|
||||
func RegisterAppCodec(cdc *codec.Codec) {
|
||||
// Proposals
|
||||
// The app codec needs the gov.Content type registered. This is done by the gov module.
|
||||
// Ideally it would registered here as well in case these modules are ever used separately.
|
||||
// However amino panics if you register the same interface a second time. So leaving it out for now.
|
||||
|
||||
//cdc.RegisterInterface((*gov.Content)(nil), nil)
|
||||
|
||||
// cdc.RegisterInterface((*gov.Content)(nil), nil)
|
||||
cdc.RegisterConcrete(CommitteeChangeProposal{}, "kava/CommitteeChangeProposal", nil)
|
||||
cdc.RegisterConcrete(CommitteeDeleteProposal{}, "kava/CommitteeDeleteProposal", nil)
|
||||
|
||||
// Permissions
|
||||
cdc.RegisterInterface((*Permission)(nil), nil)
|
||||
cdc.RegisterConcrete(GodPermission{}, "kava/GodPermission", nil)
|
||||
cdc.RegisterConcrete(ParamChangePermission{}, "kava/ParamChangePermission", nil)
|
||||
cdc.RegisterConcrete(ShutdownPermission{}, "kava/ShutdownPermission", nil)
|
||||
|
||||
// Msgs
|
||||
cdc.RegisterConcrete(MsgSubmitProposal{}, "kava/MsgSubmitProposal", nil)
|
||||
cdc.RegisterConcrete(MsgVote{}, "kava/MsgVote", nil)
|
||||
}
|
||||
|
||||
// RegisterProposalTypeCodec registers an external proposal content type defined
|
||||
// in another module for the internal ModuleCdc. This allows the MsgSubmitProposal
|
||||
// to be correctly Amino encoded and decoded.
|
||||
func RegisterProposalTypeCodec(o interface{}, name string) {
|
||||
ModuleCdc.RegisterConcrete(o, name, nil)
|
||||
}
|
||||
|
@ -25,15 +25,6 @@ func init() {
|
||||
// Gov proposals need to be registered on gov's ModuleCdc so MsgSubmitProposal can be encoded.
|
||||
govtypes.RegisterProposalType(ProposalTypeCommitteeChange)
|
||||
govtypes.RegisterProposalTypeCodec(CommitteeChangeProposal{}, "kava/CommitteeChangeProposal")
|
||||
// Since these proposals include Permissions that needs to be registered as well (including the interface and concrete types)
|
||||
govtypes.ModuleCdc.RegisterInterface((*Permission)(nil), nil)
|
||||
govtypes.RegisterProposalTypeCodec(GodPermission{}, "kava/GodPermission")
|
||||
// TODO register other permissions here
|
||||
|
||||
// TODO write these
|
||||
//RegisterProposalType(ProposalTypeCommitteeChange)
|
||||
//RegisterProposalTypeCodec(CommitteeChangeProposal{}, "kava/CommitteeChangeProposal")
|
||||
// How will we register distribution and params proposals on this codec?
|
||||
}
|
||||
|
||||
func NewCommitteeChangeProposal(title string, description string, newCommittee Committee) CommitteeChangeProposal {
|
||||
@ -83,12 +74,9 @@ type CommitteeDeleteProposal struct {
|
||||
var _ govtypes.Content = CommitteeDeleteProposal{}
|
||||
|
||||
func init() {
|
||||
// Gov proposals need to be registered on gov's ModuleCdc so MsgSubmitProposal can be encoded.
|
||||
govtypes.RegisterProposalType(ProposalTypeCommitteeDelete)
|
||||
govtypes.RegisterProposalTypeCodec(CommitteeDeleteProposal{}, "kava/CommitteeDeleteProposal")
|
||||
// TODO write these
|
||||
//RegisterProposalType(ProposalTypeCommitteeDelete)
|
||||
//RegisterProposalTypeCodec(CommitteeDeleteProposal{}, "kava/CommitteeDeleteProposal")
|
||||
// How will we register distribution and params proposals on this codec?
|
||||
}
|
||||
|
||||
func NewCommitteeDeleteProposal(title string, description string, committeeID uint64) CommitteeDeleteProposal {
|
||||
|
@ -6,64 +6,110 @@ import (
|
||||
sdtypes "github.com/kava-labs/kava/x/shutdown/types"
|
||||
)
|
||||
|
||||
// EXAMPLE PERMISSIONS ------------------------------
|
||||
func init() {
|
||||
// Gov proposals need to be registered on gov's ModuleCdc.
|
||||
// But since proposals contain Permissions, those types also need registering.
|
||||
gov.ModuleCdc.RegisterInterface((*Permission)(nil), nil)
|
||||
gov.RegisterProposalTypeCodec(GodPermission{}, "kava/GodPermission")
|
||||
gov.RegisterProposalTypeCodec(ParamChangePermission{}, "kava/ParamChangePermission")
|
||||
gov.RegisterProposalTypeCodec(ShutdownPermission{}, "kava/ShutdownPermission")
|
||||
}
|
||||
|
||||
// GodPermission allows any governance proposal. It is used mainly for testing.
|
||||
type GodPermission struct{}
|
||||
|
||||
var _ Permission = GodPermission{}
|
||||
|
||||
func (GodPermission) Allows(gov.Content) bool { return true }
|
||||
|
||||
// Allow only changes to inflation_rate
|
||||
type InflationRateChangePermission struct{}
|
||||
func (GodPermission) MarshalYAML() (interface{}, error) {
|
||||
valueToMarshal := struct {
|
||||
Type string `yaml:"type"`
|
||||
}{
|
||||
Type: "god_permission",
|
||||
}
|
||||
return valueToMarshal, nil
|
||||
}
|
||||
|
||||
var _ Permission = InflationRateChangePermission{}
|
||||
// ParamChangeProposal only allows changes to certain params
|
||||
type ParamChangePermission struct {
|
||||
AllowedParams AllowedParams `json:"allowed_params" yaml:"allowed_params"`
|
||||
}
|
||||
|
||||
func (InflationRateChangePermission) Allows(p gov.Content) bool {
|
||||
pcp, ok := p.(params.ParameterChangeProposal)
|
||||
var _ Permission = ParamChangePermission{}
|
||||
|
||||
func (perm ParamChangePermission) Allows(p gov.Content) bool {
|
||||
proposal, ok := p.(params.ParameterChangeProposal)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for _, pc := range pcp.Changes {
|
||||
if pc.Key == "inflation_rate" {
|
||||
for _, change := range proposal.Changes {
|
||||
if !perm.AllowedParams.Contains(change) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (perm ParamChangePermission) MarshalYAML() (interface{}, error) {
|
||||
valueToMarshal := struct {
|
||||
Type string `yaml:"type"`
|
||||
AllowedParams AllowedParams `yaml:"allowed_params`
|
||||
}{
|
||||
Type: "param_change_permission",
|
||||
AllowedParams: perm.AllowedParams,
|
||||
}
|
||||
return valueToMarshal, nil
|
||||
}
|
||||
|
||||
type AllowedParam struct {
|
||||
Subspace string `json:"subspace" yaml:"subspace"`
|
||||
Key string `json:"key" yaml:"key"`
|
||||
Subkey string `json:"subkey,omitempty" yaml:"subkey,omitempty"`
|
||||
}
|
||||
type AllowedParams []AllowedParam
|
||||
|
||||
func (allowed AllowedParams) Contains(paramChange params.ParamChange) bool {
|
||||
for _, p := range allowed {
|
||||
if paramChange.Subspace == p.Subspace && paramChange.Key == p.Key && paramChange.Subkey == p.Subkey {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Allow only shutdown of the CDP Deposit msg
|
||||
type ShutdownCDPDepsitPermission struct{}
|
||||
|
||||
var _ Permission = ShutdownCDPDepsitPermission{}
|
||||
|
||||
func (ShutdownCDPDepsitPermission) Allows(p gov.Content) bool {
|
||||
sdp, ok := p.(sdtypes.ShutdownProposal)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for _, r := range sdp.MsgRoutes {
|
||||
if r.Route == "cdp" && r.Msg == "MsgCDPDeposit" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Same as above but the route isn't static
|
||||
type GeneralShutdownPermission struct {
|
||||
// ShutdownPermission allows certain message types to be disabled
|
||||
type ShutdownPermission struct {
|
||||
MsgRoute sdtypes.MsgRoute `json:"msg_route" yaml:"msg_route"`
|
||||
}
|
||||
|
||||
var _ Permission = GeneralShutdownPermission{}
|
||||
var _ Permission = ShutdownPermission{}
|
||||
|
||||
func (perm GeneralShutdownPermission) Allows(p gov.Content) bool {
|
||||
sdp, ok := p.(sdtypes.ShutdownProposal)
|
||||
func (perm ShutdownPermission) Allows(p gov.Content) bool {
|
||||
proposal, ok := p.(sdtypes.ShutdownProposal)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for _, r := range sdp.MsgRoutes {
|
||||
for _, r := range proposal.MsgRoutes {
|
||||
if r == perm.MsgRoute {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (perm ShutdownPermission) MarshalYAML() (interface{}, error) {
|
||||
valueToMarshal := struct {
|
||||
Type string `yaml:"type"`
|
||||
MsgRoute sdtypes.MsgRoute `yaml:"msg_route"`
|
||||
}{
|
||||
Type: "shutdown_permission",
|
||||
MsgRoute: perm.MsgRoute,
|
||||
}
|
||||
return valueToMarshal, nil
|
||||
}
|
||||
|
||||
// TODO add more permissions?
|
||||
// - limit parameter changes to bew withing small ranges or fixed sets
|
||||
// - allow community spend proposals
|
||||
// - allow committee change proposals
|
||||
|
@ -19,9 +19,12 @@ var (
|
||||
|
||||
// A Committee is a collection of addresses that are allowed to vote and enact any governance proposal that passes their permissions.
|
||||
type Committee struct {
|
||||
ID uint64 `json:"id" yaml:"id"` // TODO or a name?
|
||||
ID uint64 `json:"id" yaml:"id"`
|
||||
//Description string `json:"description" yaml:"description"`
|
||||
Members []sdk.AccAddress `json:"members" yaml:"members"`
|
||||
Permissions []Permission `json:"permissions" yaml:"permissions"`
|
||||
// VoteThreshold sdk.Dec `json:"vote_threshold" yaml:"vote_threshold"`
|
||||
// MaxProposalDuration time.Duration `json:"max_proposal_duration" yaml:"max_proposal_duration"`
|
||||
}
|
||||
|
||||
func NewCommittee(id uint64, members []sdk.AccAddress, permissions []Permission) Committee {
|
||||
|
Loading…
Reference in New Issue
Block a user