mukan-sdk/x/gov/keeper/keeper.go
Mukan Erkin Törük 20afb5db80
Some checks failed
Build SimApp / build (amd64) (push) Waiting to run
Build SimApp / build (arm64) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Build & Push / build (push) Waiting to run
Run Gosec / Gosec (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Checks dependencies and mocks generation / Check go mod tidy (push) Waiting to run
Checks dependencies and mocks generation / Check up to date mocks (push) Waiting to run
System Tests / setup (push) Waiting to run
System Tests / test-system (push) Blocked by required conditions
System Tests / test-system-legacy (push) Blocked by required conditions
Tests / Code Coverage / split-test-files (push) Waiting to run
Tests / Code Coverage / tests (00) (push) Blocked by required conditions
Tests / Code Coverage / tests (01) (push) Blocked by required conditions
Tests / Code Coverage / tests (02) (push) Blocked by required conditions
Tests / Code Coverage / tests (03) (push) Blocked by required conditions
Tests / Code Coverage / test-integration (push) Waiting to run
Tests / Code Coverage / test-e2e (push) Waiting to run
Tests / Code Coverage / repo-analysis (push) Blocked by required conditions
Tests / Code Coverage / test-sim-nondeterminism (push) Waiting to run
Tests / Code Coverage / test-clientv2 (push) Waiting to run
Tests / Code Coverage / test-core (push) Waiting to run
Tests / Code Coverage / test-depinject (push) Waiting to run
Tests / Code Coverage / test-errors (push) Waiting to run
Tests / Code Coverage / test-math (push) Waiting to run
Tests / Code Coverage / test-schema (push) Waiting to run
Tests / Code Coverage / test-collections (push) Waiting to run
Tests / Code Coverage / test-cosmovisor (push) Waiting to run
Tests / Code Coverage / test-confix (push) Waiting to run
Tests / Code Coverage / test-store (push) Waiting to run
Tests / Code Coverage / test-log (push) Waiting to run
Tests / Code Coverage / test-x-tx (push) Waiting to run
Tests / Code Coverage / test-x-nft (push) Waiting to run
Tests / Code Coverage / test-x-circuit (push) Waiting to run
Tests / Code Coverage / test-x-feegrant (push) Waiting to run
Tests / Code Coverage / test-x-evidence (push) Waiting to run
Tests / Code Coverage / test-x-upgrade (push) Waiting to run
Tests / Code Coverage / test-tools-benchmark (push) Waiting to run
Build & Push SDK Proto Builder / build (push) Has been cancelled
initial: sovereign Mukan Network fork
2026-05-11 03:18:24 +03:00

216 lines
8.8 KiB
Go

package keeper
import (
"context"
"fmt"
"time"
"cosmossdk.io/collections"
corestoretypes "cosmossdk.io/core/store"
"cosmossdk.io/log"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
// Keeper defines the governance module Keeper
type Keeper struct {
authKeeper types.AccountKeeper
bankKeeper types.BankKeeper
distrKeeper types.DistributionKeeper
// The reference to the DelegationSet and ValidatorSet to get information about validators and delegators
sk types.StakingKeeper
// GovHooks
hooks types.GovHooks
// The (unexposed) keys used to access the stores from the Context.
storeService corestoretypes.KVStoreService
// The codec for binary encoding/decoding.
cdc codec.Codec
// Legacy Proposal router
legacyRouter v1beta1.Router
// Msg server router
router baseapp.MessageRouter
config types.Config
calculateVoteResultsAndVotingPowerFn CalculateVoteResultsAndVotingPowerFn
// the address capable of executing a MsgUpdateParams message. Typically, this
// should be the x/gov module account.
authority string
Schema collections.Schema
Constitution collections.Item[string]
Params collections.Item[v1.Params]
Deposits collections.Map[collections.Pair[uint64, sdk.AccAddress], v1.Deposit]
Votes collections.Map[collections.Pair[uint64, sdk.AccAddress], v1.Vote]
ProposalID collections.Sequence
Proposals collections.Map[uint64, v1.Proposal]
ActiveProposalsQueue collections.Map[collections.Pair[time.Time, uint64], uint64] // TODO(tip): this should be simplified and go into an index.
InactiveProposalsQueue collections.Map[collections.Pair[time.Time, uint64], uint64] // TODO(tip): this should be simplified and go into an index.
VotingPeriodProposals collections.Map[uint64, []byte] // TODO(tip): this could be a keyset or index.
}
type InitOption func(*Keeper)
// WithCustomCalculateVoteResultsAndVotingPowerFn is an optional input to set a custom CalculateVoteResultsAndVotingPowerFn.
// If this function is not provided, the default function is used.
func WithCustomCalculateVoteResultsAndVotingPowerFn(calculateVoteResultsAndVotingPowerFn CalculateVoteResultsAndVotingPowerFn) InitOption {
return func(k *Keeper) {
if calculateVoteResultsAndVotingPowerFn == nil {
panic("calculateVoteResultsAndVotingPowerFn cannot be nil")
}
k.calculateVoteResultsAndVotingPowerFn = calculateVoteResultsAndVotingPowerFn
}
}
// GetAuthority returns the x/gov module's authority.
func (k Keeper) GetAuthority() string {
return k.authority
}
// NewKeeper returns a governance keeper. It handles:
// - submitting governance proposals
// - depositing funds into proposals, and activating upon sufficient funds being deposited
// - users voting on proposals, with weight proportional to stake in the system
// - and tallying the result of the vote.
//
// CONTRACT: the parameter Subspace must have the param key table already initialized
func NewKeeper(
cdc codec.Codec, storeService corestoretypes.KVStoreService, authKeeper types.AccountKeeper,
bankKeeper types.BankKeeper, sk types.StakingKeeper, distrKeeper types.DistributionKeeper,
router baseapp.MessageRouter, config types.Config, authority string, initOptions ...InitOption,
) *Keeper {
// ensure governance module account is set
if addr := authKeeper.GetModuleAddress(types.ModuleName); addr == nil {
panic(fmt.Sprintf("%s module account has not been set", types.ModuleName))
}
if _, err := authKeeper.AddressCodec().StringToBytes(authority); err != nil {
panic(fmt.Sprintf("invalid authority address: %s", authority))
}
// If MaxMetadataLen not set by app developer, set to default value.
if config.MaxMetadataLen == 0 {
config.MaxMetadataLen = types.DefaultConfig().MaxMetadataLen
}
sb := collections.NewSchemaBuilder(storeService)
k := &Keeper{
storeService: storeService,
authKeeper: authKeeper,
bankKeeper: bankKeeper,
distrKeeper: distrKeeper,
sk: sk,
cdc: cdc,
router: router,
config: config,
calculateVoteResultsAndVotingPowerFn: defaultCalculateVoteResultsAndVotingPower,
authority: authority,
Constitution: collections.NewItem(sb, types.ConstitutionKey, "constitution", collections.StringValue),
Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[v1.Params](cdc)),
Deposits: collections.NewMap(sb, types.DepositsKeyPrefix, "deposits", collections.PairKeyCodec(collections.Uint64Key, sdk.LengthPrefixedAddressKey(sdk.AccAddressKey)), codec.CollValue[v1.Deposit](cdc)), // nolint:staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility
Votes: collections.NewMap(sb, types.VotesKeyPrefix, "votes", collections.PairKeyCodec(collections.Uint64Key, sdk.LengthPrefixedAddressKey(sdk.AccAddressKey)), codec.CollValue[v1.Vote](cdc)), // nolint:staticcheck // sdk.LengthPrefixedAddressKey is needed to retain state compatibility
ProposalID: collections.NewSequence(sb, types.ProposalIDKey, "proposal_id"),
Proposals: collections.NewMap(sb, types.ProposalsKeyPrefix, "proposals", collections.Uint64Key, codec.CollValue[v1.Proposal](cdc)),
ActiveProposalsQueue: collections.NewMap(sb, types.ActiveProposalQueuePrefix, "active_proposals_queue", collections.PairKeyCodec(sdk.TimeKey, collections.Uint64Key), collections.Uint64Value), // nolint:staticcheck // sdk.TimeKey is needed to retain state compatibility
InactiveProposalsQueue: collections.NewMap(sb, types.InactiveProposalQueuePrefix, "inactive_proposals_queue", collections.PairKeyCodec(sdk.TimeKey, collections.Uint64Key), collections.Uint64Value), // nolint:staticcheck // sdk.TimeKey is needed to retain state compatibility
VotingPeriodProposals: collections.NewMap(sb, types.VotingPeriodProposalKeyPrefix, "voting_period_proposals", collections.Uint64Key, collections.BytesValue),
}
for _, opt := range initOptions {
opt(k)
}
schema, err := sb.Build()
if err != nil {
panic(err)
}
k.Schema = schema
return k
}
// Hooks gets the hooks for governance *Keeper {
func (k *Keeper) Hooks() types.GovHooks {
if k.hooks == nil {
// return a no-op implementation if no hooks are set
return types.MultiGovHooks{}
}
return k.hooks
}
// SetHooks sets the hooks for governance
func (k *Keeper) SetHooks(gh types.GovHooks) *Keeper {
if k.hooks != nil {
panic("cannot set governance hooks twice")
}
k.hooks = gh
return k
}
// SetLegacyRouter sets the legacy router for governance
func (k *Keeper) SetLegacyRouter(router v1beta1.Router) {
// It is vital to seal the governance proposal router here as to not allow
// further handlers to be registered after the keeper is created since this
// could create invalid or non-deterministic behavior.
router.Seal()
k.legacyRouter = router
}
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx context.Context) log.Logger {
sdkCtx := sdk.UnwrapSDKContext(ctx)
return sdkCtx.Logger().With("module", "x/"+types.ModuleName)
}
// Router returns the gov keeper's router
func (k Keeper) Router() baseapp.MessageRouter {
return k.router
}
// LegacyRouter returns the gov keeper's legacy router
func (k Keeper) LegacyRouter() v1beta1.Router {
return k.legacyRouter
}
// GetGovernanceAccount returns the governance ModuleAccount
func (k Keeper) GetGovernanceAccount(ctx context.Context) sdk.ModuleAccountI {
return k.authKeeper.GetModuleAccount(ctx, types.ModuleName)
}
// ModuleAccountAddress returns gov module account address
func (k Keeper) ModuleAccountAddress() sdk.AccAddress {
return k.authKeeper.GetModuleAddress(types.ModuleName)
}
// assertMetadataLength returns an error if given metadata length
// is greater than a pre-defined MaxMetadataLen.
func (k Keeper) assertMetadataLength(metadata string) error {
if metadata != "" && uint64(len(metadata)) > k.config.MaxMetadataLen {
return types.ErrMetadataTooLong.Wrapf("got metadata with length %d", len(metadata))
}
return nil
}
// assertSummaryLength returns an error if given summary length
// is greater than a pre-defined 40*MaxMetadataLen.
func (k Keeper) assertSummaryLength(summary string) error {
if summary != "" && uint64(len(summary)) > 40*k.config.MaxMetadataLen {
return types.ErrSummaryTooLong.Wrapf("got summary with length %d", len(summary))
}
return nil
}