Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

pallet-aura: Allow multiple blocks per slot #14024

Merged
Merged
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
4 changes: 3 additions & 1 deletion bin/node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ use sp_version::RuntimeVersion;
pub use frame_support::{
construct_runtime, parameter_types,
traits::{
ConstU128, ConstU32, ConstU64, ConstU8, KeyOwnerProofSystem, Randomness, StorageInfo,
ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, KeyOwnerProofSystem, Randomness,
StorageInfo,
},
weights::{
constants::{
Expand Down Expand Up @@ -207,6 +208,7 @@ impl pallet_aura::Config for Runtime {
type AuthorityId = AuraId;
type DisabledValidators = ();
type MaxAuthorities = ConstU32<32>;
type AllowMultipleBlocksPerSlot = ConstBool<false>;
}

impl pallet_grandpa::Config for Runtime {
Expand Down
21 changes: 20 additions & 1 deletion frame/aura/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ pub mod pallet {
/// Blocks authored by a disabled validator will lead to a panic as part of this module's
/// initialization.
type DisabledValidators: DisabledValidators;

/// Whether to allow block authors to create multiple blocks per slot.
///
/// If this is `true`, the pallet will allow slots to stay the same across sequential
/// blocks. If this is `false`, the pallet will require that subsequent blocks always have
/// higher slots than previous ones.
///
/// Regardless of the setting of this storage value, the pallet will always enforce the
/// invariant that slots don't move backwards as the chain progresses.
///
/// The typical value for this should be 'false' unless this pallet is being augmented by
/// another pallet which enforces some limitation on the number of blocks authors can create
/// using the same slot.
type AllowMultipleBlocksPerSlot: Get<bool>;
}

#[pallet::pallet]
Expand All @@ -92,7 +106,12 @@ pub mod pallet {
if let Some(new_slot) = Self::current_slot_from_digests() {
let current_slot = CurrentSlot::<T>::get();

assert!(current_slot < new_slot, "Slot must increase");
if T::AllowMultipleBlocksPerSlot::get() {
assert!(current_slot <= new_slot, "Slot must not decrease");
} else {
assert!(current_slot < new_slot, "Slot must increase");
}

CurrentSlot::<T>::put(new_slot);

if let Some(n_authorities) = <Authorities<T>>::decode_len() {
Expand Down
2 changes: 2 additions & 0 deletions frame/aura/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ impl pallet_timestamp::Config for Test {

parameter_types! {
static DisabledValidatorTestValue: Vec<AuthorityIndex> = Default::default();
pub static AllowMultipleBlocksPerSlot: bool = false;
}

pub struct MockDisabledValidators;
Expand All @@ -106,6 +107,7 @@ impl pallet_aura::Config for Test {
type AuthorityId = AuthorityId;
type DisabledValidators = MockDisabledValidators;
type MaxAuthorities = ConstU32<10>;
type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot;
}

pub fn new_test_ext(authorities: Vec<u64>) -> sp_io::TestExternalities {
Expand Down
61 changes: 61 additions & 0 deletions frame/aura/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,64 @@ fn disabled_validators_cannot_author_blocks() {
Aura::on_initialize(42);
});
}

#[test]
#[should_panic(expected = "Slot must increase")]
fn pallet_requires_slot_to_increase_unless_allowed() {
new_test_ext(vec![0, 1, 2, 3]).execute_with(|| {
crate::mock::AllowMultipleBlocksPerSlot::set(false);

let slot = Slot::from(1);
let pre_digest =
Digest { logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())] };

System::reset_events();
System::initialize(&42, &System::parent_hash(), &pre_digest);

// and we should not be able to initialize the block with the same slot a second time.
Aura::on_initialize(42);
Aura::on_initialize(42);
});
}

#[test]
fn pallet_can_allow_unchanged_slot() {
new_test_ext(vec![0, 1, 2, 3]).execute_with(|| {
let slot = Slot::from(1);
let pre_digest =
Digest { logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())] };

System::reset_events();
System::initialize(&42, &System::parent_hash(), &pre_digest);

crate::mock::AllowMultipleBlocksPerSlot::set(true);

// and we should be able to initialize the block with the same slot a second time.
Aura::on_initialize(42);
Aura::on_initialize(42);
});
}

#[test]
#[should_panic(expected = "Slot must not decrease")]
fn pallet_always_rejects_decreasing_slot() {
new_test_ext(vec![0, 1, 2, 3]).execute_with(|| {
let slot = Slot::from(2);
let pre_digest =
Digest { logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())] };

System::reset_events();
System::initialize(&42, &System::parent_hash(), &pre_digest);

crate::mock::AllowMultipleBlocksPerSlot::set(true);

Aura::on_initialize(42);
System::finalize();

let earlier_slot = Slot::from(1);
let pre_digest =
Digest { logs: vec![DigestItem::PreRuntime(AURA_ENGINE_ID, earlier_slot.encode())] };
System::initialize(&43, &System::parent_hash(), &pre_digest);
Aura::on_initialize(43);
});
}