mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 09:21:04 +00:00
Do not use rely on the block initialization when calling runtime APIs (#2123)
* Don't initialize block when calling runtime APIs * Adapt check_validation_outputs We split the code path for the inclusion and for the commitments checking. * Slap #[skip_initialize_block] on safe runtime APIs That is, those that should not be affected by this attribute * Make `Scheduled` not ephemeral So that it is persisted in the storage and ready to be inspected by the runtime APIs. This is in contrast to what was before, where we would remove the storage entry and then rely on the scheduling performed by `on_initialize` again. * Add a big fat comment * Typos Co-authored-by: Robert Habermeier <rphmeier@gmail.com> * Move session change to the end of the current block Previously, it was the beginning of the next block. This allows us to put #[skip_initialize_block] * Update tests * Fix a test in paras registrar Also refactor it a bit so the next time there are more chances this kind of issue is diagnosed quicker. * Add for_runtime_api to inclusion's check_validation_outputs Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
@@ -719,16 +719,37 @@ pub struct SessionInfo {
|
||||
sp_api::decl_runtime_apis! {
|
||||
/// The API for querying the state of parachains on-chain.
|
||||
pub trait ParachainHost<H: Decode = Hash, N: Encode + Decode = BlockNumber> {
|
||||
// NOTE: Many runtime API are declared with `#[skip_initialize_block]`. This is because without
|
||||
// this attribute before each runtime call, the `initialize_block` runtime API will be called.
|
||||
// That in turns will lead to two things:
|
||||
//
|
||||
// (a) The frame_system module will be initialized to the next block.
|
||||
// (b) Initialization sequences for each runtime module (pallet) will be run.
|
||||
//
|
||||
// (a) is undesirable because the runtime APIs are querying the state against a specific
|
||||
// block state. However, due to that initialization the observed block number would be as if
|
||||
// it was the next block.
|
||||
//
|
||||
// We dont want (b) mainly because block initialization can be very heavy. Upgrade enactment,
|
||||
// storage migration, and whatever other logic exists in `on_initialize` will be executed
|
||||
// if not explicitly opted out with the `#[skip_initialize_block]` attribute.
|
||||
//
|
||||
// Additionally, some runtime APIs may depend on state that is pruned on the `on_initialize`.
|
||||
// At the moment of writing, this is `candidate_events`.
|
||||
|
||||
/// Get the current validators.
|
||||
#[skip_initialize_block]
|
||||
fn validators() -> Vec<ValidatorId>;
|
||||
|
||||
/// Returns the validator groups and rotation info localized based on the block whose state
|
||||
/// this is invoked on. Note that `now` in the `GroupRotationInfo` should be the successor of
|
||||
/// the number of the block.
|
||||
#[skip_initialize_block]
|
||||
fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<N>);
|
||||
|
||||
/// Yields information on all availability cores. Cores are either free or occupied. Free
|
||||
/// cores can have paras assigned to them.
|
||||
#[skip_initialize_block]
|
||||
fn availability_cores() -> Vec<CoreState<H, N>>;
|
||||
|
||||
/// Yields the full validation data for the given ParaId along with an assumption that
|
||||
@@ -736,6 +757,7 @@ sp_api::decl_runtime_apis! {
|
||||
///
|
||||
/// Returns `None` if either the para is not registered or the assumption is `Freed`
|
||||
/// and the para already occupies a core.
|
||||
#[skip_initialize_block]
|
||||
fn full_validation_data(para_id: Id, assumption: OccupiedCoreAssumption)
|
||||
-> Option<ValidationData<N>>;
|
||||
|
||||
@@ -744,24 +766,29 @@ sp_api::decl_runtime_apis! {
|
||||
///
|
||||
/// Returns `None` if either the para is not registered or the assumption is `Freed`
|
||||
/// and the para already occupies a core.
|
||||
#[skip_initialize_block]
|
||||
fn persisted_validation_data(para_id: Id, assumption: OccupiedCoreAssumption)
|
||||
-> Option<PersistedValidationData<N>>;
|
||||
|
||||
/// Checks if the given validation outputs pass the acceptance criteria.
|
||||
#[skip_initialize_block]
|
||||
fn check_validation_outputs(para_id: Id, outputs: CandidateCommitments) -> bool;
|
||||
|
||||
/// Returns the session index expected at a child of the block.
|
||||
///
|
||||
/// This can be used to instantiate a `SigningContext`.
|
||||
#[skip_initialize_block]
|
||||
fn session_index_for_child() -> SessionIndex;
|
||||
|
||||
/// Get the session info for the given session, if stored.
|
||||
#[skip_initialize_block]
|
||||
fn session_info(index: SessionIndex) -> Option<SessionInfo>;
|
||||
|
||||
/// Fetch the validation code used by a para, making the given `OccupiedCoreAssumption`.
|
||||
///
|
||||
/// Returns `None` if either the para is not registered or the assumption is `Freed`
|
||||
/// and the para already occupies a core.
|
||||
#[skip_initialize_block]
|
||||
fn validation_code(para_id: Id, assumption: OccupiedCoreAssumption)
|
||||
-> Option<ValidationCode>;
|
||||
|
||||
@@ -770,26 +797,28 @@ sp_api::decl_runtime_apis! {
|
||||
///
|
||||
/// `context_height` may be no greater than the height of the block in whose
|
||||
/// state the runtime API is executed.
|
||||
#[skip_initialize_block]
|
||||
fn historical_validation_code(para_id: Id, context_height: N)
|
||||
-> Option<ValidationCode>;
|
||||
|
||||
/// Get the receipt of a candidate pending availability. This returns `Some` for any paras
|
||||
/// assigned to occupied cores in `availability_cores` and `None` otherwise.
|
||||
#[skip_initialize_block]
|
||||
fn candidate_pending_availability(para_id: Id) -> Option<CommittedCandidateReceipt<H>>;
|
||||
|
||||
/// Get a vector of events concerning candidates that occurred within a block.
|
||||
// NOTE: this needs to skip block initialization as events are wiped within block
|
||||
// initialization.
|
||||
#[skip_initialize_block]
|
||||
fn candidate_events() -> Vec<CandidateEvent<H>>;
|
||||
|
||||
/// Get all the pending inbound messages in the downward message queue for a para.
|
||||
#[skip_initialize_block]
|
||||
fn dmq_contents(
|
||||
recipient: Id,
|
||||
) -> Vec<InboundDownwardMessage<N>>;
|
||||
|
||||
/// Get the contents of all channels addressed to the given recipient. Channels that have no
|
||||
/// messages in them are also included.
|
||||
#[skip_initialize_block]
|
||||
fn inbound_hrmp_channels_contents(recipient: Id) -> BTreeMap<Id, Vec<InboundHrmpMessage<N>>>;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user