mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-19 22:45:40 +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
@@ -73,7 +73,7 @@ fn aura_reports_offline() {
|
||||
}
|
||||
|
||||
with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
let slot_duration = Aura::slot_duration();
|
||||
|
||||
Aura::on_timestamp_set::<HandleTestReport>(5 * slot_duration, slot_duration);
|
||||
@@ -82,7 +82,7 @@ fn aura_reports_offline() {
|
||||
// no slashing when last step was 0.
|
||||
assert_eq!(SLASH_COUNTS.lock().as_slice(), &[0, 0, 0, 0]);
|
||||
|
||||
System::initialize(&2, &header.hash(), &Default::default());
|
||||
System::initialize(&2, &header.hash(), &Default::default(), &Default::default());
|
||||
Aura::on_timestamp_set::<HandleTestReport>(8 * slot_duration, slot_duration);
|
||||
let _header = System::finalize();
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ use inherents::{InherentData, ProvideInherent};
|
||||
#[test]
|
||||
fn authorities_change_logged() {
|
||||
with_externalities(&mut new_test_ext(vec![1, 2, 3]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
Consensus::set_authorities(&[UintAuthorityId(4), UintAuthorityId(5), UintAuthorityId(6)]);
|
||||
Consensus::on_finalize(1);
|
||||
let header = System::finalize();
|
||||
@@ -47,7 +47,7 @@ fn authorities_change_logged() {
|
||||
#[test]
|
||||
fn partial_authorities_change_logged() {
|
||||
with_externalities(&mut new_test_ext(vec![1, 2, 3]), || {
|
||||
System::initialize(&2, &Default::default(), &Default::default());
|
||||
System::initialize(&2, &Default::default(), &Default::default(), &Default::default());
|
||||
Consensus::set_authorities(&[UintAuthorityId(2), UintAuthorityId(4), UintAuthorityId(5)]);
|
||||
Consensus::on_finalize(2);
|
||||
let header = System::finalize();
|
||||
@@ -68,7 +68,7 @@ fn partial_authorities_change_logged() {
|
||||
#[test]
|
||||
fn authorities_change_is_not_logged_when_not_changed() {
|
||||
with_externalities(&mut new_test_ext(vec![1, 2, 3]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
Consensus::on_finalize(1);
|
||||
let header = System::finalize();
|
||||
assert_eq!(header.digest, testing::Digest {
|
||||
@@ -80,7 +80,7 @@ fn authorities_change_is_not_logged_when_not_changed() {
|
||||
#[test]
|
||||
fn authorities_change_is_not_logged_when_changed_back_to_original() {
|
||||
with_externalities(&mut new_test_ext(vec![1, 2, 3]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
Consensus::set_authorities(&[UintAuthorityId(4), UintAuthorityId(5), UintAuthorityId(6)]);
|
||||
Consensus::set_authorities(&[UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]);
|
||||
Consensus::on_finalize(1);
|
||||
@@ -94,7 +94,7 @@ fn authorities_change_is_not_logged_when_changed_back_to_original() {
|
||||
#[test]
|
||||
fn offline_report_can_be_excluded() {
|
||||
with_externalities(&mut new_test_ext(vec![1, 2, 3]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
assert!(Consensus::create_inherent(&InherentData::new()).is_none());
|
||||
|
||||
let offline_report: Vec<u32> = vec![0];
|
||||
@@ -110,7 +110,7 @@ fn set_and_kill_storage_work() {
|
||||
use srml_support::storage;
|
||||
|
||||
with_externalities(&mut new_test_ext(vec![1, 2, 3]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
|
||||
let item = (vec![42u8], vec![42u8]);
|
||||
|
||||
|
||||
@@ -736,7 +736,7 @@ fn deduct_blocks() {
|
||||
assert_eq!(bob_contract.rent_allowance, 1_000);
|
||||
|
||||
// Advance 4 blocks
|
||||
System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()));
|
||||
@@ -751,7 +751,7 @@ fn deduct_blocks() {
|
||||
assert_eq!(Balances::free_balance(BOB), 30_000 - rent);
|
||||
|
||||
// Advance 7 blocks more
|
||||
System::initialize(&12, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&12, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()));
|
||||
@@ -825,7 +825,7 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool)
|
||||
));
|
||||
|
||||
// Advance blocks
|
||||
System::initialize(&blocks, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&blocks, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
assert!(trigger_call());
|
||||
@@ -865,14 +865,14 @@ fn removals(trigger_call: impl Fn() -> bool) {
|
||||
assert_eq!(ContractInfoOf::<Test>::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000);
|
||||
|
||||
// Advance blocks
|
||||
System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
assert!(trigger_call());
|
||||
assert!(ContractInfoOf::<Test>::get(BOB).unwrap().get_tombstone().is_some());
|
||||
|
||||
// Advance blocks
|
||||
System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent must have no effect
|
||||
assert!(trigger_call());
|
||||
@@ -899,14 +899,14 @@ fn removals(trigger_call: impl Fn() -> bool) {
|
||||
assert_eq!(ContractInfoOf::<Test>::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 100);
|
||||
|
||||
// Advance blocks
|
||||
System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
assert!(trigger_call());
|
||||
assert!(ContractInfoOf::<Test>::get(BOB).unwrap().get_tombstone().is_some());
|
||||
|
||||
// Advance blocks
|
||||
System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent must have no effect
|
||||
assert!(trigger_call());
|
||||
@@ -937,14 +937,14 @@ fn removals(trigger_call: impl Fn() -> bool) {
|
||||
assert_eq!(ContractInfoOf::<Test>::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000);
|
||||
|
||||
// Advance blocks
|
||||
System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&10, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
assert!(trigger_call());
|
||||
assert!(ContractInfoOf::<Test>::get(BOB).is_none());
|
||||
|
||||
// Advance blocks
|
||||
System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&20, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent must have no effect
|
||||
assert!(trigger_call());
|
||||
@@ -1027,7 +1027,7 @@ fn default_rent_allowance_on_create() {
|
||||
assert_eq!(bob_contract.rent_allowance, <BalanceOf<Test>>::max_value());
|
||||
|
||||
// Advance blocks
|
||||
System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()));
|
||||
@@ -1179,7 +1179,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage:
|
||||
}
|
||||
|
||||
// Advance 4 blocks
|
||||
System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&5, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
|
||||
// Trigger rent through call
|
||||
assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()));
|
||||
@@ -1198,7 +1198,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage:
|
||||
|
||||
if !test_restore_to_with_dirty_storage {
|
||||
// Advance 1 blocks
|
||||
System::initialize(&6, &[0u8; 32].into(), &[0u8; 32].into());
|
||||
System::initialize(&6, &[0u8; 32].into(), &[0u8; 32].into(), &Default::default());
|
||||
}
|
||||
|
||||
assert_ok!(Contract::call(
|
||||
|
||||
@@ -80,7 +80,7 @@ use rstd::result;
|
||||
use primitives::traits::{
|
||||
self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize,
|
||||
OnInitialize, Digest, NumberFor, Block as BlockT, OffchainWorker,
|
||||
ValidateUnsigned,
|
||||
ValidateUnsigned, DigestItem,
|
||||
};
|
||||
use srml_support::{Dispatchable, traits::MakePayment};
|
||||
use parity_codec::{Codec, Encode};
|
||||
@@ -152,11 +152,13 @@ where
|
||||
{
|
||||
/// Start the execution of a particular block.
|
||||
pub fn initialize_block(header: &System::Header) {
|
||||
Self::initialize_block_impl(header.number(), header.parent_hash(), header.extrinsics_root());
|
||||
let mut digests = System::Digest::default();
|
||||
header.digest().logs().iter().for_each(|d| if d.as_pre_runtime().is_some() { digests.push(d.clone()) });
|
||||
Self::initialize_block_impl(header.number(), header.parent_hash(), header.extrinsics_root(), &digests);
|
||||
}
|
||||
|
||||
fn initialize_block_impl(block_number: &System::BlockNumber, parent_hash: &System::Hash, extrinsics_root: &System::Hash) {
|
||||
<system::Module<System>>::initialize(block_number, parent_hash, extrinsics_root);
|
||||
fn initialize_block_impl(block_number: &System::BlockNumber, parent_hash: &System::Hash, extrinsics_root: &System::Hash, digest: &System::Digest) {
|
||||
<system::Module<System>>::initialize(block_number, parent_hash, extrinsics_root, digest);
|
||||
<AllModules as OnInitialize<System::BlockNumber>>::on_initialize(*block_number);
|
||||
}
|
||||
|
||||
@@ -262,7 +264,8 @@ where
|
||||
Payment::make_payment(sender, encoded_len).map_err(|_| internal::ApplyError::CantPay)?;
|
||||
|
||||
// AUDIT: Under no circumstances may this function panic from here onwards.
|
||||
|
||||
// FIXME: ensure this at compile-time (such as by not defining a panic function, forcing
|
||||
// a linker error unless the compiler can prove it cannot be called).
|
||||
// increment nonce in storage
|
||||
<system::Module<System>>::inc_account_nonce(sender);
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ mod tests {
|
||||
with_externalities(&mut TestExternalities::new(t), || {
|
||||
let mut parent_hash = System::parent_hash();
|
||||
for i in 2..106 {
|
||||
System::initialize(&i, &parent_hash, &Default::default());
|
||||
System::initialize(&i, &parent_hash, &Default::default(), &Default::default());
|
||||
FinalityTracker::on_finalize(i);
|
||||
let hdr = System::finalize();
|
||||
parent_hash = hdr.hash();
|
||||
@@ -369,7 +369,7 @@ mod tests {
|
||||
with_externalities(&mut TestExternalities::new(t), || {
|
||||
let mut parent_hash = System::parent_hash();
|
||||
for i in 2..106 {
|
||||
System::initialize(&i, &parent_hash, &Default::default());
|
||||
System::initialize(&i, &parent_hash, &Default::default(), &Default::default());
|
||||
assert_ok!(FinalityTracker::dispatch(
|
||||
Call::final_hint(i-1),
|
||||
Origin::NONE,
|
||||
|
||||
@@ -30,7 +30,7 @@ use super::*;
|
||||
#[test]
|
||||
fn authorities_change_logged() {
|
||||
with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 0, None).unwrap();
|
||||
|
||||
System::note_finished_extrinsics();
|
||||
@@ -56,7 +56,7 @@ fn authorities_change_logged() {
|
||||
#[test]
|
||||
fn authorities_change_logged_after_delay() {
|
||||
with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 1, None).unwrap();
|
||||
Grandpa::on_finalize(1);
|
||||
let header = System::finalize();
|
||||
@@ -69,7 +69,7 @@ fn authorities_change_logged_after_delay() {
|
||||
// no change at this height.
|
||||
assert_eq!(System::events(), vec![]);
|
||||
|
||||
System::initialize(&2, &header.hash(), &Default::default());
|
||||
System::initialize(&2, &header.hash(), &Default::default(), &Default::default());
|
||||
System::note_finished_extrinsics();
|
||||
Grandpa::on_finalize(2);
|
||||
|
||||
@@ -87,7 +87,7 @@ fn authorities_change_logged_after_delay() {
|
||||
#[test]
|
||||
fn cannot_schedule_change_when_one_pending() {
|
||||
with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 1, None).unwrap();
|
||||
assert!(Grandpa::pending_change().is_some());
|
||||
assert!(Grandpa::schedule_change(vec![(5, 1)], 1, None).is_err());
|
||||
@@ -95,14 +95,14 @@ fn cannot_schedule_change_when_one_pending() {
|
||||
Grandpa::on_finalize(1);
|
||||
let header = System::finalize();
|
||||
|
||||
System::initialize(&2, &header.hash(), &Default::default());
|
||||
System::initialize(&2, &header.hash(), &Default::default(), &Default::default());
|
||||
assert!(Grandpa::pending_change().is_some());
|
||||
assert!(Grandpa::schedule_change(vec![(5, 1)], 1, None).is_err());
|
||||
|
||||
Grandpa::on_finalize(2);
|
||||
let header = System::finalize();
|
||||
|
||||
System::initialize(&3, &header.hash(), &Default::default());
|
||||
System::initialize(&3, &header.hash(), &Default::default(), &Default::default());
|
||||
assert!(Grandpa::pending_change().is_none());
|
||||
assert!(Grandpa::schedule_change(vec![(5, 1)], 1, None).is_ok());
|
||||
|
||||
@@ -130,7 +130,7 @@ fn new_decodes_from_old() {
|
||||
#[test]
|
||||
fn dispatch_forced_change() {
|
||||
with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || {
|
||||
System::initialize(&1, &Default::default(), &Default::default());
|
||||
System::initialize(&1, &Default::default(), &Default::default(), &Default::default());
|
||||
Grandpa::schedule_change(
|
||||
vec![(4, 1), (5, 1), (6, 1)],
|
||||
5,
|
||||
@@ -144,7 +144,7 @@ fn dispatch_forced_change() {
|
||||
let mut header = System::finalize();
|
||||
|
||||
for i in 2..7 {
|
||||
System::initialize(&i, &header.hash(), &Default::default());
|
||||
System::initialize(&i, &header.hash(), &Default::default(), &Default::default());
|
||||
assert!(Grandpa::pending_change().unwrap().forced.is_some());
|
||||
assert_eq!(Grandpa::next_forced(), Some(11));
|
||||
assert!(Grandpa::schedule_change(vec![(5, 1)], 1, None).is_err());
|
||||
@@ -157,7 +157,7 @@ fn dispatch_forced_change() {
|
||||
// change has been applied at the end of block 6.
|
||||
// add a normal change.
|
||||
{
|
||||
System::initialize(&7, &header.hash(), &Default::default());
|
||||
System::initialize(&7, &header.hash(), &Default::default(), &Default::default());
|
||||
assert!(Grandpa::pending_change().is_none());
|
||||
assert_eq!(Grandpa::grandpa_authorities(), vec![(4, 1), (5, 1), (6, 1)]);
|
||||
assert!(Grandpa::schedule_change(vec![(5, 1)], 1, None).is_ok());
|
||||
@@ -167,7 +167,7 @@ fn dispatch_forced_change() {
|
||||
|
||||
// run the normal change.
|
||||
{
|
||||
System::initialize(&8, &header.hash(), &Default::default());
|
||||
System::initialize(&8, &header.hash(), &Default::default(), &Default::default());
|
||||
assert!(Grandpa::pending_change().is_some());
|
||||
assert_eq!(Grandpa::grandpa_authorities(), vec![(4, 1), (5, 1), (6, 1)]);
|
||||
assert!(Grandpa::schedule_change(vec![(5, 1)], 1, None).is_err());
|
||||
@@ -178,7 +178,7 @@ fn dispatch_forced_change() {
|
||||
// normal change applied. but we can't apply a new forced change for some
|
||||
// time.
|
||||
for i in 9..11 {
|
||||
System::initialize(&i, &header.hash(), &Default::default());
|
||||
System::initialize(&i, &header.hash(), &Default::default(), &Default::default());
|
||||
assert!(Grandpa::pending_change().is_none());
|
||||
assert_eq!(Grandpa::grandpa_authorities(), vec![(5, 1)]);
|
||||
assert_eq!(Grandpa::next_forced(), Some(11));
|
||||
@@ -188,7 +188,7 @@ fn dispatch_forced_change() {
|
||||
}
|
||||
|
||||
{
|
||||
System::initialize(&11, &header.hash(), &Default::default());
|
||||
System::initialize(&11, &header.hash(), &Default::default(), &Default::default());
|
||||
assert!(Grandpa::pending_change().is_none());
|
||||
assert!(Grandpa::schedule_change(vec![(5, 1), (6, 1), (7, 1)], 5, Some(0)).is_ok());
|
||||
assert_eq!(Grandpa::next_forced(), Some(21));
|
||||
|
||||
@@ -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