Merge pull request #9 from paritytech/stas-6-validate-block-parent-hash

Pass parent hash to the validate_block function
This commit is contained in:
Bastian Köcher
2019-05-07 08:33:39 +02:00
committed by GitHub
3 changed files with 41 additions and 17 deletions
@@ -56,14 +56,16 @@ trait Storage {
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
#[doc(hidden)] #[doc(hidden)]
pub fn validate_block<B: BlockT, E: ExecuteBlock<B>>( pub fn validate_block<B: BlockT, E: ExecuteBlock<B>>(
mut block_data: &[u8], mut arguments: &[u8],
) { ) {
use codec::Decode; use codec::Decode;
let block_data = crate::ParachainBlockData::<B>::decode(&mut block_data) let (parent_hash, block_data): (B::Hash, crate::ParachainBlockData::<B>) = Decode::decode(&mut arguments)
.expect("Could not decode parachain block."); .expect("Could not decode parachain block.");
// TODO: Add `PolkadotInherent`. // TODO: Add `PolkadotInherent`.
let block = B::new(block_data.header, block_data.extrinsics); let block = B::new(block_data.header, block_data.extrinsics);
assert!(parent_hash == *block.header().parent_hash(), "Invalid parent hash");
let storage = WitnessStorage::<B>::new( let storage = WitnessStorage::<B>::new(
block_data.witness_data, block_data.witness_data,
block_data.witness_data_storage_root, block_data.witness_data_storage_root,
+6 -6
View File
@@ -57,17 +57,17 @@ macro_rules! register_validate_block_impl {
#[no_mangle] #[no_mangle]
unsafe fn validate_block( unsafe fn validate_block(
block_data: *const u8, arguments: *const u8,
block_data_len: u64, arguments_len: u64,
) { ) {
let block_data = $crate::slice::from_raw_parts( let arguments = $crate::slice::from_raw_parts(
block_data, arguments,
block_data_len as usize, arguments_len as usize,
); );
$crate::validate_block::implementation::validate_block::< $crate::validate_block::implementation::validate_block::<
$block, $block_executor $block, $block_executor
>(block_data); >(arguments);
} }
} }
}; };
+31 -9
View File
@@ -23,7 +23,8 @@ use runtime_primitives::traits::{Block as BlockT, Header as HeaderT};
use executor::{WasmExecutor, error::Result, wasmi::RuntimeValue::{I64, I32}}; use executor::{WasmExecutor, error::Result, wasmi::RuntimeValue::{I64, I32}};
use test_client::{ use test_client::{
TestClientBuilder, TestClient, TestClientBuilder, TestClient,
runtime::{Block, Transfer}, TestClientBuilderExt, runtime::{Block, Transfer, Hash}, TestClientBuilderExt,
client_ext::TestClient as _,
}; };
use std::collections::HashMap; use std::collections::HashMap;
@@ -33,7 +34,7 @@ use codec::Encode;
const WASM_CODE: &[u8] = const WASM_CODE: &[u8] =
include_bytes!("../../../test/runtime/wasm/target/wasm32-unknown-unknown/release/cumulus_test_runtime.compact.wasm"); include_bytes!("../../../test/runtime/wasm/target/wasm32-unknown-unknown/release/cumulus_test_runtime.compact.wasm");
fn call_validate_block(block_data: ParachainBlockData<Block>) -> Result<()> { fn call_validate_block(parent_hash: Hash, block_data: ParachainBlockData<Block>) -> Result<()> {
let mut ext = TestExternalities::default(); let mut ext = TestExternalities::default();
WasmExecutor::new().call_with_custom_signature( WasmExecutor::new().call_with_custom_signature(
&mut ext, &mut ext,
@@ -41,13 +42,13 @@ fn call_validate_block(block_data: ParachainBlockData<Block>) -> Result<()> {
&WASM_CODE, &WASM_CODE,
"validate_block", "validate_block",
|alloc| { |alloc| {
let block_data = block_data.encode(); let arguments = (parent_hash, block_data).encode();
let block_data_offset = alloc(&block_data)?; let arguments_offset = alloc(&arguments)?;
Ok( Ok(
vec![ vec![
I32(block_data_offset as i32), I32(arguments_offset as i32),
I64(block_data.len() as i64), I64(arguments.len() as i64),
] ]
) )
}, },
@@ -131,7 +132,7 @@ fn validate_block_with_no_extrinsics() {
witness_data, witness_data,
witness_data_storage_root witness_data_storage_root
); );
call_validate_block(block_data).expect("Calls `validate_block`"); call_validate_block(client.genesis_hash(), block_data).expect("Calls `validate_block`");
} }
#[test] #[test]
@@ -150,5 +151,26 @@ fn validate_block_with_extrinsics() {
witness_data, witness_data,
witness_data_storage_root witness_data_storage_root
); );
call_validate_block(block_data).expect("Calls `validate_block`"); call_validate_block(client.genesis_hash(), block_data).expect("Calls `validate_block`");
} }
#[test]
#[should_panic]
fn validate_block_invalid_parent_hash() {
let client = create_test_client();
let witness_data_storage_root = *client
.best_block_header()
.expect("Best block exists")
.state_root();
let (block, witness_data) = build_block_with_proof(&client, Vec::new());
let (mut header, extrinsics) = block.deconstruct();
header.set_parent_hash(Hash::from_low_u64_be(1));
let block_data = ParachainBlockData::new(
header,
extrinsics,
witness_data,
witness_data_storage_root
);
call_validate_block(client.genesis_hash(), block_data).expect("Calls `validate_block`");
}