Change the way we store, handle and validate the validation data (#342)

Currently validation data is shared by using a well known key between
the parachain system pallet and the validate block implementation. This
pr changes this by passing the parachain system directly to the validate
block implementation to make use of it. Besides that, we also store the
validation params in some thread local variable to make it inspectable
by parachain system. This moves the validation of validation data and
validation params to the parachain system pallet directly, instead of
having this hidden inside the validate block implementation.

Fixes: https://github.com/paritytech/cumulus/issues/217
This commit is contained in:
Bastian Köcher
2021-02-27 18:46:25 +01:00
committed by GitHub
parent 9535ee26ab
commit f511757069
9 changed files with 152 additions and 247 deletions
@@ -16,6 +16,8 @@
//! A module that enables a runtime to work as parachain.
use polkadot_parachain::primitives::ValidationParams;
#[cfg(not(feature = "std"))]
#[doc(hidden)]
pub mod implementation;
@@ -25,28 +27,50 @@ mod tests;
#[cfg(not(feature = "std"))]
#[doc(hidden)]
pub use polkadot_parachain;
#[cfg(not(feature = "std"))]
#[doc(hidden)]
pub use sp_runtime::traits::GetRuntimeBlockType;
// Stores the [`ValidationParams`] that are being passed to `validate_block`.
//
// This value will only be set when a parachain validator validates a given `PoV`.
environmental::environmental!(VALIDATION_PARAMS: ValidationParams);
/// Execute the given closure with the [`ValidationParams`].
///
/// Returns `None` if the [`ValidationParams`] are not set, because the code is currently not being
/// executed in the context of `validate_block`.
pub(crate) fn with_validation_params<R>(f: impl FnOnce(&ValidationParams) -> R) -> Option<R> {
VALIDATION_PARAMS::with(|v| f(v))
}
/// Set the [`ValidationParams`] for the local context and execute the given closure in this context.
#[cfg(not(feature = "std"))]
fn set_and_run_with_validation_params<R>(mut params: ValidationParams, f: impl FnOnce() -> R) -> R {
VALIDATION_PARAMS::using(&mut params, f)
}
/// Register the `validate_block` function that is used by parachains to validate blocks on a
/// validator.
///
/// Does *nothing* when `std` feature is enabled.
///
/// Expects as parameters the block and the block executor.
/// Expects as parameters the runtime and a block executor.
///
/// # Example
///
/// ```
/// struct Block;
/// struct BlockExecutor;
/// struct Runtime;
///
/// cumulus_pallet_parachain_system::register_validate_block!(Block, BlockExecutor);
/// cumulus_pallet_parachain_system::register_validate_block!(Runtime, BlockExecutor);
///
/// # fn main() {}
/// ```
#[macro_export]
macro_rules! register_validate_block {
($block:ty, $block_executor:ty) => {
$crate::register_validate_block_impl!($block, $block_executor);
($runtime:ty, $block_executor:ty) => {
$crate::register_validate_block_impl!($runtime, $block_executor);
};
}
@@ -55,19 +79,22 @@ macro_rules! register_validate_block {
#[doc(hidden)]
#[macro_export]
macro_rules! register_validate_block_impl {
($block:ty, $block_executor:ty) => {
($runtime:ty, $block_executor:ty) => {
#[doc(hidden)]
mod parachain_validate_block {
use super::*;
#[no_mangle]
unsafe fn validate_block(arguments: *const u8, arguments_len: usize) -> u64 {
let params =
$crate::validate_block::polkadot_parachain::load_params(arguments, arguments_len);
let params = $crate::validate_block::polkadot_parachain::load_params(
arguments,
arguments_len,
);
let res = $crate::validate_block::implementation::validate_block::<
$block,
<$runtime as $crate::validate_block::GetRuntimeBlockType>::RuntimeBlock,
$block_executor,
$runtime,
>(params);
$crate::validate_block::polkadot_parachain::write_result(&res)
@@ -81,5 +108,5 @@ macro_rules! register_validate_block_impl {
#[doc(hidden)]
#[macro_export]
macro_rules! register_validate_block_impl {
($block:ty, $block_executor:ty) => {};
($runtime:ty, $block_executor:ty) => {};
}