Skip to content

Commit

Permalink
wip: governance refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Fraccaman committed Aug 10, 2023
1 parent c7cafbc commit 901efd3
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 46 deletions.
6 changes: 3 additions & 3 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ pub mod genesis_config {
// Maximum size of proposal in kibibytes (KiB)
pub max_proposal_code_size: u64,
// Minimum proposal period length in epochs
pub min_proposal_period: u64,
pub min_proposal_voting_period: u64,
// Maximum proposal period length in epochs
pub max_proposal_period: u64,
// Maximum number of characters in the proposal content
Expand Down Expand Up @@ -622,15 +622,15 @@ pub mod genesis_config {
let GovernanceParamsConfig {
min_proposal_fund,
max_proposal_code_size,
min_proposal_period,
min_proposal_voting_period,
max_proposal_content_size,
min_proposal_grace_epochs,
max_proposal_period,
} = gov_params;
let gov_params = GovernanceParameters {
min_proposal_fund: token::Amount::native_whole(min_proposal_fund),
max_proposal_code_size,
min_proposal_period,
min_proposal_voting_period,
max_proposal_content_size,
min_proposal_grace_epochs,
max_proposal_period,
Expand Down
36 changes: 26 additions & 10 deletions core/src/ledger/governance/cli/onchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use serde::{Deserialize, Serialize};
use super::validation::{
is_valid_author_balance, is_valid_content, is_valid_default_proposal_data,
is_valid_end_epoch, is_valid_grace_epoch, is_valid_pgf_funding_data,
is_valid_pgf_stewards_data, is_valid_start_epoch, ProposalValidation,
is_valid_pgf_stewards_data, is_valid_proposal_period, is_valid_start_epoch,
ProposalValidation,
};
use crate::ledger::governance::parameters::GovernanceParameters;
use crate::ledger::storage_api::token;
Expand Down Expand Up @@ -54,21 +55,26 @@ impl DefaultProposal {
is_valid_start_epoch(
self.proposal.voting_start_epoch,
current_epoch,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_voting_period,
)?;
is_valid_end_epoch(
self.proposal.voting_start_epoch,
self.proposal.voting_end_epoch,
current_epoch,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_voting_period,
governance_parameters.min_proposal_voting_period,
governance_parameters.max_proposal_period,
)?;
is_valid_grace_epoch(
self.proposal.grace_epoch,
self.proposal.voting_end_epoch,
governance_parameters.min_proposal_grace_epochs,
)?;
is_valid_proposal_period(
self.proposal.voting_start_epoch,
self.proposal.grace_epoch,
governance_parameters.max_proposal_period,
)?;
is_valid_author_balance(
balance,
governance_parameters.min_proposal_fund,
Expand Down Expand Up @@ -116,21 +122,26 @@ impl PgfStewardProposal {
is_valid_start_epoch(
self.proposal.voting_start_epoch,
current_epoch,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_voting_period,
)?;
is_valid_end_epoch(
self.proposal.voting_start_epoch,
self.proposal.voting_end_epoch,
current_epoch,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_voting_period,
governance_parameters.min_proposal_voting_period,
governance_parameters.max_proposal_period,
)?;
is_valid_grace_epoch(
self.proposal.grace_epoch,
self.proposal.voting_end_epoch,
governance_parameters.min_proposal_grace_epochs,
)?;
is_valid_proposal_period(
self.proposal.voting_start_epoch,
self.proposal.grace_epoch,
governance_parameters.max_proposal_period,
)?;
is_valid_author_balance(
balance,
governance_parameters.min_proposal_fund,
Expand Down Expand Up @@ -174,21 +185,26 @@ impl PgfFundingProposal {
is_valid_start_epoch(
self.proposal.voting_start_epoch,
current_epoch,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_voting_period,
)?;
is_valid_end_epoch(
self.proposal.voting_start_epoch,
self.proposal.voting_end_epoch,
current_epoch,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_period,
governance_parameters.min_proposal_voting_period,
governance_parameters.min_proposal_voting_period,
governance_parameters.max_proposal_period,
)?;
is_valid_grace_epoch(
self.proposal.grace_epoch,
self.proposal.voting_end_epoch,
governance_parameters.min_proposal_grace_epochs,
)?;
is_valid_proposal_period(
self.proposal.voting_start_epoch,
self.proposal.grace_epoch,
governance_parameters.max_proposal_period,
)?;
is_valid_content(
&self.proposal.content,
governance_parameters.max_proposal_content_size,
Expand Down
31 changes: 27 additions & 4 deletions core/src/ledger/governance/cli/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ pub enum ProposalValidation {
end epoch must be at least {0}, but found {1}"
)]
InvalidEndGraceDifference(u64, u64),
/// The proposal difference between end and grace epoch is invalid
#[error(
"Invalid proposal period: difference between proposal start and grace \
epoch must be at most {1}, but found {0}"
)]
InvalidProposalPeriod(u64, u64),
/// The proposal author does not have enought balance to pay for proposal
/// fees
#[error(
Expand Down Expand Up @@ -103,21 +109,21 @@ pub fn is_valid_end_epoch(
proposal_end_epoch: Epoch,
_current_epoch: Epoch,
proposal_epoch_multiplier: u64,
min_proposal_period: u64,
min_proposal_voting_period: u64,
max_proposal_period: u64,
) -> Result<(), ProposalValidation> {
let voting_period = proposal_end_epoch.0 - proposal_start_epoch.0;
let end_epoch_is_multipler =
proposal_end_epoch % proposal_epoch_multiplier == 0;
let is_valid_voting_period = voting_period > 0
&& voting_period >= min_proposal_period
&& min_proposal_period <= max_proposal_period;
&& voting_period >= min_proposal_voting_period
&& min_proposal_voting_period <= max_proposal_period;

if end_epoch_is_multipler && is_valid_voting_period {
Ok(())
} else {
Err(ProposalValidation::InvalidStartEndDifference(
min_proposal_period,
min_proposal_voting_period,
max_proposal_period,
))
}
Expand All @@ -140,6 +146,23 @@ pub fn is_valid_grace_epoch(
}
}

pub fn is_valid_proposal_period(
proposal_start_epoch: Epoch,
proposal_grace_epoch: Epoch,
max_proposal_period: u64,
) -> Result<(), ProposalValidation> {
let proposal_period = proposal_grace_epoch.0 - proposal_start_epoch.0;

if proposal_period > 0 && proposal_period <= max_proposal_period {
Ok(())
} else {
Err(ProposalValidation::InvalidProposalPeriod(
proposal_period,
max_proposal_period,
))
}
}

pub fn is_valid_content(
proposal_content: &BTreeMap<String, String>,
max_content_length: u64,
Expand Down
17 changes: 10 additions & 7 deletions core/src/ledger/governance/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct GovernanceParameters {
/// Maximum kibibyte length for proposal code
pub max_proposal_code_size: u64,
/// Minimum proposal voting period in epochs
pub min_proposal_period: u64,
pub min_proposal_voting_period: u64,
/// Maximum proposal voting period in epochs
pub max_proposal_period: u64,
/// Maximum number of characters for proposal content
Expand All @@ -42,7 +42,7 @@ impl Display for GovernanceParameters {
content size: {}\nMin. proposal grace epochs: {}",
self.min_proposal_fund.to_string_native(),
self.max_proposal_code_size,
self.min_proposal_period,
self.min_proposal_voting_period,
self.max_proposal_period,
self.max_proposal_content_size,
self.min_proposal_grace_epochs
Expand All @@ -55,7 +55,7 @@ impl Default for GovernanceParameters {
Self {
min_proposal_fund: token::Amount::native_whole(500),
max_proposal_code_size: 300_000,
min_proposal_period: 3,
min_proposal_voting_period: 3,
max_proposal_period: 27,
max_proposal_content_size: 10_000,
min_proposal_grace_epochs: 6,
Expand All @@ -72,7 +72,7 @@ impl GovernanceParameters {
let Self {
min_proposal_fund,
max_proposal_code_size,
min_proposal_period,
min_proposal_voting_period,
max_proposal_period,
max_proposal_content_size,
min_proposal_grace_epochs,
Expand All @@ -86,9 +86,12 @@ impl GovernanceParameters {
goverance_storage::get_max_proposal_code_size_key();
storage.write(&max_proposal_code_size_key, max_proposal_code_size)?;

let min_proposal_period_key =
goverance_storage::get_min_proposal_period_key();
storage.write(&min_proposal_period_key, min_proposal_period)?;
let min_proposal_voting_period_key =
goverance_storage::get_min_proposal_voting_period_key();
storage.write(
&min_proposal_voting_period_key,
min_proposal_voting_period,
)?;

let max_proposal_period_key =
goverance_storage::get_max_proposal_period_key();
Expand Down
10 changes: 5 additions & 5 deletions core/src/ledger/governance/storage/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,12 @@ pub fn is_max_proposal_code_size_key(key: &Key) -> bool {
}

/// Check if key is a min proposal period param key
pub fn is_min_proposal_period_key(key: &Key) -> bool {
pub fn is_min_proposal_voting_period_key(key: &Key) -> bool {
matches!(&key.segments[..], [
DbKeySeg::AddressSeg(addr),
DbKeySeg::StringSeg(min_proposal_period_param),
DbKeySeg::StringSeg(min_proposal_voting_period_param),
] if addr == &ADDRESS
&& min_proposal_period_param == Keys::VALUES.min_period)
&& min_proposal_voting_period_param == Keys::VALUES.min_period)
}

/// Check if key is a max proposal period param key
Expand Down Expand Up @@ -274,7 +274,7 @@ pub fn is_parameter_key(key: &Key) -> bool {
is_min_proposal_fund_key(key)
|| is_max_content_size_key(key)
|| is_max_proposal_code_size_key(key)
|| is_min_proposal_period_key(key)
|| is_min_proposal_voting_period_key(key)
|| is_max_proposal_period_key(key)
|| is_min_grace_epoch_key(key)
}
Expand Down Expand Up @@ -306,7 +306,7 @@ pub fn get_max_proposal_code_size_key() -> Key {
}

/// Get minimum proposal period key
pub fn get_min_proposal_period_key() -> Key {
pub fn get_min_proposal_voting_period_key() -> Key {
Key::from(ADDRESS.to_db_key())
.push(&Keys::VALUES.min_period.to_owned())
.expect("Cannot obtain a storage key")
Expand Down
10 changes: 5 additions & 5 deletions documentation/dev/src/explore/design/ledger/governance.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Also, it introduces some protocol parameters:

- `min_proposal_fund`
- `max_proposal_code_size`
- `min_proposal_period`
- `min_proposal_voting_period`
- `max_proposal_period`
- `max_proposal_content_size`
- `min_proposal_grace_epochs`
Expand All @@ -26,7 +26,7 @@ On-chain proposals are created under the `governance_address` storage space and,
/$GovernanceAddress/counter: u64
/$GovernanceAddress/min_proposal_fund: u64
/$GovernanceAddress/max_proposal_code_size: u64
/$GovernanceAddress/min_proposal_period: u64
/$GovernanceAddress/min_proposal_voting_period: u64
/$GovernanceAddress/max_proposal_period: u64
/$GovernanceAddress/max_proposal_content_size: u64
/$GovernanceAddress/min_proposal_grace_epochs: u64
Expand All @@ -50,11 +50,11 @@ and follow these rules:
- `$id` must be equal to `counter + 1`.
- `startEpoch` must:
- be greater than `currentEpoch`, where current epoch is the epoch in which the transaction is executed and included in a block
- be a multiple of `min_proposal_period`.
- be a multiple of `min_proposal_voting_period`.
- `endEpoch` must:
- be at least `min_proposal_period` epochs greater than `startEpoch`
- be at least `min_proposal_voting_period` epochs greater than `startEpoch`
- be at most `max_proposal_period` epochs greater than `startEpoch`
- be a multiple of `min_proposal_period`
- be a multiple of `min_proposal_voting_period`
- `graceEpoch` must:
- be at least `min_grace_epoch` epochs greater than `endEpoch`
- `proposalCode` can be empty and must be a valid transaction with size less than `max_proposal_code_size` kibibytes.
Expand Down
4 changes: 2 additions & 2 deletions genesis/dev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ validator_stake_threshold = "1"
min_proposal_fund = 500
# proposal code size in bytes
max_proposal_code_size = 500000
# min proposal period length in epochs
min_proposal_period = 3
# min proposal voting period length in epochs
min_proposal_voting_period = 3
# max proposal period length in epochs
max_proposal_period = 27
# maximum number of characters in the proposal content
Expand Down
2 changes: 1 addition & 1 deletion genesis/e2e-tests-single-node.toml
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ min_proposal_fund = 500
# proposal code size in bytes
max_proposal_code_size = 1000000
# min proposal period length in epochs
min_proposal_period = 3
min_proposal_voting_period = 3
# max proposal period length in epochs
max_proposal_period = 27
# maximum number of characters in the proposal content
Expand Down
20 changes: 16 additions & 4 deletions shared/src/ledger/governance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,11 @@ where

/// Validate a grace_epoch key
pub fn is_valid_grace_epoch(&self, proposal_id: u64) -> Result<bool> {
let start_epoch_key =
gov_storage::get_voting_start_epoch_key(proposal_id);
let end_epoch_key = gov_storage::get_voting_end_epoch_key(proposal_id);
let grace_epoch_key = gov_storage::get_grace_epoch_key(proposal_id);
let max_proposal_period = gov_storage::get_max_proposal_period_key();
let min_grace_epoch_key =
gov_storage::get_min_proposal_grace_epoch_key();

Expand All @@ -346,12 +349,16 @@ where
return Ok(false);
}

let start_epoch: Epoch =
self.force_read(&start_epoch_key, ReadType::Post)?;
let end_epoch: Epoch =
self.force_read(&end_epoch_key, ReadType::Post)?;
let grace_epoch: Epoch =
self.force_read(&grace_epoch_key, ReadType::Post)?;
let min_grace_epoch: u64 =
self.force_read(&min_grace_epoch_key, ReadType::Pre)?;
let max_proposal_period: u64 =
self.force_read(&max_proposal_period, ReadType::Pre)?;

let committing_epoch_key = gov_storage::get_committing_proposals_key(
proposal_id,
Expand All @@ -360,9 +367,14 @@ where
let has_post_committing_epoch =
self.ctx.has_key_post(&committing_epoch_key)?;

let is_valid_grace_epoch = end_epoch < grace_epoch
&& (grace_epoch - end_epoch).0 >= min_grace_epoch;
let is_valid_max_proposal_perido = start_epoch < grace_epoch
&& grace_epoch.0 - start_epoch.0 <= max_proposal_period;

Ok(has_post_committing_epoch
&& end_epoch < grace_epoch
&& (grace_epoch - end_epoch).0 >= min_grace_epoch)
&& is_valid_grace_epoch
&& is_valid_max_proposal_perido)
}

/// Validate a start_epoch key
Expand All @@ -371,7 +383,7 @@ where
gov_storage::get_voting_start_epoch_key(proposal_id);
let end_epoch_key = gov_storage::get_voting_end_epoch_key(proposal_id);
let min_period_parameter_key =
gov_storage::get_min_proposal_period_key();
gov_storage::get_min_proposal_voting_period_key();

let current_epoch = self.ctx.get_block_epoch()?;

Expand Down Expand Up @@ -403,7 +415,7 @@ where
gov_storage::get_voting_start_epoch_key(proposal_id);
let end_epoch_key = gov_storage::get_voting_end_epoch_key(proposal_id);
let min_period_parameter_key =
gov_storage::get_min_proposal_period_key();
gov_storage::get_min_proposal_voting_period_key();
let max_period_parameter_key =
gov_storage::get_max_proposal_period_key();

Expand Down
Loading

0 comments on commit 901efd3

Please sign in to comment.