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

Commit

Permalink
pallet-aura: Allow multiple blocks per slot
Browse files Browse the repository at this point in the history
  • Loading branch information
rphmeier committed Apr 26, 2023
1 parent 943c520 commit 9ad2437
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 2 deletions.
23 changes: 22 additions & 1 deletion frame/aura/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,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 AllowMultipleBlocksPerSlot::<T>::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 Expand Up @@ -128,6 +133,22 @@ pub mod pallet {
#[pallet::getter(fn current_slot)]
pub(super) type CurrentSlot<T: Config> = StorageValue<_, Slot, ValueQuery>;

/// Whether to allow 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.
#[pallet::storage]
#[pallet::getter(fn allow_multiple_blocks)]
pub(super) type AllowMultipleBlocksPerSlot<T: Config> = StorageValue<_, bool, ValueQuery>;

#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
pub authorities: Vec<T::AuthorityId>,
Expand Down
65 changes: 64 additions & 1 deletion frame/aura/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#![cfg(test)]

use crate::mock::{new_test_ext, Aura, MockDisabledValidators, System};
use crate::mock::{new_test_ext, Aura, MockDisabledValidators, System, Test};
use codec::Encode;
use frame_support::traits::OnInitialize;
use sp_consensus_aura::{Slot, AURA_ENGINE_ID};
Expand Down Expand Up @@ -54,3 +54,66 @@ 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(|| {
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::AllowMultipleBlocksPerSlot::<Test>::put(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::AllowMultipleBlocksPerSlot::<Test>::put(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);
});
}

0 comments on commit 9ad2437

Please sign in to comment.