more clear randomness API for BABE (#8180)

* more clear randomness API for BABE

* babe: move randomness utilities to its own file

* node: use babe::RandomnessFromOneEpochAgo in random_seed implementation

* frame-support: annotate randomness trait with block number

* pallet-randomness-collective-flip: fix for new randomness trait

* pallet-society: fix randomness usage

* pallet-lottery: fix randomness usage

* pallet-contracts: fix randomness usage

* 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

* node: fix random_seed

* node-template: fix random_seed

* frame-support: extend docs

* babe: add test for epoch starting block number tracking

* babe: fix epoch randomness docs

* frame: add todos for dealing with randomness api changes

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Robert Habermeier
2021-03-10 10:31:49 -06:00
committed by GitHub
parent f3d4355a20
commit e2960c383e
18 changed files with 286 additions and 78 deletions
@@ -56,7 +56,7 @@
#![cfg_attr(not(feature = "std"), no_std)]
use sp_std::{prelude::*, convert::TryInto};
use sp_runtime::traits::Hash;
use sp_runtime::traits::{Hash, Saturating};
use frame_support::{
decl_module, decl_storage, traits::Randomness,
weights::Weight
@@ -99,7 +99,7 @@ decl_storage! {
}
}
impl<T: Config> Randomness<T::Hash> for Module<T> {
impl<T: Config> Randomness<T::Hash, T::BlockNumber> for Module<T> {
/// This randomness uses a low-influence function, drawing upon the block hashes from the
/// previous 81 blocks. Its result for any given subject will be known far in advance by anyone
/// observing the chain. Any block producer has significant influence over their block hashes
@@ -110,14 +110,15 @@ impl<T: Config> Randomness<T::Hash> for Module<T> {
/// WARNING: Hashing the result of this function will remove any low-influence properties it has
/// and mean that all bits of the resulting value are entirely manipulatable by the author of
/// the parent block, who can determine the value of `parent_hash`.
fn random(subject: &[u8]) -> T::Hash {
fn random(subject: &[u8]) -> (T::Hash, T::BlockNumber) {
let block_number = <frame_system::Module<T>>::block_number();
let index = block_number_to_index::<T>(block_number);
let hash_series = <RandomMaterial<T>>::get();
if !hash_series.is_empty() {
let seed = if !hash_series.is_empty() {
// Always the case after block 1 is initialized.
hash_series.iter()
hash_series
.iter()
.cycle()
.skip(index)
.take(RANDOM_MATERIAL_LEN as usize)
@@ -126,7 +127,12 @@ impl<T: Config> Randomness<T::Hash> for Module<T> {
.triplet_mix()
} else {
T::Hash::default()
}
};
(
seed,
block_number.saturating_sub(RANDOM_MATERIAL_LEN.into()),
)
}
}
@@ -272,8 +278,9 @@ mod tests {
assert_eq!(CollectiveFlip::random_seed(), CollectiveFlip::random_seed());
assert_ne!(CollectiveFlip::random(b"random_1"), CollectiveFlip::random(b"random_2"));
let random = CollectiveFlip::random_seed();
let (random, known_since) = CollectiveFlip::random_seed();
assert_eq!(known_since, 162 - RANDOM_MATERIAL_LEN as u64);
assert_ne!(random, H256::zero());
assert!(!CollectiveFlip::random_material().contains(&random));
});