mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 21:27:57 +00:00
Ensure referenda TracksInfo is sorted (#3325)
Changes: - Add `integrity_check` to trait `TracksInfo` to assert the sorting - Use the check in `integrity_test` - Rely upon sorted property in the `info` for speedup Note that the pallet already relies upon this (so far) untested assumption [here](https://github.com/paritytech/polkadot-sdk/blob/44c7a5eb8c375d77f685abf585961421e5f8b228/substrate/frame/referenda/src/lib.rs#L1280). --------- Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
committed by
GitHub
parent
de73dd9ac5
commit
8dc910c8a1
@@ -433,6 +433,11 @@ pub mod pallet {
|
||||
Self::do_try_state()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
fn integrity_test() {
|
||||
T::Tracks::check_integrity().expect("Static tracks configuration is valid.");
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::call]
|
||||
|
||||
@@ -144,7 +144,10 @@ pub trait TracksInfo<Balance, Moment> {
|
||||
/// The origin type from which a track is implied.
|
||||
type RuntimeOrigin;
|
||||
|
||||
/// Return the array of known tracks and their information.
|
||||
/// Sorted array of known tracks and their information.
|
||||
///
|
||||
/// The array MUST be sorted by `Id`. Consumers of this trait are advised to assert
|
||||
/// [`Self::check_integrity`] prior to any use.
|
||||
fn tracks() -> &'static [(Self::Id, TrackInfo<Balance, Moment>)];
|
||||
|
||||
/// Determine the voting track for the given `origin`.
|
||||
@@ -152,7 +155,23 @@ pub trait TracksInfo<Balance, Moment> {
|
||||
|
||||
/// Return the track info for track `id`, by default this just looks it up in `Self::tracks()`.
|
||||
fn info(id: Self::Id) -> Option<&'static TrackInfo<Balance, Moment>> {
|
||||
Self::tracks().iter().find(|x| x.0 == id).map(|x| &x.1)
|
||||
let tracks = Self::tracks();
|
||||
let maybe_index = tracks.binary_search_by_key(&id, |t| t.0).ok()?;
|
||||
|
||||
tracks.get(maybe_index).map(|(_, info)| info)
|
||||
}
|
||||
|
||||
/// Check assumptions about the static data that this trait provides.
|
||||
fn check_integrity() -> Result<(), &'static str>
|
||||
where
|
||||
Balance: 'static,
|
||||
Moment: 'static,
|
||||
{
|
||||
if Self::tracks().windows(2).all(|w| w[0].0 < w[1].0) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("The tracks that were returned by `tracks` were not sorted by `Id`")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -670,4 +689,72 @@ mod tests {
|
||||
assert_eq!(c.delay(pc(30).less_epsilon()), pc(100));
|
||||
assert_eq!(c.delay(pc(0)), pc(100));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tracks_integrity_check_detects_unsorted() {
|
||||
use crate::mock::RuntimeOrigin;
|
||||
|
||||
pub struct BadTracksInfo;
|
||||
impl TracksInfo<u64, u64> for BadTracksInfo {
|
||||
type Id = u8;
|
||||
type RuntimeOrigin = <RuntimeOrigin as OriginTrait>::PalletsOrigin;
|
||||
fn tracks() -> &'static [(Self::Id, TrackInfo<u64, u64>)] {
|
||||
static DATA: [(u8, TrackInfo<u64, u64>); 2] = [
|
||||
(
|
||||
1u8,
|
||||
TrackInfo {
|
||||
name: "root",
|
||||
max_deciding: 1,
|
||||
decision_deposit: 10,
|
||||
prepare_period: 4,
|
||||
decision_period: 4,
|
||||
confirm_period: 2,
|
||||
min_enactment_period: 4,
|
||||
min_approval: Curve::LinearDecreasing {
|
||||
length: Perbill::from_percent(100),
|
||||
floor: Perbill::from_percent(50),
|
||||
ceil: Perbill::from_percent(100),
|
||||
},
|
||||
min_support: Curve::LinearDecreasing {
|
||||
length: Perbill::from_percent(100),
|
||||
floor: Perbill::from_percent(0),
|
||||
ceil: Perbill::from_percent(100),
|
||||
},
|
||||
},
|
||||
),
|
||||
(
|
||||
0u8,
|
||||
TrackInfo {
|
||||
name: "none",
|
||||
max_deciding: 3,
|
||||
decision_deposit: 1,
|
||||
prepare_period: 2,
|
||||
decision_period: 2,
|
||||
confirm_period: 1,
|
||||
min_enactment_period: 2,
|
||||
min_approval: Curve::LinearDecreasing {
|
||||
length: Perbill::from_percent(100),
|
||||
floor: Perbill::from_percent(95),
|
||||
ceil: Perbill::from_percent(100),
|
||||
},
|
||||
min_support: Curve::LinearDecreasing {
|
||||
length: Perbill::from_percent(100),
|
||||
floor: Perbill::from_percent(90),
|
||||
ceil: Perbill::from_percent(100),
|
||||
},
|
||||
},
|
||||
),
|
||||
];
|
||||
&DATA[..]
|
||||
}
|
||||
fn track_for(_: &Self::RuntimeOrigin) -> Result<Self::Id, ()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
BadTracksInfo::check_integrity(),
|
||||
Err("The tracks that were returned by `tracks` were not sorted by `Id`")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user