mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-23 19:01:08 +00:00
runtime-api: add validation_code_hash API (#4629)
This is the first step to close https://github.com/paritytech/polkadot/issues/4524
This commit is contained in:
@@ -48,6 +48,7 @@ const INBOUND_HRMP_CHANNELS_CACHE_SIZE: usize = 64 * 1024;
|
|||||||
const CURRENT_BABE_EPOCH_CACHE_SIZE: usize = 64 * 1024;
|
const CURRENT_BABE_EPOCH_CACHE_SIZE: usize = 64 * 1024;
|
||||||
const ON_CHAIN_VOTES_CACHE_SIZE: usize = 3 * 1024;
|
const ON_CHAIN_VOTES_CACHE_SIZE: usize = 3 * 1024;
|
||||||
const PVFS_REQUIRE_PRECHECK_SIZE: usize = 1024;
|
const PVFS_REQUIRE_PRECHECK_SIZE: usize = 1024;
|
||||||
|
const VALIDATION_CODE_HASH_CACHE_SIZE: usize = 64 * 1024;
|
||||||
|
|
||||||
struct ResidentSizeOf<T>(T);
|
struct ResidentSizeOf<T>(T);
|
||||||
|
|
||||||
@@ -111,6 +112,10 @@ pub(crate) struct RequestResultCache {
|
|||||||
current_babe_epoch: MemoryLruCache<Hash, DoesNotAllocate<Epoch>>,
|
current_babe_epoch: MemoryLruCache<Hash, DoesNotAllocate<Epoch>>,
|
||||||
on_chain_votes: MemoryLruCache<Hash, ResidentSizeOf<Option<ScrapedOnChainVotes>>>,
|
on_chain_votes: MemoryLruCache<Hash, ResidentSizeOf<Option<ScrapedOnChainVotes>>>,
|
||||||
pvfs_require_precheck: MemoryLruCache<Hash, ResidentSizeOf<Vec<ValidationCodeHash>>>,
|
pvfs_require_precheck: MemoryLruCache<Hash, ResidentSizeOf<Vec<ValidationCodeHash>>>,
|
||||||
|
validation_code_hash: MemoryLruCache<
|
||||||
|
(Hash, ParaId, OccupiedCoreAssumption),
|
||||||
|
ResidentSizeOf<Option<ValidationCodeHash>>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RequestResultCache {
|
impl Default for RequestResultCache {
|
||||||
@@ -136,6 +141,7 @@ impl Default for RequestResultCache {
|
|||||||
current_babe_epoch: MemoryLruCache::new(CURRENT_BABE_EPOCH_CACHE_SIZE),
|
current_babe_epoch: MemoryLruCache::new(CURRENT_BABE_EPOCH_CACHE_SIZE),
|
||||||
on_chain_votes: MemoryLruCache::new(ON_CHAIN_VOTES_CACHE_SIZE),
|
on_chain_votes: MemoryLruCache::new(ON_CHAIN_VOTES_CACHE_SIZE),
|
||||||
pvfs_require_precheck: MemoryLruCache::new(PVFS_REQUIRE_PRECHECK_SIZE),
|
pvfs_require_precheck: MemoryLruCache::new(PVFS_REQUIRE_PRECHECK_SIZE),
|
||||||
|
validation_code_hash: MemoryLruCache::new(VALIDATION_CODE_HASH_CACHE_SIZE),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,6 +387,21 @@ impl RequestResultCache {
|
|||||||
) {
|
) {
|
||||||
self.pvfs_require_precheck.insert(relay_parent, ResidentSizeOf(pvfs))
|
self.pvfs_require_precheck.insert(relay_parent, ResidentSizeOf(pvfs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validation_code_hash(
|
||||||
|
&mut self,
|
||||||
|
key: (Hash, ParaId, OccupiedCoreAssumption),
|
||||||
|
) -> Option<&Option<ValidationCodeHash>> {
|
||||||
|
self.validation_code_hash.get(&key).map(|v| &v.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn cache_validation_code_hash(
|
||||||
|
&mut self,
|
||||||
|
key: (Hash, ParaId, OccupiedCoreAssumption),
|
||||||
|
value: Option<ValidationCodeHash>,
|
||||||
|
) {
|
||||||
|
self.validation_code_hash.insert(key, ResidentSizeOf(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum RequestResult {
|
pub(crate) enum RequestResult {
|
||||||
@@ -414,4 +435,5 @@ pub(crate) enum RequestResult {
|
|||||||
PvfsRequirePrecheck(Hash, Vec<ValidationCodeHash>),
|
PvfsRequirePrecheck(Hash, Vec<ValidationCodeHash>),
|
||||||
// This is a request with side-effects and no result, hence ().
|
// This is a request with side-effects and no result, hence ().
|
||||||
SubmitPvfCheckStatement(Hash, PvfCheckStatement, ValidatorSignature, ()),
|
SubmitPvfCheckStatement(Hash, PvfCheckStatement, ValidatorSignature, ()),
|
||||||
|
ValidationCodeHash(Hash, ParaId, OccupiedCoreAssumption, Option<ValidationCodeHash>),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,9 @@ where
|
|||||||
PvfsRequirePrecheck(relay_parent, pvfs) =>
|
PvfsRequirePrecheck(relay_parent, pvfs) =>
|
||||||
self.requests_cache.cache_pvfs_require_precheck(relay_parent, pvfs),
|
self.requests_cache.cache_pvfs_require_precheck(relay_parent, pvfs),
|
||||||
SubmitPvfCheckStatement(_, _, _, ()) => {},
|
SubmitPvfCheckStatement(_, _, _, ()) => {},
|
||||||
|
ValidationCodeHash(relay_parent, para_id, assumption, hash) => self
|
||||||
|
.requests_cache
|
||||||
|
.cache_validation_code_hash((relay_parent, para_id, assumption), hash),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +252,9 @@ where
|
|||||||
// This request is side-effecting and thus cannot be cached.
|
// This request is side-effecting and thus cannot be cached.
|
||||||
Some(request)
|
Some(request)
|
||||||
},
|
},
|
||||||
|
Request::ValidationCodeHash(para, assumption, sender) =>
|
||||||
|
query!(validation_code_hash(para, assumption), sender)
|
||||||
|
.map(|sender| Request::ValidationCodeHash(para, assumption, sender)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,6 +492,8 @@ where
|
|||||||
Request::PvfsRequirePrecheck(sender) => {
|
Request::PvfsRequirePrecheck(sender) => {
|
||||||
query!(PvfsRequirePrecheck, pvfs_require_precheck(), ver = 2, sender)
|
query!(PvfsRequirePrecheck, pvfs_require_precheck(), ver = 2, sender)
|
||||||
},
|
},
|
||||||
|
Request::ValidationCodeHash(para, assumption, sender) =>
|
||||||
|
query!(ValidationCodeHash, validation_code_hash(para, assumption), ver = 2, sender),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ struct MockRuntimeApi {
|
|||||||
on_chain_votes: Option<ScrapedOnChainVotes>,
|
on_chain_votes: Option<ScrapedOnChainVotes>,
|
||||||
submitted_pvf_check_statement: Arc<Mutex<Vec<(PvfCheckStatement, ValidatorSignature)>>>,
|
submitted_pvf_check_statement: Arc<Mutex<Vec<(PvfCheckStatement, ValidatorSignature)>>>,
|
||||||
pvfs_require_precheck: Vec<ValidationCodeHash>,
|
pvfs_require_precheck: Vec<ValidationCodeHash>,
|
||||||
|
validation_code_hash: HashMap<ParaId, ValidationCodeHash>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProvideRuntimeApi<Block> for MockRuntimeApi {
|
impl ProvideRuntimeApi<Block> for MockRuntimeApi {
|
||||||
@@ -183,6 +184,14 @@ sp_api::mock_impl_runtime_apis! {
|
|||||||
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
||||||
self.pvfs_require_precheck.clone()
|
self.pvfs_require_precheck.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validation_code_hash(
|
||||||
|
&self,
|
||||||
|
para: ParaId,
|
||||||
|
_assumption: OccupiedCoreAssumption,
|
||||||
|
) -> Option<ValidationCodeHash> {
|
||||||
|
self.validation_code_hash.get(¶).map(|c| c.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BabeApi<Block> for MockRuntimeApi {
|
impl BabeApi<Block> for MockRuntimeApi {
|
||||||
@@ -987,3 +996,51 @@ fn requests_pvfs_require_precheck() {
|
|||||||
|
|
||||||
futures::executor::block_on(future::join(subsystem_task, test_task));
|
futures::executor::block_on(future::join(subsystem_task, test_task));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn requests_validation_code_hash() {
|
||||||
|
let (ctx, mut ctx_handle) = make_subsystem_context(TaskExecutor::new());
|
||||||
|
|
||||||
|
let relay_parent = [1; 32].into();
|
||||||
|
let para_a = 5.into();
|
||||||
|
let para_b = 6.into();
|
||||||
|
let spawner = sp_core::testing::TaskExecutor::new();
|
||||||
|
let validation_code_hash = dummy_validation_code().hash();
|
||||||
|
|
||||||
|
let mut runtime_api = MockRuntimeApi::default();
|
||||||
|
runtime_api.validation_code_hash.insert(para_a, validation_code_hash.clone());
|
||||||
|
let runtime_api = Arc::new(runtime_api);
|
||||||
|
|
||||||
|
let subsystem = RuntimeApiSubsystem::new(runtime_api.clone(), Metrics(None), spawner);
|
||||||
|
let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap());
|
||||||
|
let test_task = async move {
|
||||||
|
let (tx, rx) = oneshot::channel();
|
||||||
|
|
||||||
|
ctx_handle
|
||||||
|
.send(FromOverseer::Communication {
|
||||||
|
msg: RuntimeApiMessage::Request(
|
||||||
|
relay_parent,
|
||||||
|
Request::ValidationCodeHash(para_a, OccupiedCoreAssumption::Included, tx),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(rx.await.unwrap().unwrap(), Some(validation_code_hash));
|
||||||
|
|
||||||
|
let (tx, rx) = oneshot::channel();
|
||||||
|
ctx_handle
|
||||||
|
.send(FromOverseer::Communication {
|
||||||
|
msg: RuntimeApiMessage::Request(
|
||||||
|
relay_parent,
|
||||||
|
Request::ValidationCodeHash(para_b, OccupiedCoreAssumption::Included, tx),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(rx.await.unwrap().unwrap(), None);
|
||||||
|
|
||||||
|
ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await;
|
||||||
|
};
|
||||||
|
|
||||||
|
futures::executor::block_on(future::join(subsystem_task, test_task));
|
||||||
|
}
|
||||||
|
|||||||
@@ -673,6 +673,13 @@ pub enum RuntimeApiRequest {
|
|||||||
SubmitPvfCheckStatement(PvfCheckStatement, ValidatorSignature, RuntimeApiSender<()>),
|
SubmitPvfCheckStatement(PvfCheckStatement, ValidatorSignature, RuntimeApiSender<()>),
|
||||||
/// Returns code hashes of PVFs that require pre-checking by validators in the active set.
|
/// Returns code hashes of PVFs that require pre-checking by validators in the active set.
|
||||||
PvfsRequirePrecheck(RuntimeApiSender<Vec<ValidationCodeHash>>),
|
PvfsRequirePrecheck(RuntimeApiSender<Vec<ValidationCodeHash>>),
|
||||||
|
/// Get the validation code used by the specified para, taking the given `OccupiedCoreAssumption`, which
|
||||||
|
/// will inform on how the validation data should be computed if the para currently occupies a core.
|
||||||
|
ValidationCodeHash(
|
||||||
|
ParaId,
|
||||||
|
OccupiedCoreAssumption,
|
||||||
|
RuntimeApiSender<Option<ValidationCodeHash>>,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A message to the Runtime API subsystem.
|
/// A message to the Runtime API subsystem.
|
||||||
|
|||||||
@@ -215,6 +215,8 @@ specialize_requests! {
|
|||||||
fn request_candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt>; CandidatePendingAvailability;
|
fn request_candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt>; CandidatePendingAvailability;
|
||||||
fn request_candidate_events() -> Vec<CandidateEvent>; CandidateEvents;
|
fn request_candidate_events() -> Vec<CandidateEvent>; CandidateEvents;
|
||||||
fn request_session_info(index: SessionIndex) -> Option<SessionInfo>; SessionInfo;
|
fn request_session_info(index: SessionIndex) -> Option<SessionInfo>; SessionInfo;
|
||||||
|
fn request_validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
|
||||||
|
-> Option<ValidationCodeHash>; ValidationCodeHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// From the given set of validators, find the first key we can sign with, if any.
|
/// From the given set of validators, find the first key we can sign with, if any.
|
||||||
|
|||||||
@@ -222,5 +222,11 @@ sp_api::decl_runtime_apis! {
|
|||||||
///
|
///
|
||||||
/// NOTE: This function is only available since parachain host version 2.
|
/// NOTE: This function is only available since parachain host version 2.
|
||||||
fn pvfs_require_precheck() -> Vec<v1::ValidationCodeHash>;
|
fn pvfs_require_precheck() -> Vec<v1::ValidationCodeHash>;
|
||||||
|
|
||||||
|
/// Fetch the hash of the validation code used by a para, making the given `OccupiedCoreAssumption`.
|
||||||
|
///
|
||||||
|
/// NOTE: This function is only available since parachain host version 2.
|
||||||
|
fn validation_code_hash(para_id: v1::Id, assumption: v1::OccupiedCoreAssumption)
|
||||||
|
-> Option<v1::ValidationCodeHash>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,3 +11,11 @@ Fetch the validation code (past, present or future) by its hash.
|
|||||||
```rust
|
```rust
|
||||||
fn validation_code_by_hash(at: Block, ValidationCodeHash) -> Option<ValidationCode>;
|
fn validation_code_by_hash(at: Block, ValidationCodeHash) -> Option<ValidationCode>;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Fetch the validation code hash used by a para, making the given `OccupiedCoreAssumption`.
|
||||||
|
|
||||||
|
> ⚠️ This API was introduced in `ParachainHost` v2.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
fn validation_code_hash(at: Block, ParaId, OccupiedCoreAssumption) -> Option<ValidationCodeHash>;
|
||||||
|
```
|
||||||
|
|||||||
@@ -1830,6 +1830,12 @@ sp_api::impl_runtime_apis! {
|
|||||||
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
||||||
parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
|
parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
|
||||||
|
-> Option<ValidationCodeHash>
|
||||||
|
{
|
||||||
|
parachains_runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
||||||
|
|||||||
@@ -389,3 +389,16 @@ pub fn submit_pvf_check_statement<T: paras::Config>(
|
|||||||
pub fn pvfs_require_precheck<T: paras::Config>() -> Vec<ValidationCodeHash> {
|
pub fn pvfs_require_precheck<T: paras::Config>() -> Vec<ValidationCodeHash> {
|
||||||
<paras::Pallet<T>>::pvfs_require_precheck()
|
<paras::Pallet<T>>::pvfs_require_precheck()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the validation code hash for the given parachain making the given `OccupiedCoreAssumption`.
|
||||||
|
pub fn validation_code_hash<T>(
|
||||||
|
para_id: ParaId,
|
||||||
|
assumption: OccupiedCoreAssumption,
|
||||||
|
) -> Option<ValidationCodeHash>
|
||||||
|
where
|
||||||
|
T: inclusion::Config,
|
||||||
|
{
|
||||||
|
with_assumption::<T, _, _>(para_id, assumption, || {
|
||||||
|
<paras::Pallet<T>>::current_code_hash(¶_id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1797,6 +1797,12 @@ sp_api::impl_runtime_apis! {
|
|||||||
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
||||||
parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
|
parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
|
||||||
|
-> Option<ValidationCodeHash>
|
||||||
|
{
|
||||||
|
parachains_runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
||||||
|
|||||||
@@ -1383,6 +1383,12 @@ sp_api::impl_runtime_apis! {
|
|||||||
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
||||||
runtime_api_impl::pvfs_require_precheck::<Runtime>()
|
runtime_api_impl::pvfs_require_precheck::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
|
||||||
|
-> Option<ValidationCodeHash>
|
||||||
|
{
|
||||||
|
runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fg_primitives::GrandpaApi<Block> for Runtime {
|
impl fg_primitives::GrandpaApi<Block> for Runtime {
|
||||||
|
|||||||
@@ -888,6 +888,12 @@ sp_api::impl_runtime_apis! {
|
|||||||
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
||||||
runtime_impl::pvfs_require_precheck::<Runtime>()
|
runtime_impl::pvfs_require_precheck::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
|
||||||
|
-> Option<ValidationCodeHash>
|
||||||
|
{
|
||||||
|
runtime_impl::validation_code_hash::<Runtime>(para_id, assumption)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
||||||
|
|||||||
@@ -1401,6 +1401,12 @@ sp_api::impl_runtime_apis! {
|
|||||||
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
fn pvfs_require_precheck() -> Vec<ValidationCodeHash> {
|
||||||
parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
|
parachains_runtime_api_impl::pvfs_require_precheck::<Runtime>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validation_code_hash(para_id: ParaId, assumption: OccupiedCoreAssumption)
|
||||||
|
-> Option<ValidationCodeHash>
|
||||||
|
{
|
||||||
|
parachains_runtime_api_impl::validation_code_hash::<Runtime>(para_id, assumption)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
impl beefy_primitives::BeefyApi<Block> for Runtime {
|
||||||
|
|||||||
Reference in New Issue
Block a user