mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 12:07:57 +00:00
5e7b27e98c
* Initial setup * Adds node block * Uses UncheckedExtrinsic and removes Where section * Updates frame_system to use Block * Adds deprecation warning * Fixes pallet-timestamp * Removes Header and BlockNumber * Addresses review comments * Addresses review comments * Adds comment about compiler bug * Removes where clause * Refactors code * Fixes errors in cargo check * Fixes errors in cargo check * Fixes warnings in cargo check * Formatting * Fixes construct_runtime tests * Uses import instead of full path for BlockNumber * Uses import instead of full path for Header * Formatting * Fixes construct_runtime tests * Fixes imports in benchmarks * Formatting * Fixes construct_runtime tests * Formatting * Minor updates * Fixes construct_runtime ui tests * Fixes construct_runtime ui tests with 1.70 * Fixes docs * Fixes docs * Adds u128 mock block type * Fixes split example * fixes for cumulus * ".git/.scripts/commands/fmt/fmt.sh" * Updates new tests * Fixes fully-qualified path in few places * Formatting * Update frame/examples/default-config/src/lib.rs Co-authored-by: Juan <juangirini@gmail.com> * Update frame/support/procedural/src/construct_runtime/mod.rs Co-authored-by: Juan <juangirini@gmail.com> * ".git/.scripts/commands/fmt/fmt.sh" * Addresses some review comments * Fixes build * ".git/.scripts/commands/fmt/fmt.sh" * Update frame/democracy/src/lib.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update frame/democracy/src/lib.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update frame/support/procedural/src/construct_runtime/mod.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update frame/support/procedural/src/construct_runtime/mod.rs Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Addresses review comments * Updates trait bounds * Minor fix * ".git/.scripts/commands/fmt/fmt.sh" * Removes unnecessary bound * ".git/.scripts/commands/fmt/fmt.sh" * Updates test * Fixes build * Adds a bound for header * ".git/.scripts/commands/fmt/fmt.sh" * Removes where block * Minor fix * Minor fix * Fixes tests * ".git/.scripts/commands/update-ui/update-ui.sh" 1.70 * Updates test * Update primitives/runtime/src/traits.rs Co-authored-by: Bastian Köcher <git@kchr.de> * Update primitives/runtime/src/traits.rs Co-authored-by: Bastian Köcher <git@kchr.de> * Updates doc * Updates doc --------- Co-authored-by: command-bot <> Co-authored-by: Juan <juangirini@gmail.com> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Bastian Köcher <git@kchr.de>
174 lines
8.8 KiB
Rust
174 lines
8.8 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//! Provides multiple implementations of the randomness trait based on the on-chain epoch
|
|
//! randomness collected from VRF outputs.
|
|
|
|
use super::{
|
|
AuthorVrfRandomness, Config, EpochStart, NextRandomness, Randomness, RANDOMNESS_LENGTH,
|
|
};
|
|
use frame_support::traits::Randomness as RandomnessT;
|
|
use frame_system::pallet_prelude::BlockNumberFor;
|
|
use sp_runtime::traits::{Hash, One, Saturating};
|
|
|
|
/// Randomness usable by consensus protocols that **depend** upon finality and take action
|
|
/// based upon on-chain commitments made during the epoch before the previous epoch.
|
|
///
|
|
/// An off-chain consensus protocol requires randomness be finalized before usage, but one
|
|
/// extra epoch delay beyond `RandomnessFromOneEpochAgo` suffices, under the assumption
|
|
/// that finality never stalls for longer than one epoch.
|
|
///
|
|
/// All randomness is relative to commitments to any other inputs to the computation: If
|
|
/// Alice samples randomness near perfectly using radioactive decay, but then afterwards
|
|
/// Eve selects an arbitrary value with which to xor Alice's randomness, then Eve always
|
|
/// wins whatever game they play.
|
|
///
|
|
/// All input commitments used with `RandomnessFromTwoEpochsAgo` should come from at least
|
|
/// three epochs ago. We require BABE session keys be registered at least three epochs
|
|
/// before being used to derive `ParentBlockRandomness` for example.
|
|
///
|
|
/// All users learn `RandomnessFromTwoEpochsAgo` when epoch `current_epoch - 1` starts,
|
|
/// although some learn it a few block earlier inside epoch `current_epoch - 2`.
|
|
///
|
|
/// Adversaries with enough block producers could bias this randomness by choosing upon
|
|
/// what their block producers build at the end of epoch `current_epoch - 2` or the
|
|
/// beginning epoch `current_epoch - 1`, or skipping slots at the end of epoch
|
|
/// `current_epoch - 2`.
|
|
///
|
|
/// Adversaries should not possess many block production slots towards the beginning or
|
|
/// end of every epoch, but they possess some influence over when they possess more slots.
|
|
pub struct RandomnessFromTwoEpochsAgo<T>(sp_std::marker::PhantomData<T>);
|
|
|
|
/// Randomness usable by on-chain code that **does not depend** upon finality and takes
|
|
/// action based upon on-chain commitments made during the previous epoch.
|
|
///
|
|
/// All randomness is relative to commitments to any other inputs to the computation: If
|
|
/// Alice samples randomness near perfectly using radioactive decay, but then afterwards
|
|
/// Eve selects an arbitrary value with which to xor Alice's randomness, then Eve always
|
|
/// wins whatever game they play.
|
|
///
|
|
/// All input commitments used with `RandomnessFromOneEpochAgo` should come from at least
|
|
/// two epochs ago, although the previous epoch might work in special cases under
|
|
/// additional assumption.
|
|
///
|
|
/// All users learn `RandomnessFromOneEpochAgo` at the end of the previous epoch, although
|
|
/// some block producers learn it several block earlier.
|
|
///
|
|
/// Adversaries with enough block producers could bias this randomness by choosing upon
|
|
/// what their block producers build at either the end of the previous epoch or the
|
|
/// beginning of the current epoch, or electing to skipping some of their own block
|
|
/// production slots towards the end of the previous epoch.
|
|
///
|
|
/// Adversaries should not possess many block production slots towards the beginning or
|
|
/// end of every epoch, but they possess some influence over when they possess more slots.
|
|
///
|
|
/// As an example usage, we determine parachain auctions ending times in Polkadot using
|
|
/// `RandomnessFromOneEpochAgo` because it reduces bias from `ParentBlockRandomness` and
|
|
/// does not require the extra finality delay of `RandomnessFromTwoEpochsAgo`.
|
|
pub struct RandomnessFromOneEpochAgo<T>(sp_std::marker::PhantomData<T>);
|
|
|
|
/// Randomness produced semi-freshly with each block, but inherits limitations of
|
|
/// `RandomnessFromTwoEpochsAgo` from which it derives.
|
|
///
|
|
/// All randomness is relative to commitments to any other inputs to the computation: If
|
|
/// Alice samples randomness near perfectly using radioactive decay, but then afterwards
|
|
/// Eve selects an arbitrary value with which to xor Alice's randomness, then Eve always
|
|
/// wins whatever game they play.
|
|
///
|
|
/// As with `RandomnessFromTwoEpochsAgo`, all input commitments combined with
|
|
/// `ParentBlockRandomness` should come from at least two epoch ago, except preferably
|
|
/// not near epoch ending, and thus ideally three epochs ago.
|
|
///
|
|
/// Almost all users learn this randomness for a given block by the time they receive it's
|
|
/// parent block, which makes this randomness appear fresh enough. Yet, the block producer
|
|
/// themselves learned this randomness at the beginning of epoch `current_epoch - 2`, at
|
|
/// the same time as they learn `RandomnessFromTwoEpochsAgo`.
|
|
///
|
|
/// Aside from just biasing `RandomnessFromTwoEpochsAgo`, adversaries could also bias
|
|
/// `ParentBlockRandomness` by never announcing their block if doing so yields an
|
|
/// unfavorable randomness. As such, `ParentBlockRandomness` should be considered weaker
|
|
/// than both other randomness sources provided by BABE, but `ParentBlockRandomness`
|
|
/// remains constrained by declared staking, while a randomness source like block hash is
|
|
/// only constrained by adversaries' unknowable computational power.
|
|
///
|
|
/// As an example use, parachains could assign block production slots based upon the
|
|
/// `ParentBlockRandomness` of their relay parent or relay parent's parent, provided the
|
|
/// parachain registers collators but avoids censorship sensitive functionality like
|
|
/// slashing. Any parachain with slashing could operate BABE itself or perhaps better yet
|
|
/// a BABE-like approach that derives its `ParentBlockRandomness`, and authorizes block
|
|
/// production, based upon the relay parent's `ParentBlockRandomness` or more likely the
|
|
/// relay parent's `RandomnessFromTwoEpochsAgo`.
|
|
///
|
|
/// NOTE: there is some nuance here regarding what is current and parent randomness. If
|
|
/// you are using this trait from within the runtime (i.e. as part of block execution)
|
|
/// then the randomness provided here will always be generated from the parent block. If
|
|
/// instead you are using this randomness externally, i.e. after block execution, then
|
|
/// this randomness will be provided by the "current" block (this stems from the fact that
|
|
/// we process VRF outputs on block execution finalization, i.e. `on_finalize`).
|
|
pub struct ParentBlockRandomness<T>(sp_std::marker::PhantomData<T>);
|
|
|
|
/// Randomness produced semi-freshly with each block, but inherits limitations of
|
|
/// `RandomnessFromTwoEpochsAgo` from which it derives.
|
|
///
|
|
/// See [`ParentBlockRandomness`].
|
|
#[deprecated(note = "Should not be relied upon for correctness, \
|
|
will not provide fresh randomness for the current block. \
|
|
Please use `ParentBlockRandomness` instead.")]
|
|
pub struct CurrentBlockRandomness<T>(sp_std::marker::PhantomData<T>);
|
|
|
|
impl<T: Config> RandomnessT<T::Hash, BlockNumberFor<T>> for RandomnessFromTwoEpochsAgo<T> {
|
|
fn random(subject: &[u8]) -> (T::Hash, BlockNumberFor<T>) {
|
|
let mut subject = subject.to_vec();
|
|
subject.reserve(RANDOMNESS_LENGTH);
|
|
subject.extend_from_slice(&Randomness::<T>::get()[..]);
|
|
|
|
(T::Hashing::hash(&subject[..]), EpochStart::<T>::get().0)
|
|
}
|
|
}
|
|
|
|
impl<T: Config> RandomnessT<T::Hash, BlockNumberFor<T>> for RandomnessFromOneEpochAgo<T> {
|
|
fn random(subject: &[u8]) -> (T::Hash, BlockNumberFor<T>) {
|
|
let mut subject = subject.to_vec();
|
|
subject.reserve(RANDOMNESS_LENGTH);
|
|
subject.extend_from_slice(&NextRandomness::<T>::get()[..]);
|
|
|
|
(T::Hashing::hash(&subject[..]), EpochStart::<T>::get().1)
|
|
}
|
|
}
|
|
|
|
impl<T: Config> RandomnessT<Option<T::Hash>, BlockNumberFor<T>> for ParentBlockRandomness<T> {
|
|
fn random(subject: &[u8]) -> (Option<T::Hash>, BlockNumberFor<T>) {
|
|
let random = AuthorVrfRandomness::<T>::get().map(|random| {
|
|
let mut subject = subject.to_vec();
|
|
subject.reserve(RANDOMNESS_LENGTH);
|
|
subject.extend_from_slice(&random);
|
|
|
|
T::Hashing::hash(&subject[..])
|
|
});
|
|
|
|
(random, <frame_system::Pallet<T>>::block_number().saturating_sub(One::one()))
|
|
}
|
|
}
|
|
|
|
#[allow(deprecated)]
|
|
impl<T: Config> RandomnessT<Option<T::Hash>, BlockNumberFor<T>> for CurrentBlockRandomness<T> {
|
|
fn random(subject: &[u8]) -> (Option<T::Hash>, BlockNumberFor<T>) {
|
|
let (random, _) = ParentBlockRandomness::<T>::random(subject);
|
|
(random, <frame_system::Pallet<T>>::block_number())
|
|
}
|
|
}
|