mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 03:27:58 +00:00
Try-state for Referenda pallet (#13949)
* Try-state for Referenda pallet * fix & more tests * checking more stuff * remove log * two more tests * Update frame/referenda/src/lib.rs Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com> * fixes * new check * merge fixes * fix warning * remove check * Update frame/referenda/src/lib.rs Co-authored-by: Gonçalo Pestana <g6pestana@gmail.com> * separate into multiple functions * clean up * unnecessary return value specified * fix * Update frame/referenda/src/lib.rs * fmt * remove import * fmt * fix CI * Update frame/referenda/src/lib.rs Co-authored-by: Liam Aharon <liam.aharon@hotmail.com> * last fixes * :P * fmt --------- Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com> Co-authored-by: Gonçalo Pestana <g6pestana@gmail.com> Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>
This commit is contained in:
@@ -66,6 +66,7 @@
|
||||
|
||||
use codec::{Codec, Encode};
|
||||
use frame_support::{
|
||||
dispatch::DispatchResult,
|
||||
ensure,
|
||||
traits::{
|
||||
schedule::{
|
||||
@@ -416,6 +417,15 @@ pub mod pallet {
|
||||
PreimageNotExist,
|
||||
}
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn try_state(_n: BlockNumberFor<T>) -> Result<(), sp_runtime::TryRuntimeError> {
|
||||
Self::do_try_state()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
/// Propose a referendum on a privileged action.
|
||||
@@ -1032,7 +1042,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
/// - If it's ready to be decided, start deciding;
|
||||
/// - If it's not ready to be decided and non-deciding timeout has passed, fail;
|
||||
/// - If it's ongoing and passing, ensure confirming; if at end of confirmation period, pass.
|
||||
/// - If it's ongoing and not passing, stop confirning; if it has reached end time, fail.
|
||||
/// - If it's ongoing and not passing, stop confirming; if it has reached end time, fail.
|
||||
///
|
||||
/// Weight will be a bit different depending on what it does, but it's designed so as not to
|
||||
/// differ dramatically, especially if `MaxQueue` is kept small. In particular _there are no
|
||||
@@ -1284,4 +1294,87 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
Self::deposit_event(Event::<T, I>::MetadataCleared { index, hash });
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure the correctness of the state of this pallet.
|
||||
///
|
||||
/// The following assertions must always apply.
|
||||
///
|
||||
/// General assertions:
|
||||
///
|
||||
/// * [`ReferendumCount`] must always be equal to the number of referenda in
|
||||
/// [`ReferendumInfoFor`].
|
||||
/// * Referendum indices in [`MetadataOf`] must also be stored in [`ReferendumInfoFor`].
|
||||
#[cfg(any(feature = "try-runtime", test))]
|
||||
fn do_try_state() -> Result<(), sp_runtime::TryRuntimeError> {
|
||||
ensure!(
|
||||
ReferendumCount::<T, I>::get() as usize ==
|
||||
ReferendumInfoFor::<T, I>::iter_keys().count(),
|
||||
"Number of referenda in `ReferendumInfoFor` is different than `ReferendumCount`"
|
||||
);
|
||||
|
||||
MetadataOf::<T, I>::iter_keys().try_for_each(|referendum_index| -> DispatchResult {
|
||||
ensure!(
|
||||
ReferendumInfoFor::<T, I>::contains_key(referendum_index),
|
||||
"Referendum indices in `MetadataOf` must also be stored in `ReferendumInfoOf`"
|
||||
);
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Self::try_state_referenda_info()?;
|
||||
Self::try_state_tracks()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Looking at referenda info:
|
||||
///
|
||||
/// - Data regarding ongoing phase:
|
||||
///
|
||||
/// * There must exist track info for the track of the referendum.
|
||||
/// * The deciding stage has to begin before confirmation period.
|
||||
/// * If alarm is set the nudge call has to be at most [`UndecidingTimeout`] blocks away
|
||||
/// from the submission block.
|
||||
#[cfg(any(feature = "try-runtime", test))]
|
||||
fn try_state_referenda_info() -> Result<(), sp_runtime::TryRuntimeError> {
|
||||
ReferendumInfoFor::<T, I>::iter().try_for_each(|(_, referendum)| {
|
||||
match referendum {
|
||||
ReferendumInfo::Ongoing(status) => {
|
||||
ensure!(
|
||||
Self::track(status.track).is_some(),
|
||||
"No track info for the track of the referendum."
|
||||
);
|
||||
|
||||
if let Some(deciding) = status.deciding {
|
||||
ensure!(
|
||||
deciding.since <
|
||||
deciding.confirming.unwrap_or(BlockNumberFor::<T>::max_value()),
|
||||
"Deciding status cannot begin before confirming stage."
|
||||
)
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
/// Looking at tracks:
|
||||
///
|
||||
/// * The referendum indices stored in [`TrackQueue`] must exist as keys in the
|
||||
/// [`ReferendumInfoFor`] storage map.
|
||||
#[cfg(any(feature = "try-runtime", test))]
|
||||
fn try_state_tracks() -> Result<(), sp_runtime::TryRuntimeError> {
|
||||
T::Tracks::tracks().iter().try_for_each(|track| {
|
||||
TrackQueue::<T, I>::get(track.0).iter().try_for_each(
|
||||
|(referendum_index, _)| -> Result<(), sp_runtime::TryRuntimeError> {
|
||||
ensure!(
|
||||
ReferendumInfoFor::<T, I>::contains_key(referendum_index),
|
||||
"`ReferendumIndex` inside the `TrackQueue` should be a key in `ReferendumInfoFor`"
|
||||
);
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user