Unverified Commit b9204405 authored by André Silva's avatar André Silva Committed by GitHub
Browse files

replace HistoricalValidationCode usages with ValidationCodeByHash (#3210)

* replace HistoricalValidationCode usages with ValidationCodeByHash

* runtime-api: tabify tests file

* update implementers guide
parent 0e6a3a3e
Pipeline #141852 failed with stages
in 35 minutes and 35 seconds
...@@ -1879,7 +1879,6 @@ async fn launch_approval( ...@@ -1879,7 +1879,6 @@ async fn launch_approval(
) -> SubsystemResult<Option<RemoteHandle<()>>> { ) -> SubsystemResult<Option<RemoteHandle<()>>> {
let (a_tx, a_rx) = oneshot::channel(); let (a_tx, a_rx) = oneshot::channel();
let (code_tx, code_rx) = oneshot::channel(); let (code_tx, code_rx) = oneshot::channel();
let (context_num_tx, context_num_rx) = oneshot::channel();
let candidate_hash = candidate.hash(); let candidate_hash = candidate.hash();
...@@ -1897,30 +1896,11 @@ async fn launch_approval( ...@@ -1897,30 +1896,11 @@ async fn launch_approval(
a_tx, a_tx,
).into()).await; ).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( ctx.send_message(
RuntimeApiMessage::Request( RuntimeApiMessage::Request(
block_hash, block_hash,
RuntimeApiRequest::HistoricalValidationCode( RuntimeApiRequest::ValidationCodeByHash(
candidate.descriptor.para_id, candidate.descriptor.validation_code_hash,
in_context_number,
code_tx, code_tx,
), ),
).into() ).into()
......
...@@ -14,20 +14,18 @@ ...@@ -14,20 +14,18 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use polkadot_primitives::v1::{ use std::collections::btree_map::BTreeMap;
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 memory_lru::{MemoryLruCache, ResidentSize}; 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 AUTHORITIES_CACHE_SIZE: usize = 128 * 1024;
const VALIDATORS_CACHE_SIZE: usize = 64 * 1024; const VALIDATORS_CACHE_SIZE: usize = 64 * 1024;
...@@ -37,7 +35,6 @@ const PERSISTED_VALIDATION_DATA_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 CHECK_VALIDATION_OUTPUTS_CACHE_SIZE: usize = 64 * 1024;
const SESSION_INDEX_FOR_CHILD_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 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_PENDING_AVAILABILITY_CACHE_SIZE: usize = 64 * 1024;
const CANDIDATE_EVENTS_CACHE_SIZE: usize = 64 * 1024; const CANDIDATE_EVENTS_CACHE_SIZE: usize = 64 * 1024;
const SESSION_INFO_CACHE_SIZE: usize = 64 * 1024; const SESSION_INFO_CACHE_SIZE: usize = 64 * 1024;
...@@ -80,7 +77,7 @@ pub(crate) struct RequestResultCache { ...@@ -80,7 +77,7 @@ pub(crate) struct RequestResultCache {
check_validation_outputs: MemoryLruCache<(Hash, ParaId, CandidateCommitments), ResidentSizeOf<bool>>, check_validation_outputs: MemoryLruCache<(Hash, ParaId, CandidateCommitments), ResidentSizeOf<bool>>,
session_index_for_child: MemoryLruCache<Hash, ResidentSizeOf<SessionIndex>>, session_index_for_child: MemoryLruCache<Hash, ResidentSizeOf<SessionIndex>>,
validation_code: MemoryLruCache<(Hash, ParaId, OccupiedCoreAssumption), ResidentSizeOf<Option<ValidationCode>>>, validation_code: MemoryLruCache<(Hash, ParaId, OccupiedCoreAssumption), ResidentSizeOf<Option<ValidationCode>>>,
historical_validation_code: MemoryLruCache<(Hash, ParaId, BlockNumber), ResidentSizeOf<Option<ValidationCode>>>, validation_code_by_hash: MemoryLruCache<(Hash, ValidationCodeHash), ResidentSizeOf<Option<ValidationCode>>>,
candidate_pending_availability: MemoryLruCache<(Hash, ParaId), ResidentSizeOf<Option<CommittedCandidateReceipt>>>, candidate_pending_availability: MemoryLruCache<(Hash, ParaId), ResidentSizeOf<Option<CommittedCandidateReceipt>>>,
candidate_events: MemoryLruCache<Hash, ResidentSizeOf<Vec<CandidateEvent>>>, candidate_events: MemoryLruCache<Hash, ResidentSizeOf<Vec<CandidateEvent>>>,
session_info: MemoryLruCache<(Hash, SessionIndex), ResidentSizeOf<Option<SessionInfo>>>, session_info: MemoryLruCache<(Hash, SessionIndex), ResidentSizeOf<Option<SessionInfo>>>,
...@@ -100,7 +97,7 @@ impl Default for RequestResultCache { ...@@ -100,7 +97,7 @@ impl Default for RequestResultCache {
check_validation_outputs: MemoryLruCache::new(CHECK_VALIDATION_OUTPUTS_CACHE_SIZE), check_validation_outputs: MemoryLruCache::new(CHECK_VALIDATION_OUTPUTS_CACHE_SIZE),
session_index_for_child: MemoryLruCache::new(SESSION_INDEX_FOR_CHILD_CACHE_SIZE), session_index_for_child: MemoryLruCache::new(SESSION_INDEX_FOR_CHILD_CACHE_SIZE),
validation_code: MemoryLruCache::new(VALIDATION_CODE_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_pending_availability: MemoryLruCache::new(CANDIDATE_PENDING_AVAILABILITY_CACHE_SIZE),
candidate_events: MemoryLruCache::new(CANDIDATE_EVENTS_CACHE_SIZE), candidate_events: MemoryLruCache::new(CANDIDATE_EVENTS_CACHE_SIZE),
session_info: MemoryLruCache::new(SESSION_INFO_CACHE_SIZE), session_info: MemoryLruCache::new(SESSION_INFO_CACHE_SIZE),
...@@ -176,12 +173,12 @@ impl RequestResultCache { ...@@ -176,12 +173,12 @@ impl RequestResultCache {
self.validation_code.insert(key, ResidentSizeOf(value)); self.validation_code.insert(key, ResidentSizeOf(value));
} }
pub(crate) fn historical_validation_code(&mut self, key: (Hash, ParaId, BlockNumber)) -> Option<&Option<ValidationCode>> { pub(crate) fn validation_code_by_hash(&mut self, key: (Hash, ValidationCodeHash)) -> Option<&Option<ValidationCode>> {
self.historical_validation_code.get(&key).map(|v| &v.0) 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<ValidationCode>) { pub(crate) fn cache_validation_code_by_hash(&mut self, key: (Hash, ValidationCodeHash), value: Option<ValidationCode>) {
self.historical_validation_code.insert(key, ResidentSizeOf(value)); self.validation_code_by_hash.insert(key, ResidentSizeOf(value));
} }
pub(crate) fn candidate_pending_availability(&mut self, key: (Hash, ParaId)) -> Option<&Option<CommittedCandidateReceipt>> { pub(crate) fn candidate_pending_availability(&mut self, key: (Hash, ParaId)) -> Option<&Option<CommittedCandidateReceipt>> {
...@@ -242,7 +239,7 @@ pub(crate) enum RequestResult { ...@@ -242,7 +239,7 @@ pub(crate) enum RequestResult {
CheckValidationOutputs(Hash, ParaId, CandidateCommitments, bool), CheckValidationOutputs(Hash, ParaId, CandidateCommitments, bool),
SessionIndexForChild(Hash, SessionIndex), SessionIndexForChild(Hash, SessionIndex),
ValidationCode(Hash, ParaId, OccupiedCoreAssumption, Option<ValidationCode>), ValidationCode(Hash, ParaId, OccupiedCoreAssumption, Option<ValidationCode>),
HistoricalValidationCode(Hash, ParaId, BlockNumber, Option<ValidationCode>), ValidationCodeByHash(Hash, ValidationCodeHash, Option<ValidationCode>),
CandidatePendingAvailability(Hash, ParaId, Option<CommittedCandidateReceipt>), CandidatePendingAvailability(Hash, ParaId, Option<CommittedCandidateReceipt>),
CandidateEvents(Hash, Vec<CandidateEvent>), CandidateEvents(Hash, Vec<CandidateEvent>),
SessionInfo(Hash, SessionIndex, Option<SessionInfo>), SessionInfo(Hash, SessionIndex, Option<SessionInfo>),
......
...@@ -119,8 +119,8 @@ impl<Client> RuntimeApiSubsystem<Client> where ...@@ -119,8 +119,8 @@ impl<Client> RuntimeApiSubsystem<Client> where
self.requests_cache.cache_session_index_for_child(relay_parent, session_index), self.requests_cache.cache_session_index_for_child(relay_parent, session_index),
ValidationCode(relay_parent, para_id, assumption, code) => ValidationCode(relay_parent, para_id, assumption, code) =>
self.requests_cache.cache_validation_code((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) => ValidationCodeByHash(relay_parent, validation_code_hash, code) =>
self.requests_cache.cache_historical_validation_code((relay_parent, para_id, n), code), self.requests_cache.cache_validation_code_by_hash((relay_parent, validation_code_hash), code),
CandidatePendingAvailability(relay_parent, para_id, candidate) => CandidatePendingAvailability(relay_parent, para_id, candidate) =>
self.requests_cache.cache_candidate_pending_availability((relay_parent, para_id), candidate), self.requests_cache.cache_candidate_pending_availability((relay_parent, para_id), candidate),
CandidateEvents(relay_parent, events) => CandidateEvents(relay_parent, events) =>
...@@ -183,9 +183,9 @@ impl<Client> RuntimeApiSubsystem<Client> where ...@@ -183,9 +183,9 @@ impl<Client> RuntimeApiSubsystem<Client> where
Request::ValidationCode(para, assumption, sender) => Request::ValidationCode(para, assumption, sender) =>
query!(validation_code(para, assumption), sender) query!(validation_code(para, assumption), sender)
.map(|sender| Request::ValidationCode(para, assumption, sender)), .map(|sender| Request::ValidationCode(para, assumption, sender)),
Request::HistoricalValidationCode(para, at, sender) => Request::ValidationCodeByHash(validation_code_hash, sender) =>
query!(historical_validation_code(para, at), sender) query!(validation_code_by_hash(validation_code_hash), sender)
.map(|sender| Request::HistoricalValidationCode(para, at, sender)), .map(|sender| Request::ValidationCodeByHash(validation_code_hash, sender)),
Request::CandidatePendingAvailability(para, sender) => Request::CandidatePendingAvailability(para, sender) =>
query!(candidate_pending_availability(para), sender) query!(candidate_pending_availability(para), sender)
.map(|sender| Request::CandidatePendingAvailability(para, sender)), .map(|sender| Request::CandidatePendingAvailability(para, sender)),
...@@ -341,8 +341,8 @@ where ...@@ -341,8 +341,8 @@ where
Request::SessionIndexForChild(sender) => query!(SessionIndexForChild, session_index_for_child(), sender), Request::SessionIndexForChild(sender) => query!(SessionIndexForChild, session_index_for_child(), sender),
Request::ValidationCode(para, assumption, sender) => Request::ValidationCode(para, assumption, sender) =>
query!(ValidationCode, validation_code(para, assumption), sender), query!(ValidationCode, validation_code(para, assumption), sender),
Request::HistoricalValidationCode(para, at, sender) => Request::ValidationCodeByHash(validation_code_hash, sender) =>
query!(HistoricalValidationCode, historical_validation_code(para, at), sender), query!(ValidationCodeByHash, validation_code_by_hash(validation_code_hash), sender),
Request::CandidatePendingAvailability(para, sender) => Request::CandidatePendingAvailability(para, sender) =>
query!(CandidatePendingAvailability, candidate_pending_availability(para), sender), query!(CandidatePendingAvailability, candidate_pending_availability(para), sender),
Request::CandidateEvents(sender) => query!(CandidateEvents, candidate_events(), sender), Request::CandidateEvents(sender) => query!(CandidateEvents, candidate_events(), sender),
......
This diff is collapsed.
...@@ -22,37 +22,34 @@ ...@@ -22,37 +22,34 @@
//! //!
//! Subsystems' APIs are defined separately from their implementation, leading to easier mocking. //! 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 futures::channel::{mpsc, oneshot};
use thiserror::Error; use thiserror::Error;
pub use sc_network::IfDisconnected; pub use sc_network::IfDisconnected;
use polkadot_node_network_protocol::{ use polkadot_node_network_protocol::{
PeerId, UnifiedReputationChange, peer_set::PeerSet, peer_set::PeerSet,
request_response::{ request_response::{request::IncomingRequest, v1 as req_res_v1, Requests},
Requests, request::IncomingRequest, v1 as req_res_v1 v1 as protocol_v1, PeerId, UnifiedReputationChange,
},
v1 as protocol_v1,
}; };
use polkadot_node_primitives::{ use polkadot_node_primitives::{
CollationGenerationConfig, SignedFullStatement, ValidationResult,
approval::{BlockApprovalMeta, IndirectAssignmentCert, IndirectSignedApprovalVote}, approval::{BlockApprovalMeta, IndirectAssignmentCert, IndirectSignedApprovalVote},
BabeEpoch, AvailableData, PoV, ErasureChunk AvailableData, BabeEpoch, CollationGenerationConfig, ErasureChunk, PoV, SignedFullStatement,
ValidationResult,
}; };
use polkadot_primitives::v1::{ use polkadot_primitives::v1::{
AuthorityDiscoveryId, BackedCandidate, BlockNumber, SessionInfo, AuthorityDiscoveryId, BackedCandidate, BlockNumber, CandidateDescriptor, CandidateEvent,
Header as BlockHeader, CandidateDescriptor, CandidateEvent, CandidateReceipt, CandidateHash, CandidateIndex, CandidateReceipt, CollatorId, CommittedCandidateReceipt,
CollatorId, CommittedCandidateReceipt, CoreState, CoreState, GroupIndex, GroupRotationInfo, Hash, Header as BlockHeader, Id as ParaId,
GroupRotationInfo, Hash, Id as ParaId, OccupiedCoreAssumption, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet, OccupiedCoreAssumption,
PersistedValidationData, SessionIndex, SignedAvailabilityBitfield, PersistedValidationData, SessionIndex, SessionInfo, SignedAvailabilityBitfield,
ValidationCode, ValidatorId, CandidateHash, SignedAvailabilityBitfields, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex,
ValidatorIndex, ValidatorSignature, InboundDownwardMessage, InboundHrmpMessage, ValidatorSignature,
CandidateIndex, GroupIndex, MultiDisputeStatementSet, SignedAvailabilityBitfields,
}; };
use polkadot_statement_table::v1::Misbehavior;
use polkadot_procmacro_subsystem_dispatch_gen::subsystem_dispatch_gen; 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. /// Network events as transmitted to other subsystems, wrapped in their message types.
pub mod network_bridge_event; pub mod network_bridge_event;
...@@ -464,16 +461,9 @@ pub enum RuntimeApiRequest { ...@@ -464,16 +461,9 @@ pub enum RuntimeApiRequest {
OccupiedCoreAssumption, OccupiedCoreAssumption,
RuntimeApiSender<Option<ValidationCode>>, RuntimeApiSender<Option<ValidationCode>>,
), ),
/// Fetch the historical validation code used by a para for candidates executed in the /// Get validation code by its hash, either past, current or future code can be returned, as long as state is still
/// context of a given block height in the current chain. /// available.
/// ValidationCodeByHash(ValidationCodeHash, RuntimeApiSender<Option<ValidationCode>>),
/// `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<Option<ValidationCode>>,
),
/// Get a the candidate pending availability for a particular parachain by parachain / core index /// Get a the candidate pending availability for a particular parachain by parachain / core index
CandidatePendingAvailability(ParaId, RuntimeApiSender<Option<CommittedCandidateReceipt>>), CandidatePendingAvailability(ParaId, RuntimeApiSender<Option<CommittedCandidateReceipt>>),
/// Get all events concerning candidates (backing, inclusion, time-out) in the parent of /// Get all events concerning candidates (backing, inclusion, time-out) in the parent of
......
...@@ -62,6 +62,9 @@ impl ValidationCode { ...@@ -62,6 +62,9 @@ impl ValidationCode {
} }
} }
/// A hash of the parachain validation code.
pub type ValidationCodeHash = Hash;
/// Parachain block data. /// Parachain block data.
/// ///
/// Contains everything required to validate para-block, may contain block and witness data. /// Contains everything required to validate para-block, may contain block and witness data.
......
...@@ -38,7 +38,7 @@ pub use polkadot_core_primitives::v1::{ ...@@ -38,7 +38,7 @@ pub use polkadot_core_primitives::v1::{
// Export some polkadot-parachain primitives // Export some polkadot-parachain primitives
pub use 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. // Export some basic parachain primitives from v0.
...@@ -909,15 +909,6 @@ sp_api::decl_runtime_apis! { ...@@ -909,15 +909,6 @@ sp_api::decl_runtime_apis! {
fn validation_code(para_id: Id, assumption: OccupiedCoreAssumption) fn validation_code(para_id: Id, assumption: OccupiedCoreAssumption)
-> Option<ValidationCode>; -> Option<ValidationCode>;
/// 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<ValidationCode>;
/// Get the receipt of a candidate pending availability. This returns `Some` for any paras /// Get the receipt of a candidate pending availability. This returns `Some` for any paras
/// assigned to occupied cores in `availability_cores` and `None` otherwise. /// assigned to occupied cores in `availability_cores` and `None` otherwise.
#[skip_initialize_block] #[skip_initialize_block]
......
...@@ -271,7 +271,7 @@ On receiving an `ApprovedAncestor(Hash, BlockNumber, response_channel)`: ...@@ -271,7 +271,7 @@ On receiving an `ApprovedAncestor(Hash, BlockNumber, response_channel)`:
* Requires `(SessionIndex, SessionInfo, CandidateReceipt, ValidatorIndex, backing_group, block_hash, candidate_index)` * Requires `(SessionIndex, SessionInfo, CandidateReceipt, ValidatorIndex, backing_group, block_hash, candidate_index)`
* Extract the public key of the `ValidatorIndex` from the `SessionInfo` for the session. * 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)` * 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` * Spawn a background task with a clone of `background_tx`
* Wait for the available data * Wait for the available data
* Issue a `CandidateValidationMessage::ValidateFromExhaustive` message * Issue a `CandidateValidationMessage::ValidateFromExhaustive` message
......
...@@ -16,14 +16,6 @@ Output: ...@@ -16,14 +16,6 @@ Output:
## Functionality ## Functionality
In-memory state:
```rust
struct State {
recent_block_hash: Hash
}
```
### On `OverseerSignal::ActiveLeavesUpdate` ### On `OverseerSignal::ActiveLeavesUpdate`
Do nothing. Do nothing.
...@@ -38,16 +30,14 @@ Conclude. ...@@ -38,16 +30,14 @@ Conclude.
### On `DisputeParticipationMessage::Participate` ### 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 }` * Decompose into parts: `{ candidate_hash, candidate_receipt, session, voted_indices }`
* Issue an [`AvailabilityRecoveryMessage::RecoverAvailableData`][AvailabilityRecoveryMessage] * Issue an [`AvailabilityRecoveryMessage::RecoverAvailableData`][AvailabilityRecoveryMessage]
* If the result is `Unavailable`, return. * If the result is `Unavailable`, return.
* If the result is `Invalid`, [cast invalid votes](#cast-votes) and 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]. * 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. * 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. * 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 result is `Invalid`, [cast invalid votes](#cast-votes) and return.
* If the validation fails, [cast invalid votes](#cast-votes) and return. * If the validation fails, [cast invalid votes](#cast-votes) and return.
...@@ -57,9 +47,7 @@ Conclude. ...@@ -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`. 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::IssueLocalStatement`][DisputeCoordinatorMessage] with `is_valid` according to the parametrization.
Invoke [`DisputeCoordinatorMessage::ImportStatements`][DisputeCoordinatorMessage] with each signed statement.
[RuntimeApiMessage]: ../../types/overseer-protocol.md#runtime-api-message [RuntimeApiMessage]: ../../types/overseer-protocol.md#runtime-api-message
[DisputeParticipationMessage]: ../../types/overseer-protocol.md#dispute-participation-message [DisputeParticipationMessage]: ../../types/overseer-protocol.md#dispute-participation-message
......
# 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<ValidationCode>;
```
...@@ -5,3 +5,9 @@ Fetch the validation code used by a para, making the given `OccupiedCoreAssumpti ...@@ -5,3 +5,9 @@ Fetch the validation code used by a para, making the given `OccupiedCoreAssumpti
```rust ```rust
fn validation_code(at: Block, ParaId, OccupiedCoreAssumption) -> Option<ValidationCode>; fn validation_code(at: Block, ParaId, OccupiedCoreAssumption) -> Option<ValidationCode>;
``` ```
Fetch the validation code (past, present or future) by its hash.
```rust
fn validation_code_by_hash(at: Block, Hash) -> Option<ValidationCode>;
```
...@@ -144,7 +144,7 @@ UpcomingParasGenesis: map ParaId => Option<ParaGenesisArgs>; ...@@ -144,7 +144,7 @@ UpcomingParasGenesis: map ParaId => Option<ParaGenesisArgs>;
/// The number of references on the validation code in `CodeByHash` storage. /// The number of references on the validation code in `CodeByHash` storage.
CodeByHashRefs: map Hash => u32; CodeByHashRefs: map Hash => u32;
/// Validation code stored by its hash. /// Validation code stored by its hash.
CoeByHash: map Hash => Option<ValidationCode> CodeByHash: map Hash => Option<ValidationCode>
``` ```
## Session Change ## Session Change
......
...@@ -618,9 +618,9 @@ enum RuntimeApiRequest { ...@@ -618,9 +618,9 @@ enum RuntimeApiRequest {
SessionIndexForChild(ResponseChannel<SessionIndex>), SessionIndexForChild(ResponseChannel<SessionIndex>),
/// Get the validation code for a specific para, using the given occupied core assumption. /// Get the validation code for a specific para, using the given occupied core assumption.
ValidationCode(ParaId, OccupiedCoreAssumption, ResponseChannel<Option<ValidationCode>>), ValidationCode(ParaId, OccupiedCoreAssumption, ResponseChannel<Option<ValidationCode>>),
/// Fetch the historical validation code used by a para for candidates executed in /// Get validation code by its hash, either past, current or future code can be returned,
/// the context of a given block height in the current chain. /// as long as state is still available.
HistoricalValidationCode(ParaId, BlockNumber, ResponseChannel<Option<ValidationCode>>), ValidationCodeByHash(ValidationCodeHash, RuntimeApiSender<Option<ValidationCode>>),
/// Get a committed candidate receipt for all candidates pending availability. /// Get a committed candidate receipt for all candidates pending availability.
CandidatePendingAvailability(ParaId, ResponseChannel<Option<CommittedCandidateReceipt>>), CandidatePendingAvailability(ParaId, ResponseChannel<Option<CommittedCandidateReceipt>>),
/// Get all events concerning candidates in the last block. /// Get all events concerning candidates in the last block.
......
...@@ -1625,12 +1625,6 @@ sp_api::impl_runtime_apis! { ...@@ -1625,12 +1625,6 @@ sp_api::impl_runtime_apis! {
parachains_runtime_api_impl::validation_code::<Runtime>(para_id, assumption) parachains_runtime_api_impl::validation_code::<Runtime>(para_id, assumption)
} }
fn historical_validation_code(para_id: ParaId, context_height: BlockNumber)
-> Option<ValidationCode>
{
parachains_runtime_api_impl::historical_validation_code::<Runtime>(para_id, context_height)
}
fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> { fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
parachains_runtime_api_impl::candidate_pending_availability::<Runtime>(para_id) parachains_runtime_api_impl::candidate_pending_availability::<Runtime>(para_id)
} }
......
...@@ -858,25 +858,6 @@ impl<T: Config> Module<T> { ...@@ -858,25 +858,6 @@ impl<T: Config> Module<T> {
} }
} }
/// 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<T::BlockNumber>,
) -> Option<ValidationCode> {
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. /// Returns the current lifecycle state of the para.
pub fn lifecycle(id: ParaId) -> Option<ParaLifecycle> { pub fn lifecycle(id: ParaId) -> Option<ParaLifecycle> {
ParaLifecycles::get(&id) ParaLifecycles::get(&id)
...@@ -1022,6 +1003,15 @@ mod tests { ...@@ -1022,6 +1003,15 @@ mod tests {
assert!(!<Paras as Store>::CodeByHash::contains_key(validation_code.hash())); assert!(!<Paras as Store>::CodeByHash::contains_key(validation_code.hash()));
} }
fn fetch_validation_code_at(
para_id: ParaId,
at: BlockNumber,
assume_intermediate: Option<BlockNumber>,
) -> Option<ValidationCode> {
Paras::validation_code_hash_at(para_id, at, assume_intermediate)
.and_then(Paras::code_by_hash)
}
#[test] #[test]
fn para_past_code_meta_gives_right_code() { fn para_past_code_meta_gives_right_code() {
let mut past_code = ParaPastCodeMeta::default(); let mut past_code = ParaPastCodeMeta::default();
...@@ -1661,7 +1651,7 @@ mod tests { ...@@ -1661,7 +1651,7 @@ mod tests {
} }
#[test] #[test]
fn code_at_with_intermediate() { fn code_hash_at_with_intermediate() {
let code_retention_period = 10; let code_retention_period = 10;
let paras = vec![ let paras = vec![
...@@ -1691,29 +1681,29 @@ mod tests { ...@@ -1691,29 +1681,29 @@ mod tests {
Paras::schedule_code_upgrade(para_id, new_code.clone(), 10); Paras::schedule_code_upgrade(para_id, new_code.clone(), 10);
// no intermediate, falls back on current/past. // no intermediate, falls back on current/past.