|
@@ -1,17 +1,18 @@
|
|
|
-use srml_support::{StorageValue, StorageMap, dispatch, decl_module, decl_event, decl_storage, ensure};
|
|
|
-use srml_support::traits::{Currency};
|
|
|
-use runtime_primitives::traits::{As, Hash, Zero};
|
|
|
+use rstd::prelude::*;
|
|
|
use runtime_io::print;
|
|
|
+use runtime_primitives::traits::{As, Hash, Zero};
|
|
|
+use srml_support::traits::Currency;
|
|
|
+use srml_support::{
|
|
|
+ decl_event, decl_module, decl_storage, dispatch, ensure, StorageMap, StorageValue,
|
|
|
+};
|
|
|
use system::{self, ensure_signed};
|
|
|
-use rstd::prelude::*;
|
|
|
|
|
|
#[cfg(test)]
|
|
|
-use primitives::{storage::well_known_keys};
|
|
|
-
|
|
|
+use primitives::storage::well_known_keys;
|
|
|
|
|
|
use super::council;
|
|
|
-pub use super::{ GovernanceCurrency, BalanceOf };
|
|
|
-use crate::traits::{Members};
|
|
|
+pub use super::{BalanceOf, GovernanceCurrency};
|
|
|
+use crate::traits::Members;
|
|
|
|
|
|
const DEFAULT_APPROVAL_QUORUM: u32 = 60;
|
|
|
const DEFAULT_MIN_STAKE: u64 = 100;
|
|
@@ -346,7 +347,6 @@ decl_module! {
|
|
|
}
|
|
|
|
|
|
impl<T: Trait> Module<T> {
|
|
|
-
|
|
|
fn current_block() -> T::BlockNumber {
|
|
|
<system::Module<T>>::block_number()
|
|
|
}
|
|
@@ -386,20 +386,18 @@ impl<T: Trait> Module<T> {
|
|
|
}
|
|
|
|
|
|
fn end_block(_now: T::BlockNumber) -> dispatch::Result {
|
|
|
-
|
|
|
// TODO refactor this method
|
|
|
|
|
|
// TODO iterate over not expired proposals and tally
|
|
|
|
|
|
- Self::tally()?;
|
|
|
- // TODO approve or reject a proposal
|
|
|
+ Self::tally()?;
|
|
|
+ // TODO approve or reject a proposal
|
|
|
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
/// Get the voters for the current proposal.
|
|
|
- pub fn tally(/* proposal_id: u32 */) -> dispatch::Result {
|
|
|
-
|
|
|
+ pub fn tally() -> dispatch::Result {
|
|
|
let councilors: u32 = Self::councilors_count();
|
|
|
let quorum: u32 = Self::approval_quorum_seats();
|
|
|
|
|
@@ -436,26 +434,25 @@ impl<T: Trait> Module<T> {
|
|
|
// Instead let other councilors cast their vote
|
|
|
// up until the proposal's expired.
|
|
|
|
|
|
- let new_status: Option<ProposalStatus> =
|
|
|
- if all_councilors_slashed {
|
|
|
- Some(Slashed)
|
|
|
- } else if all_councilors_voted {
|
|
|
- if quorum_reached {
|
|
|
- Some(Approved)
|
|
|
- } else {
|
|
|
- Some(Rejected)
|
|
|
- }
|
|
|
- } else if is_expired {
|
|
|
- if quorum_reached {
|
|
|
- Some(Approved)
|
|
|
- } else {
|
|
|
- // Proposal has been expired and quorum not reached.
|
|
|
- Some(Expired)
|
|
|
- }
|
|
|
+ let new_status: Option<ProposalStatus> = if all_councilors_slashed {
|
|
|
+ Some(Slashed)
|
|
|
+ } else if all_councilors_voted {
|
|
|
+ if quorum_reached {
|
|
|
+ Some(Approved)
|
|
|
} else {
|
|
|
- // Councilors still have time to vote on this proposal.
|
|
|
- None
|
|
|
- };
|
|
|
+ Some(Rejected)
|
|
|
+ }
|
|
|
+ } else if is_expired {
|
|
|
+ if quorum_reached {
|
|
|
+ Some(Approved)
|
|
|
+ } else {
|
|
|
+ // Proposal has been expired and quorum not reached.
|
|
|
+ Some(Expired)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // Councilors still have time to vote on this proposal.
|
|
|
+ None
|
|
|
+ };
|
|
|
|
|
|
// TODO move next block outside of tally to 'end_block'
|
|
|
if let Some(status) = new_status {
|
|
@@ -496,7 +493,7 @@ impl<T: Trait> Module<T> {
|
|
|
Slashed => Self::_slash_proposal(pid)?,
|
|
|
Rejected | Expired => Self::_reject_proposal(pid)?,
|
|
|
Approved => Self::_approve_proposal(pid)?,
|
|
|
- Active | Cancelled => { /* nothing */ },
|
|
|
+ Active | Cancelled => { /* nothing */ }
|
|
|
}
|
|
|
<ActiveProposalIds<T>>::put(other_active_ids);
|
|
|
<Proposals<T>>::mutate(proposal_id, |p| p.status = new_status.clone());
|
|
@@ -552,14 +549,14 @@ impl<T: Trait> Module<T> {
|
|
|
mod tests {
|
|
|
|
|
|
use super::*;
|
|
|
+ use primitives::{Blake2Hasher, H256};
|
|
|
use runtime_io::with_externalities;
|
|
|
- use primitives::{H256, Blake2Hasher};
|
|
|
// The testing primitives are very useful for avoiding having to work with signatures
|
|
|
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
|
|
|
use runtime_primitives::{
|
|
|
+ testing::{Digest, DigestItem, Header, UintAuthorityId},
|
|
|
+ traits::{BlakeTwo256, IdentityLookup, OnFinalise},
|
|
|
BuildStorage,
|
|
|
- traits::{BlakeTwo256, OnFinalise, IdentityLookup},
|
|
|
- testing::{Digest, DigestItem, Header, UintAuthorityId}
|
|
|
};
|
|
|
use srml_support::*;
|
|
|
|
|
@@ -652,13 +649,7 @@ mod tests {
|
|
|
|
|
|
const NOT_COUNCILOR: u64 = 22;
|
|
|
|
|
|
- const ALL_COUNCILORS: [u64; 5] = [
|
|
|
- COUNCILOR1,
|
|
|
- COUNCILOR2,
|
|
|
- COUNCILOR3,
|
|
|
- COUNCILOR4,
|
|
|
- COUNCILOR5
|
|
|
- ];
|
|
|
+ const ALL_COUNCILORS: [u64; 5] = [COUNCILOR1, COUNCILOR2, COUNCILOR3, COUNCILOR4, COUNCILOR5];
|
|
|
|
|
|
// TODO Figure out how to test Events in test... (low priority)
|
|
|
// mod proposals {
|
|
@@ -673,21 +664,36 @@ mod tests {
|
|
|
// This function basically just builds a genesis storage key/value store according to
|
|
|
// our desired mockup.
|
|
|
fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
|
|
|
- let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
|
|
+ let mut t = system::GenesisConfig::<Test>::default()
|
|
|
+ .build_storage()
|
|
|
+ .unwrap()
|
|
|
+ .0;
|
|
|
// We use default for brevity, but you can configure as desired if needed.
|
|
|
- t.extend(balances::GenesisConfig::<Test>::default().build_storage().unwrap().0);
|
|
|
-
|
|
|
- let council_mock: council::Seats<u64, u64> =
|
|
|
- ALL_COUNCILORS.iter().map(|&c| council::Seat {
|
|
|
+ t.extend(
|
|
|
+ balances::GenesisConfig::<Test>::default()
|
|
|
+ .build_storage()
|
|
|
+ .unwrap()
|
|
|
+ .0,
|
|
|
+ );
|
|
|
+
|
|
|
+ let council_mock: council::Seats<u64, u64> = ALL_COUNCILORS
|
|
|
+ .iter()
|
|
|
+ .map(|&c| council::Seat {
|
|
|
member: c,
|
|
|
stake: 0u64,
|
|
|
backers: vec![],
|
|
|
- }).collect();
|
|
|
+ })
|
|
|
+ .collect();
|
|
|
|
|
|
- t.extend(council::GenesisConfig::<Test>{
|
|
|
- active_council: council_mock,
|
|
|
- term_ends_at: 0,
|
|
|
- }.build_storage().unwrap().0);
|
|
|
+ t.extend(
|
|
|
+ council::GenesisConfig::<Test> {
|
|
|
+ active_council: council_mock,
|
|
|
+ term_ends_at: 0,
|
|
|
+ }
|
|
|
+ .build_storage()
|
|
|
+ .unwrap()
|
|
|
+ .0,
|
|
|
+ );
|
|
|
|
|
|
// t.extend(GenesisConfig::<Test>{
|
|
|
// // Here we can override defaults.
|
|
@@ -737,14 +743,14 @@ mod tests {
|
|
|
stake: Option<u64>,
|
|
|
name: Option<Vec<u8>>,
|
|
|
description: Option<Vec<u8>>,
|
|
|
- wasm_code: Option<Vec<u8>>
|
|
|
+ wasm_code: Option<Vec<u8>>,
|
|
|
) -> dispatch::Result {
|
|
|
Proposals::create_proposal(
|
|
|
Origin::signed(origin.unwrap_or(PROPOSER1)),
|
|
|
stake.unwrap_or(min_stake()),
|
|
|
name.unwrap_or(self::name()),
|
|
|
description.unwrap_or(self::description()),
|
|
|
- wasm_code.unwrap_or(self::wasm_code())
|
|
|
+ wasm_code.unwrap_or(self::wasm_code()),
|
|
|
)
|
|
|
}
|
|
|
|
|
@@ -753,11 +759,15 @@ mod tests {
|
|
|
}
|
|
|
|
|
|
macro_rules! assert_runtime_code_empty {
|
|
|
- () => { assert_eq!(get_runtime_code(), None) }
|
|
|
+ () => {
|
|
|
+ assert_eq!(get_runtime_code(), None)
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
macro_rules! assert_runtime_code {
|
|
|
- ($code:expr) => { assert_eq!(get_runtime_code(), Some($code)) }
|
|
|
+ ($code:expr) => {
|
|
|
+ assert_eq!(get_runtime_code(), Some($code))
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
@@ -768,7 +778,10 @@ mod tests {
|
|
|
assert_eq!(Proposals::cancellation_fee(), DEFAULT_CANCELLATION_FEE);
|
|
|
assert_eq!(Proposals::rejection_fee(), DEFAULT_REJECTION_FEE);
|
|
|
assert_eq!(Proposals::name_max_len(), DEFAULT_NAME_MAX_LEN);
|
|
|
- assert_eq!(Proposals::description_max_len(), DEFAULT_DESCRIPTION_MAX_LEN);
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::description_max_len(),
|
|
|
+ DEFAULT_DESCRIPTION_MAX_LEN
|
|
|
+ );
|
|
|
assert_eq!(Proposals::wasm_code_max_len(), DEFAULT_WASM_CODE_MAX_LEN);
|
|
|
assert_eq!(Proposals::proposal_count(), 0);
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
@@ -794,12 +807,15 @@ mod tests {
|
|
|
description: description(),
|
|
|
wasm_hash,
|
|
|
proposed_at: 1,
|
|
|
- status: Active
|
|
|
+ status: Active,
|
|
|
};
|
|
|
assert_eq!(Proposals::proposals(1), expected_proposal);
|
|
|
|
|
|
// Check that stake amount has been locked on proposer's balance:
|
|
|
- assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - min_stake());
|
|
|
+ assert_eq!(
|
|
|
+ Balances::free_balance(PROPOSER1),
|
|
|
+ initial_balance() - min_stake()
|
|
|
+ );
|
|
|
assert_eq!(Balances::reserved_balance(PROPOSER1), min_stake());
|
|
|
|
|
|
// TODO expect event ProposalCreated(AccountId, u32)
|
|
@@ -811,8 +827,10 @@ mod tests {
|
|
|
with_externalities(&mut new_test_ext(), || {
|
|
|
// In this test a proposer has an empty balance
|
|
|
// thus he is not considered as a member.
|
|
|
- assert_eq!(_create_default_proposal(),
|
|
|
- Err(MSG_ONLY_MEMBERS_CAN_PROPOSE));
|
|
|
+ assert_eq!(
|
|
|
+ _create_default_proposal(),
|
|
|
+ Err(MSG_ONLY_MEMBERS_CAN_PROPOSE)
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -822,9 +840,10 @@ mod tests {
|
|
|
Balances::set_free_balance(&PROPOSER1, initial_balance());
|
|
|
Balances::increase_total_stake_by(initial_balance());
|
|
|
|
|
|
- assert_eq!(_create_proposal(
|
|
|
- None, Some(min_stake() - 1), None, None, None),
|
|
|
- Err(MSG_STAKE_IS_TOO_LOW));
|
|
|
+ assert_eq!(
|
|
|
+ _create_proposal(None, Some(min_stake() - 1), None, None, None),
|
|
|
+ Err(MSG_STAKE_IS_TOO_LOW)
|
|
|
+ );
|
|
|
|
|
|
// Check that balances remain unchanged afer a failed attempt to create a proposal:
|
|
|
assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
|
|
@@ -838,9 +857,10 @@ mod tests {
|
|
|
Balances::set_free_balance(&PROPOSER1, initial_balance());
|
|
|
Balances::increase_total_stake_by(initial_balance());
|
|
|
|
|
|
- assert_eq!(_create_proposal(
|
|
|
- None, Some(initial_balance() + 1), None, None, None),
|
|
|
- Err(MSG_STAKE_IS_GREATER_THAN_BALANCE));
|
|
|
+ assert_eq!(
|
|
|
+ _create_proposal(None, Some(initial_balance() + 1), None, None, None),
|
|
|
+ Err(MSG_STAKE_IS_GREATER_THAN_BALANCE)
|
|
|
+ );
|
|
|
|
|
|
// Check that balances remain unchanged afer a failed attempt to create a proposal:
|
|
|
assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
|
|
@@ -855,19 +875,22 @@ mod tests {
|
|
|
Balances::increase_total_stake_by(initial_balance());
|
|
|
|
|
|
// Empty name:
|
|
|
- assert_eq!(_create_proposal(
|
|
|
- None, None, Some(vec![]), None, None),
|
|
|
- Err(MSG_EMPTY_NAME_PROVIDED));
|
|
|
+ assert_eq!(
|
|
|
+ _create_proposal(None, None, Some(vec![]), None, None),
|
|
|
+ Err(MSG_EMPTY_NAME_PROVIDED)
|
|
|
+ );
|
|
|
|
|
|
// Empty description:
|
|
|
- assert_eq!(_create_proposal(
|
|
|
- None, None, None, Some(vec![]), None),
|
|
|
- Err(MSG_EMPTY_DESCRIPTION_PROVIDED));
|
|
|
+ assert_eq!(
|
|
|
+ _create_proposal(None, None, None, Some(vec![]), None),
|
|
|
+ Err(MSG_EMPTY_DESCRIPTION_PROVIDED)
|
|
|
+ );
|
|
|
|
|
|
// Empty WASM code:
|
|
|
- assert_eq!(_create_proposal(
|
|
|
- None, None, None, None, Some(vec![])),
|
|
|
- Err(MSG_EMPTY_WASM_CODE_PROVIDED));
|
|
|
+ assert_eq!(
|
|
|
+ _create_proposal(None, None, None, None, Some(vec![])),
|
|
|
+ Err(MSG_EMPTY_WASM_CODE_PROVIDED)
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -878,19 +901,22 @@ mod tests {
|
|
|
Balances::increase_total_stake_by(initial_balance());
|
|
|
|
|
|
// Too long name:
|
|
|
- assert_eq!(_create_proposal(
|
|
|
- None, None, Some(too_long_name()), None, None),
|
|
|
- Err(MSG_TOO_LONG_NAME));
|
|
|
+ assert_eq!(
|
|
|
+ _create_proposal(None, None, Some(too_long_name()), None, None),
|
|
|
+ Err(MSG_TOO_LONG_NAME)
|
|
|
+ );
|
|
|
|
|
|
// Too long description:
|
|
|
- assert_eq!(_create_proposal(
|
|
|
- None, None, None, Some(too_long_description()), None),
|
|
|
- Err(MSG_TOO_LONG_DESCRIPTION));
|
|
|
+ assert_eq!(
|
|
|
+ _create_proposal(None, None, None, Some(too_long_description()), None),
|
|
|
+ Err(MSG_TOO_LONG_DESCRIPTION)
|
|
|
+ );
|
|
|
|
|
|
// Too long WASM code:
|
|
|
- assert_eq!(_create_proposal(
|
|
|
- None, None, None, None, Some(too_long_wasm_code())),
|
|
|
- Err(MSG_TOO_LONG_WASM_CODE));
|
|
|
+ assert_eq!(
|
|
|
+ _create_proposal(None, None, None, None, Some(too_long_wasm_code())),
|
|
|
+ Err(MSG_TOO_LONG_WASM_CODE)
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -921,7 +947,10 @@ mod tests {
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
|
|
|
|
// Check that proposer's balance reduced by cancellation fee and other part of his stake returned to his balance:
|
|
|
- assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - cancellation_fee());
|
|
|
+ assert_eq!(
|
|
|
+ Balances::free_balance(PROPOSER1),
|
|
|
+ initial_balance() - cancellation_fee()
|
|
|
+ );
|
|
|
assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
|
|
|
|
|
|
// TODO expect event ProposalCancelled(AccountId, u32)
|
|
@@ -942,12 +971,17 @@ mod tests {
|
|
|
let updated_free_balance = Balances::free_balance(PROPOSER1);
|
|
|
let updated_reserved_balance = Balances::reserved_balance(PROPOSER1);
|
|
|
|
|
|
- assert_eq!(Proposals::cancel_proposal(Origin::signed(PROPOSER1), 1),
|
|
|
- Err(MSG_PROPOSAL_FINALIZED));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::cancel_proposal(Origin::signed(PROPOSER1), 1),
|
|
|
+ Err(MSG_PROPOSAL_FINALIZED)
|
|
|
+ );
|
|
|
|
|
|
// Check that proposer's balance and locked stake haven't been changed:
|
|
|
assert_eq!(Balances::free_balance(PROPOSER1), updated_free_balance);
|
|
|
- assert_eq!(Balances::reserved_balance(PROPOSER1), updated_reserved_balance);
|
|
|
+ assert_eq!(
|
|
|
+ Balances::reserved_balance(PROPOSER1),
|
|
|
+ updated_reserved_balance
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -958,8 +992,10 @@ mod tests {
|
|
|
Balances::set_free_balance(&PROPOSER2, initial_balance());
|
|
|
Balances::increase_total_stake_by(initial_balance() * 2);
|
|
|
assert_ok!(_create_default_proposal());
|
|
|
- assert_eq!(Proposals::cancel_proposal(Origin::signed(PROPOSER2), 1),
|
|
|
- Err(MSG_YOU_DONT_OWN_THIS_PROPOSAL));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::cancel_proposal(Origin::signed(PROPOSER2), 1),
|
|
|
+ Err(MSG_YOU_DONT_OWN_THIS_PROPOSAL)
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -974,11 +1010,17 @@ mod tests {
|
|
|
assert_ok!(_create_default_proposal());
|
|
|
|
|
|
assert_ok!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(COUNCILOR1), 1, Approve));
|
|
|
+ Origin::signed(COUNCILOR1),
|
|
|
+ 1,
|
|
|
+ Approve
|
|
|
+ ));
|
|
|
|
|
|
// Check that a vote has been saved:
|
|
|
assert_eq!(Proposals::votes_by_proposal(1), vec![(COUNCILOR1, Approve)]);
|
|
|
- assert_eq!(Proposals::vote_by_account_and_proposal((COUNCILOR1, 1)), Approve);
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_by_account_and_proposal((COUNCILOR1, 1)),
|
|
|
+ Approve
|
|
|
+ );
|
|
|
|
|
|
// TODO expect event Voted(PROPOSER1, 1, Approve)
|
|
|
});
|
|
@@ -992,10 +1034,14 @@ mod tests {
|
|
|
assert_ok!(_create_default_proposal());
|
|
|
|
|
|
assert_ok!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(COUNCILOR1), 1, Approve));
|
|
|
- assert_eq!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(COUNCILOR1), 1, Approve),
|
|
|
- Err(MSG_YOU_ALREADY_VOTED));
|
|
|
+ Origin::signed(COUNCILOR1),
|
|
|
+ 1,
|
|
|
+ Approve
|
|
|
+ ));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_on_proposal(Origin::signed(COUNCILOR1), 1, Approve),
|
|
|
+ Err(MSG_YOU_ALREADY_VOTED)
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -1004,14 +1050,15 @@ mod tests {
|
|
|
with_externalities(&mut new_test_ext(), || {
|
|
|
Balances::set_free_balance(&COUNCILOR1, initial_balance());
|
|
|
Balances::increase_total_stake_by(initial_balance());
|
|
|
- assert_ok!(_create_proposal(
|
|
|
- Some(COUNCILOR1), None, None, None, None
|
|
|
- ));
|
|
|
+ assert_ok!(_create_proposal(Some(COUNCILOR1), None, None, None, None));
|
|
|
|
|
|
// Check that a vote has been sent automatically,
|
|
|
// such as the proposer is a councilor:
|
|
|
assert_eq!(Proposals::votes_by_proposal(1), vec![(COUNCILOR1, Approve)]);
|
|
|
- assert_eq!(Proposals::vote_by_account_and_proposal((COUNCILOR1, 1)), Approve);
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_by_account_and_proposal((COUNCILOR1, 1)),
|
|
|
+ Approve
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -1021,9 +1068,10 @@ mod tests {
|
|
|
Balances::set_free_balance(&PROPOSER1, initial_balance());
|
|
|
Balances::increase_total_stake_by(initial_balance());
|
|
|
assert_ok!(_create_default_proposal());
|
|
|
- assert_eq!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(NOT_COUNCILOR), 1, Approve),
|
|
|
- Err(MSG_ONLY_COUNCILORS_CAN_VOTE));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_on_proposal(Origin::signed(NOT_COUNCILOR), 1, Approve),
|
|
|
+ Err(MSG_ONLY_COUNCILORS_CAN_VOTE)
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -1034,9 +1082,10 @@ mod tests {
|
|
|
Balances::increase_total_stake_by(initial_balance());
|
|
|
assert_ok!(_create_default_proposal());
|
|
|
assert_ok!(Proposals::cancel_proposal(Origin::signed(PROPOSER1), 1));
|
|
|
- assert_eq!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(COUNCILOR1), 1, Approve),
|
|
|
- Err(MSG_PROPOSAL_FINALIZED));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_on_proposal(Origin::signed(COUNCILOR1), 1, Approve),
|
|
|
+ Err(MSG_PROPOSAL_FINALIZED)
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -1052,8 +1101,15 @@ mod tests {
|
|
|
let mut expected_votes: Vec<(u64, VoteKind)> = vec![];
|
|
|
for &councilor in ALL_COUNCILORS.iter() {
|
|
|
expected_votes.push((councilor, Approve));
|
|
|
- assert_ok!(Proposals::vote_on_proposal(Origin::signed(councilor), 1, Approve));
|
|
|
- assert_eq!(Proposals::vote_by_account_and_proposal((councilor, 1)), Approve);
|
|
|
+ assert_ok!(Proposals::vote_on_proposal(
|
|
|
+ Origin::signed(councilor),
|
|
|
+ 1,
|
|
|
+ Approve
|
|
|
+ ));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_by_account_and_proposal((councilor, 1)),
|
|
|
+ Approve
|
|
|
+ );
|
|
|
}
|
|
|
assert_eq!(Proposals::votes_by_proposal(1), expected_votes);
|
|
|
|
|
@@ -1064,9 +1120,10 @@ mod tests {
|
|
|
assert_eq!(Proposals::proposals(1).status, Approved);
|
|
|
|
|
|
// Try to vote on finalized proposal:
|
|
|
- assert_eq!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(COUNCILOR1), 1, Reject),
|
|
|
- Err(MSG_PROPOSAL_FINALIZED));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_on_proposal(Origin::signed(COUNCILOR1), 1, Reject),
|
|
|
+ Err(MSG_PROPOSAL_FINALIZED)
|
|
|
+ );
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -1085,8 +1142,15 @@ mod tests {
|
|
|
let mut expected_votes: Vec<(u64, VoteKind)> = vec![];
|
|
|
for &councilor in ALL_COUNCILORS.iter() {
|
|
|
expected_votes.push((councilor, Approve));
|
|
|
- assert_ok!(Proposals::vote_on_proposal(Origin::signed(councilor), 1, Approve));
|
|
|
- assert_eq!(Proposals::vote_by_account_and_proposal((councilor, 1)), Approve);
|
|
|
+ assert_ok!(Proposals::vote_on_proposal(
|
|
|
+ Origin::signed(councilor),
|
|
|
+ 1,
|
|
|
+ Approve
|
|
|
+ ));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_by_account_and_proposal((councilor, 1)),
|
|
|
+ Approve
|
|
|
+ );
|
|
|
}
|
|
|
assert_eq!(Proposals::votes_by_proposal(1), expected_votes);
|
|
|
|
|
@@ -1100,15 +1164,18 @@ mod tests {
|
|
|
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
|
assert_eq!(Proposals::proposals(1).status, Approved);
|
|
|
- assert_eq!(Proposals::tally_results(1), TallyResult {
|
|
|
- proposal_id: 1,
|
|
|
- abstentions: 0,
|
|
|
- approvals: ALL_COUNCILORS.len() as u32,
|
|
|
- rejections: 0,
|
|
|
- slashes: 0,
|
|
|
- status: Approved,
|
|
|
- finalized_at: 2
|
|
|
- });
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::tally_results(1),
|
|
|
+ TallyResult {
|
|
|
+ proposal_id: 1,
|
|
|
+ abstentions: 0,
|
|
|
+ approvals: ALL_COUNCILORS.len() as u32,
|
|
|
+ rejections: 0,
|
|
|
+ slashes: 0,
|
|
|
+ status: Approved,
|
|
|
+ finalized_at: 2
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
// Check that proposer's stake has been added back to his balance:
|
|
|
assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
|
|
@@ -1131,9 +1198,16 @@ mod tests {
|
|
|
let approvals = Proposals::approval_quorum_seats();
|
|
|
let rejections = councilors - approvals;
|
|
|
for i in 0..councilors as usize {
|
|
|
- let vote = if (i as u32) < approvals { Approve } else { Reject };
|
|
|
+ let vote = if (i as u32) < approvals {
|
|
|
+ Approve
|
|
|
+ } else {
|
|
|
+ Reject
|
|
|
+ };
|
|
|
assert_ok!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(ALL_COUNCILORS[i]), 1, vote));
|
|
|
+ Origin::signed(ALL_COUNCILORS[i]),
|
|
|
+ 1,
|
|
|
+ vote
|
|
|
+ ));
|
|
|
}
|
|
|
assert_eq!(Proposals::votes_by_proposal(1).len() as u32, councilors);
|
|
|
|
|
@@ -1147,15 +1221,18 @@ mod tests {
|
|
|
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
|
assert_eq!(Proposals::proposals(1).status, Approved);
|
|
|
- assert_eq!(Proposals::tally_results(1), TallyResult {
|
|
|
- proposal_id: 1,
|
|
|
- abstentions: 0,
|
|
|
- approvals: approvals,
|
|
|
- rejections: rejections,
|
|
|
- slashes: 0,
|
|
|
- status: Approved,
|
|
|
- finalized_at: 2
|
|
|
- });
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::tally_results(1),
|
|
|
+ TallyResult {
|
|
|
+ proposal_id: 1,
|
|
|
+ abstentions: 0,
|
|
|
+ approvals: approvals,
|
|
|
+ rejections: rejections,
|
|
|
+ slashes: 0,
|
|
|
+ status: Approved,
|
|
|
+ finalized_at: 2
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
// Check that proposer's stake has been added back to his balance:
|
|
|
assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
|
|
@@ -1176,9 +1253,16 @@ mod tests {
|
|
|
// Only quorum of councilors approved, other councilors didn't vote:
|
|
|
let approvals = Proposals::approval_quorum_seats();
|
|
|
for i in 0..approvals as usize {
|
|
|
- let vote = if (i as u32) < approvals { Approve } else { Slash };
|
|
|
+ let vote = if (i as u32) < approvals {
|
|
|
+ Approve
|
|
|
+ } else {
|
|
|
+ Slash
|
|
|
+ };
|
|
|
assert_ok!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(ALL_COUNCILORS[i]), 1, vote));
|
|
|
+ Origin::signed(ALL_COUNCILORS[i]),
|
|
|
+ 1,
|
|
|
+ vote
|
|
|
+ ));
|
|
|
}
|
|
|
assert_eq!(Proposals::votes_by_proposal(1).len() as u32, approvals);
|
|
|
|
|
@@ -1200,15 +1284,18 @@ mod tests {
|
|
|
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
|
assert_eq!(Proposals::proposals(1).status, Approved);
|
|
|
- assert_eq!(Proposals::tally_results(1), TallyResult {
|
|
|
- proposal_id: 1,
|
|
|
- abstentions: 0,
|
|
|
- approvals: approvals,
|
|
|
- rejections: 0,
|
|
|
- slashes: 0,
|
|
|
- status: Approved,
|
|
|
- finalized_at: expiration_block
|
|
|
- });
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::tally_results(1),
|
|
|
+ TallyResult {
|
|
|
+ proposal_id: 1,
|
|
|
+ abstentions: 0,
|
|
|
+ approvals: approvals,
|
|
|
+ rejections: 0,
|
|
|
+ slashes: 0,
|
|
|
+ status: Approved,
|
|
|
+ finalized_at: expiration_block
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
// Check that proposer's stake has been added back to his balance:
|
|
|
assert_eq!(Balances::free_balance(PROPOSER1), initial_balance());
|
|
@@ -1231,9 +1318,16 @@ mod tests {
|
|
|
let approvals = Proposals::approval_quorum_seats() - 1;
|
|
|
let abstentions = councilors - approvals;
|
|
|
for i in 0..councilors as usize {
|
|
|
- let vote = if (i as u32) < approvals { Approve } else { Abstain };
|
|
|
+ let vote = if (i as u32) < approvals {
|
|
|
+ Approve
|
|
|
+ } else {
|
|
|
+ Abstain
|
|
|
+ };
|
|
|
assert_ok!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(ALL_COUNCILORS[i]), 1, vote));
|
|
|
+ Origin::signed(ALL_COUNCILORS[i]),
|
|
|
+ 1,
|
|
|
+ vote
|
|
|
+ ));
|
|
|
}
|
|
|
assert_eq!(Proposals::votes_by_proposal(1).len() as u32, councilors);
|
|
|
|
|
@@ -1247,18 +1341,24 @@ mod tests {
|
|
|
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
|
assert_eq!(Proposals::proposals(1).status, Rejected);
|
|
|
- assert_eq!(Proposals::tally_results(1), TallyResult {
|
|
|
- proposal_id: 1,
|
|
|
- abstentions: abstentions,
|
|
|
- approvals: approvals,
|
|
|
- rejections: 0,
|
|
|
- slashes: 0,
|
|
|
- status: Rejected,
|
|
|
- finalized_at: 2
|
|
|
- });
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::tally_results(1),
|
|
|
+ TallyResult {
|
|
|
+ proposal_id: 1,
|
|
|
+ abstentions: abstentions,
|
|
|
+ approvals: approvals,
|
|
|
+ rejections: 0,
|
|
|
+ slashes: 0,
|
|
|
+ status: Rejected,
|
|
|
+ finalized_at: 2
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
// Check that proposer's balance reduced by burnt stake:
|
|
|
- assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - rejection_fee());
|
|
|
+ assert_eq!(
|
|
|
+ Balances::free_balance(PROPOSER1),
|
|
|
+ initial_balance() - rejection_fee()
|
|
|
+ );
|
|
|
assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
|
|
|
|
|
|
// TODO expect event ProposalStatusUpdated(1, Rejected)
|
|
@@ -1277,8 +1377,15 @@ mod tests {
|
|
|
let mut expected_votes: Vec<(u64, VoteKind)> = vec![];
|
|
|
for &councilor in ALL_COUNCILORS.iter() {
|
|
|
expected_votes.push((councilor, Reject));
|
|
|
- assert_ok!(Proposals::vote_on_proposal(Origin::signed(councilor), 1, Reject));
|
|
|
- assert_eq!(Proposals::vote_by_account_and_proposal((councilor, 1)), Reject);
|
|
|
+ assert_ok!(Proposals::vote_on_proposal(
|
|
|
+ Origin::signed(councilor),
|
|
|
+ 1,
|
|
|
+ Reject
|
|
|
+ ));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_by_account_and_proposal((councilor, 1)),
|
|
|
+ Reject
|
|
|
+ );
|
|
|
}
|
|
|
assert_eq!(Proposals::votes_by_proposal(1), expected_votes);
|
|
|
|
|
@@ -1292,18 +1399,24 @@ mod tests {
|
|
|
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
|
assert_eq!(Proposals::proposals(1).status, Rejected);
|
|
|
- assert_eq!(Proposals::tally_results(1), TallyResult {
|
|
|
- proposal_id: 1,
|
|
|
- abstentions: 0,
|
|
|
- approvals: 0,
|
|
|
- rejections: ALL_COUNCILORS.len() as u32,
|
|
|
- slashes: 0,
|
|
|
- status: Rejected,
|
|
|
- finalized_at: 2
|
|
|
- });
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::tally_results(1),
|
|
|
+ TallyResult {
|
|
|
+ proposal_id: 1,
|
|
|
+ abstentions: 0,
|
|
|
+ approvals: 0,
|
|
|
+ rejections: ALL_COUNCILORS.len() as u32,
|
|
|
+ slashes: 0,
|
|
|
+ status: Rejected,
|
|
|
+ finalized_at: 2
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
// Check that proposer's balance reduced by burnt stake:
|
|
|
- assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - rejection_fee());
|
|
|
+ assert_eq!(
|
|
|
+ Balances::free_balance(PROPOSER1),
|
|
|
+ initial_balance() - rejection_fee()
|
|
|
+ );
|
|
|
assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
|
|
|
|
|
|
// TODO expect event ProposalStatusUpdated(1, Rejected)
|
|
@@ -1322,8 +1435,15 @@ mod tests {
|
|
|
let mut expected_votes: Vec<(u64, VoteKind)> = vec![];
|
|
|
for &councilor in ALL_COUNCILORS.iter() {
|
|
|
expected_votes.push((councilor, Slash));
|
|
|
- assert_ok!(Proposals::vote_on_proposal(Origin::signed(councilor), 1, Slash));
|
|
|
- assert_eq!(Proposals::vote_by_account_and_proposal((councilor, 1)), Slash);
|
|
|
+ assert_ok!(Proposals::vote_on_proposal(
|
|
|
+ Origin::signed(councilor),
|
|
|
+ 1,
|
|
|
+ Slash
|
|
|
+ ));
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::vote_by_account_and_proposal((councilor, 1)),
|
|
|
+ Slash
|
|
|
+ );
|
|
|
}
|
|
|
assert_eq!(Proposals::votes_by_proposal(1), expected_votes);
|
|
|
|
|
@@ -1337,18 +1457,24 @@ mod tests {
|
|
|
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
|
assert_eq!(Proposals::proposals(1).status, Slashed);
|
|
|
- assert_eq!(Proposals::tally_results(1), TallyResult {
|
|
|
- proposal_id: 1,
|
|
|
- abstentions: 0,
|
|
|
- approvals: 0,
|
|
|
- rejections: 0,
|
|
|
- slashes: ALL_COUNCILORS.len() as u32,
|
|
|
- status: Slashed,
|
|
|
- finalized_at: 2
|
|
|
- });
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::tally_results(1),
|
|
|
+ TallyResult {
|
|
|
+ proposal_id: 1,
|
|
|
+ abstentions: 0,
|
|
|
+ approvals: 0,
|
|
|
+ rejections: 0,
|
|
|
+ slashes: ALL_COUNCILORS.len() as u32,
|
|
|
+ status: Slashed,
|
|
|
+ finalized_at: 2
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
// Check that proposer's balance reduced by burnt stake:
|
|
|
- assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - min_stake());
|
|
|
+ assert_eq!(
|
|
|
+ Balances::free_balance(PROPOSER1),
|
|
|
+ initial_balance() - min_stake()
|
|
|
+ );
|
|
|
assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
|
|
|
|
|
|
// TODO expect event ProposalStatusUpdated(1, Slashed)
|
|
@@ -1375,9 +1501,16 @@ mod tests {
|
|
|
// Less than a quorum of councilors approved:
|
|
|
let approvals = Proposals::approval_quorum_seats() - 1;
|
|
|
for i in 0..approvals as usize {
|
|
|
- let vote = if (i as u32) < approvals { Approve } else { Slash };
|
|
|
+ let vote = if (i as u32) < approvals {
|
|
|
+ Approve
|
|
|
+ } else {
|
|
|
+ Slash
|
|
|
+ };
|
|
|
assert_ok!(Proposals::vote_on_proposal(
|
|
|
- Origin::signed(ALL_COUNCILORS[i]), 1, vote));
|
|
|
+ Origin::signed(ALL_COUNCILORS[i]),
|
|
|
+ 1,
|
|
|
+ vote
|
|
|
+ ));
|
|
|
}
|
|
|
assert_eq!(Proposals::votes_by_proposal(1).len() as u32, approvals);
|
|
|
|
|
@@ -1392,18 +1525,24 @@ mod tests {
|
|
|
|
|
|
assert!(Proposals::active_proposal_ids().is_empty());
|
|
|
assert_eq!(Proposals::proposals(1).status, Expired);
|
|
|
- assert_eq!(Proposals::tally_results(1), TallyResult {
|
|
|
- proposal_id: 1,
|
|
|
- abstentions: 0,
|
|
|
- approvals: approvals,
|
|
|
- rejections: 0,
|
|
|
- slashes: 0,
|
|
|
- status: Expired,
|
|
|
- finalized_at: expiration_block
|
|
|
- });
|
|
|
+ assert_eq!(
|
|
|
+ Proposals::tally_results(1),
|
|
|
+ TallyResult {
|
|
|
+ proposal_id: 1,
|
|
|
+ abstentions: 0,
|
|
|
+ approvals: approvals,
|
|
|
+ rejections: 0,
|
|
|
+ slashes: 0,
|
|
|
+ status: Expired,
|
|
|
+ finalized_at: expiration_block
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
// Check that proposer's balance reduced by burnt stake:
|
|
|
- assert_eq!(Balances::free_balance(PROPOSER1), initial_balance() - rejection_fee());
|
|
|
+ assert_eq!(
|
|
|
+ Balances::free_balance(PROPOSER1),
|
|
|
+ initial_balance() - rejection_fee()
|
|
|
+ );
|
|
|
assert_eq!(Balances::reserved_balance(PROPOSER1), 0);
|
|
|
|
|
|
// TODO expect event ProposalStatusUpdated(1, Rejected)
|