Skip to content

Commit

Permalink
change: Append block producer to log on block finalization
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolaos Dymitriadis <[email protected]>
  • Loading branch information
AmbientTea committed Feb 25, 2025
1 parent b299346 commit 2728c5b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
30 changes: 28 additions & 2 deletions toolkit/pallets/block-production-log/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub mod pallet {
#[pallet::unbounded]
pub type Log<T: Config> = StorageValue<_, Vec<(Slot, T::BlockProducerId)>, ValueQuery>;

/// Temporary storage of the current block's producer, to be appended to the log on block finalization.
#[pallet::storage]
pub type CurrentProducer<T: Config> = StorageValue<_, T::BlockProducerId, OptionQuery>;

/// This storage is used to prevent calling `append` multiple times for the same block or for past blocks.
#[pallet::storage]
pub type LatestBlock<T: Config> = StorageValue<_, BlockNumberFor<T>, OptionQuery>;
Expand Down Expand Up @@ -70,7 +74,7 @@ pub mod pallet {

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Appends an entry to the log. Log has to be ordered by slots and writing the same slot twice is forbidden.
/// Schedules an entry to be appended to the log. Log has to be ordered by slots and writing the same slot twice is forbidden.
#[pallet::call_index(0)]
#[pallet::weight((T::WeightInfo::append(), DispatchClass::Mandatory))]
pub fn append(
Expand All @@ -86,7 +90,19 @@ pub mod pallet {
}?;
LatestBlock::<T>::put(current_block);

Ok(Log::<T>::append((T::current_slot(), block_producer_id)))
Ok(CurrentProducer::<T>::put(block_producer_id))
}
}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_finalize(block: BlockNumberFor<T>) {
let block_producer_id =
CurrentProducer::<T>::take().expect("Author is set before on_finalize; qed");

log::info!("👷 Block {block:?} producer is {block_producer_id:?}");

Log::<T>::append((T::current_slot(), block_producer_id))
}
}

Expand All @@ -96,5 +112,15 @@ pub mod pallet {
Log::<T>::put(to_retain);
to_return
}

pub fn peek_prefix<'a>(slot: Slot) -> impl Iterator<Item = (Slot, T::BlockProducerId)> {
Log::<T>::get().into_iter().filter(move |(s, _)| s <= &slot)
}

pub fn drop_prefix<'a>(slot: Slot) {
let entries_left: Vec<_> =
Log::<T>::get().into_iter().filter(move |(s, _)| s > &slot).collect();
Log::<T>::put(entries_left);
}
}
}
16 changes: 15 additions & 1 deletion toolkit/pallets/block-production-log/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use super::*;
use frame_support::{assert_err, assert_ok, traits::UnfilteredDispatchable};
use frame_support::{
assert_err, assert_ok,
traits::{Hooks, UnfilteredDispatchable},
};
use mock::*;
use sp_consensus_slots::Slot;

Expand All @@ -15,6 +18,13 @@ fn first_append_should_succeed() {
let call = Call::<Test>::append { block_producer_id: make_id(1) };
assert_ok!(call.dispatch_bypass_filter(RuntimeOrigin::none()));

assert_eq!(CurrentProducer::<Test>::get(), Some(make_id(1)));

// Log should not be appended to until block finalization
assert!(Log::<Test>::get().is_empty());

Pallet::<Test>::on_finalize(System::block_number());

assert_eq!(Log::<Test>::get().to_vec(), vec![(Slot::from(1001000), make_id(1))]);
})
}
Expand All @@ -29,6 +39,10 @@ fn append_to_end_of_log() {
let call = Call::<Test>::append { block_producer_id: make_id(2) };
assert_ok!(call.dispatch_bypass_filter(RuntimeOrigin::none()));
assert_eq!(LatestBlock::<Test>::get(), Some(1001));
assert_eq!(CurrentProducer::<Test>::get(), Some(make_id(2)));

Pallet::<Test>::on_finalize(System::block_number());

assert_eq!(
Log::<Test>::get().to_vec(),
vec![(Slot::from(100), make_id(1)), (Slot::from(1001000), make_id(2))]
Expand Down

0 comments on commit 2728c5b

Please sign in to comment.