Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Governance fixes rebase #501

Merged
merged 37 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9a61587
[fix]: governance overflow, proposal validation
Fraccaman May 26, 2022
2aee155
[feat]: added total votes to query
Fraccaman May 26, 2022
9a08d61
[misc]: clippy, fmt
Fraccaman May 26, 2022
afe779a
[fix]: clippy, fmt
Fraccaman May 27, 2022
ee303e5
[fix]: clippy, fmt
Fraccaman May 27, 2022
124b2d9
[fix]: bad validation condition
Fraccaman May 27, 2022
4373e5d
[fix]: governance vp author address, proposal submission validation
Fraccaman May 27, 2022
f7cb4c0
[feat]: vote transaction validation
Fraccaman May 27, 2022
4903744
[fix]: error println
Fraccaman May 27, 2022
3ca66b2
[misc]: clippy, fmt
Fraccaman May 27, 2022
9450054
[fix]: e2e test
Fraccaman May 27, 2022
6cbf9dc
[fix]: e2e test
Fraccaman May 27, 2022
ecbefd0
Fixes e2e tests
grarco May 30, 2022
e49d8b0
Fixes test artifacts folder persistence
grarco May 31, 2022
2a385bd
[fix]: votes accumulation
Fraccaman Jun 13, 2022
20de724
[misc]: remove logs
Fraccaman Jun 13, 2022
2423a02
Fixes `safe_exit` call only if `force` is not set
grarco Jun 14, 2022
a6bf03a
Speeds up testing
grarco Jun 14, 2022
0a7f0f5
fmt and fix clippy
tzemanovic Jul 1, 2022
a8f6c64
Rename `Treasury` to `SlashFund`
grarco Sep 20, 2022
ff951ff
Skip tx whitelist for proposal code
grarco Sep 21, 2022
4a3d097
Use proposal `end_epoch` instead of `start_epoch` for voting power
grarco Sep 21, 2022
de18d0f
Removes `max_proposal_fund_transfer` parameter
grarco Sep 21, 2022
172a930
Adds `max_proposal_period` governance parameter
grarco Sep 21, 2022
4b22589
[misc] rebase
Sep 22, 2022
3863caa
fix proposal_submission e2e test
Sep 22, 2022
860e175
fix display proposal result in cli
Sep 22, 2022
8e8af7a
[ci] wasm checksums update
github-actions[bot] Sep 22, 2022
7119de4
Fixes specs
grarco Sep 22, 2022
467fcc8
[ci] wasm checksums update
github-actions[bot] Sep 23, 2022
88513f6
Refactors governance e2e tests
grarco Sep 23, 2022
218f45d
Uses `end_epoch` in `query_proposal_result`
grarco Sep 23, 2022
5b34bff
Misc refactoring
grarco Sep 23, 2022
e4ab8c9
fix e2e tests
Sep 26, 2022
c0e18b9
fix e2e tests
Sep 26, 2022
ccfa965
changelog: add #501
grarco Sep 26, 2022
7e3cf90
[ci] wasm checksums update
github-actions[bot] Sep 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
264 changes: 183 additions & 81 deletions apps/src/lib/client/rpc.rs

Large diffs are not rendered by default.

137 changes: 109 additions & 28 deletions apps/src/lib/client/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use namada::types::governance::{
use namada::types::key::*;
use namada::types::nft::{self, Nft, NftToken};
use namada::types::storage::Epoch;
use namada::types::token::Amount;
use namada::types::transaction::governance::{
InitProposalData, VoteProposalData,
};
Expand Down Expand Up @@ -532,7 +531,68 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) {
let proposal: Proposal =
serde_json::from_reader(file).expect("JSON was not well-formatted");

let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap();

let signer = WalletAddress::new(proposal.clone().author.to_string());
let governance_parameters = rpc::get_governance_parameters(&client).await;
let current_epoch = rpc::query_epoch(args::Query {
ledger_address: args.tx.ledger_address.clone(),
})
.await;

if proposal.voting_start_epoch <= current_epoch
|| proposal.voting_start_epoch.0
% governance_parameters.min_proposal_period
!= 0
{
println!("{}", proposal.voting_start_epoch <= current_epoch);
println!(
"{}",
proposal.voting_start_epoch.0
% governance_parameters.min_proposal_period
== 0
);
eprintln!(
"Invalid proposal start epoch: {} must be greater than current \
epoch {} and a multiple of {}",
proposal.voting_start_epoch,
current_epoch,
governance_parameters.min_proposal_period
);
if !args.tx.force {
safe_exit(1)
}
} else if proposal.voting_end_epoch <= proposal.voting_start_epoch
|| proposal.voting_end_epoch.0 - proposal.voting_start_epoch.0
< governance_parameters.min_proposal_period
|| proposal.voting_end_epoch.0 - proposal.voting_start_epoch.0
> governance_parameters.max_proposal_period
|| proposal.voting_end_epoch.0 % 3 != 0
{
eprintln!(
"Invalid proposal end epoch: difference between proposal start \
and end epoch must be at least {} and at max {} and end epoch \
must be a multiple of {}",
governance_parameters.min_proposal_period,
governance_parameters.max_proposal_period,
governance_parameters.min_proposal_period
);
if !args.tx.force {
safe_exit(1)
}
} else if proposal.grace_epoch <= proposal.voting_end_epoch
|| proposal.grace_epoch.0 - proposal.voting_end_epoch.0
< governance_parameters.min_proposal_grace_epochs
{
eprintln!(
"Invalid proposal grace epoch: difference between proposal grace \
and end epoch must be at least {}",
governance_parameters.min_proposal_grace_epochs
);
if !args.tx.force {
safe_exit(1)
}
}

if args.offline {
let signer = ctx.get(&signer);
Expand All @@ -544,20 +604,25 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) {
.await;
let offline_proposal =
OfflineProposal::new(proposal, signer, &signing_key);
let proposal_filename = "proposal".to_string();
let proposal_filename = args
.proposal_data
.parent()
.expect("No parent found")
.join("proposal");
let out = File::create(&proposal_filename).unwrap();
match serde_json::to_writer_pretty(out, &offline_proposal) {
Ok(_) => {
println!("Proposal created: {}.", proposal_filename);
println!(
"Proposal created: {}.",
proposal_filename.to_string_lossy()
);
}
Err(e) => {
eprintln!("Error while creating proposal file: {}.", e);
safe_exit(1)
}
}
} else {
let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap();

let tx_data: Result<InitProposalData, _> = proposal.clone().try_into();
let init_proposal_data = if let Ok(data) = tx_data {
data
Expand All @@ -566,35 +631,23 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) {
safe_exit(1)
};

let min_proposal_funds_key = gov_storage::get_min_proposal_fund_key();
let min_proposal_funds: Amount =
rpc::query_storage_value(&client, &min_proposal_funds_key)
.await
.unwrap();
let balance = rpc::get_token_balance(&client, &m1t(), &proposal.author)
.await
.unwrap_or_default();
if balance < min_proposal_funds {
if balance
< token::Amount::from(governance_parameters.min_proposal_fund)
{
eprintln!(
"Address {} doesn't have enough funds.",
&proposal.author
);
safe_exit(1);
}
let min_proposal_funds_key = gov_storage::get_min_proposal_fund_key();
let min_proposal_funds: Amount =
rpc::query_storage_value(&client, &min_proposal_funds_key)
.await
.unwrap();

let balance = rpc::get_token_balance(&client, &m1t(), &proposal.author)
.await
.unwrap_or_default();
if balance < min_proposal_funds {
eprintln!(
"Address {} doesn't have enough funds.",
&proposal.author
);
if init_proposal_data.content.len()
> governance_parameters.max_proposal_content_size as usize
{
eprintln!("Proposal content size too big.",);
safe_exit(1);
}

Expand Down Expand Up @@ -648,12 +701,17 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) {
&signing_key,
);

let proposal_vote_filename =
format!("proposal-vote-{}", &signer.to_string());
let proposal_vote_filename = proposal_file_path
.parent()
.expect("No parent found")
.join(format!("proposal-vote-{}", &signer.to_string()));
let out = File::create(&proposal_vote_filename).unwrap();
match serde_json::to_writer_pretty(out, &offline_vote) {
Ok(_) => {
println!("Proposal vote created: {}.", proposal_vote_filename);
println!(
"Proposal vote created: {}.",
proposal_vote_filename.to_string_lossy()
);
}
Err(e) => {
eprintln!("Error while creating proposal vote file: {}.", e);
Expand All @@ -662,6 +720,10 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) {
}
} else {
let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap();
let current_epoch = rpc::query_epoch(args::Query {
ledger_address: args.tx.ledger_address.clone(),
})
.await;

let voter_address = ctx.get(signer);
let proposal_id = args.proposal_id.unwrap();
Expand All @@ -675,6 +737,17 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) {

match proposal_start_epoch {
Some(epoch) => {
if current_epoch < epoch {
eprintln!(
"Current epoch {} is not greater than proposal start \
epoch {}",
current_epoch, epoch
);

if !args.tx.force {
safe_exit(1)
}
}
let mut delegation_addresses = rpc::get_delegators_delegation(
&client,
&voter_address,
Expand Down Expand Up @@ -706,6 +779,8 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) {
.await;
}

println!("{:?}", delegation_addresses);

let tx_data = VoteProposalData {
id: proposal_id,
vote: args.vote,
Expand All @@ -722,7 +797,13 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) {
process_tx(ctx, &args.tx, tx, Some(signer)).await;
}
None => {
eprintln!("Proposal start epoch is not in the storage.")
eprintln!(
"Proposal start epoch for proposal id {} is not definied.",
proposal_id
);
if !args.tx.force {
safe_exit(1)
}
}
}
}
Expand Down
24 changes: 5 additions & 19 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use derivative::Derivative;
use namada::ledger::governance::parameters::GovParams;
use namada::ledger::parameters::Parameters;
use namada::ledger::pos::{GenesisValidator, PosParams};
use namada::ledger::treasury::parameters::TreasuryParams;
use namada::types::address::Address;
#[cfg(not(feature = "dev"))]
use namada::types::chain::ChainId;
Expand All @@ -31,7 +30,6 @@ pub mod genesis_config {
use namada::ledger::parameters::{EpochDuration, Parameters};
use namada::ledger::pos::types::BasisPoints;
use namada::ledger::pos::{GenesisValidator, PosParams};
use namada::ledger::treasury::parameters::TreasuryParams;
use namada::types::address::Address;
use namada::types::key::dkg_session_keys::DkgPublicKey;
use namada::types::key::*;
Expand Down Expand Up @@ -119,8 +117,6 @@ pub mod genesis_config {
pub pos_params: PosParamsConfig,
// Governance parameters
pub gov_params: GovernanceParamsConfig,
// Treasury parameters
pub treasury_params: TreasuryParamasConfig,
// Wasm definitions
pub wasm: HashMap<String, WasmConfig>,
}
Expand All @@ -133,9 +129,12 @@ pub mod genesis_config {
// Maximum size of proposal in kibibytes (KiB)
// XXX: u64 doesn't work with toml-rs!
pub max_proposal_code_size: u64,
// Proposal period length in epoch
// Minimum proposal period length in epochs
// XXX: u64 doesn't work with toml-rs!
pub min_proposal_period: u64,
// Maximum proposal period length in epochs
// XXX: u64 doesn't work with toml-rs!
pub max_proposal_period: u64,
// Maximum number of characters in the proposal content
// XXX: u64 doesn't work with toml-rs!
pub max_proposal_content_size: u64,
Expand All @@ -144,13 +143,6 @@ pub mod genesis_config {
pub min_proposal_grace_epochs: u64,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TreasuryParamasConfig {
// Maximum funds that can be moved from treasury in a single transfer
// XXX: u64 doesn't work with toml-rs!
pub max_proposal_fund_transfer: u64,
}

/// Validator pre-genesis configuration can be created with client utils
/// `init-genesis-validator` command and added to a genesis for
/// `init-network` cmd and that can be subsequently read by `join-network`
Expand Down Expand Up @@ -550,6 +542,7 @@ pub mod genesis_config {
min_proposal_fund: config.gov_params.min_proposal_fund,
max_proposal_code_size: config.gov_params.max_proposal_code_size,
min_proposal_period: config.gov_params.min_proposal_period,
max_proposal_period: config.gov_params.max_proposal_period,
max_proposal_content_size: config
.gov_params
.max_proposal_content_size,
Expand All @@ -558,10 +551,6 @@ pub mod genesis_config {
.min_proposal_grace_epochs,
};

let treasury_params = TreasuryParams {
max_proposal_fund_transfer: 10_000,
};

let pos_params = PosParams {
max_validator_slots: config.pos_params.max_validator_slots,
pipeline_len: config.pos_params.pipeline_len,
Expand All @@ -588,7 +577,6 @@ pub mod genesis_config {
parameters,
pos_params,
gov_params,
treasury_params,
};
genesis.init();
genesis
Expand Down Expand Up @@ -623,7 +611,6 @@ pub struct Genesis {
pub parameters: Parameters,
pub pos_params: PosParams,
pub gov_params: GovParams,
pub treasury_params: TreasuryParams,
}

impl Genesis {
Expand Down Expand Up @@ -859,7 +846,6 @@ pub fn genesis() -> Genesis {
parameters,
pos_params: PosParams::default(),
gov_params: GovParams::default(),
treasury_params: TreasuryParams::default(),
}
}

Expand Down
16 changes: 8 additions & 8 deletions apps/src/lib/node/ledger/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use namada::ledger::ibc::vp::{Ibc, IbcToken};
use namada::ledger::native_vp::{self, NativeVp};
use namada::ledger::parameters::{self, ParametersVp};
use namada::ledger::pos::{self, PosVP};
use namada::ledger::slash_fund::SlashFundVp;
use namada::ledger::storage::write_log::WriteLog;
use namada::ledger::storage::{DBIter, Storage, StorageHasher, DB};
use namada::ledger::treasury::TreasuryVp;
use namada::proto::{self, Tx};
use namada::types::address::{Address, InternalAddress};
use namada::types::storage;
Expand Down Expand Up @@ -49,8 +49,8 @@ pub enum Error {
IbcTokenNativeVpError(namada::ledger::ibc::vp::IbcTokenError),
#[error("Governance native VP error: {0}")]
GovernanceNativeVpError(namada::ledger::governance::vp::Error),
#[error("Treasury native VP error: {0}")]
TreasuryNativeVpError(namada::ledger::treasury::Error),
#[error("SlashFund native VP error: {0}")]
SlashFundNativeVpError(namada::ledger::slash_fund::Error),
#[error("Ethereum bridge native VP error: {0}")]
EthBridgeNativeVpError(namada::ledger::eth_bridge::vp::Error),
#[error("Access to an internal address {0} is forbidden")]
Expand Down Expand Up @@ -325,12 +325,12 @@ where
gas_meter = governance.ctx.gas_meter.into_inner();
result
}
InternalAddress::Treasury => {
let treasury = TreasuryVp { ctx };
let result = treasury
InternalAddress::SlashFund => {
let slash_fund = SlashFundVp { ctx };
let result = slash_fund
.validate_tx(tx_data, &keys_changed, &verifiers)
.map_err(Error::TreasuryNativeVpError);
gas_meter = treasury.ctx.gas_meter.into_inner();
.map_err(Error::SlashFundNativeVpError);
gas_meter = slash_fund.ctx.gas_meter.into_inner();
result
}
InternalAddress::IbcEscrow(_)
Expand Down
Loading