From 2c7c152cc805326014f6989f8502f66952d33731 Mon Sep 17 00:00:00 2001 From: Nisheeth Barthwal Date: Wed, 21 Dec 2022 10:37:57 +0100 Subject: [PATCH] [MOON-1812] attempt using pallet_randomness for auth_slot_filter (#1956) * attempt using pallet_randomness for auth_slot_filter * use subject with local vrf output for randomness * fix slice copy --- pallets/randomness/src/lib.rs | 39 +++++++++++++++++++++++++++++++++-- runtime/moonbase/src/lib.rs | 2 +- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/pallets/randomness/src/lib.rs b/pallets/randomness/src/lib.rs index b7d85a3648..d8b4bf4e2a 100644 --- a/pallets/randomness/src/lib.rs +++ b/pallets/randomness/src/lib.rs @@ -53,8 +53,8 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::pallet; - pub use pallet::*; +use sp_std::vec::Vec; #[cfg(any(test, feature = "runtime-benchmarks"))] mod benchmarks; @@ -85,7 +85,7 @@ pub mod pallet { use pallet_evm::AddressMapping; use session_keys_primitives::{InherentError, KeysLookup, VrfId, INHERENT_IDENTIFIER}; use sp_core::{H160, H256}; - use sp_runtime::traits::{AccountIdConversion, Saturating}; + use sp_runtime::traits::{AccountIdConversion, Hash, Saturating}; use sp_std::convert::TryInto; /// The Randomness's pallet id @@ -225,6 +225,12 @@ pub mod pallet { pub type RandomnessResults = StorageMap<_, Twox64Concat, RequestType, RandomnessResult>; + /// Previous local per-block VRF randomness + /// Set in `on_finalize` of last block + #[pallet::storage] + #[pallet::getter(fn previous_local_vrf_output)] + pub type PreviousLocalVrfOutput = StorageValue<_, T::Hash, ValueQuery>; + #[pallet::call] impl Pallet { /// Populates `RandomnessResults` due this epoch with BABE epoch randomness @@ -306,6 +312,35 @@ pub mod pallet { >::take().is_some(), "Mandatory randomness inherent not included; InherentIncluded storage item is empty" ); + + // set previous vrf output + PreviousLocalVrfOutput::::put( + LocalVrfOutput::::get().expect("LocalVrfOutput must exist; qed"), + ); + } + } + + // Randomness trait + impl frame_support::traits::Randomness> for Pallet { + /// Uses the vrf output of previous block to generate a random seed. The provided `subject` + /// must have the property to uniquely generate different randomness given the same vrf + /// output (e.g. relay block number). + /// + /// In our case the `subject` is provided via Nimbus and consists of three parts: + /// 1. Constant string *b"filter" - to identify author-slot-filter pallet + /// 2. First 2 bytes of index.to_le_bytes() when selecting the ith eligible author + /// 3. First 4 bytes of slot_number.to_be_bytes() + /// + /// Note: This needs to be updated when asynchronous backing is in effect, + /// as it will be unsafe. + fn random(subject: &[u8]) -> (T::Hash, BlockNumberFor) { + let local_vrf_output = PreviousLocalVrfOutput::::get(); + let block_number = frame_system::Pallet::::block_number(); + let mut digest = Vec::new(); + digest.extend_from_slice(local_vrf_output.as_ref()); + digest.extend_from_slice(subject); + let randomness = T::Hashing::hash(digest.as_slice()); + (randomness, block_number) } } diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index 24e1a493ef..fde5a04ba2 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -709,7 +709,7 @@ impl pallet_author_inherent::Config for Runtime { impl pallet_author_slot_filter::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type RandomnessSource = RandomnessCollectiveFlip; + type RandomnessSource = Randomness; type PotentialAuthors = ParachainStaking; type WeightInfo = pallet_author_slot_filter::weights::SubstrateWeight; }