mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-25 15:55:18 +00:00
rough draft
This commit is contained in:
parent
7eede47769
commit
4989c0938a
31
x/circuit-breaker/ante/ante.go
Normal file
31
x/circuit-breaker/ante/ante.go
Normal file
@ -0,0 +1,31 @@
|
||||
package circuit-breaker
|
||||
|
||||
// CircuiteBreakerDecorator needs to be combined with other standard decorators (from auth) to create the app's AnteHandler.
|
||||
|
||||
// CircuitBreakerDecorator errors if a tx contains a disallowed msg type
|
||||
// Call next AnteHandler if all msgs are allowed
|
||||
type CircuitBreakerDecorator struct {
|
||||
cbk Keeper
|
||||
}
|
||||
|
||||
func NewCircuitBreakerDecorator(cbk Keeper) CircuitBreakerDecorator {
|
||||
return CircuitBreakerDecorator{
|
||||
cbk: cbk,
|
||||
}
|
||||
}
|
||||
|
||||
func (cbd CircuitBreakerDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
|
||||
// TODO need to tidy up the types used to store broken routes
|
||||
|
||||
// get msg route, error if not allowed
|
||||
disallowedRoutes := cbd.cbk.GetRoutes(ctx)
|
||||
requestedRoutes := tx.Msgs
|
||||
for m, _ := range tx.Msgs {
|
||||
for r, _ := range disallowedRoutes {
|
||||
if r == m.Route() {
|
||||
return ctx, fmt.Errorf("route %s has been circuit broken, tx rejected", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
14
x/circuit-breaker/gov-handler.go
Normal file
14
x/circuit-breaker/gov-handler.go
Normal file
@ -0,0 +1,14 @@
|
||||
package circuit-breaker
|
||||
|
||||
func NewCircuitBreakerProposalHandler(k Keeper) govtypes.Handler {
|
||||
return func(ctx sdk.Context, content govtypes.Content) sdk.Error {
|
||||
switch c := content.(type) {
|
||||
case types.CircuitBreakerProposal:
|
||||
return keeper.HandleCircuitBreakerProposal(ctx, k, c)
|
||||
|
||||
default:
|
||||
errMsg := fmt.Sprintf("unrecognized circuit-breaker proposal content type: %T", c)
|
||||
return sdk.ErrUnknownRequest(errMsg)
|
||||
}
|
||||
}
|
||||
}
|
18
x/circuit-breaker/keeper/keeper.go
Normal file
18
x/circuit-breaker/keeper/keeper.go
Normal file
@ -0,0 +1,18 @@
|
||||
package circuit-breaker
|
||||
|
||||
// Keeper stores routes that have been "broken"
|
||||
type Keeper struct {
|
||||
}
|
||||
|
||||
|
||||
func (k Keeper) GetRoutes(ctx sdk.Context) []string {
|
||||
// TODO
|
||||
}
|
||||
|
||||
func (k Keeper) SetRoutes(ctx sdk.Context, routes []string) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
func (k Keeper) HandleCircuitBreakerProposal(ctx sdk.Context, c Content) {
|
||||
k.SetRoutes(ctx, c.Routes)
|
||||
}
|
10
x/circuit-breaker/spec/README.md
Normal file
10
x/circuit-breaker/spec/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
# `groupgov`
|
||||
|
||||
## Table of Contents
|
||||
|
||||
## Overview
|
||||
|
||||
The `x/groupgov` module is an additional governance module to `cosmos-sdk/x/gov`. It allows groups of accounts to vote on and enact proposals, mainly to allow certain proposal types to be decided on quickly in emergency situations, or to delegate low risk parameter updates to a smaller group of individuals.
|
||||
|
||||
Groups have permissions.
|
14
x/circuit-breaker/types/types.go
Normal file
14
x/circuit-breaker/types/types.go
Normal file
@ -0,0 +1,14 @@
|
||||
package types
|
||||
|
||||
// TODO implement a gov proposal for adding a route to the circuit breaker keeper.
|
||||
|
||||
type CircuitBreakProposal struct {
|
||||
MsgRoutes []MsgRoute
|
||||
}
|
||||
|
||||
type MsgRoute struct {
|
||||
Route string
|
||||
Msg sdk.Msg // how best to store a Msg type? as a string?
|
||||
}
|
||||
|
||||
// TODO gov.Proposal methods...
|
6
x/groupgov/abci.go
Normal file
6
x/groupgov/abci.go
Normal file
@ -0,0 +1,6 @@
|
||||
package groupgov
|
||||
|
||||
func BeginBlocker() {
|
||||
// TODO do much the same as the current gov endblocker does
|
||||
// if voting periods are over, collect votes and run proposals through proposal handlers
|
||||
}
|
56
x/groupgov/handler.go
Normal file
56
x/groupgov/handler.go
Normal file
@ -0,0 +1,56 @@
|
||||
package cdp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/kava-labs/kava/x/groupgov/types"
|
||||
)
|
||||
|
||||
// NewHandler creates an sdk.Handler for cdp messages
|
||||
func NewHandler(k Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
switch msg := msg.(type) {
|
||||
case types.MsgSubmitProposal:
|
||||
handleMsgSubmitProposal(ctx, k, msg)
|
||||
case types.MsgVote:
|
||||
handleMsgVote(ctx, k, msg)
|
||||
default:
|
||||
errMsg := fmt.Sprintf("unrecognized %s msg type: %T", , types.ModuleName, msg)
|
||||
return sdk.ErrUnknownRequest(errMsg).Result()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleMsgSubmitProposal(ctx sdk.Context, k Keeper, msg types.MsgSubmitProposal) sdk.Result {
|
||||
// TODO limit proposals to only be submitted by group members
|
||||
|
||||
// get group
|
||||
group, _ := k.GetGroup(ctx, msg.GroupID)
|
||||
// Check group has permissions to enact proposal. As long as one permission allows the proposal then it goes through. Its the OR of all permissions.
|
||||
var hasPermissions := false
|
||||
for p, _ := range group.Permissions {
|
||||
if p.Allows(msg.Proposal) {
|
||||
hasPermissions = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasPermissions {
|
||||
return sdk.ErrInternal("group does not have permissions to enact proposal").Result()
|
||||
}
|
||||
// TODO validate proposal by running it with cached context like how gov does it
|
||||
// TODO store the proposal, probably put it in a queue
|
||||
|
||||
}
|
||||
|
||||
func handleMsgVote(ctx sdk.Context, k Keeper, msg types.MsgVote) sdk.Result {
|
||||
/* TODO
|
||||
- validate vote
|
||||
- store vote
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO create a GroupChangeProposalHandler
|
10
x/groupgov/keeper/keeper.go
Normal file
10
x/groupgov/keeper/keeper.go
Normal file
@ -0,0 +1,10 @@
|
||||
package types
|
||||
|
||||
import "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
type Keeper struct {
|
||||
// TODO other stuff as needed
|
||||
|
||||
// Proposal router
|
||||
router types.Router
|
||||
}
|
8
x/groupgov/spec/README.md
Normal file
8
x/groupgov/spec/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
# `circuit-breaker`
|
||||
|
||||
## Table of Contents
|
||||
|
||||
## Overview
|
||||
|
||||
The `x/circuit-breaker` module allows certain message types to be disabled based on governance votes.
|
13
x/groupgov/types/msg.go
Normal file
13
x/groupgov/types/msg.go
Normal file
@ -0,0 +1,13 @@
|
||||
package types
|
||||
|
||||
// These msg types should be basically the same as for gov
|
||||
|
||||
// MsgSubmitProposal is used by group members to create a new proposal that they can vote on.
|
||||
type MsgSubmitProposal struct {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// MsgVote is submitted by group members to vote on proposals.
|
||||
type MsgVote struct {
|
||||
// TODO
|
||||
}
|
24
x/groupgov/types/permissions.go
Normal file
24
x/groupgov/types/permissions.go
Normal file
@ -0,0 +1,24 @@
|
||||
package types
|
||||
|
||||
// EXAMPLE PERMISSIONS ------------------------------
|
||||
type InflationRateChangePermission uint8
|
||||
|
||||
func (InflationRateChangePermission) Allows(p gov.Proposal) bool {
|
||||
pcp, _ := p.Content.(params.ParameterChangeProposal)
|
||||
for pc, _ := range pcp.Changes {
|
||||
if pc.Key == "inflation_rate" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type CircuitBreakCDPDepsitPermission uint8
|
||||
|
||||
func (CircuitBreakCDPDepsitPermission) Allows(p gov.Proposal) bool {
|
||||
cbp, _ := p.Content.(CircuitBreakProposal)
|
||||
if cbp.Route == "cdp" && cbp.Msg == "MsgCDPDeposit" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
46
x/groupgov/types/types.go
Normal file
46
x/groupgov/types/types.go
Normal file
@ -0,0 +1,46 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
)
|
||||
|
||||
// A Group is a collection of addresses that are allowed to vote and enact any governance proposal that passes their permissions.
|
||||
type Group struct {
|
||||
Members []sdk.AccAddress
|
||||
Permissions []Permission
|
||||
}
|
||||
|
||||
// handler for MsgSubmitProposal needs to loop apply all group permission Allows methods to the proposal and do a bit OR to see if it should be accepted
|
||||
|
||||
// Permission is anything with a method that validates whether a proposal is allowed by it or not.
|
||||
// Collectively, if one permission allows a proposal then the proposal is allowed through.
|
||||
type Permission interface {
|
||||
Allows(gov.Proposal) bool // maybe don't reuse gov's type here
|
||||
}
|
||||
|
||||
// A gov.Proposal to used to add/remove members from a group, or to add/remove permissions.
|
||||
// Normally registered with standard gov. But could also be registed with groupgov to allow groups to be controlled by other groups.
|
||||
type GroupChangeProposal struct {
|
||||
Members []sdk.AccAddress
|
||||
Permissions []Permission
|
||||
}
|
||||
|
||||
// STANDARD GOV STUFF --------------------------
|
||||
// Should be much the same as in gov module. Either import gov types directly or do some copy n pasting.
|
||||
|
||||
type Router struct {
|
||||
// TODO
|
||||
}
|
||||
|
||||
type Proposal struct {
|
||||
ID uint64
|
||||
groupID uint64
|
||||
// TODO
|
||||
}
|
||||
|
||||
type Vote struct {
|
||||
proposalID uint64
|
||||
option uint64
|
||||
// TODO
|
||||
}
|
Loading…
Reference in New Issue
Block a user