Refactor validate_block (#2069)

* Refactor `validate_block`

This pull request changes the `validate_block` implementation. One of the key changes are that we
free data structures as early as possible. The memory while validating the block is scarce and we
need to give as much as possible to the actual execution of the block. Besides that the pr moves the
validation of the `validation_data` into the `validate_block` implementation completely instead of
using this machinery with putting the data into some global variable that would then be read while
executing the block. There are also some new docs to explain the internals of `validate_block`.

* No clone wars!!

* Integrate more feedback

* FMT

* Delay the header encoding
This commit is contained in:
Bastian Köcher
2023-01-10 17:42:41 +01:00
committed by GitHub
parent 7679cee58b
commit d5d92edcbf
5 changed files with 197 additions and 110 deletions
@@ -16,36 +16,43 @@
//! A module that enables a runtime to work as parachain.
use polkadot_parachain::primitives::ValidationParams;
#[cfg(not(feature = "std"))]
#[doc(hidden)]
pub mod implementation;
#[cfg(test)]
mod tests;
#[cfg(not(feature = "std"))]
#[doc(hidden)]
pub use bytes;
#[cfg(not(feature = "std"))]
#[doc(hidden)]
pub use codec::decode_from_bytes;
#[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)
#[doc(hidden)]
pub use sp_std;
/// Basically the same as [`ValidationParams`](polkadot_parachain::primitives::ValidationParams),
/// but a little bit optimized for our use case here.
///
/// `block_data` and `head_data` are represented as [`bytes::Bytes`] to make them reuse
/// the memory of the input parameter of the exported `validate_blocks` function.
///
/// The layout of this type must match exactly the layout of
/// [`ValidationParams`](polkadot_parachain::primitives::ValidationParams) to have the same
/// SCALE encoding.
#[derive(codec::Decode)]
#[cfg_attr(feature = "std", derive(codec::Encode))]
#[doc(hidden)]
pub struct MemoryOptimizedValidationParams {
pub parent_head: bytes::Bytes,
pub block_data: bytes::Bytes,
pub relay_parent_number: cumulus_primitives_core::relay_chain::v2::BlockNumber,
pub relay_parent_storage_root: cumulus_primitives_core::relay_chain::v2::Hash,
}