diff --git a/command/genesis/genesis.go b/command/genesis/genesis.go index c4a06577ba..d5c8f47b89 100644 --- a/command/genesis/genesis.go +++ b/command/genesis/genesis.go @@ -281,6 +281,13 @@ func setFlags(cmd *cobra.Command) { "address of a governance admin (governance admin can add new or remove old proposers "+ "of governance proposals, and add new and remove old executors of accepted proposals)", ) + + cmd.Flags().Uint64Var( + ¶ms.proposalQuorum, + proposalQuorumFlag, + defaultProposalQuorumPercentage, + "percentage of total validator stake needed for a governance proposal to be accepted (from 0 to 100%)", + ) } // Access Control Lists diff --git a/command/genesis/params.go b/command/genesis/params.go index f1757fab47..4435f34e58 100644 --- a/command/genesis/params.go +++ b/command/genesis/params.go @@ -45,6 +45,7 @@ const ( votePeriodFlag = "vote-period" voteProposalThresholdFlag = "vote-proposal-threshold" governorAdminFlag = "governor-admin" + proposalQuorumFlag = "proposal-quorum" defaultNativeTokenName = "Polygon" defaultNativeTokenSymbol = "MATIC" @@ -146,6 +147,7 @@ type genesisParams struct { voteDelay string votingPeriod string proposalThreshold string + proposalQuorum uint64 governorAdmin string } diff --git a/command/genesis/polybft_params.go b/command/genesis/polybft_params.go index 929de2e852..cdcda8d31b 100644 --- a/command/genesis/polybft_params.go +++ b/command/genesis/polybft_params.go @@ -37,17 +37,18 @@ const ( blockTimeDriftFlag = "block-time-drift" - defaultEpochSize = uint64(10) - defaultSprintSize = uint64(5) - defaultValidatorSetSize = 100 - defaultBlockTime = 2 * time.Second - defaultEpochReward = 1 - defaultBlockTimeDrift = uint64(10) - defaultCheckpointInterval = uint64(900) - defaultWithdrawalWaitPeriod = uint64(1) - defaultVotingDelay = "10" - defaultVotingPeriod = "20" - defaultVoteProposalThreshold = "1000" + defaultEpochSize = uint64(10) + defaultSprintSize = uint64(5) + defaultValidatorSetSize = 100 + defaultBlockTime = 2 * time.Second + defaultEpochReward = 1 + defaultBlockTimeDrift = uint64(10) + defaultCheckpointInterval = uint64(900) + defaultWithdrawalWaitPeriod = uint64(1) + defaultVotingDelay = "10" + defaultVotingPeriod = "20" + defaultVoteProposalThreshold = "1000" + defaultProposalQuorumPercentage = uint64(67) contractDeployerAllowListAdminFlag = "contract-deployer-allow-list-admin" contractDeployerAllowListEnabledFlag = "contract-deployer-allow-list-enabled" @@ -163,6 +164,12 @@ func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) er governorAdminAddr = types.StringToAddress(p.governorAdmin) } + proposalQuorum := p.proposalQuorum + if proposalQuorum > 100 { + // proposal can be from 0 to 100, so we sanitize the value + proposalQuorum = 100 + } + polyBftConfig := &polybft.PolyBFTConfig{ InitialValidatorSet: initialValidators, BlockTime: common.Duration{Duration: p.blockTime}, @@ -184,10 +191,11 @@ func (p *genesisParams) generatePolyBftChainConfig(o command.OutputFormatter) er }, BlockTimeDrift: p.blockTimeDrift, GovernanceConfig: &polybft.GovernanceConfig{ - VotingDelay: voteDelay, - VotingPeriod: votingPeriod, - ProposalThreshold: proposalThreshold, - GovernorAdmin: governorAdminAddr, + VotingDelay: voteDelay, + VotingPeriod: votingPeriod, + ProposalThreshold: proposalThreshold, + ProposalQuorumPercentage: proposalQuorum, + GovernorAdmin: governorAdminAddr, }, } diff --git a/consensus/polybft/polybft_config.go b/consensus/polybft/polybft_config.go index 69fb6b7d8b..ead9666fe8 100644 --- a/consensus/polybft/polybft_config.go +++ b/consensus/polybft/polybft_config.go @@ -248,14 +248,18 @@ type GovernanceConfig struct { // GovernorAdmin is the address of governance contract admin // (he is the only one able to add new and remove old executors and proposers) GovernorAdmin types.Address + // ProposalQuorumPercentage is the percentage of total validator stake needed for a + // governance proposal to be accepted + ProposalQuorumPercentage uint64 } func (g *GovernanceConfig) MarshalJSON() ([]byte, error) { raw := &governanceConfigRaw{ - VotingDelay: types.EncodeBigInt(g.VotingDelay), - VotingPeriod: types.EncodeBigInt(g.VotingPeriod), - ProposalThreshold: types.EncodeBigInt(g.ProposalThreshold), - GovernorAdmin: g.GovernorAdmin, + VotingDelay: types.EncodeBigInt(g.VotingDelay), + VotingPeriod: types.EncodeBigInt(g.VotingPeriod), + ProposalThreshold: types.EncodeBigInt(g.ProposalThreshold), + GovernorAdmin: g.GovernorAdmin, + ProposalQuorumPercentage: g.ProposalQuorumPercentage, } return json.Marshal(raw) @@ -287,13 +291,15 @@ func (g *GovernanceConfig) UnmarshalJSON(data []byte) error { } g.GovernorAdmin = raw.GovernorAdmin + g.ProposalQuorumPercentage = raw.ProposalQuorumPercentage return nil } type governanceConfigRaw struct { - VotingDelay *string `json:"votingDelay"` - VotingPeriod *string `json:"votingPeriod"` - ProposalThreshold *string `json:"proposalThreshold"` - GovernorAdmin types.Address `json:"governorAdmin"` + VotingDelay *string `json:"votingDelay"` + VotingPeriod *string `json:"votingPeriod"` + ProposalThreshold *string `json:"proposalThreshold"` + GovernorAdmin types.Address `json:"governorAdmin"` + ProposalQuorumPercentage uint64 `json:"proposalQuorumPercentage"` }