diff --git a/client/service/src/client/client.rs b/client/service/src/client/client.rs index 45a471dc38e13..52ac012bbf92e 100644 --- a/client/service/src/client/client.rs +++ b/client/service/src/client/client.rs @@ -37,7 +37,7 @@ use sp_runtime::{ Justification, BuildStorage, generic::{BlockId, SignedBlock, DigestItem}, traits::{ - Block as BlockT, Header as HeaderT, Zero, NumberFor, + Hash, Block as BlockT, Header as HeaderT, Zero, NumberFor, HashFor, SaturatedConversion, One, DigestFor, UniqueSaturatedInto, }, }; @@ -870,10 +870,12 @@ impl Client where Some(previous_block_extrinsics) => { //TODO include serialize/deserialize seed field in header //and use received seed instead + let prev_header = self.backend.blockchain().header(BlockId::Hash(*parent_hash)).unwrap().unwrap(); let mut header = import_block.header.clone(); + header.set_extrinsics_root(*prev_header.extrinsics_root()); - if previous_block_extrinsics.len() > 1{ - let mut seed = extrinsic_shuffler::apply_inherents_and_fetch_seed::( + let block = if previous_block_extrinsics.len() > 1{ + let seed = extrinsic_shuffler::apply_inherents_and_fetch_seed::( &runtime_api, &at, body.clone(), @@ -883,18 +885,25 @@ impl Client where sp_blockchain::Error::Backend(format!("{}", e)) })?; - let mut slice: &[u8] = & mut seed.seed; - header.set_seed(::decode(& mut slice).unwrap()); - } + let shuffled_extrinsics = extrinsic_shuffler::shuffle::(&runtime_api, &at, previous_block_extrinsics, seed); + // temporarly shuffle extrinsics here as we cannot pass shuffling seed to + // runtime easily + // temporarly update extrinsics_root that stores hash of ordered extrinsics so it can be + // validated properly + let trie_root = HashFor::::ordered_trie_root(shuffled_extrinsics.iter().map(codec::Encode::encode).collect()); + header.set_extrinsics_root(trie_root); + Block::new(header.clone(), shuffled_extrinsics) + }else{ + Block::new(header.clone(), previous_block_extrinsics) + }; + + - // TODO fail gracefully - let prev_header = self.backend.blockchain().header(BlockId::Hash(*parent_hash)).unwrap().unwrap(); - header.set_extrinsics_root(*prev_header.extrinsics_root()); runtime_api.execute_block_with_context( &at, execution_context, - Block::new(header, previous_block_extrinsics), + block, )?; } None => { diff --git a/client/shuffler/src/lib.rs b/client/shuffler/src/lib.rs index 075ab66047aef..c2e573bc6cdff 100644 --- a/client/shuffler/src/lib.rs +++ b/client/shuffler/src/lib.rs @@ -83,10 +83,17 @@ fn fisher_yates(data: &mut Vec, seed: [u8; 32]) { } } -pub fn shuffle_using_seed( - extrinsics: Vec<(Option, Block::Extrinsic)>, +pub fn shuffle_using_seed( + extrinsics: Vec<(Option, E)>, seed: [u8; 32], -) -> Vec { +) -> Vec { + log::debug!(target: "block_shuffler", "shuffling extrinsics with seed: {:2X?}", &seed[..]); + log::debug!(target: "block_shuffler", "origin order: ["); + for (_,tx) in extrinsics.iter() { + log::debug!(target: "block_shuffler", "{:?}", BlakeTwo256::hash(&tx.encode())); + } + log::debug!(target: "block_shuffler", "]"); + // generate exact number of slots for each account // [ Alice, Alice, Alice, ... , Bob, Bob, Bob, ... ] let mut slots: Vec> = @@ -120,11 +127,12 @@ pub fn shuffle_using_seed( }) .collect(); - log::debug!(target: "block_shuffler", "shuffled order"); + log::debug!(target: "block_shuffler", "shuffled order:["); for tx in shuffled_extrinsics.iter() { let tx_hash = BlakeTwo256::hash(&tx.encode()); - log::debug!(target: "block_shuffler", "extrinsic:{:?}", tx_hash); + log::debug!(target: "block_shuffler", "{:?}", tx_hash); } + log::debug!(target: "block_shuffler", "]"); shuffled_extrinsics } @@ -143,7 +151,6 @@ where Api: ProvideRuntimeApi + 'a, Api::Api: ExtrinsicInfoRuntimeApi, { - log::debug!(target: "block_shuffler", "shuffling extrinsics with seed: {:#X?}", seed.seed ); let extrinsics: Vec<(Option, Block::Extrinsic)> = extrinsics .into_iter() @@ -161,7 +168,7 @@ where (who, tx) }).collect(); - shuffle_using_seed::(extrinsics, seed.seed) + shuffle_using_seed::(extrinsics, seed.seed) } #[derive(derive_more::Display, Debug)] diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 9beefdce302e0..d145307e81bf6 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -131,7 +131,7 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionSource}, }; use codec::{Codec, Encode}; -use extrinsic_shuffler::shuffle_using_seed; +// use extrinsic_shuffler::shuffle_using_seed; use frame_system::{extrinsics_root, DigestOf}; /// Trait that can be used to execute a block. pub trait ExecuteBlock { @@ -297,7 +297,7 @@ where } /// Actually execute all transitions for `block`. - pub fn execute_block(block: Block, info: Vec>) { + pub fn execute_block(block: Block, _info: Vec>) { sp_io::init_tracing(); sp_tracing::within_span! { sp_tracing::info_span!( "execute_block", ?block); @@ -311,14 +311,20 @@ where // execute extrinsics let (header, extrinsics) = block.deconstruct(); - let extrinsics_with_author: Vec<(Option<_>,_)> = info.into_iter().zip(extrinsics.into_iter()).collect(); - let mut seed: [u8;32] = Default::default(); - seed.copy_from_slice(header.seed().as_ref()); - let shuffled_extrinsics = shuffle_using_seed::(extrinsics_with_author, seed); + // TODO: shuffling temporarly moved to native code. + // Motivation: + // There is no easy way to pass seed from native to wasm runtime. Shuffling at + // runtime can be reverted once we have fully working Header::seed field + // (including serialization & deserialization that is currently missing) - Self::execute_extrinsics_with_book_keeping(shuffled_extrinsics, *header.number()); + // let extrinsics_with_author: Vec<(Option<_>,_)> = info.into_iter().zip(extrinsics.into_iter()).collect(); + // let mut seed: [u8;32] = Default::default(); + // seed.copy_from_slice(header.seed().as_ref()); + // let shuffled_extrinsics = shuffle_using_seed::(extrinsics_with_author, seed); + // Self::execute_extrinsics_with_book_keeping(shuffled_extrinsics, *header.number()); + Self::execute_extrinsics_with_book_keeping(extrinsics, *header.number()); if !signature_batching.verify() { panic!("Signature verification failed."); }