mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 05:51:02 +00:00
Introduce inherent digests (#2466)
* Introduce inherent digests * Implement inherent digests * fix silly error * Implementation of inherent digests in BABE All tests pass. There are still limitations: 1. The runtime strips out inherent digests, so BABE must re-add them. 2. The test runtime checks that it can re-compute all digests. It can’t, so I had to comment out that test. * Fix compilation and seal import Seals were not imported correctly: the pre-digest was imported twice, instead of both it and the seal being imported. Also, other parts of the code did not compile due to incomplete refactoring. * Remove bogus assertion * Fix testsuite compilation * Remove unused import * Fix compiler diagnostics * Add inherent digest parameters to block constructors This enforces that inherent digests are added first. * Fixup Cargo.lock * Fix build errors * Re-add an incorrectly removed import * Bump primitive-types version * Update Cargo.lock * Refactoring * Use inherent digests for AuRa They do reach the runtime, but get stripped. I have not figured out where. * Fix compilation errors * Fix compilation errors due to incorrect types * Fix whitespace Suggested-by: Tomasz Drwiega <tomasz@parity.io> * Add preamble Suggested-by: Tomasz Drwiega <tomasz@parity.io> * Fix silly compile error * Refactor pre-digest finding code into a separate function * Remove unwanted assertion It is too likely to bring down the entire blockchain. Suggested-by: Tomasz Drwiega <tomasz@parity.io> * Use `find_pre_digest` after runtime, too Also, use `Member` trait rather than rolling our own requirements. Suggested-by: Tomasz Drwiega <tomasz@parity.io> * Fix various warnings mostly due to upgrading the dependency on `error_chain`. * Pre-digests nearly complete This nearly completes the implementation of pre-runtime digests. * `Seal2` → `Seal` and fix test suite * Try to fix the storage error * Try to fix storage (again) * Fix tests * Hopefully finish pre-runtime digests The key is to pass *only* the pre-runtime digests to the runtime. The others must be stripped out by `initialize_block`. * Fix silly typo * Fix another silly mistake * Remove unnecessary filtering of BABE pre-digests We no longer get duplicate BABE pre-digests, so if they appear, the header should be rejected outright. * Update Cargo.lock files * Reformatting * Fix silly typo in inherent digest code Also, revert `error.rs` files that contained calls to the `error_chain!` macro. * Try to keep the runtime from stripping pre-digests Currently runs into the “Storage root must match that calculated” assertion. * Don’t compute storage root until storage changes are done. Also, fix a compilation error. * Fix compile-time error * Fix compilation errors * Fix more compile errors * Hopefully it compiles this time… * Fix compilation and add docs * Prevent BABE from adding duplicate pre-runtime digests Found by comparing with the AuRa code. I also did some refactoring. * Respond to review and fix some warnings * Delete some dead code introduced earlier * More dead code goes away * `ref mut` → `&mut` * Respond to review and fix some warnings * Fix compilation error * Remove unneeded `HashT` type parameter Suggested-by: Robert Habermeier <robert@parity.io> * Remove spurious #[allow(deprecated)] * Document inherent digest parameter to `build_block` * Delete `Simple` trait It wasn’t needed * delete wrongly added files * Fix trait bounds * Digest serialization tests I also did some reformatting and cleanup. * Apply suggestions from code review Reformatting Co-Authored-By: André Silva <andre.beat@gmail.com> * Swap two arguments to `propose` and `propose_with` Also, remove some needless unsafe code. * Remove bogus `#![allow(deprecated)]` annotations With the removal of the deprecated `Seal` variant, these are not needed. * Add a missing `#[allow(deprecated)]` in the AuRa tests * Fix silly compile error * Fix silly compiler error RLS did not tell me that I hadn’t fixed `babe/lib.rs`, so I missed it. * Fixes made automatically by Cargo
This commit is contained in:
committed by
Gavin Wood
parent
e9a4c80c40
commit
c7d1204ce5
@@ -465,10 +465,16 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
|
||||
/// Start the execution of a particular block.
|
||||
pub fn initialize(number: &T::BlockNumber, parent_hash: &T::Hash, txs_root: &T::Hash) {
|
||||
pub fn initialize(
|
||||
number: &T::BlockNumber,
|
||||
parent_hash: &T::Hash,
|
||||
txs_root: &T::Hash,
|
||||
digest: &T::Digest,
|
||||
) {
|
||||
// populate environment
|
||||
storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32);
|
||||
<Number<T>>::put(number);
|
||||
<Digest<T>>::put(digest);
|
||||
<ParentHash<T>>::put(parent_hash);
|
||||
<BlockHash<T>>::insert(*number - One::one(), parent_hash);
|
||||
<ExtrinsicsRoot<T>>::put(txs_root);
|
||||
@@ -553,38 +559,51 @@ impl<T: Trait> Module<T> {
|
||||
|
||||
/// Get the basic random seed.
|
||||
///
|
||||
/// In general you won't want to use this, but rather `Self::random` which allows you to give a subject for the
|
||||
/// random result and whose value will be independently low-influence random from any other such seeds.
|
||||
/// In general you won't want to use this, but rather `Self::random` which
|
||||
/// allows you to give a subject for the random result and whose value will
|
||||
/// be independently low-influence random from any other such seeds.
|
||||
pub fn random_seed() -> T::Hash {
|
||||
Self::random(&[][..])
|
||||
}
|
||||
|
||||
/// Get a low-influence "random" value.
|
||||
///
|
||||
/// Being a deterministic block chain, real randomness is difficult to come by. This gives you something that
|
||||
/// approximates it. `subject` is a context identifier and allows you to get a different result to other callers
|
||||
/// of this function; use it like `random(&b"my context"[..])`.
|
||||
/// Being a deterministic block chain, real randomness is difficult to come
|
||||
/// by. This gives you something that approximates it. `subject` is a
|
||||
/// context identifier and allows you to get a different result to other
|
||||
/// callers of this function; use it like `random(&b"my context"[..])`.
|
||||
///
|
||||
/// This is initially implemented through a low-influence "triplet mix" convolution of previous block hash values.
|
||||
/// In the future it will be generated from a secure "VRF".
|
||||
/// This is initially implemented through a low-influence "triplet mix"
|
||||
/// convolution of previous block hash values. In the future it will be
|
||||
/// generated from a secure verifiable random function (VRF).
|
||||
///
|
||||
/// ### Security Notes
|
||||
/// 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 in advance by the block producer of this block (and, indeed, anyone
|
||||
/// who knows the block's `parent_hash`). However, it is mostly impossible for the producer of this block *alone*
|
||||
/// to influence the value of this hash. A sizable minority of dishonest and coordinating block producers would be
|
||||
/// required in order to affect this value. If that is an insufficient security guarantee then two things can be
|
||||
/// used to improve this randomness:
|
||||
/// - Name, in advance, the block number whose random value will be used; ensure your module retains a buffer of
|
||||
/// previous random values for its subject and then index into these in order to obviate the ability of your user
|
||||
/// to look up the parent hash and choose when to transact based upon it.
|
||||
/// - Require your user to first commit to an additional value by first posting its hash. Require them to reveal
|
||||
/// the value to determine the final result, hashing it with the output of this random function. This reduces the
|
||||
/// ability of a cabal of block producers from conspiring against individuals.
|
||||
///
|
||||
/// WARNING: Hashing the result of this function will remove any low-infleunce 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`.
|
||||
/// 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 in advance by the block producer of this block (and,
|
||||
/// indeed, anyone who knows the block's `parent_hash`). However, it is
|
||||
/// mostly impossible for the producer of this block *alone* to influence
|
||||
/// the value of this hash. A sizable minority of dishonest and coordinating
|
||||
/// block producers would be required in order to affect this value. If that
|
||||
/// is an insufficient security guarantee then two things can be used to
|
||||
/// improve this randomness:
|
||||
///
|
||||
/// - Name, in advance, the block number whose random value will be used;
|
||||
/// ensure your module retains a buffer of previous random values for its
|
||||
/// subject and then index into these in order to obviate the ability of
|
||||
/// your user to look up the parent hash and choose when to transact based
|
||||
/// upon it.
|
||||
/// - Require your user to first commit to an additional value by first
|
||||
/// posting its hash. Require them to reveal the value to determine the
|
||||
/// final result, hashing it with the output of this random function. This
|
||||
/// reduces the ability of a cabal of block producers from conspiring
|
||||
/// against individuals.
|
||||
///
|
||||
/// WARNING: Hashing the result of this function will remove any
|
||||
/// low-influnce 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`.
|
||||
pub fn random(subject: &[u8]) -> T::Hash {
|
||||
let (index, hash_series) = <RandomMaterial<T>>::get();
|
||||
if hash_series.len() > 0 {
|
||||
@@ -606,8 +625,9 @@ impl<T: Trait> Module<T> {
|
||||
<AccountNonce<T>>::insert(who, Self::account_nonce(who) + T::Index::one());
|
||||
}
|
||||
|
||||
/// Note what the extrinsic data of the current extrinsic index is. If this is called, then
|
||||
/// ensure `derive_extrinsics` is also called before block-building is completed.
|
||||
/// Note what the extrinsic data of the current extrinsic index is. If this
|
||||
/// is called, then ensure `derive_extrinsics` is also called before
|
||||
/// block-building is completed.
|
||||
///
|
||||
/// NOTE: This function is called only when the block is being constructed locally.
|
||||
/// `execute_block` doesn't note any extrinsics.
|
||||
@@ -722,7 +742,7 @@ mod tests {
|
||||
#[test]
|
||||
fn deposit_event_should_work() {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
System::initialize(&1, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&1, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
System::note_finished_extrinsics();
|
||||
System::deposit_event(1u16);
|
||||
System::finalize();
|
||||
@@ -737,7 +757,7 @@ mod tests {
|
||||
]
|
||||
);
|
||||
|
||||
System::initialize(&2, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&2, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
System::deposit_event(42u16);
|
||||
System::note_applied_extrinsic(&Ok(()), 0);
|
||||
System::note_applied_extrinsic(&Err(""), 0);
|
||||
@@ -758,7 +778,7 @@ mod tests {
|
||||
with_externalities(&mut new_test_ext(), || {
|
||||
const BLOCK_NUMBER: u64 = 1;
|
||||
|
||||
System::initialize(&BLOCK_NUMBER, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&BLOCK_NUMBER, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
System::note_finished_extrinsics();
|
||||
|
||||
let topics = vec![
|
||||
|
||||
Reference in New Issue
Block a user