mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-17 15:55:42 +00:00
Council events (#703)
* Initial bits * More stuff * Cleave voting from council * More events * Rearrange council a little * Fix demo * More info in events
This commit is contained in:
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -65,8 +65,8 @@ build_rpc_trait! {
|
||||
fn storage_size(&self, StorageKey, Trailing<Hash>) -> Result<Option<u64>>;
|
||||
|
||||
/// Returns the runtime metadata as JSON.
|
||||
#[rpc(name = "state_metadata", alias = ["state_metadataAt", ])]
|
||||
fn json_metadata(&self, Trailing<Hash>) -> Result<serde_json::Value>;
|
||||
#[rpc(name = "state_getMetadata")]
|
||||
fn metadata(&self, Trailing<Hash>) -> Result<serde_json::Value>;
|
||||
|
||||
/// Query historical storage entries (by key) starting from a block given as the second parameter.
|
||||
///
|
||||
@@ -143,7 +143,7 @@ impl<B, E, Block> StateApi<Block::Hash> for State<B, E, Block> where
|
||||
Ok(self.storage(key, block)?.map(|x| x.0.len() as u64))
|
||||
}
|
||||
|
||||
fn json_metadata(&self, block: Trailing<Block::Hash>) -> Result<serde_json::Value> {
|
||||
fn metadata(&self, block: Trailing<Block::Hash>) -> Result<serde_json::Value> {
|
||||
let block = self.unwrap_or_best(block)?;
|
||||
let metadata = self.client.json_metadata(&BlockId::Hash(block))?;
|
||||
serde_json::from_str(&metadata).map_err(Into::into)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@
|
||||
use rstd::prelude::*;
|
||||
use rstd::result;
|
||||
use substrate_primitives::u32_trait::Value as U32;
|
||||
use primitives::traits::{Hash, EnsureOrigin, MaybeSerializeDebug};
|
||||
use primitives::traits::{Hash, EnsureOrigin, MaybeSerializeDebug, OnFinalise};
|
||||
use substrate_runtime_support::dispatch::{Result, Dispatchable, Parameter};
|
||||
use substrate_runtime_support::{StorageValue, StorageMap};
|
||||
use super::{Trait as CouncilTrait, Module as Council};
|
||||
@@ -167,7 +167,7 @@ impl<T: Trait> Module<T> {
|
||||
let threshold = voting.1;
|
||||
let potential_votes = <Council<T>>::active_council().len() as u32;
|
||||
let approved = yes_votes >= threshold;
|
||||
let disapproved = potential_votes - no_votes < threshold;
|
||||
let disapproved = potential_votes.saturating_sub(no_votes) < threshold;
|
||||
if approved || disapproved {
|
||||
if approved {
|
||||
Self::deposit_event(RawEvent::Approved(proposal));
|
||||
@@ -194,6 +194,11 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
fn on_finalise(_n: T::BlockNumber) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure that the origin `o` represents at least `n` council members. Returns
|
||||
/// `Ok` or an `Err` otherwise.
|
||||
pub fn ensure_council_members<OuterOrigin>(o: OuterOrigin, n: u32) -> result::Result<u32, &'static str>
|
||||
@@ -218,13 +223,12 @@ impl<O, N: U32> EnsureOrigin<O> for EnsureMembers<N>
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::RawEvent;
|
||||
use ::tests::*;
|
||||
use ::tests::{Call, Origin, Event as OuterEvent};
|
||||
use substrate_runtime_support::Hashable;
|
||||
use system::{EventRecord, Phase};
|
||||
|
||||
type CouncilMotions = super::Module<Test>;
|
||||
|
||||
#[test]
|
||||
fn motions_basic_environment_works() {
|
||||
with_externalities(&mut new_test_ext(true), || {
|
||||
@@ -252,7 +256,7 @@ mod tests {
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Proposed(1, 0, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), 3))
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), 3))
|
||||
}
|
||||
]);
|
||||
});
|
||||
@@ -305,11 +309,11 @@ mod tests {
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Proposed(1, 0, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), 2))
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), 2))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Voted(1, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), false, 0, 1))
|
||||
event: OuterEvent::motions(RawEvent::Voted(1, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), false, 0, 1))
|
||||
}
|
||||
]);
|
||||
});
|
||||
@@ -327,15 +331,15 @@ mod tests {
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Proposed(1, 0, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), 3))
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), 3))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Voted(2, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), false, 1, 1))
|
||||
event: OuterEvent::motions(RawEvent::Voted(2, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), false, 1, 1))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Disapproved(hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into()))
|
||||
event: OuterEvent::motions(RawEvent::Disapproved(hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into()))
|
||||
}
|
||||
]);
|
||||
});
|
||||
@@ -353,19 +357,19 @@ mod tests {
|
||||
assert_eq!(System::events(), vec![
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Proposed(1, 0, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), 2))
|
||||
event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), 2))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Voted(2, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), true, 2, 0))
|
||||
event: OuterEvent::motions(RawEvent::Voted(2, hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), true, 2, 0))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Approved(hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into()))
|
||||
event: OuterEvent::motions(RawEvent::Approved(hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into()))
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::ApplyExtrinsic(0),
|
||||
event: OuterEvent::council_motions(RawEvent::Executed(hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), false))
|
||||
event: OuterEvent::motions(RawEvent::Executed(hex!["a900ca23832b1f42a5d4af5d0ece88da63fbb4049cc00bac3f741eabb5a79c45"].into(), false))
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,9 +23,13 @@ use runtime_io::print;
|
||||
use substrate_runtime_support::dispatch::Result;
|
||||
use substrate_runtime_support::{StorageValue, StorageMap, IsSubType};
|
||||
use {system, democracy};
|
||||
use super::{Trait, Module as Council};
|
||||
use super::{Trait as CouncilTrait, Module as Council};
|
||||
use system::{ensure_signed, ensure_root};
|
||||
|
||||
pub trait Trait: CouncilTrait {
|
||||
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
|
||||
fn propose(origin, proposal: Box<T::Proposal>) -> Result;
|
||||
@@ -49,7 +53,29 @@ decl_storage! {
|
||||
}
|
||||
}
|
||||
|
||||
pub type Event<T> = RawEvent<<T as system::Trait>::Hash>;
|
||||
|
||||
/// An event in this module.
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
|
||||
pub enum RawEvent<Hash> {
|
||||
/// A voting tally has happened for a referendum cancelation vote. Last three are yes, no, abstain counts.
|
||||
TallyCancelation(Hash, u32, u32, u32),
|
||||
/// A voting tally has happened for a referendum vote. Last three are yes, no, abstain counts.
|
||||
TallyReferendum(Hash, u32, u32, u32),
|
||||
}
|
||||
|
||||
impl<N> From<RawEvent<N>> for () {
|
||||
fn from(_: RawEvent<N>) -> () { () }
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
|
||||
/// Deposit one of this module's events.
|
||||
fn deposit_event(event: Event<T>) {
|
||||
<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
|
||||
}
|
||||
|
||||
pub fn is_vetoed<B: Borrow<T::Hash>>(proposal: B) -> bool {
|
||||
Self::veto_of(proposal.borrow())
|
||||
.map(|(expiry, _): (T::BlockNumber, Vec<T::AccountId>)| <system::Module<T>>::block_number() < expiry)
|
||||
@@ -91,7 +117,8 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
<ProposalOf<T>>::insert(proposal_hash, *proposal);
|
||||
<ProposalVoters<T>>::insert(proposal_hash, vec![who.clone()]);
|
||||
<CouncilVoteOf<T>>::insert((proposal_hash, who), true);
|
||||
<CouncilVoteOf<T>>::insert((proposal_hash, who.clone()), true);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -101,9 +128,7 @@ impl<T: Trait> Module<T> {
|
||||
ensure!(Self::is_councillor(&who), "only councillors may vote on council proposals");
|
||||
|
||||
if Self::vote_of((proposal, who.clone())).is_none() {
|
||||
let mut voters = Self::proposal_voters(&proposal);
|
||||
voters.push(who.clone());
|
||||
<ProposalVoters<T>>::insert(proposal, voters);
|
||||
<ProposalVoters<T>>::mutate(proposal, |voters| voters.push(who.clone()));
|
||||
}
|
||||
<CouncilVoteOf<T>>::insert((proposal, who), approve);
|
||||
Ok(())
|
||||
@@ -188,10 +213,12 @@ impl<T: Trait> Module<T> {
|
||||
while let Some((proposal, proposal_hash)) = Self::take_proposal_if_expiring_at(now) {
|
||||
let tally = Self::take_tally(&proposal_hash);
|
||||
if let Some(&democracy::Call::cancel_referendum(ref_index)) = IsSubType::<democracy::Module<T>>::is_aux_sub_type(&proposal) {
|
||||
Self::deposit_event(RawEvent::TallyCancelation(proposal_hash, tally.0, tally.1, tally.2));
|
||||
if let (_, 0, 0) = tally {
|
||||
<democracy::Module<T>>::internal_cancel_referendum(ref_index);
|
||||
}
|
||||
} else {
|
||||
Self::deposit_event(RawEvent::TallyReferendum(proposal_hash.clone(), tally.0, tally.1, tally.2));
|
||||
if tally.0 > tally.1 + tally.2 {
|
||||
Self::kill_veto_of(&proposal_hash);
|
||||
match tally {
|
||||
@@ -205,16 +232,12 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> OnFinalise<T::BlockNumber> for Council<T> {
|
||||
impl<T: Trait> OnFinalise<T::BlockNumber> for Module<T> {
|
||||
fn on_finalise(n: T::BlockNumber) {
|
||||
if let Err(e) = Self::end_block(n) {
|
||||
print("Guru meditation");
|
||||
print(e);
|
||||
}
|
||||
if let Err(e) = <Module<T>>::end_block(n) {
|
||||
print("Guru meditation");
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,8 +249,6 @@ mod tests {
|
||||
use substrate_runtime_support::Hashable;
|
||||
use democracy::VoteThreshold;
|
||||
|
||||
type CouncilVoting = super::Module<Test>;
|
||||
|
||||
#[test]
|
||||
fn basic_environment_works() {
|
||||
with_externalities(&mut new_test_ext(true), || {
|
||||
|
||||
@@ -185,13 +185,33 @@ pub trait OnFinalise<BlockNumber> {
|
||||
}
|
||||
|
||||
impl<N> OnFinalise<N> for () {}
|
||||
impl<N: Copy, A: OnFinalise<N>, B: OnFinalise<N>> OnFinalise<N> for (A, B) {
|
||||
fn on_finalise(n: N) {
|
||||
A::on_finalise(n);
|
||||
B::on_finalise(n);
|
||||
|
||||
macro_rules! tuple_impl {
|
||||
($one:ident,) => {
|
||||
impl<Number: Copy, $one: OnFinalise<Number>> OnFinalise<Number> for ($one,) {
|
||||
fn on_finalise(n: Number) {
|
||||
$one::on_finalise(n);
|
||||
}
|
||||
}
|
||||
};
|
||||
($first:ident, $($rest:ident,)+) => {
|
||||
impl<
|
||||
Number: Copy,
|
||||
$first: OnFinalise<Number>,
|
||||
$($rest: OnFinalise<Number>),+
|
||||
> OnFinalise<Number> for ($first, $($rest),+) {
|
||||
fn on_finalise(n: Number) {
|
||||
$first::on_finalise(n);
|
||||
$($rest::on_finalise(n);)+
|
||||
}
|
||||
}
|
||||
tuple_impl!($($rest,)+);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,);
|
||||
|
||||
/// Abstraction around hashing
|
||||
pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived
|
||||
// traits must be fulfilled by all type parameters.
|
||||
|
||||
@@ -122,6 +122,12 @@ decl_storage! {
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
|
||||
/// Deposit one of this module's events.
|
||||
fn deposit_event(event: Event<T>) {
|
||||
<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
|
||||
}
|
||||
|
||||
/// The number of validators currently.
|
||||
pub fn validator_count() -> u32 {
|
||||
<Validators<T>>::get().len() as u32 // TODO: can probably optimised
|
||||
@@ -186,11 +192,6 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Deposit one of this module's events.
|
||||
fn deposit_event(event: Event<T>) {
|
||||
<system::Module<T>>::deposit_event(<T as Trait>::Event::from(event).into());
|
||||
}
|
||||
|
||||
/// Move onto next session: register the new authority set.
|
||||
pub fn rotate_session(is_final_block: bool, apply_rewards: bool) {
|
||||
let now = <timestamp::Module<T>>::get();
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user