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

more clear randomness API for BABE #8180

Merged
16 commits merged into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
pallet-babe: fix randomness usage
we need to track when the current and previous epoch started so that we
know the block number by each existing on-chain was known
  • Loading branch information
andresilva committed Mar 5, 2021
commit d71b4e4928773afaf0f81e5aa9d7d6ae4057673b
13 changes: 13 additions & 0 deletions frame/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,13 @@ decl_storage! {
/// secondary plain slots are enabled (which don't contain a VRF output).
AuthorVrfRandomness get(fn author_vrf_randomness): MaybeRandomness;

/// The block numbers when the last and current epoch have started, respectively `N-1` and
/// `N`.
/// NOTE: We track this is in order to annotate the block number when a given pool of
/// entropy was fixed (i.e. it was known to chain observers). Since epochs are defined in
/// slots, which may be skipped, the block numbers may not line up with the slot numbers.
EpochStart: (T::BlockNumber, T::BlockNumber);

/// How late the current block is compared to its parent.
///
/// This entry is populated as part of block execution and is cleaned up
Expand Down Expand Up @@ -452,6 +459,12 @@ impl<T: Config> Module<T> {
// Update the next epoch authorities.
NextAuthorities::put(&next_authorities);

// Update the start blocks of the previous and new current epoch.
<EpochStart<T>>::mutate(|(previous_epoch_start_block, current_epoch_start_block)| {
*previous_epoch_start_block = sp_std::mem::take(current_epoch_start_block);
*current_epoch_start_block = <frame_system::Module<T>>::block_number();
});

// After we update the current epoch, we signal the *next* epoch change
// so that nodes can track changes.
let next_randomness = NextRandomness::get();
Expand Down
30 changes: 16 additions & 14 deletions frame/babe/src/randomness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
//! Provides multiple implementations of the randomness trait based on the on-chain epoch
//! randomness collected from VRF outputs.

use super::{AuthorVrfRandomness, Config, NextRandomness, Randomness, VRF_OUTPUT_LENGTH};
use super::{
AuthorVrfRandomness, Config, EpochStart, NextRandomness, Randomness, VRF_OUTPUT_LENGTH,
};
use frame_support::{traits::Randomness as RandomnessT, StorageValue};
use sp_runtime::traits::Hash;

Expand Down Expand Up @@ -111,36 +113,36 @@ pub struct RandomnessFromOneEpochAgo<T>(sp_std::marker::PhantomData<T>);
/// relay parent's `RandomnessFromTwoEpochsAgo`.
pub struct CurrentBlockRandomness<T>(sp_std::marker::PhantomData<T>);

impl<T: Config> RandomnessT<<T as frame_system::Config>::Hash> for RandomnessFromTwoEpochsAgo<T> {
fn random(subject: &[u8]) -> T::Hash {
impl<T: Config> RandomnessT<T::Hash, T::BlockNumber> for RandomnessFromTwoEpochsAgo<T> {
fn random(subject: &[u8]) -> (T::Hash, T::BlockNumber) {
let mut subject = subject.to_vec();
subject.reserve(VRF_OUTPUT_LENGTH);
subject.extend_from_slice(&Randomness::get()[..]);

<T as frame_system::Config>::Hashing::hash(&subject[..])
(T::Hashing::hash(&subject[..]), EpochStart::<T>::get().0)
}
}

impl<T: Config> RandomnessT<<T as frame_system::Config>::Hash> for RandomnessFromOneEpochAgo<T> {
fn random(subject: &[u8]) -> T::Hash {
impl<T: Config> RandomnessT<T::Hash, T::BlockNumber> for RandomnessFromOneEpochAgo<T> {
fn random(subject: &[u8]) -> (T::Hash, T::BlockNumber) {
let mut subject = subject.to_vec();
subject.reserve(VRF_OUTPUT_LENGTH);
subject.extend_from_slice(&NextRandomness::get()[..]);

<T as frame_system::Config>::Hashing::hash(&subject[..])
(T::Hashing::hash(&subject[..]), EpochStart::<T>::get().1)
}
}

impl<T: Config> RandomnessT<Option<<T as frame_system::Config>::Hash>>
for CurrentBlockRandomness<T>
{
fn random(subject: &[u8]) -> Option<T::Hash> {
AuthorVrfRandomness::get().map(|random| {
impl<T: Config> RandomnessT<Option<T::Hash>, T::BlockNumber> for CurrentBlockRandomness<T> {
fn random(subject: &[u8]) -> (Option<T::Hash>, T::BlockNumber) {
let random = AuthorVrfRandomness::get().map(|random| {
let mut subject = subject.to_vec();
subject.reserve(VRF_OUTPUT_LENGTH);
subject.extend_from_slice(&random);

<T as frame_system::Config>::Hashing::hash(&subject[..])
})
T::Hashing::hash(&subject[..])
});

(random, <frame_system::Module<T>>::block_number())
}
}