From 8c3bc2b2bb4f41f54fba78add13d076f03571c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Fri, 11 Jun 2021 19:00:57 +0100 Subject: [PATCH] replace HistoricalValidationCode usages with ValidationCodeByHash (#3210) * replace HistoricalValidationCode usages with ValidationCodeByHash * runtime-api: tabify tests file * update implementers guide --- polkadot/node/core/approval-voting/src/lib.rs | 24 +- polkadot/node/core/runtime-api/src/cache.rs | 35 +- polkadot/node/core/runtime-api/src/lib.rs | 14 +- polkadot/node/core/runtime-api/src/tests.rs | 1169 ++++++++--------- polkadot/node/subsystem/src/messages.rs | 46 +- polkadot/parachain/src/primitives.rs | 3 + polkadot/primitives/src/v1/mod.rs | 11 +- .../src/node/approval/approval-voting.md | 2 +- .../node/disputes/dispute-participation.md | 18 +- .../runtime-api/historical_validation_code.md | 7 - .../src/runtime-api/validation-code.md | 6 + .../implementers-guide/src/runtime/paras.md | 2 +- .../src/types/overseer-protocol.md | 6 +- polkadot/runtime/kusama/src/lib.rs | 6 - polkadot/runtime/parachains/src/paras.rs | 76 +- .../parachains/src/runtime_api_impl/v1.rs | 8 - polkadot/runtime/polkadot/src/lib.rs | 4 - polkadot/runtime/rococo/src/lib.rs | 6 - polkadot/runtime/test-runtime/src/lib.rs | 7 - polkadot/runtime/westend/src/lib.rs | 6 - 20 files changed, 659 insertions(+), 797 deletions(-) delete mode 100644 polkadot/roadmap/implementers-guide/src/runtime-api/historical_validation_code.md diff --git a/polkadot/node/core/approval-voting/src/lib.rs b/polkadot/node/core/approval-voting/src/lib.rs index bedfeb5790..926e89696e 100644 --- a/polkadot/node/core/approval-voting/src/lib.rs +++ b/polkadot/node/core/approval-voting/src/lib.rs @@ -1879,7 +1879,6 @@ async fn launch_approval( ) -> SubsystemResult>> { let (a_tx, a_rx) = oneshot::channel(); let (code_tx, code_rx) = oneshot::channel(); - let (context_num_tx, context_num_rx) = oneshot::channel(); let candidate_hash = candidate.hash(); @@ -1897,30 +1896,11 @@ async fn launch_approval( a_tx, ).into()).await; - ctx.send_message( - ChainApiMessage::BlockNumber(candidate.descriptor.relay_parent, context_num_tx).into() - ).await; - - let in_context_number = match context_num_rx.await { - Ok(Ok(Some(n))) => n, - Ok(Ok(None)) | Ok(Err(_)) | Err(_) => { - tracing::warn!( - target: LOG_TARGET, - "Could not launch approval work for candidate {:?}: Number of block {} unknown", - (candidate_hash, candidate.descriptor.para_id), - candidate.descriptor.relay_parent, - ); - - return Ok(None); - } - }; - ctx.send_message( RuntimeApiMessage::Request( block_hash, - RuntimeApiRequest::HistoricalValidationCode( - candidate.descriptor.para_id, - in_context_number, + RuntimeApiRequest::ValidationCodeByHash( + candidate.descriptor.validation_code_hash, code_tx, ), ).into() diff --git a/polkadot/node/core/runtime-api/src/cache.rs b/polkadot/node/core/runtime-api/src/cache.rs index 1bc6f682ff..97d392863d 100644 --- a/polkadot/node/core/runtime-api/src/cache.rs +++ b/polkadot/node/core/runtime-api/src/cache.rs @@ -14,20 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -use polkadot_primitives::v1::{ - BlockNumber, CandidateCommitments, CommittedCandidateReceipt, CandidateEvent, - CoreState, GroupRotationInfo, InboundDownwardMessage, InboundHrmpMessage, Hash, - PersistedValidationData, Id as ParaId, OccupiedCoreAssumption, - SessionIndex, SessionInfo, ValidationCode, ValidatorId, ValidatorIndex, - AuthorityDiscoveryId, -}; -use sp_consensus_babe::Epoch; -use parity_util_mem::{MallocSizeOf, MallocSizeOfExt}; - +use std::collections::btree_map::BTreeMap; use memory_lru::{MemoryLruCache, ResidentSize}; +use parity_util_mem::{MallocSizeOf, MallocSizeOfExt}; +use sp_consensus_babe::Epoch; -use std::collections::btree_map::BTreeMap; +use polkadot_primitives::v1::{ + AuthorityDiscoveryId, BlockNumber, CandidateCommitments, CandidateEvent, + CommittedCandidateReceipt, CoreState, GroupRotationInfo, Hash, Id as ParaId, + InboundDownwardMessage, InboundHrmpMessage, OccupiedCoreAssumption, PersistedValidationData, + SessionIndex, SessionInfo, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, +}; const AUTHORITIES_CACHE_SIZE: usize = 128 * 1024; const VALIDATORS_CACHE_SIZE: usize = 64 * 1024; @@ -37,7 +35,6 @@ const PERSISTED_VALIDATION_DATA_CACHE_SIZE: usize = 64 * 1024; const CHECK_VALIDATION_OUTPUTS_CACHE_SIZE: usize = 64 * 1024; const SESSION_INDEX_FOR_CHILD_CACHE_SIZE: usize = 64 * 1024; const VALIDATION_CODE_CACHE_SIZE: usize = 10 * 1024 * 1024; -const HISTORICAL_VALIDATION_CODE_CACHE_SIZE: usize = 10 * 1024 * 1024; const CANDIDATE_PENDING_AVAILABILITY_CACHE_SIZE: usize = 64 * 1024; const CANDIDATE_EVENTS_CACHE_SIZE: usize = 64 * 1024; const SESSION_INFO_CACHE_SIZE: usize = 64 * 1024; @@ -80,7 +77,7 @@ pub(crate) struct RequestResultCache { check_validation_outputs: MemoryLruCache<(Hash, ParaId, CandidateCommitments), ResidentSizeOf>, session_index_for_child: MemoryLruCache>, validation_code: MemoryLruCache<(Hash, ParaId, OccupiedCoreAssumption), ResidentSizeOf>>, - historical_validation_code: MemoryLruCache<(Hash, ParaId, BlockNumber), ResidentSizeOf>>, + validation_code_by_hash: MemoryLruCache<(Hash, ValidationCodeHash), ResidentSizeOf>>, candidate_pending_availability: MemoryLruCache<(Hash, ParaId), ResidentSizeOf>>, candidate_events: MemoryLruCache>>, session_info: MemoryLruCache<(Hash, SessionIndex), ResidentSizeOf>>, @@ -100,7 +97,7 @@ impl Default for RequestResultCache { check_validation_outputs: MemoryLruCache::new(CHECK_VALIDATION_OUTPUTS_CACHE_SIZE), session_index_for_child: MemoryLruCache::new(SESSION_INDEX_FOR_CHILD_CACHE_SIZE), validation_code: MemoryLruCache::new(VALIDATION_CODE_CACHE_SIZE), - historical_validation_code: MemoryLruCache::new(HISTORICAL_VALIDATION_CODE_CACHE_SIZE), + validation_code_by_hash: MemoryLruCache::new(VALIDATION_CODE_CACHE_SIZE), candidate_pending_availability: MemoryLruCache::new(CANDIDATE_PENDING_AVAILABILITY_CACHE_SIZE), candidate_events: MemoryLruCache::new(CANDIDATE_EVENTS_CACHE_SIZE), session_info: MemoryLruCache::new(SESSION_INFO_CACHE_SIZE), @@ -176,12 +173,12 @@ impl RequestResultCache { self.validation_code.insert(key, ResidentSizeOf(value)); } - pub(crate) fn historical_validation_code(&mut self, key: (Hash, ParaId, BlockNumber)) -> Option<&Option> { - self.historical_validation_code.get(&key).map(|v| &v.0) + pub(crate) fn validation_code_by_hash(&mut self, key: (Hash, ValidationCodeHash)) -> Option<&Option> { + self.validation_code_by_hash.get(&key).map(|v| &v.0) } - pub(crate) fn cache_historical_validation_code(&mut self, key: (Hash, ParaId, BlockNumber), value: Option) { - self.historical_validation_code.insert(key, ResidentSizeOf(value)); + pub(crate) fn cache_validation_code_by_hash(&mut self, key: (Hash, ValidationCodeHash), value: Option) { + self.validation_code_by_hash.insert(key, ResidentSizeOf(value)); } pub(crate) fn candidate_pending_availability(&mut self, key: (Hash, ParaId)) -> Option<&Option> { @@ -242,7 +239,7 @@ pub(crate) enum RequestResult { CheckValidationOutputs(Hash, ParaId, CandidateCommitments, bool), SessionIndexForChild(Hash, SessionIndex), ValidationCode(Hash, ParaId, OccupiedCoreAssumption, Option), - HistoricalValidationCode(Hash, ParaId, BlockNumber, Option), + ValidationCodeByHash(Hash, ValidationCodeHash, Option), CandidatePendingAvailability(Hash, ParaId, Option), CandidateEvents(Hash, Vec), SessionInfo(Hash, SessionIndex, Option), diff --git a/polkadot/node/core/runtime-api/src/lib.rs b/polkadot/node/core/runtime-api/src/lib.rs index caddd0a80d..31d0471fe3 100644 --- a/polkadot/node/core/runtime-api/src/lib.rs +++ b/polkadot/node/core/runtime-api/src/lib.rs @@ -119,8 +119,8 @@ impl RuntimeApiSubsystem where self.requests_cache.cache_session_index_for_child(relay_parent, session_index), ValidationCode(relay_parent, para_id, assumption, code) => self.requests_cache.cache_validation_code((relay_parent, para_id, assumption), code), - HistoricalValidationCode(relay_parent, para_id, n, code) => - self.requests_cache.cache_historical_validation_code((relay_parent, para_id, n), code), + ValidationCodeByHash(relay_parent, validation_code_hash, code) => + self.requests_cache.cache_validation_code_by_hash((relay_parent, validation_code_hash), code), CandidatePendingAvailability(relay_parent, para_id, candidate) => self.requests_cache.cache_candidate_pending_availability((relay_parent, para_id), candidate), CandidateEvents(relay_parent, events) => @@ -183,9 +183,9 @@ impl RuntimeApiSubsystem where Request::ValidationCode(para, assumption, sender) => query!(validation_code(para, assumption), sender) .map(|sender| Request::ValidationCode(para, assumption, sender)), - Request::HistoricalValidationCode(para, at, sender) => - query!(historical_validation_code(para, at), sender) - .map(|sender| Request::HistoricalValidationCode(para, at, sender)), + Request::ValidationCodeByHash(validation_code_hash, sender) => + query!(validation_code_by_hash(validation_code_hash), sender) + .map(|sender| Request::ValidationCodeByHash(validation_code_hash, sender)), Request::CandidatePendingAvailability(para, sender) => query!(candidate_pending_availability(para), sender) .map(|sender| Request::CandidatePendingAvailability(para, sender)), @@ -341,8 +341,8 @@ where Request::SessionIndexForChild(sender) => query!(SessionIndexForChild, session_index_for_child(), sender), Request::ValidationCode(para, assumption, sender) => query!(ValidationCode, validation_code(para, assumption), sender), - Request::HistoricalValidationCode(para, at, sender) => - query!(HistoricalValidationCode, historical_validation_code(para, at), sender), + Request::ValidationCodeByHash(validation_code_hash, sender) => + query!(ValidationCodeByHash, validation_code_by_hash(validation_code_hash), sender), Request::CandidatePendingAvailability(para, sender) => query!(CandidatePendingAvailability, candidate_pending_availability(para), sender), Request::CandidateEvents(sender) => query!(CandidateEvents, candidate_events(), sender), diff --git a/polkadot/node/core/runtime-api/src/tests.rs b/polkadot/node/core/runtime-api/src/tests.rs index 3e5dbaa98f..1c4e9f24c7 100644 --- a/polkadot/node/core/runtime-api/src/tests.rs +++ b/polkadot/node/core/runtime-api/src/tests.rs @@ -17,813 +17,774 @@ use super::*; use polkadot_primitives::v1::{ - ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, PersistedValidationData, - Id as ParaId, OccupiedCoreAssumption, SessionIndex, ValidationCode, - CommittedCandidateReceipt, CandidateEvent, InboundDownwardMessage, - BlockNumber, InboundHrmpMessage, SessionInfo, AuthorityDiscoveryId, + ValidatorId, ValidatorIndex, GroupRotationInfo, CoreState, PersistedValidationData, + Id as ParaId, OccupiedCoreAssumption, SessionIndex, ValidationCode, + CommittedCandidateReceipt, CandidateEvent, InboundDownwardMessage, + InboundHrmpMessage, SessionInfo, AuthorityDiscoveryId, ValidationCodeHash, }; use polkadot_node_subsystem_test_helpers as test_helpers; use sp_core::testing::TaskExecutor; use std::{collections::{HashMap, BTreeMap}, sync::{Arc, Mutex}}; use futures::channel::oneshot; use polkadot_node_primitives::{ - BabeEpoch, BabeEpochConfiguration, BabeAllowedSlots, + BabeEpoch, BabeEpochConfiguration, BabeAllowedSlots, }; #[derive(Default, Clone)] struct MockRuntimeApi { - authorities: Vec, - validators: Vec, - validator_groups: Vec>, - availability_cores: Vec, - availability_cores_wait: Arc>, - validation_data: HashMap, - session_index_for_child: SessionIndex, - session_info: HashMap, - validation_code: HashMap, - historical_validation_code: HashMap>, - validation_outputs_results: HashMap, - candidate_pending_availability: HashMap, - candidate_events: Vec, - dmq_contents: HashMap>, - hrmp_channels: HashMap>>, - babe_epoch: Option, + authorities: Vec, + validators: Vec, + validator_groups: Vec>, + availability_cores: Vec, + availability_cores_wait: Arc>, + validation_data: HashMap, + session_index_for_child: SessionIndex, + session_info: HashMap, + validation_code: HashMap, + validation_code_by_hash: HashMap, + validation_outputs_results: HashMap, + candidate_pending_availability: HashMap, + candidate_events: Vec, + dmq_contents: HashMap>, + hrmp_channels: HashMap>>, + babe_epoch: Option, } impl ProvideRuntimeApi for MockRuntimeApi { - type Api = Self; + type Api = Self; - fn runtime_api<'a>(&'a self) -> sp_api::ApiRef<'a, Self::Api> { - self.clone().into() - } + fn runtime_api<'a>(&'a self) -> sp_api::ApiRef<'a, Self::Api> { + self.clone().into() + } } sp_api::mock_impl_runtime_apis! { - impl ParachainHost for MockRuntimeApi { - fn validators(&self) -> Vec { - self.validators.clone() - } + impl ParachainHost for MockRuntimeApi { + fn validators(&self) -> Vec { + self.validators.clone() + } - fn validator_groups(&self) -> (Vec>, GroupRotationInfo) { - ( - self.validator_groups.clone(), - GroupRotationInfo { - session_start_block: 1, - group_rotation_frequency: 100, - now: 10, - }, - ) - } + fn validator_groups(&self) -> (Vec>, GroupRotationInfo) { + ( + self.validator_groups.clone(), + GroupRotationInfo { + session_start_block: 1, + group_rotation_frequency: 100, + now: 10, + }, + ) + } - fn availability_cores(&self) -> Vec { - let _ = self.availability_cores_wait.lock().unwrap(); - self.availability_cores.clone() - } + fn availability_cores(&self) -> Vec { + let _ = self.availability_cores_wait.lock().unwrap(); + self.availability_cores.clone() + } - fn persisted_validation_data( - &self, - para: ParaId, - _assumption: OccupiedCoreAssumption, - ) -> Option { - self.validation_data.get(¶).cloned() - } + fn persisted_validation_data( + &self, + para: ParaId, + _assumption: OccupiedCoreAssumption, + ) -> Option { + self.validation_data.get(¶).cloned() + } - fn check_validation_outputs( - &self, - para_id: ParaId, - _commitments: polkadot_primitives::v1::CandidateCommitments, - ) -> bool { - self.validation_outputs_results - .get(¶_id) - .cloned() - .expect( - "`check_validation_outputs` called but the expected result hasn't been supplied" - ) - } + fn check_validation_outputs( + &self, + para_id: ParaId, + _commitments: polkadot_primitives::v1::CandidateCommitments, + ) -> bool { + self.validation_outputs_results + .get(¶_id) + .cloned() + .expect( + "`check_validation_outputs` called but the expected result hasn't been supplied" + ) + } - fn session_index_for_child(&self) -> SessionIndex { - self.session_index_for_child.clone() - } + fn session_index_for_child(&self) -> SessionIndex { + self.session_index_for_child.clone() + } - fn session_info(&self, index: SessionIndex) -> Option { - self.session_info.get(&index).cloned() - } + fn session_info(&self, index: SessionIndex) -> Option { + self.session_info.get(&index).cloned() + } - fn validation_code( - &self, - para: ParaId, - _assumption: OccupiedCoreAssumption, - ) -> Option { - self.validation_code.get(¶).map(|c| c.clone()) - } + fn validation_code( + &self, + para: ParaId, + _assumption: OccupiedCoreAssumption, + ) -> Option { + self.validation_code.get(¶).map(|c| c.clone()) + } - fn historical_validation_code( - &self, - para: ParaId, - at: BlockNumber, - ) -> Option { - self.historical_validation_code.get(¶).and_then(|h_code| { - h_code.iter() - .take_while(|(changed_at, _)| changed_at <= &at) - .last() - .map(|(_, code)| code.clone()) - }) - } + fn candidate_pending_availability( + &self, + para: ParaId, + ) -> Option { + self.candidate_pending_availability.get(¶).map(|c| c.clone()) + } - fn candidate_pending_availability( - &self, - para: ParaId, - ) -> Option { - self.candidate_pending_availability.get(¶).map(|c| c.clone()) - } + fn candidate_events(&self) -> Vec { + self.candidate_events.clone() + } - fn candidate_events(&self) -> Vec { - self.candidate_events.clone() - } + fn dmq_contents( + &self, + recipient: ParaId, + ) -> Vec { + self.dmq_contents.get(&recipient).map(|q| q.clone()).unwrap_or_default() + } - fn dmq_contents( - &self, - recipient: ParaId, - ) -> Vec { - self.dmq_contents.get(&recipient).map(|q| q.clone()).unwrap_or_default() - } + fn inbound_hrmp_channels_contents( + &self, + recipient: ParaId + ) -> BTreeMap> { + self.hrmp_channels.get(&recipient).map(|q| q.clone()).unwrap_or_default() + } - fn inbound_hrmp_channels_contents( - &self, - recipient: ParaId - ) -> BTreeMap> { - self.hrmp_channels.get(&recipient).map(|q| q.clone()).unwrap_or_default() - } + fn validation_code_by_hash( + &self, + hash: Hash, + ) -> Option { + self.validation_code_by_hash.get(&hash).map(|c| c.clone()) + } + } - fn validation_code_by_hash( - &self, - _hash: Hash, - ) -> Option { - unreachable!("not used in tests"); - } - } + impl BabeApi for MockRuntimeApi { + fn configuration(&self) -> sp_consensus_babe::BabeGenesisConfiguration { + unimplemented!() + } - impl BabeApi for MockRuntimeApi { - fn configuration(&self) -> sp_consensus_babe::BabeGenesisConfiguration { - unimplemented!() - } + fn current_epoch_start(&self) -> sp_consensus_babe::Slot { + self.babe_epoch.as_ref().unwrap().start_slot + } - fn current_epoch_start(&self) -> sp_consensus_babe::Slot { - self.babe_epoch.as_ref().unwrap().start_slot - } + fn current_epoch(&self) -> BabeEpoch { + self.babe_epoch.as_ref().unwrap().clone() + } - fn current_epoch(&self) -> BabeEpoch { - self.babe_epoch.as_ref().unwrap().clone() - } + fn next_epoch(&self) -> BabeEpoch { + unimplemented!() + } - fn next_epoch(&self) -> BabeEpoch { - unimplemented!() - } + fn generate_key_ownership_proof( + _slot: sp_consensus_babe::Slot, + _authority_id: sp_consensus_babe::AuthorityId, + ) -> Option { + None + } - fn generate_key_ownership_proof( - _slot: sp_consensus_babe::Slot, - _authority_id: sp_consensus_babe::AuthorityId, - ) -> Option { - None - } + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: sp_consensus_babe::EquivocationProof, + _key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + } - fn submit_report_equivocation_unsigned_extrinsic( - _equivocation_proof: sp_consensus_babe::EquivocationProof, - _key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof, - ) -> Option<()> { - None - } - } - - impl AuthorityDiscoveryApi for MockRuntimeApi { - fn authorities(&self) -> Vec { - self.authorities.clone() - } - } + impl AuthorityDiscoveryApi for MockRuntimeApi { + fn authorities(&self) -> Vec { + self.authorities.clone() + } + } } #[test] fn requests_authorities() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let runtime_api = Arc::new(MockRuntimeApi::default()); - let relay_parent = [1; 32].into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let runtime_api = Arc::new(MockRuntimeApi::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); - 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(); + 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::Authorities(tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::Authorities(tx)) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), runtime_api.authorities); + assert_eq!(rx.await.unwrap().unwrap(), runtime_api.authorities); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_validators() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let runtime_api = Arc::new(MockRuntimeApi::default()); - let relay_parent = [1; 32].into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let runtime_api = Arc::new(MockRuntimeApi::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); - 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(); + 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::Validators(tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::Validators(tx)) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), runtime_api.validators); + assert_eq!(rx.await.unwrap().unwrap(), runtime_api.validators); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_validator_groups() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let runtime_api = Arc::new(MockRuntimeApi::default()); - let relay_parent = [1; 32].into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let runtime_api = Arc::new(MockRuntimeApi::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); - 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(); + 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::ValidatorGroups(tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::ValidatorGroups(tx)) + }).await; - assert_eq!(rx.await.unwrap().unwrap().0, runtime_api.validator_groups); + assert_eq!(rx.await.unwrap().unwrap().0, runtime_api.validator_groups); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_availability_cores() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let runtime_api = Arc::new(MockRuntimeApi::default()); - let relay_parent = [1; 32].into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let runtime_api = Arc::new(MockRuntimeApi::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); - 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(); + 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::AvailabilityCores(tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), runtime_api.availability_cores); + assert_eq!(rx.await.unwrap().unwrap(), runtime_api.availability_cores); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_persisted_validation_data() { - let (ctx, mut ctx_handle) = test_helpers::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 (ctx, mut ctx_handle) = test_helpers::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 mut runtime_api = MockRuntimeApi::default(); - runtime_api.validation_data.insert(para_a, Default::default()); - let runtime_api = Arc::new(runtime_api); + let mut runtime_api = MockRuntimeApi::default(); + runtime_api.validation_data.insert(para_a, Default::default()); + 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(); + 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::PersistedValidationData(para_a, OccupiedCoreAssumption::Included, tx) - ), - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::PersistedValidationData(para_a, OccupiedCoreAssumption::Included, tx) + ), + }).await; - assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); + assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); - let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::PersistedValidationData(para_b, OccupiedCoreAssumption::Included, tx) - ), - }).await; + let (tx, rx) = oneshot::channel(); + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::PersistedValidationData(para_b, OccupiedCoreAssumption::Included, tx) + ), + }).await; - assert_eq!(rx.await.unwrap().unwrap(), None); + assert_eq!(rx.await.unwrap().unwrap(), None); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_check_validation_outputs() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let mut runtime_api = MockRuntimeApi::default(); - let relay_parent = [1; 32].into(); - let para_a = 5.into(); - let para_b = 6.into(); - let commitments = polkadot_primitives::v1::CandidateCommitments::default(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let mut runtime_api = MockRuntimeApi::default(); + let relay_parent = [1; 32].into(); + let para_a = 5.into(); + let para_b = 6.into(); + let commitments = polkadot_primitives::v1::CandidateCommitments::default(); + let spawner = sp_core::testing::TaskExecutor::new(); - runtime_api.validation_outputs_results.insert(para_a, false); - runtime_api.validation_outputs_results.insert(para_b, true); + runtime_api.validation_outputs_results.insert(para_a, false); + runtime_api.validation_outputs_results.insert(para_b, true); - let runtime_api = Arc::new(runtime_api); + 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(); + 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::CheckValidationOutputs( - para_a, - commitments.clone(), - tx, - ), - ) - }).await; - assert_eq!( - rx.await.unwrap().unwrap(), - runtime_api.validation_outputs_results[¶_a], - ); + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CheckValidationOutputs( + para_a, + commitments.clone(), + tx, + ), + ) + }).await; + assert_eq!( + rx.await.unwrap().unwrap(), + runtime_api.validation_outputs_results[¶_a], + ); - let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::CheckValidationOutputs( - para_b, - commitments, - tx, - ), - ) - }).await; - assert_eq!( - rx.await.unwrap().unwrap(), - runtime_api.validation_outputs_results[¶_b], - ); + let (tx, rx) = oneshot::channel(); + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CheckValidationOutputs( + para_b, + commitments, + tx, + ), + ) + }).await; + assert_eq!( + rx.await.unwrap().unwrap(), + runtime_api.validation_outputs_results[¶_b], + ); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_session_index_for_child() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let runtime_api = Arc::new(MockRuntimeApi::default()); - let relay_parent = [1; 32].into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let runtime_api = Arc::new(MockRuntimeApi::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); - 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(); + 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::SessionIndexForChild(tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::SessionIndexForChild(tx)) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), runtime_api.session_index_for_child); + assert_eq!(rx.await.unwrap().unwrap(), runtime_api.session_index_for_child); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_session_info() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let mut runtime_api = MockRuntimeApi::default(); - let session_index = 1; - runtime_api.session_info.insert(session_index, Default::default()); - let runtime_api = Arc::new(runtime_api); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let mut runtime_api = MockRuntimeApi::default(); + let session_index = 1; + runtime_api.session_info.insert(session_index, Default::default()); + let runtime_api = Arc::new(runtime_api); + let spawner = sp_core::testing::TaskExecutor::new(); - let relay_parent = [1; 32].into(); + let relay_parent = [1; 32].into(); - 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(); + 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::SessionInfo(session_index, tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::SessionInfo(session_index, tx)) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); + assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - 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() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let (ctx, mut ctx_handle) = test_helpers::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 relay_parent = [1; 32].into(); + let para_a = 5.into(); + let para_b = 6.into(); + let spawner = sp_core::testing::TaskExecutor::new(); - let mut runtime_api = MockRuntimeApi::default(); - runtime_api.validation_code.insert(para_a, Default::default()); - let runtime_api = Arc::new(runtime_api); + let mut runtime_api = MockRuntimeApi::default(); + runtime_api.validation_code.insert(para_a, Default::default()); + 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(); + 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::ValidationCode(para_a, OccupiedCoreAssumption::Included, tx) - ), - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCode(para_a, OccupiedCoreAssumption::Included, tx) + ), + }).await; - assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); + assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); - let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::ValidationCode(para_b, OccupiedCoreAssumption::Included, tx) - ), - }).await; + let (tx, rx) = oneshot::channel(); + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCode(para_b, OccupiedCoreAssumption::Included, tx) + ), + }).await; - assert_eq!(rx.await.unwrap().unwrap(), None); + assert_eq!(rx.await.unwrap().unwrap(), None); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_candidate_pending_availability() { - let (ctx, mut ctx_handle) = test_helpers::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 (ctx, mut ctx_handle) = test_helpers::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 mut runtime_api = MockRuntimeApi::default(); - runtime_api.candidate_pending_availability.insert(para_a, Default::default()); - let runtime_api = Arc::new(runtime_api); + let mut runtime_api = MockRuntimeApi::default(); + runtime_api.candidate_pending_availability.insert(para_a, Default::default()); + 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(); + 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::CandidatePendingAvailability(para_a, tx), - ) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CandidatePendingAvailability(para_a, tx), + ) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); + assert_eq!(rx.await.unwrap().unwrap(), Some(Default::default())); - let (tx, rx) = oneshot::channel(); + let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::CandidatePendingAvailability(para_b, tx), - ) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::CandidatePendingAvailability(para_b, tx), + ) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), None); + assert_eq!(rx.await.unwrap().unwrap(), None); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_candidate_events() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let runtime_api = Arc::new(MockRuntimeApi::default()); - let relay_parent = [1; 32].into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let runtime_api = Arc::new(MockRuntimeApi::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); - 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(); + 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::CandidateEvents(tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::CandidateEvents(tx)) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), runtime_api.candidate_events); + assert_eq!(rx.await.unwrap().unwrap(), runtime_api.candidate_events); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_dmq_contents() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let (ctx, mut ctx_handle) = test_helpers::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 relay_parent = [1; 32].into(); + let para_a = 5.into(); + let para_b = 6.into(); + let spawner = sp_core::testing::TaskExecutor::new(); - let runtime_api = Arc::new({ - let mut runtime_api = MockRuntimeApi::default(); + let runtime_api = Arc::new({ + let mut runtime_api = MockRuntimeApi::default(); - runtime_api.dmq_contents.insert(para_a, vec![]); - runtime_api.dmq_contents.insert( - para_b, - vec![InboundDownwardMessage { - sent_at: 228, - msg: b"Novus Ordo Seclorum".to_vec(), - }], - ); + runtime_api.dmq_contents.insert(para_a, vec![]); + runtime_api.dmq_contents.insert( + para_b, + vec![InboundDownwardMessage { + sent_at: 228, + msg: b"Novus Ordo Seclorum".to_vec(), + }], + ); - runtime_api - }); + 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::DmqContents(para_a, tx)), - }) - .await; - assert_eq!(rx.await.unwrap().unwrap(), vec![]); + 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::DmqContents(para_a, tx)), + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), vec![]); - let (tx, rx) = oneshot::channel(); - ctx_handle - .send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::DmqContents(para_b, tx)), - }) - .await; - assert_eq!( - rx.await.unwrap().unwrap(), - vec![InboundDownwardMessage { - sent_at: 228, - msg: b"Novus Ordo Seclorum".to_vec(), - }] - ); + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::DmqContents(para_b, tx)), + }) + .await; + assert_eq!( + rx.await.unwrap().unwrap(), + vec![InboundDownwardMessage { + sent_at: 228, + msg: b"Novus Ordo Seclorum".to_vec(), + }] + ); - ctx_handle - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .await; - }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + ctx_handle + .send(FromOverseer::Signal(OverseerSignal::Conclude)) + .await; + }; + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn requests_inbound_hrmp_channels_contents() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let relay_parent = [1; 32].into(); - let para_a = 99.into(); - let para_b = 66.into(); - let para_c = 33.into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let relay_parent = [1; 32].into(); + let para_a = 99.into(); + let para_b = 66.into(); + let para_c = 33.into(); + let spawner = sp_core::testing::TaskExecutor::new(); - let para_b_inbound_channels = [ - (para_a, vec![]), - ( - para_c, - vec![InboundHrmpMessage { - sent_at: 1, - data: "๐™€=๐™ˆ๐˜พยฒ".as_bytes().to_owned(), - }], - ), - ] - .iter() - .cloned() - .collect::>(); + let para_b_inbound_channels = [ + (para_a, vec![]), + ( + para_c, + vec![InboundHrmpMessage { + sent_at: 1, + data: "๐™€=๐™ˆ๐˜พยฒ".as_bytes().to_owned(), + }], + ), + ] + .iter() + .cloned() + .collect::>(); - let runtime_api = Arc::new({ - let mut runtime_api = MockRuntimeApi::default(); + let runtime_api = Arc::new({ + let mut runtime_api = MockRuntimeApi::default(); - runtime_api.hrmp_channels.insert(para_a, BTreeMap::new()); - runtime_api - .hrmp_channels - .insert(para_b, para_b_inbound_channels.clone()); + runtime_api.hrmp_channels.insert(para_a, BTreeMap::new()); + runtime_api + .hrmp_channels + .insert(para_b, para_b_inbound_channels.clone()); - runtime_api - }); + 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::InboundHrmpChannelsContents(para_a, tx), - ), - }) - .await; - assert_eq!(rx.await.unwrap().unwrap(), BTreeMap::new()); + 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::InboundHrmpChannelsContents(para_a, tx), + ), + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), BTreeMap::new()); - let (tx, rx) = oneshot::channel(); - ctx_handle - .send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::InboundHrmpChannelsContents(para_b, tx), - ), - }) - .await; - assert_eq!(rx.await.unwrap().unwrap(), para_b_inbound_channels,); + let (tx, rx) = oneshot::channel(); + ctx_handle + .send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::InboundHrmpChannelsContents(para_b, tx), + ), + }) + .await; + assert_eq!(rx.await.unwrap().unwrap(), para_b_inbound_channels,); - ctx_handle - .send(FromOverseer::Signal(OverseerSignal::Conclude)) - .await; - }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + ctx_handle + .send(FromOverseer::Signal(OverseerSignal::Conclude)) + .await; + }; + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] -fn requests_historical_code() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); +fn requests_validation_code_by_hash() { + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let spawner = sp_core::testing::TaskExecutor::new(); - let para_a = 5.into(); - let para_b = 6.into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (runtime_api, validation_code) = { + let mut runtime_api = MockRuntimeApi::default(); + let mut validation_code = Vec::new(); - let runtime_api = Arc::new({ - let mut runtime_api = MockRuntimeApi::default(); + for n in 0..5 { + let code = ValidationCode::from(vec![n; 32]); + runtime_api.validation_code_by_hash.insert( + code.hash(), + code.clone(), + ); + validation_code.push(code); + } - runtime_api.historical_validation_code.insert( - para_a, - vec![(1, vec![1, 2, 3].into()), (10, vec![4, 5, 6].into())], - ); + (runtime_api, validation_code) + }; - runtime_api.historical_validation_code.insert( - para_b, - vec![(5, vec![7, 8, 9].into())], - ); + let subsystem = RuntimeApiSubsystem::new(Arc::new(runtime_api), Metrics(None), spawner); + let subsystem_task = run(ctx, subsystem).map(|x| x.unwrap()); - runtime_api - }); - let relay_parent = [1; 32].into(); + let relay_parent = [1; 32].into(); + let test_task = async move { + for code in validation_code { + let (tx, rx) = oneshot::channel(); + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request( + relay_parent, + Request::ValidationCodeByHash(code.hash(), tx), + ) + }).await; - let subsystem = RuntimeApiSubsystem::new(runtime_api, 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::HistoricalValidationCode(para_a, 5, tx), - ) - }).await; + assert_eq!(rx.await.unwrap().unwrap(), Some(code)); + } - assert_eq!(rx.await.unwrap().unwrap(), Some(ValidationCode::from(vec![1, 2, 3]))); - } + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - { - let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::HistoricalValidationCode(para_a, 10, tx), - ) - }).await; - - assert_eq!(rx.await.unwrap().unwrap(), Some(ValidationCode::from(vec![4, 5, 6]))); - } - - { - let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request( - relay_parent, - Request::HistoricalValidationCode(para_b, 1, tx), - ) - }).await; - - assert!(rx.await.unwrap().unwrap().is_none()); - } - - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; - - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn multiple_requests_in_parallel_are_working() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let runtime_api = Arc::new(MockRuntimeApi::default()); - let relay_parent = [1; 32].into(); - let spawner = sp_core::testing::TaskExecutor::new(); - let mutex = runtime_api.availability_cores_wait.clone(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let runtime_api = Arc::new(MockRuntimeApi::default()); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); + let mutex = runtime_api.availability_cores_wait.clone(); - 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 { - // Make all requests block until we release this mutex. - let lock = mutex.lock().unwrap(); + 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 { + // Make all requests block until we release this mutex. + let lock = mutex.lock().unwrap(); - let mut receivers = Vec::new(); + let mut receivers = Vec::new(); - for _ in 0..MAX_PARALLEL_REQUESTS * 10 { - let (tx, rx) = oneshot::channel(); + for _ in 0..MAX_PARALLEL_REQUESTS * 10 { + let (tx, rx) = oneshot::channel(); - ctx_handle.send(FromOverseer::Communication { - msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::AvailabilityCores(tx)) + }).await; - receivers.push(rx); - } + receivers.push(rx); + } - let join = future::join_all(receivers); + let join = future::join_all(receivers); - drop(lock); + drop(lock); - join.await - .into_iter() - .for_each(|r| assert_eq!(r.unwrap().unwrap(), runtime_api.availability_cores)); + join.await + .into_iter() + .for_each(|r| assert_eq!(r.unwrap().unwrap(), runtime_api.availability_cores)); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } #[test] fn request_babe_epoch() { - let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); - let mut runtime_api = MockRuntimeApi::default(); - let epoch = BabeEpoch { - epoch_index: 100, - start_slot: sp_consensus_babe::Slot::from(1000), - duration: 10, - authorities: Vec::new(), - randomness: [1u8; 32], - config: BabeEpochConfiguration { - c: (1, 4), - allowed_slots: BabeAllowedSlots::PrimarySlots, - }, - }; - runtime_api.babe_epoch = Some(epoch.clone()); - let runtime_api = Arc::new(runtime_api); - let relay_parent = [1; 32].into(); - let spawner = sp_core::testing::TaskExecutor::new(); + let (ctx, mut ctx_handle) = test_helpers::make_subsystem_context(TaskExecutor::new()); + let mut runtime_api = MockRuntimeApi::default(); + let epoch = BabeEpoch { + epoch_index: 100, + start_slot: sp_consensus_babe::Slot::from(1000), + duration: 10, + authorities: Vec::new(), + randomness: [1u8; 32], + config: BabeEpochConfiguration { + c: (1, 4), + allowed_slots: BabeAllowedSlots::PrimarySlots, + }, + }; + runtime_api.babe_epoch = Some(epoch.clone()); + let runtime_api = Arc::new(runtime_api); + let relay_parent = [1; 32].into(); + let spawner = sp_core::testing::TaskExecutor::new(); - 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(); + 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::CurrentBabeEpoch(tx)) - }).await; + ctx_handle.send(FromOverseer::Communication { + msg: RuntimeApiMessage::Request(relay_parent, Request::CurrentBabeEpoch(tx)) + }).await; - assert_eq!(rx.await.unwrap().unwrap(), epoch); - ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; - }; + assert_eq!(rx.await.unwrap().unwrap(), epoch); + ctx_handle.send(FromOverseer::Signal(OverseerSignal::Conclude)).await; + }; - futures::executor::block_on(future::join(subsystem_task, test_task)); + futures::executor::block_on(future::join(subsystem_task, test_task)); } diff --git a/polkadot/node/subsystem/src/messages.rs b/polkadot/node/subsystem/src/messages.rs index 0bc8896466..c5da3caae8 100644 --- a/polkadot/node/subsystem/src/messages.rs +++ b/polkadot/node/subsystem/src/messages.rs @@ -22,37 +22,34 @@ //! //! Subsystems' APIs are defined separately from their implementation, leading to easier mocking. +use std::{collections::btree_map::BTreeMap, sync::Arc}; + use futures::channel::{mpsc, oneshot}; use thiserror::Error; pub use sc_network::IfDisconnected; use polkadot_node_network_protocol::{ - PeerId, UnifiedReputationChange, peer_set::PeerSet, - request_response::{ - Requests, request::IncomingRequest, v1 as req_res_v1 - }, - v1 as protocol_v1, + peer_set::PeerSet, + request_response::{request::IncomingRequest, v1 as req_res_v1, Requests}, + v1 as protocol_v1, PeerId, UnifiedReputationChange, }; use polkadot_node_primitives::{ - CollationGenerationConfig, SignedFullStatement, ValidationResult, approval::{BlockApprovalMeta, IndirectAssignmentCert, IndirectSignedApprovalVote}, - BabeEpoch, AvailableData, PoV, ErasureChunk + AvailableData, BabeEpoch, CollationGenerationConfig, ErasureChunk, PoV, SignedFullStatement, + ValidationResult, }; use polkadot_primitives::v1::{ - AuthorityDiscoveryId, BackedCandidate, BlockNumber, SessionInfo, - Header as BlockHeader, CandidateDescriptor, CandidateEvent, CandidateReceipt, - CollatorId, CommittedCandidateReceipt, CoreState, - GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption, - PersistedValidationData, SessionIndex, SignedAvailabilityBitfield, - ValidationCode, ValidatorId, CandidateHash, - ValidatorIndex, ValidatorSignature, InboundDownwardMessage, InboundHrmpMessage, - CandidateIndex, GroupIndex, MultiDisputeStatementSet, SignedAvailabilityBitfields, + AuthorityDiscoveryId, BackedCandidate, BlockNumber, CandidateDescriptor, CandidateEvent, + CandidateHash, CandidateIndex, CandidateReceipt, CollatorId, CommittedCandidateReceipt, + CoreState, GroupIndex, GroupRotationInfo, Hash, Header as BlockHeader, Id as ParaId, + InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet, OccupiedCoreAssumption, + PersistedValidationData, SessionIndex, SessionInfo, SignedAvailabilityBitfield, + SignedAvailabilityBitfields, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, + ValidatorSignature, }; -use polkadot_statement_table::v1::Misbehavior; use polkadot_procmacro_subsystem_dispatch_gen::subsystem_dispatch_gen; -use std::{sync::Arc, collections::btree_map::BTreeMap}; - +use polkadot_statement_table::v1::Misbehavior; /// Network events as transmitted to other subsystems, wrapped in their message types. pub mod network_bridge_event; @@ -464,16 +461,9 @@ pub enum RuntimeApiRequest { OccupiedCoreAssumption, RuntimeApiSender>, ), - /// Fetch the historical validation code used by a para for candidates executed in the - /// context of a given block height in the current chain. - /// - /// `context_height` may be no greater than the height of the block in whose - /// state the runtime API is executed. Otherwise `None` is returned. - HistoricalValidationCode( - ParaId, - BlockNumber, - RuntimeApiSender>, - ), + /// Get validation code by its hash, either past, current or future code can be returned, as long as state is still + /// available. + ValidationCodeByHash(ValidationCodeHash, RuntimeApiSender>), /// Get a the candidate pending availability for a particular parachain by parachain / core index CandidatePendingAvailability(ParaId, RuntimeApiSender>), /// Get all events concerning candidates (backing, inclusion, time-out) in the parent of diff --git a/polkadot/parachain/src/primitives.rs b/polkadot/parachain/src/primitives.rs index 939103abf8..5774b0a14f 100644 --- a/polkadot/parachain/src/primitives.rs +++ b/polkadot/parachain/src/primitives.rs @@ -62,6 +62,9 @@ impl ValidationCode { } } +/// A hash of the parachain validation code. +pub type ValidationCodeHash = Hash; + /// Parachain block data. /// /// Contains everything required to validate para-block, may contain block and witness data. diff --git a/polkadot/primitives/src/v1/mod.rs b/polkadot/primitives/src/v1/mod.rs index 8950f689fa..f592831b32 100644 --- a/polkadot/primitives/src/v1/mod.rs +++ b/polkadot/primitives/src/v1/mod.rs @@ -38,7 +38,7 @@ pub use polkadot_core_primitives::v1::{ // Export some polkadot-parachain primitives pub use polkadot_parachain::primitives::{ - Id, LOWEST_USER_ID, LOWEST_PUBLIC_ID, HrmpChannelId, UpwardMessage, HeadData, ValidationCode, + Id, LOWEST_USER_ID, LOWEST_PUBLIC_ID, HrmpChannelId, UpwardMessage, HeadData, ValidationCode, ValidationCodeHash, }; // Export some basic parachain primitives from v0. @@ -909,15 +909,6 @@ sp_api::decl_runtime_apis! { fn validation_code(para_id: Id, assumption: OccupiedCoreAssumption) -> Option; - /// Fetch the historical validation code used by a para for candidates executed in the - /// context of a given block height in the current chain. - /// - /// `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; - /// 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] diff --git a/polkadot/roadmap/implementers-guide/src/node/approval/approval-voting.md b/polkadot/roadmap/implementers-guide/src/node/approval/approval-voting.md index 89042ebd7e..e5d30174d9 100644 --- a/polkadot/roadmap/implementers-guide/src/node/approval/approval-voting.md +++ b/polkadot/roadmap/implementers-guide/src/node/approval/approval-voting.md @@ -271,7 +271,7 @@ On receiving an `ApprovedAncestor(Hash, BlockNumber, response_channel)`: * Requires `(SessionIndex, SessionInfo, CandidateReceipt, ValidatorIndex, backing_group, block_hash, candidate_index)` * Extract the public key of the `ValidatorIndex` from the `SessionInfo` for the session. * Issue an `AvailabilityRecoveryMessage::RecoverAvailableData(candidate, session_index, Some(backing_group), response_sender)` - * Load the historical validation code of the parachain by dispatching a `RuntimeApiRequest::HistoricalValidationCode(`descriptor.para_id`, `descriptor.relay_parent`)` against the state of `block_hash`. + * Load the historical validation code of the parachain by dispatching a `RuntimeApiRequest::ValidationCodeByHash(`descriptor.validation_code_hash`)` against the state of `block_hash`. * Spawn a background task with a clone of `background_tx` * Wait for the available data * Issue a `CandidateValidationMessage::ValidateFromExhaustive` message diff --git a/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-participation.md b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-participation.md index 545f39abde..c901d4d1db 100644 --- a/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-participation.md +++ b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-participation.md @@ -16,14 +16,6 @@ Output: ## Functionality -In-memory state: - -```rust -struct State { - recent_block_hash: Hash -} -``` - ### On `OverseerSignal::ActiveLeavesUpdate` Do nothing. @@ -38,16 +30,14 @@ Conclude. ### On `DisputeParticipationMessage::Participate` -> TODO: this validation code fetching procedure is not helpful for disputed blocks that are in chains we do not know. After https://github.com/paritytech/polkadot/issues/2457 we should use the `ValidationCodeByHash` runtime API using the code hash in the candidate receipt. - * Decompose into parts: `{ candidate_hash, candidate_receipt, session, voted_indices }` * Issue an [`AvailabilityRecoveryMessage::RecoverAvailableData`][AvailabilityRecoveryMessage] * If the result is `Unavailable`, return. * If the result is `Invalid`, [cast invalid votes](#cast-votes) and return. * Fetch the block number of `candidate_receipt.descriptor.relay_parent` using a [`ChainApiMessage::BlockNumber`][ChainApiMessage]. -* If the data is recovered, dispatch a [`RuntimeApiMessage::HistoricalValidationCode`][RuntimeApiMessage] with the parameters `(candidate_receipt.descriptor.para_id, relay_parent_number)`. +* If the data is recovered, dispatch a [`RuntimeApiMessage::ValidationCodeByHash`][RuntimeApiMessage] with the parameters `(candidate_receipt.descriptor.validation_code_hash)`. * Dispatch a [`AvailabilityStoreMessage::StoreAvailableData`][AvailabilityStoreMessage] with the data. -* If the code is not fetched from the chain, return. This should be impossible with correct relay chain configuration after the TODO above is addressed and is unlikely before then, at least if chain synchronization is working correctly. +* If the code is not fetched from the chain, return. This should be impossible with correct relay chain configuration, at least if chain synchronization is working correctly. * Dispatch a [`CandidateValidationMessage::ValidateFromExhaustive`][CandidateValidationMessage] with the available data and the validation code. * If the validation result is `Invalid`, [cast invalid votes](#cast-votes) and return. * If the validation fails, [cast invalid votes](#cast-votes) and return. @@ -57,9 +47,7 @@ Conclude. This requires the parameters `{ candidate_receipt, candidate_hash, session, voted_indices }` as well as a choice of either `Valid` or `Invalid`. -Invoke [`DisputeCoordinatorMessage::IssueLocalStatement`][DisputeCoordinatorMessage] with `is_valid` according to the parameterization. - -Invoke [`DisputeCoordinatorMessage::ImportStatements`][DisputeCoordinatorMessage] with each signed statement. +Invoke [`DisputeCoordinatorMessage::IssueLocalStatement`][DisputeCoordinatorMessage] with `is_valid` according to the parametrization. [RuntimeApiMessage]: ../../types/overseer-protocol.md#runtime-api-message [DisputeParticipationMessage]: ../../types/overseer-protocol.md#dispute-participation-message diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/historical_validation_code.md b/polkadot/roadmap/implementers-guide/src/runtime-api/historical_validation_code.md deleted file mode 100644 index 0b63f247df..0000000000 --- a/polkadot/roadmap/implementers-guide/src/runtime-api/historical_validation_code.md +++ /dev/null @@ -1,7 +0,0 @@ -# Historical Validation Code - -Fetch the historical validation code used by a para for candidates executed in the context of a given block height in the current chain. - -```rust -fn historical_validation_code(at: Block, para_id: ParaId, context_height: BlockNumber) -> Option; -``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime-api/validation-code.md b/polkadot/roadmap/implementers-guide/src/runtime-api/validation-code.md index 908e3bfbd1..eaf22bf498 100644 --- a/polkadot/roadmap/implementers-guide/src/runtime-api/validation-code.md +++ b/polkadot/roadmap/implementers-guide/src/runtime-api/validation-code.md @@ -5,3 +5,9 @@ Fetch the validation code used by a para, making the given `OccupiedCoreAssumpti ```rust fn validation_code(at: Block, ParaId, OccupiedCoreAssumption) -> Option; ``` + +Fetch the validation code (past, present or future) by its hash. + +```rust +fn validation_code_by_hash(at: Block, Hash) -> Option; +``` diff --git a/polkadot/roadmap/implementers-guide/src/runtime/paras.md b/polkadot/roadmap/implementers-guide/src/runtime/paras.md index 1007a3c27c..72c843475b 100644 --- a/polkadot/roadmap/implementers-guide/src/runtime/paras.md +++ b/polkadot/roadmap/implementers-guide/src/runtime/paras.md @@ -144,7 +144,7 @@ UpcomingParasGenesis: map ParaId => Option; /// The number of references on the validation code in `CodeByHash` storage. CodeByHashRefs: map Hash => u32; /// Validation code stored by its hash. -CoeByHash: map Hash => Option +CodeByHash: map Hash => Option ``` ## Session Change diff --git a/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md b/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md index 891be333ef..88f9deb408 100644 --- a/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md +++ b/polkadot/roadmap/implementers-guide/src/types/overseer-protocol.md @@ -618,9 +618,9 @@ enum RuntimeApiRequest { SessionIndexForChild(ResponseChannel), /// Get the validation code for a specific para, using the given occupied core assumption. ValidationCode(ParaId, OccupiedCoreAssumption, ResponseChannel>), - /// Fetch the historical validation code used by a para for candidates executed in - /// the context of a given block height in the current chain. - HistoricalValidationCode(ParaId, BlockNumber, ResponseChannel>), + /// Get validation code by its hash, either past, current or future code can be returned, + /// as long as state is still available. + ValidationCodeByHash(ValidationCodeHash, RuntimeApiSender>), /// Get a committed candidate receipt for all candidates pending availability. CandidatePendingAvailability(ParaId, ResponseChannel>), /// Get all events concerning candidates in the last block. diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs index de6b93d8d2..ec29243fc8 100644 --- a/polkadot/runtime/kusama/src/lib.rs +++ b/polkadot/runtime/kusama/src/lib.rs @@ -1625,12 +1625,6 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::validation_code::(para_id, assumption) } - fn historical_validation_code(para_id: ParaId, context_height: BlockNumber) - -> Option - { - parachains_runtime_api_impl::historical_validation_code::(para_id, context_height) - } - fn candidate_pending_availability(para_id: ParaId) -> Option> { parachains_runtime_api_impl::candidate_pending_availability::(para_id) } diff --git a/polkadot/runtime/parachains/src/paras.rs b/polkadot/runtime/parachains/src/paras.rs index 38815d14b0..f4d9a44ccd 100644 --- a/polkadot/runtime/parachains/src/paras.rs +++ b/polkadot/runtime/parachains/src/paras.rs @@ -858,25 +858,6 @@ impl Module { } } - /// Fetch validation code of para in specific context, see [`Self::validation_code_hash_at`]. - pub(crate) fn validation_code_at( - id: ParaId, - at: T::BlockNumber, - assume_intermediate: Option, - ) -> Option { - Self::validation_code_hash_at(id, at, assume_intermediate).and_then(|code_hash| { - let code = CodeByHash::get(&code_hash); - if code.is_none() { - log::error!( - "Pallet paras storage is inconsistent, code not found for hash {}", - code_hash, - ); - debug_assert!(false, "inconsistent paras storages"); - } - code - }) - } - /// Returns the current lifecycle state of the para. pub fn lifecycle(id: ParaId) -> Option { ParaLifecycles::get(&id) @@ -1022,6 +1003,15 @@ mod tests { assert!(!::CodeByHash::contains_key(validation_code.hash())); } + fn fetch_validation_code_at( + para_id: ParaId, + at: BlockNumber, + assume_intermediate: Option, + ) -> Option { + Paras::validation_code_hash_at(para_id, at, assume_intermediate) + .and_then(Paras::code_by_hash) + } + #[test] fn para_past_code_meta_gives_right_code() { let mut past_code = ParaPastCodeMeta::default(); @@ -1661,7 +1651,7 @@ mod tests { } #[test] - fn code_at_with_intermediate() { + fn code_hash_at_with_intermediate() { let code_retention_period = 10; let paras = vec![ @@ -1691,29 +1681,29 @@ mod tests { Paras::schedule_code_upgrade(para_id, new_code.clone(), 10); // no intermediate, falls back on current/past. - assert_eq!(Paras::validation_code_at(para_id, 1, None), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 10, None), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 100, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 1, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 10, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 100, None), Some(old_code.clone())); // intermediate before upgrade meant to be applied, falls back on current. - assert_eq!(Paras::validation_code_at(para_id, 9, Some(8)), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 10, Some(9)), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 11, Some(9)), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 9, Some(8)), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 10, Some(9)), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 11, Some(9)), Some(old_code.clone())); // intermediate at or after upgrade applied - assert_eq!(Paras::validation_code_at(para_id, 11, Some(10)), Some(new_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 100, Some(11)), Some(new_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 11, Some(10)), Some(new_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 100, Some(11)), Some(new_code.clone())); run_to_block(code_retention_period + 5, None); // at <= intermediate not allowed - assert_eq!(Paras::validation_code_at(para_id, 10, Some(10)), None); - assert_eq!(Paras::validation_code_at(para_id, 9, Some(10)), None); + assert_eq!(fetch_validation_code_at(para_id, 10, Some(10)), None); + assert_eq!(fetch_validation_code_at(para_id, 9, Some(10)), None); }); } #[test] - fn code_at_returns_up_to_end_of_code_retention_period() { + fn code_hash_at_returns_up_to_end_of_code_retention_period() { let code_retention_period = 10; let paras = vec![ @@ -1750,17 +1740,17 @@ mod tests { vec![upgrade_at(2, 10)], ); - assert_eq!(Paras::validation_code_at(para_id, 2, None), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 3, None), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 9, None), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 10, None), Some(new_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 2, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 3, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 9, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 10, None), Some(new_code.clone())); run_to_block(10 + code_retention_period, None); - assert_eq!(Paras::validation_code_at(para_id, 2, None), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 3, None), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 9, None), Some(old_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 10, None), Some(new_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 2, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 3, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 9, None), Some(old_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 10, None), Some(new_code.clone())); run_to_block(10 + code_retention_period + 1, None); @@ -1774,10 +1764,10 @@ mod tests { }, ); - assert_eq!(Paras::validation_code_at(para_id, 2, None), None); // pruned :( - assert_eq!(Paras::validation_code_at(para_id, 9, None), None); - assert_eq!(Paras::validation_code_at(para_id, 10, None), Some(new_code.clone())); - assert_eq!(Paras::validation_code_at(para_id, 11, None), Some(new_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 2, None), None); // pruned :( + assert_eq!(fetch_validation_code_at(para_id, 9, None), None); + assert_eq!(fetch_validation_code_at(para_id, 10, None), Some(new_code.clone())); + assert_eq!(fetch_validation_code_at(para_id, 11, None), Some(new_code.clone())); }); } diff --git a/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs b/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs index 10f3a33fdc..b73c8e03a2 100644 --- a/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs +++ b/polkadot/runtime/parachains/src/runtime_api_impl/v1.rs @@ -274,14 +274,6 @@ pub fn validation_code( ) } -/// Implementation for the `historical_validation_code` function of the runtime API. -pub fn historical_validation_code( - para_id: ParaId, - context_height: T::BlockNumber, -) -> Option { - >::validation_code_at(para_id, context_height, None) -} - /// Implementation for the `candidate_pending_availability` function of the runtime API. pub fn candidate_pending_availability(para_id: ParaId) -> Option> diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs index 7585fa5301..3b1c6e0303 100644 --- a/polkadot/runtime/polkadot/src/lib.rs +++ b/polkadot/runtime/polkadot/src/lib.rs @@ -1187,10 +1187,6 @@ sp_api::impl_runtime_apis! { None } - fn historical_validation_code(_: Id, _: BlockNumber) -> Option { - None - } - fn candidate_pending_availability(_: Id) -> Option> { None } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 74b036794c..129fdbe4fe 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -1107,12 +1107,6 @@ sp_api::impl_runtime_apis! { runtime_api_impl::validation_code::(para_id, assumption) } - fn historical_validation_code(para_id: Id, context_height: BlockNumber) - -> Option - { - runtime_api_impl::historical_validation_code::(para_id, context_height) - } - fn candidate_pending_availability(para_id: Id) -> Option> { runtime_api_impl::candidate_pending_availability::(para_id) } diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 0cbf946e8b..d4776cfa2b 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -670,13 +670,6 @@ sp_api::impl_runtime_apis! { runtime_impl::validation_code::(para_id, assumption) } - fn historical_validation_code(para_id: ParaId, context_height: BlockNumber) - -> Option - { - runtime_impl::historical_validation_code::(para_id, context_height) - } - - fn candidate_pending_availability(para_id: ParaId) -> Option> { runtime_impl::candidate_pending_availability::(para_id) } diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 4c6ff7b569..1f5dcfc461 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -1223,12 +1223,6 @@ sp_api::impl_runtime_apis! { parachains_runtime_api_impl::validation_code::(para_id, assumption) } - fn historical_validation_code(para_id: ParaId, context_height: BlockNumber) - -> Option - { - parachains_runtime_api_impl::historical_validation_code::(para_id, context_height) - } - fn candidate_pending_availability(para_id: ParaId) -> Option> { parachains_runtime_api_impl::candidate_pending_availability::(para_id) }