github.com/Finschia/finschia-sdk@v0.48.1/x/gov/keeper/keeper.go (about)

     1  package keeper
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/Finschia/ostracon/libs/log"
     8  
     9  	"github.com/Finschia/finschia-sdk/codec"
    10  	sdk "github.com/Finschia/finschia-sdk/types"
    11  	authtypes "github.com/Finschia/finschia-sdk/x/auth/types"
    12  	"github.com/Finschia/finschia-sdk/x/gov/types"
    13  )
    14  
    15  // Keeper defines the governance module Keeper
    16  type Keeper struct {
    17  	// The reference to the Paramstore to get and set gov specific params
    18  	paramSpace types.ParamSubspace
    19  
    20  	authKeeper types.AccountKeeper
    21  	bankKeeper types.BankKeeper
    22  
    23  	// The reference to the DelegationSet and ValidatorSet to get information about validators and delegators
    24  	sk types.StakingKeeper
    25  
    26  	// GovHooks
    27  	hooks types.GovHooks
    28  
    29  	// The (unexposed) keys used to access the stores from the Context.
    30  	storeKey sdk.StoreKey
    31  
    32  	// The codec codec for binary encoding/decoding.
    33  	cdc codec.BinaryCodec
    34  
    35  	// Proposal router
    36  	router types.Router
    37  }
    38  
    39  // NewKeeper returns a governance keeper. It handles:
    40  // - submitting governance proposals
    41  // - depositing funds into proposals, and activating upon sufficient funds being deposited
    42  // - users voting on proposals, with weight proportional to stake in the system
    43  // - and tallying the result of the vote.
    44  //
    45  // CONTRACT: the parameter Subspace must have the param key table already initialized
    46  func NewKeeper(
    47  	cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace types.ParamSubspace,
    48  	authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, sk types.StakingKeeper, rtr types.Router,
    49  ) Keeper {
    50  	// ensure governance module account is set
    51  	if addr := authKeeper.GetModuleAddress(types.ModuleName); addr.Empty() {
    52  		panic(fmt.Sprintf("%s module account has not been set", types.ModuleName))
    53  	}
    54  
    55  	// It is vital to seal the governance proposal router here as to not allow
    56  	// further handlers to be registered after the keeper is created since this
    57  	// could create invalid or non-deterministic behavior.
    58  	rtr.Seal()
    59  
    60  	return Keeper{
    61  		storeKey:   key,
    62  		paramSpace: paramSpace,
    63  		authKeeper: authKeeper,
    64  		bankKeeper: bankKeeper,
    65  		sk:         sk,
    66  		cdc:        cdc,
    67  		router:     rtr,
    68  	}
    69  }
    70  
    71  // SetHooks sets the hooks for governance
    72  func (keeper *Keeper) SetHooks(gh types.GovHooks) *Keeper {
    73  	if keeper.hooks != nil {
    74  		panic("cannot set governance hooks twice")
    75  	}
    76  
    77  	keeper.hooks = gh
    78  
    79  	return keeper
    80  }
    81  
    82  // Logger returns a module-specific logger.
    83  func (keeper Keeper) Logger(ctx sdk.Context) log.Logger {
    84  	return ctx.Logger().With("module", "x/"+types.ModuleName)
    85  }
    86  
    87  // Router returns the gov Keeper's Router
    88  func (keeper Keeper) Router() types.Router {
    89  	return keeper.router
    90  }
    91  
    92  // GetGovernanceAccount returns the governance ModuleAccount
    93  func (keeper Keeper) GetGovernanceAccount(ctx sdk.Context) authtypes.ModuleAccountI {
    94  	return keeper.authKeeper.GetModuleAccount(ctx, types.ModuleName)
    95  }
    96  
    97  // ProposalQueues
    98  
    99  // InsertActiveProposalQueue inserts a ProposalID into the active proposal queue at endTime
   100  func (keeper Keeper) InsertActiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) {
   101  	store := ctx.KVStore(keeper.storeKey)
   102  	bz := types.GetProposalIDBytes(proposalID)
   103  	store.Set(types.ActiveProposalQueueKey(proposalID, endTime), bz)
   104  }
   105  
   106  // RemoveFromActiveProposalQueue removes a proposalID from the Active Proposal Queue
   107  func (keeper Keeper) RemoveFromActiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) {
   108  	store := ctx.KVStore(keeper.storeKey)
   109  	store.Delete(types.ActiveProposalQueueKey(proposalID, endTime))
   110  }
   111  
   112  // InsertInactiveProposalQueue Inserts a ProposalID into the inactive proposal queue at endTime
   113  func (keeper Keeper) InsertInactiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) {
   114  	store := ctx.KVStore(keeper.storeKey)
   115  	bz := types.GetProposalIDBytes(proposalID)
   116  	store.Set(types.InactiveProposalQueueKey(proposalID, endTime), bz)
   117  }
   118  
   119  // RemoveFromInactiveProposalQueue removes a proposalID from the Inactive Proposal Queue
   120  func (keeper Keeper) RemoveFromInactiveProposalQueue(ctx sdk.Context, proposalID uint64, endTime time.Time) {
   121  	store := ctx.KVStore(keeper.storeKey)
   122  	store.Delete(types.InactiveProposalQueueKey(proposalID, endTime))
   123  }
   124  
   125  // Iterators
   126  
   127  // IterateActiveProposalsQueue iterates over the proposals in the active proposal queue
   128  // and performs a callback function
   129  func (keeper Keeper) IterateActiveProposalsQueue(ctx sdk.Context, endTime time.Time, cb func(proposal types.Proposal) (stop bool)) {
   130  	iterator := keeper.ActiveProposalQueueIterator(ctx, endTime)
   131  
   132  	defer iterator.Close()
   133  	for ; iterator.Valid(); iterator.Next() {
   134  		proposalID, _ := types.SplitActiveProposalQueueKey(iterator.Key())
   135  		proposal, found := keeper.GetProposal(ctx, proposalID)
   136  		if !found {
   137  			panic(fmt.Sprintf("proposal %d does not exist", proposalID))
   138  		}
   139  
   140  		if cb(proposal) {
   141  			break
   142  		}
   143  	}
   144  }
   145  
   146  // IterateInactiveProposalsQueue iterates over the proposals in the inactive proposal queue
   147  // and performs a callback function
   148  func (keeper Keeper) IterateInactiveProposalsQueue(ctx sdk.Context, endTime time.Time, cb func(proposal types.Proposal) (stop bool)) {
   149  	iterator := keeper.InactiveProposalQueueIterator(ctx, endTime)
   150  
   151  	defer iterator.Close()
   152  	for ; iterator.Valid(); iterator.Next() {
   153  		proposalID, _ := types.SplitInactiveProposalQueueKey(iterator.Key())
   154  		proposal, found := keeper.GetProposal(ctx, proposalID)
   155  		if !found {
   156  			panic(fmt.Sprintf("proposal %d does not exist", proposalID))
   157  		}
   158  
   159  		if cb(proposal) {
   160  			break
   161  		}
   162  	}
   163  }
   164  
   165  // ActiveProposalQueueIterator returns an sdk.Iterator for all the proposals in the Active Queue that expire by endTime
   166  func (keeper Keeper) ActiveProposalQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
   167  	store := ctx.KVStore(keeper.storeKey)
   168  	return store.Iterator(types.ActiveProposalQueuePrefix, sdk.PrefixEndBytes(types.ActiveProposalByTimeKey(endTime)))
   169  }
   170  
   171  // InactiveProposalQueueIterator returns an sdk.Iterator for all the proposals in the Inactive Queue that expire by endTime
   172  func (keeper Keeper) InactiveProposalQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
   173  	store := ctx.KVStore(keeper.storeKey)
   174  	return store.Iterator(types.InactiveProposalQueuePrefix, sdk.PrefixEndBytes(types.InactiveProposalByTimeKey(endTime)))
   175  }