github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/gov/genesis.go (about)

     1  package gov
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strconv"
     7  	"time"
     8  
     9  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    10  	"github.com/fibonacci-chain/fbc/x/gov/keeper"
    11  	"github.com/fibonacci-chain/fbc/x/gov/types"
    12  )
    13  
    14  // GenesisState - all staking state that must be provided at genesis
    15  type GenesisState struct {
    16  	StartingProposalID uint64            `json:"starting_proposal_id" yaml:"starting_proposal_id"`
    17  	Deposits           Deposits          `json:"deposits" yaml:"deposits"`
    18  	Votes              Votes             `json:"votes" yaml:"votes"`
    19  	Proposals          []Proposal        `json:"proposals" yaml:"proposals"`
    20  	WaitingProposals   map[string]uint64 `json:"waiting_proposals" yaml:"waiting_proposals"`
    21  	DepositParams      DepositParams     `json:"deposit_params" yaml:"deposit_params"`
    22  	VotingParams       VotingParams      `json:"voting_params" yaml:"voting_params"`
    23  	TallyParams        TallyParams       `json:"tally_params" yaml:"tally_params"`
    24  }
    25  
    26  // DefaultGenesisState get raw genesis raw message for testing
    27  func DefaultGenesisState() GenesisState {
    28  	var minDeposit = sdk.SysCoins{sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(100))}
    29  	return GenesisState{
    30  		StartingProposalID: 1,
    31  		Proposals:          []types.Proposal{},
    32  		DepositParams: DepositParams{
    33  			MinDeposit:       minDeposit,
    34  			MaxDepositPeriod: time.Hour * 24,
    35  		},
    36  		VotingParams: VotingParams{
    37  			VotingPeriod: time.Hour * 72,
    38  		},
    39  		TallyParams: TallyParams{
    40  			Quorum:          sdk.NewDecWithPrec(334, 3),
    41  			Threshold:       sdk.NewDecWithPrec(5, 1),
    42  			Veto:            sdk.NewDecWithPrec(334, 3),
    43  			YesInVotePeriod: sdk.NewDecWithPrec(667, 3),
    44  		},
    45  	}
    46  }
    47  
    48  // Checks whether 2 GenesisState structs are equivalent.
    49  func (data GenesisState) equal(data2 GenesisState) bool {
    50  	b1 := types.ModuleCdc.MustMarshalBinaryBare(data)
    51  	b2 := types.ModuleCdc.MustMarshalBinaryBare(data2)
    52  	return bytes.Equal(b1, b2)
    53  }
    54  
    55  // Returns if a GenesisState is empty or has data in it
    56  func (data GenesisState) isEmpty() bool {
    57  	emptyGenState := GenesisState{}
    58  	return data.equal(emptyGenState)
    59  }
    60  
    61  // ValidateGenesis checks if parameters are within valid ranges
    62  func ValidateGenesis(data GenesisState) error {
    63  	threshold := data.TallyParams.Threshold
    64  	if threshold.IsNegative() || threshold.GT(sdk.OneDec()) {
    65  		return fmt.Errorf("governance vote Threshold should be positive and less or equal to one, is %s",
    66  			threshold.String())
    67  	}
    68  
    69  	veto := data.TallyParams.Veto
    70  	if veto.IsNegative() || veto.GT(sdk.OneDec()) {
    71  		return fmt.Errorf("governance vote Veto threshold should be positive and less or equal to one, is %s",
    72  			veto.String())
    73  	}
    74  
    75  	quorum := data.TallyParams.Quorum
    76  	if quorum.IsNegative() || quorum.GT(sdk.OneDec()) {
    77  		return fmt.Errorf("governance vote Quorum should be positive and less or equal to one, is %s",
    78  			threshold.String())
    79  	}
    80  
    81  	yesInVotePeriod := data.TallyParams.YesInVotePeriod
    82  	if yesInVotePeriod.IsNegative() || yesInVotePeriod.GT(sdk.OneDec()) {
    83  		return fmt.Errorf("governance vote YesInVotePeriod should be positive and less or equal to one, is %s",
    84  			threshold.String())
    85  	}
    86  
    87  	if !data.DepositParams.MinDeposit.IsValid() {
    88  		return fmt.Errorf("governance deposit amount must be a valid sdk.Coins amount, is %s",
    89  			data.DepositParams.MinDeposit.String())
    90  	}
    91  
    92  	return nil
    93  }
    94  
    95  // InitGenesis - store genesis parameters
    96  func InitGenesis(ctx sdk.Context, k keeper.Keeper, supplyKeeper keeper.SupplyKeeper, data GenesisState) {
    97  	k.SetProposalID(ctx, data.StartingProposalID)
    98  	k.SetDepositParams(ctx, data.DepositParams)
    99  	k.SetVotingParams(ctx, data.VotingParams)
   100  	k.SetTallyParams(ctx, data.TallyParams)
   101  
   102  	// check if the deposits pool account exists
   103  	moduleAcc := k.GetGovernanceAccount(ctx)
   104  	if moduleAcc == nil {
   105  		panic(fmt.Sprintf("%s module account has not been set", types.ModuleName))
   106  	}
   107  
   108  	var totalDeposits sdk.SysCoins
   109  	for _, deposit := range data.Deposits {
   110  		k.SetDeposit(ctx, deposit)
   111  		totalDeposits = totalDeposits.Add(deposit.Amount...)
   112  	}
   113  
   114  	for _, vote := range data.Votes {
   115  		k.SetVote(ctx, vote.ProposalID, vote)
   116  	}
   117  
   118  	for _, proposal := range data.Proposals {
   119  		switch proposal.Status {
   120  		case StatusDepositPeriod:
   121  			k.InsertInactiveProposalQueue(ctx, proposal.ProposalID, proposal.DepositEndTime)
   122  		case StatusVotingPeriod:
   123  			k.InsertActiveProposalQueue(ctx, proposal.ProposalID, proposal.VotingEndTime)
   124  		}
   125  		k.SetProposal(ctx, proposal)
   126  	}
   127  
   128  	for proposalIDStr, height := range data.WaitingProposals {
   129  		proposalID, err := strconv.ParseUint(proposalIDStr, 10, 64)
   130  		if err != nil {
   131  			panic(err)
   132  		}
   133  		k.InsertWaitingProposalQueue(ctx, height, proposalID)
   134  	}
   135  
   136  	// add coins if not provided on genesis
   137  	if moduleAcc.GetCoins().IsZero() {
   138  		if err := moduleAcc.SetCoins(totalDeposits); err != nil {
   139  			panic(err)
   140  		}
   141  		supplyKeeper.SetModuleAccount(ctx, moduleAcc)
   142  	}
   143  }
   144  
   145  // ExportGenesis - output genesis parameters
   146  func ExportGenesis(ctx sdk.Context, k keeper.Keeper) GenesisState {
   147  	startingProposalID, err := k.GetProposalID(ctx)
   148  	if err != nil {
   149  		panic(err)
   150  	}
   151  	depositParams := k.GetDepositParams(ctx)
   152  	votingParams := k.GetVotingParams(ctx)
   153  	tallyParams := k.GetTallyParams(ctx)
   154  
   155  	proposals := k.GetProposalsFiltered(ctx, nil, nil, StatusNil, 0)
   156  
   157  	var proposalsDeposits Deposits
   158  	var proposalsVotes Votes
   159  	for _, proposal := range proposals {
   160  		deposits := k.GetDeposits(ctx, proposal.ProposalID)
   161  		proposalsDeposits = append(proposalsDeposits, deposits...)
   162  
   163  		votes := k.GetVotes(ctx, proposal.ProposalID)
   164  		proposalsVotes = append(proposalsVotes, votes...)
   165  	}
   166  
   167  	waitingProposals := make(map[string]uint64)
   168  	k.IterateAllWaitingProposals(ctx, func(proposal types.Proposal, proposalID, height uint64) (stop bool) {
   169  		waitingProposals[strconv.FormatUint(proposalID, 10)] = height
   170  		return false
   171  	})
   172  
   173  	return GenesisState{
   174  		StartingProposalID: startingProposalID,
   175  		Deposits:           proposalsDeposits,
   176  		Votes:              proposalsVotes,
   177  		Proposals:          proposals,
   178  		WaitingProposals:   waitingProposals,
   179  		DepositParams:      depositParams,
   180  		VotingParams:       votingParams,
   181  		TallyParams:        tallyParams,
   182  	}
   183  }