Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 32 additions & 2 deletions pallets/async-backing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ mod tests;

pub use pallet::*;

use frame_support::pallet_prelude::*;
use frame_support::{pallet_prelude::*, traits::OnTimestampSet};
use sp_consensus_slots::{Slot, SlotDuration};
use sp_runtime::SaturatedConversion;

/// The InherentIdentifier for nimbus's extension inherent
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"nimb-ext";
Expand Down Expand Up @@ -98,7 +99,7 @@ pub mod pallet {
/// Purely informative, but used by mocking tools like chospticks to allow knowing how to mock
/// blocks
#[pallet::constant]
type ExpectedBlockTime: Get<Self::Moment>;
type SlotDuration: Get<Self::Moment>;
}

/// First tuple element is the highest slot that has been seen in the history of this chain.
Expand All @@ -107,4 +108,33 @@ pub mod pallet {
#[pallet::storage]
#[pallet::getter(fn slot_info)]
pub type SlotInfo<T: Config> = StorageValue<_, (Slot, u32), OptionQuery>;

impl<T: Config> Pallet<T> {
/// Determine the slot-duration based on the Timestamp module configuration.
pub fn slot_duration() -> T::Moment {
T::SlotDuration::get()
}
}
}

impl<T: Config> OnTimestampSet<T::Moment> for Pallet<T> {
fn on_timestamp_set(moment: T::Moment) {
let slot_duration = Self::slot_duration();
assert!(!slot_duration.is_zero(), "Slot duration cannot be zero.");

let timestamp_slot = moment / slot_duration;
let timestamp_slot = Slot::from(timestamp_slot.saturated_into::<u64>());

let Some((current_slot, _)) = SlotInfo::<T>::get() else {
unreachable!("`SlotInfo` should exist at this point; qed");
};

assert_eq!(
current_slot,
timestamp_slot,
"`timestamp_slot` must match `current_slot`. This likely means that the configured block \
time in the node and/or rest of the runtime is not compatible with Nimbus's Async backing \
`SlotDuration`",
);
}
}
2 changes: 1 addition & 1 deletion pallets/async-backing/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ parameter_types! {
impl async_backing::Config for Test {
type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot;
type GetAndVerifySlot = RelaySlot;
type ExpectedBlockTime = ConstU64<1>;
type SlotDuration = ConstU64<1>;
}

/// Build genesis storage according to the mock runtime.
Expand Down
6 changes: 3 additions & 3 deletions template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ parameter_types! {
impl pallet_timestamp::Config for Runtime {
/// A timestamp: milliseconds since the unix epoch.
type Moment = u64;
type OnTimestampSet = ();
type OnTimestampSet = NimbusAsyncBacking;
type MinimumPeriod = MinimumPeriod;
type WeightInfo = ();
}
Expand Down Expand Up @@ -667,13 +667,13 @@ impl pallet_author_slot_filter::Config for Runtime {
}

parameter_types! {
pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK;
pub const SlotDuration: u64 = MILLISECS_PER_BLOCK;
}

impl pallet_async_backing::Config for Runtime {
type AllowMultipleBlocksPerSlot = ConstBool<false>;
type GetAndVerifySlot = pallet_async_backing::RelaySlot;
type ExpectedBlockTime = ExpectedBlockTime;
type SlotDuration = SlotDuration;
}

parameter_types! {
Expand Down