Skip to content

Commit

Permalink
add governance hooks (cosmos#2)
Browse files Browse the repository at this point in the history
* add governance hooks

* Update x/gov/types/hooks.go

* fixed

* Update x/gov/keeper/keeper.go

* remove VoteOption from hooks

* fix lint

* remove depositAmount and add depositorAddr

* fix lint

* fix cosmosvisor?

* sh -> gh

* Apply suggestions from code review

Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>

Co-authored-by: ahmedaly113 <ahmedaly113@outlook.com>
Co-authored-by: Dev Ojha <ValarDragon@users.noreply.github.com>
  • Loading branch information
3 people committed May 30, 2021
1 parent 842b060 commit 26b99b4
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 1 deletion.
Binary file added cosmovisor/cosmovisor
Binary file not shown.
9 changes: 8 additions & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,18 @@ func NewSimApp(
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper))
app.GovKeeper = govkeeper.NewKeeper(

govKeeper := govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter,
)

app.GovKeeper = *govKeeper.SetHooks(
govtypes.NewMultiGovHooks(
// register the governance hooks
),
)

// Create Transfer Keepers
app.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
Expand Down
6 changes: 6 additions & 0 deletions x/gov/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {
keeper.DeleteProposal(ctx, proposal.ProposalId)
keeper.DeleteDeposits(ctx, proposal.ProposalId)

// called when proposal become inactive
keeper.AfterProposalInactive(ctx, proposal.ProposalId)

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeInactiveProposal,
Expand Down Expand Up @@ -96,6 +99,9 @@ func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) {
"result", logMsg,
)

// when proposal become active
keeper.AfterProposalActive(ctx, proposal.ProposalId)

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeActiveProposal,
Expand Down
3 changes: 3 additions & 0 deletions x/gov/keeper/deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAdd
deposit = types.NewDeposit(proposalID, depositorAddr, depositAmount)
}

// called when deposit has been added to a proposal, however the proposal may not be active
keeper.AfterProposalDeposit(ctx, proposalID, depositorAddr)

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeProposalDeposit,
Expand Down
44 changes: 44 additions & 0 deletions x/gov/keeper/hooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/types"
)

// Implements GovHooks interface
var _ types.GovHooks = Keeper{}

// AfterProposalSubmission - call hook if registered
func (keeper Keeper) AfterProposalSubmission(ctx sdk.Context, proposalID uint64) {
if keeper.hooks != nil {
keeper.hooks.AfterProposalSubmission(ctx, proposalID)
}
}

// AfterProposalDeposit - call hook if registered
func (keeper Keeper) AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositAddr sdk.AccAddress) {
if keeper.hooks != nil {
keeper.hooks.AfterProposalDeposit(ctx, proposalID, depositAddr)
}
}

// AfterProposalVote - call hook if registered
func (keeper Keeper) AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) {
if keeper.hooks != nil {
keeper.hooks.AfterProposalVote(ctx, proposalID, voterAddr)
}
}

// AfterProposalInactive - call hook if registered
func (keeper Keeper) AfterProposalInactive(ctx sdk.Context, proposalID uint64) {
if keeper.hooks != nil {
keeper.hooks.AfterProposalInactive(ctx, proposalID)
}
}

// AfterProposalActive - call hook if registered
func (keeper Keeper) AfterProposalActive(ctx sdk.Context, proposalID uint64) {
if keeper.hooks != nil {
keeper.hooks.AfterProposalActive(ctx, proposalID)
}
}
14 changes: 14 additions & 0 deletions x/gov/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ type Keeper struct {
// The (unexposed) keys used to access the stores from the Context.
storeKey sdk.StoreKey

// GovHooks
hooks types.GovHooks

// The codec codec for binary encoding/decoding.
cdc codec.BinaryMarshaler

Expand Down Expand Up @@ -71,6 +74,17 @@ func (keeper Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+types.ModuleName)
}

// SetHooks sets the hooks for governance
func (keeper *Keeper) SetHooks(gh types.GovHooks) *Keeper {
if keeper.hooks != nil {
panic("cannot set governance hooks twice")
}

keeper.hooks = gh

return keeper
}

// Router returns the gov Keeper's Router
func (keeper Keeper) Router() types.Router {
return keeper.router
Expand Down
3 changes: 3 additions & 0 deletions x/gov/keeper/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ func (keeper Keeper) SubmitProposal(ctx sdk.Context, content types.Content) (typ
keeper.InsertInactiveProposalQueue(ctx, proposalID, proposal.DepositEndTime)
keeper.SetProposalID(ctx, proposalID+1)

// called right after a proposal is submitted
keeper.AfterProposalSubmission(ctx, proposalID)

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeSubmitProposal,
Expand Down
3 changes: 3 additions & 0 deletions x/gov/keeper/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ func (keeper Keeper) AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.A
vote := types.NewVote(proposalID, voterAddr, option)
keeper.SetVote(ctx, vote)

// called after a vote on a proposal
keeper.AfterProposalVote(ctx, proposalID, voterAddr)

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeProposalVote,
Expand Down
14 changes: 14 additions & 0 deletions x/gov/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,17 @@ type BankKeeper interface {
SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error
}

//_______________________________________________________________________________
// Event Hooks
// These can be utilized to communicate between a governance keeper and another
// keepers.

// GovHooks event hooks for governance proposal object (noalias)
type GovHooks interface {
AfterProposalSubmission(ctx sdk.Context, proposalID uint64) // Must be called when proposal is submitted
AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) // Must be called when deposit is made
AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) // Must be called when vote on a proposal
AfterProposalInactive(ctx sdk.Context, proposalID uint64) // Must be called when proposal become inactive
AfterProposalActive(ctx sdk.Context, proposalID uint64) // Must be called when proposal become active
}
42 changes: 42 additions & 0 deletions x/gov/types/hooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

var _ GovHooks = MultiGovHooks{}

// combine multiple governance hooks, all hook functions are run in array sequence
type MultiGovHooks []GovHooks

func NewMultiGovHooks(hooks ...GovHooks) MultiGovHooks {
return hooks
}

func (h MultiGovHooks) AfterProposalSubmission(ctx sdk.Context, proposalID uint64) {
for i := range h {
h[i].AfterProposalSubmission(ctx, proposalID)
}
}

func (h MultiGovHooks) AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) {
for i := range h {
h[i].AfterProposalDeposit(ctx, proposalID, depositorAddr)
}
}

func (h MultiGovHooks) AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) {
for i := range h {
h[i].AfterProposalVote(ctx, proposalID, voterAddr)
}
}
func (h MultiGovHooks) AfterProposalInactive(ctx sdk.Context, proposalID uint64) {
for i := range h {
h[i].AfterProposalInactive(ctx, proposalID)
}
}
func (h MultiGovHooks) AfterProposalActive(ctx sdk.Context, proposalID uint64) {
for i := range h {
h[i].AfterProposalActive(ctx, proposalID)
}
}

0 comments on commit 26b99b4

Please sign in to comment.