mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 12:51:02 +00:00
Implement Runtime APIs (#1411)
* create a README on Runtime APIs * add ParaId type * write up runtime APIs * more preamble * rename * rejig runtime APIs * add occupied_since to `BlockNumber` * skeleton crate for runtime API subsystem * improve group_for_core * improve docs on availability cores runtime API * guide: freed -> free * add primitives for runtime APIs * create a v1 ParachainHost API trait * guide: make validation code return `Option`al. * skeleton runtime API helpers * make parachain-host runtime-generic * skeleton for most runtime API implementation functions * guide: add runtime API helper methods * implement new helpers of the inclusion module * guide: remove retries check, as it is unneeded * implement helpers for scheduler module for Runtime APIs * clean up `validator_groups` implementation * implement next_rotation_at and last_rotation_at * guide: more helpers on GroupRotationInfo * almost finish implementing runtime APIs * add explicit block parameter to runtime API fns * guide: generalize number parameter * guide: add group_responsible to occupied-core * update primitives due to guide changes * finishing touches on runtime API implementation; squash warnings * break out runtime API impl to separate file * add tests for next_up logic * test group rotation info * point to filed TODO * remove unused TODO [now] * indentation * guide: para -> para_id * rename para field to para_id for core meta * remove reference to outdated AvailabilityCores type * add an event in `inclusion` for candidates being included or timing out * guide: candidate events * guide: adjust language * Candidate events type from guide and adjust inclusion event * implement `candidate_events` runtime API * fix runtime test compilation * max -> min * fix typos * guide: add `RuntimeAPIRequest::CandidateEvents`
This commit is contained in:
committed by
GitHub
parent
5624bd8bf4
commit
dddde219a2
@@ -25,12 +25,11 @@ use primitives::v1::{
|
||||
ValidatorId, CandidateCommitments, CandidateDescriptor, ValidatorIndex, Id as ParaId,
|
||||
AvailabilityBitfield as AvailabilityBitfield, SignedAvailabilityBitfields, SigningContext,
|
||||
BackedCandidate, CoreIndex, GroupIndex, CoreAssignment, CommittedCandidateReceipt,
|
||||
CandidateReceipt, HeadData,
|
||||
};
|
||||
use frame_support::{
|
||||
decl_storage, decl_module, decl_error, ensure, dispatch::DispatchResult, IterableStorageMap,
|
||||
weights::Weight,
|
||||
traits::Get,
|
||||
debug,
|
||||
decl_storage, decl_module, decl_error, decl_event, ensure, debug,
|
||||
dispatch::DispatchResult, IterableStorageMap, weights::Weight, traits::Get,
|
||||
};
|
||||
use codec::{Encode, Decode};
|
||||
use bitvec::{order::Lsb0 as BitOrderLsb0, vec::BitVec};
|
||||
@@ -69,7 +68,28 @@ pub struct CandidatePendingAvailability<H, N> {
|
||||
backed_in_number: N,
|
||||
}
|
||||
|
||||
pub trait Trait: system::Trait + paras::Trait + configuration::Trait { }
|
||||
impl<H, N> CandidatePendingAvailability<H, N> {
|
||||
/// Get the availability votes on the candidate.
|
||||
pub(crate) fn availability_votes(&self) -> &BitVec<BitOrderLsb0, u8> {
|
||||
&self.availability_votes
|
||||
}
|
||||
|
||||
/// Get the relay-chain block number this was backed in.
|
||||
pub(crate) fn backed_in_number(&self) -> &N {
|
||||
&self.backed_in_number
|
||||
}
|
||||
|
||||
/// Get the core index.
|
||||
pub(crate) fn core_occupied(&self)-> CoreIndex {
|
||||
self.core.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Trait:
|
||||
system::Trait + paras::Trait + configuration::Trait
|
||||
{
|
||||
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as ParaInclusion {
|
||||
@@ -89,7 +109,7 @@ decl_storage! {
|
||||
Validators get(fn validators) config(validators): Vec<ValidatorId>;
|
||||
|
||||
/// The current session index.
|
||||
CurrentSessionIndex: SessionIndex;
|
||||
CurrentSessionIndex get(fn session_index): SessionIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,10 +150,25 @@ decl_error! {
|
||||
}
|
||||
}
|
||||
|
||||
decl_event! {
|
||||
pub enum Event<T> where <T as system::Trait>::Hash {
|
||||
/// A candidate was backed.
|
||||
CandidateBacked(CandidateReceipt<Hash>, HeadData),
|
||||
/// A candidate was included.
|
||||
CandidateIncluded(CandidateReceipt<Hash>, HeadData),
|
||||
/// A candidate timed out.
|
||||
CandidateTimedOut(CandidateReceipt<Hash>, HeadData),
|
||||
}
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
/// The parachain-candidate inclusion module.
|
||||
pub struct Module<T: Trait> for enum Call where origin: <T as system::Trait>::Origin, system = system {
|
||||
pub struct Module<T: Trait>
|
||||
for enum Call where origin: <T as system::Trait>::Origin, system = system
|
||||
{
|
||||
type Error = Error<T>;
|
||||
|
||||
fn deposit_event() = default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,7 +485,17 @@ impl<T: Trait> Module<T> {
|
||||
// initialize all availability votes to 0.
|
||||
let availability_votes: BitVec<BitOrderLsb0, u8>
|
||||
= bitvec::bitvec![BitOrderLsb0, u8; 0; validators.len()];
|
||||
let (descriptor, commitments) = (candidate.candidate.descriptor, candidate.candidate.commitments);
|
||||
|
||||
Self::deposit_event(Event::<T>::CandidateBacked(
|
||||
candidate.candidate.to_plain(),
|
||||
candidate.candidate.commitments.head_data.clone(),
|
||||
));
|
||||
|
||||
let (descriptor, commitments) = (
|
||||
candidate.candidate.descriptor,
|
||||
candidate.candidate.commitments,
|
||||
);
|
||||
|
||||
<PendingAvailability<T>>::insert(¶_id, CandidatePendingAvailability {
|
||||
core,
|
||||
descriptor,
|
||||
@@ -468,6 +513,7 @@ impl<T: Trait> Module<T> {
|
||||
relay_parent_number: T::BlockNumber,
|
||||
receipt: CommittedCandidateReceipt<T::Hash>,
|
||||
) -> Weight {
|
||||
let plain = receipt.to_plain();
|
||||
let commitments = receipt.commitments;
|
||||
let config = <configuration::Module<T>>::config();
|
||||
|
||||
@@ -481,6 +527,10 @@ impl<T: Trait> Module<T> {
|
||||
);
|
||||
}
|
||||
|
||||
Self::deposit_event(
|
||||
Event::<T>::CandidateIncluded(plain, commitments.head_data.clone())
|
||||
);
|
||||
|
||||
weight + <paras::Module<T>>::note_new_head(
|
||||
receipt.descriptor.para_id,
|
||||
commitments.head_data,
|
||||
@@ -506,12 +556,66 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
|
||||
for para_id in cleaned_up_ids {
|
||||
<PendingAvailability<T>>::remove(¶_id);
|
||||
<PendingAvailabilityCommitments>::remove(¶_id);
|
||||
let pending = <PendingAvailability<T>>::take(¶_id);
|
||||
let commitments = <PendingAvailabilityCommitments>::take(¶_id);
|
||||
|
||||
if let (Some(pending), Some(commitments)) = (pending, commitments) {
|
||||
// defensive: this should always be true.
|
||||
let candidate = CandidateReceipt {
|
||||
descriptor: pending.descriptor,
|
||||
commitments_hash: commitments.hash(),
|
||||
};
|
||||
|
||||
Self::deposit_event(Event::<T>::CandidateTimedOut(
|
||||
candidate,
|
||||
commitments.head_data,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
cleaned_up_cores
|
||||
}
|
||||
|
||||
/// Forcibly enact the candidate with the given ID as though it had been deemed available
|
||||
/// by bitfields.
|
||||
///
|
||||
/// Is a no-op if there is no candidate pending availability for this para-id.
|
||||
/// This should generally not be used but it is useful during execution of Runtime APIs,
|
||||
/// where the changes to the state are expected to be discarded directly after.
|
||||
pub(crate) fn force_enact(para: ParaId) {
|
||||
let pending = <PendingAvailability<T>>::take(¶);
|
||||
let commitments = <PendingAvailabilityCommitments>::take(¶);
|
||||
|
||||
if let (Some(pending), Some(commitments)) = (pending, commitments) {
|
||||
let candidate = CommittedCandidateReceipt {
|
||||
descriptor: pending.descriptor,
|
||||
commitments,
|
||||
};
|
||||
|
||||
Self::enact_candidate(
|
||||
pending.relay_parent_number,
|
||||
candidate,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the CommittedCandidateReceipt pending availability for the para provided, if any.
|
||||
pub(crate) fn candidate_pending_availability(para: ParaId)
|
||||
-> Option<CommittedCandidateReceipt<T::Hash>>
|
||||
{
|
||||
<PendingAvailability<T>>::get(¶)
|
||||
.map(|p| p.descriptor)
|
||||
.and_then(|d| <PendingAvailabilityCommitments>::get(¶).map(move |c| (d, c)))
|
||||
.map(|(d, c)| CommittedCandidateReceipt { descriptor: d, commitments: c })
|
||||
}
|
||||
|
||||
/// Returns the metadata around the candidate pending availability for the
|
||||
/// para provided, if any.
|
||||
pub(crate) fn pending_availability(para: ParaId)
|
||||
-> Option<CandidatePendingAvailability<T::Hash, T::BlockNumber>>
|
||||
{
|
||||
<PendingAvailability<T>>::get(¶)
|
||||
}
|
||||
}
|
||||
|
||||
const fn availability_threshold(n_validators: usize) -> usize {
|
||||
@@ -527,7 +631,7 @@ mod tests {
|
||||
use primitives::v1::{BlockNumber, Hash};
|
||||
use primitives::v1::{
|
||||
SignedAvailabilityBitfield, CompactStatement as Statement, ValidityAttestation, CollatorId,
|
||||
CandidateCommitments, SignedStatement, CandidateDescriptor, HeadData, ValidationCode,
|
||||
CandidateCommitments, SignedStatement, CandidateDescriptor, ValidationCode,
|
||||
AssignmentKind,
|
||||
};
|
||||
use frame_support::traits::{OnFinalize, OnInitialize};
|
||||
|
||||
Reference in New Issue
Block a user