mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-07 14:18:03 +00:00
Clean up PersistedValidationData (#2353)
* PVD: `block_number`->`relay_parent_number` * ValidationParams: `relay_chain_height`->`relay_parent_number` * Expose DMQ MQC hash as a well-known-key This way the relay storage merkle proofs will be able to obtain the DMQ MQC hash and we will be able to remove the it from the PersistedValidationData struct. * PersistedValidationData: Remove HRMP MQC heads * PersistedValidationData: Remove `dmq_mqc_head` * Expose the HRMP ingress channel index as a well-known-key This way a parachain (PVF and collator) can find all the parachains that have an outbound channel to the given one. That allows in turn to find all the inbound channels for the given para. Having access to that allows the parachain to get the same information as the hrmp_mqc_heads now provide. * Rename `relay_storage_root` to `relay_parent_storage_root`
This commit is contained in:
@@ -103,11 +103,9 @@ impl Default for TestState {
|
||||
fn default() -> Self {
|
||||
let persisted_validation_data = PersistedValidationData {
|
||||
parent_head: HeadData(vec![7, 8, 9]),
|
||||
block_number: 5,
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: 5,
|
||||
max_pov_size: 1024,
|
||||
relay_storage_root: Default::default(),
|
||||
relay_parent_storage_root: Default::default(),
|
||||
};
|
||||
|
||||
let pruning_config = PruningConfig {
|
||||
|
||||
@@ -1274,11 +1274,9 @@ mod tests {
|
||||
|
||||
let validation_data = PersistedValidationData {
|
||||
parent_head: HeadData(vec![7, 8, 9]),
|
||||
block_number: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: Default::default(),
|
||||
max_pov_size: 1024,
|
||||
relay_storage_root: Default::default(),
|
||||
relay_parent_storage_root: Default::default(),
|
||||
};
|
||||
|
||||
Self {
|
||||
|
||||
@@ -438,10 +438,8 @@ fn validate_candidate_exhaustive<B: ValidationBackend, S: SpawnNamed + 'static>(
|
||||
let params = ValidationParams {
|
||||
parent_head: persisted_validation_data.parent_head.clone(),
|
||||
block_data: pov.block_data.clone(),
|
||||
relay_chain_height: persisted_validation_data.block_number,
|
||||
relay_storage_root: persisted_validation_data.relay_storage_root,
|
||||
dmq_mqc_head: persisted_validation_data.dmq_mqc_head,
|
||||
hrmp_mqc_heads: persisted_validation_data.hrmp_mqc_heads.clone(),
|
||||
relay_parent_number: persisted_validation_data.relay_parent_number,
|
||||
relay_parent_storage_root: persisted_validation_data.relay_parent_storage_root,
|
||||
};
|
||||
|
||||
match B::validate(backend_arg, &validation_code, params, spawn) {
|
||||
|
||||
@@ -201,11 +201,9 @@ impl Default for TestState {
|
||||
|
||||
let persisted_validation_data = PersistedValidationData {
|
||||
parent_head: HeadData(vec![7, 8, 9]),
|
||||
block_number: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: Default::default(),
|
||||
max_pov_size: 1024,
|
||||
relay_storage_root: Default::default(),
|
||||
relay_parent_storage_root: Default::default(),
|
||||
};
|
||||
|
||||
let pov_block_a = PoV {
|
||||
|
||||
@@ -362,11 +362,9 @@ impl Default for TestState {
|
||||
|
||||
let persisted_validation_data = PersistedValidationData {
|
||||
parent_head: HeadData(vec![7, 8, 9]),
|
||||
block_number: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: Default::default(),
|
||||
max_pov_size: 1024,
|
||||
relay_storage_root: Default::default(),
|
||||
relay_parent_storage_root: Default::default(),
|
||||
};
|
||||
|
||||
let pov = PoV {
|
||||
|
||||
@@ -267,18 +267,9 @@ pub struct ValidationParams {
|
||||
/// The collation body.
|
||||
pub block_data: BlockData,
|
||||
/// The current relay-chain block number.
|
||||
pub relay_chain_height: RelayChainBlockNumber,
|
||||
pub relay_parent_number: RelayChainBlockNumber,
|
||||
/// The relay-chain block's storage root.
|
||||
pub relay_storage_root: Hash,
|
||||
/// The MQC head for the DMQ.
|
||||
///
|
||||
/// The DMQ MQC head will be used by the validation function to authorize the downward messages
|
||||
/// passed by the collator.
|
||||
pub dmq_mqc_head: Hash,
|
||||
/// The list of MQC heads for the inbound HRMP channels paired with the sender para ids. This
|
||||
/// vector is sorted ascending by the para id and doesn't contain multiple entries with the same
|
||||
/// sender.
|
||||
pub hrmp_mqc_heads: Vec<(Id, Hash)>,
|
||||
pub relay_parent_storage_root: Hash,
|
||||
}
|
||||
|
||||
/// The result of parachain validation.
|
||||
|
||||
@@ -168,7 +168,7 @@ impl Collator {
|
||||
block_data: block_data.encode().into(),
|
||||
},
|
||||
processed_downward_messages: 0,
|
||||
hrmp_watermark: validation_data.block_number,
|
||||
hrmp_watermark: validation_data.relay_parent_number,
|
||||
};
|
||||
|
||||
async move { Some(collation) }.boxed()
|
||||
@@ -230,10 +230,8 @@ mod tests {
|
||||
ValidationParams {
|
||||
parent_head: parent_head.encode().into(),
|
||||
block_data: collation.proof_of_validity.block_data,
|
||||
relay_chain_height: 1,
|
||||
relay_storage_root: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: 1,
|
||||
relay_parent_storage_root: Default::default(),
|
||||
},
|
||||
&IsolationStrategy::InProcess,
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
|
||||
@@ -41,7 +41,7 @@ pub extern "C" fn validate_block(params: *const u8, len: usize) -> u64 {
|
||||
upward_messages: sp_std::vec::Vec::new(),
|
||||
horizontal_messages: sp_std::vec::Vec::new(),
|
||||
processed_downward_messages: 0,
|
||||
hrmp_watermark: params.relay_chain_height,
|
||||
hrmp_watermark: params.relay_parent_number,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -67,10 +67,8 @@ fn execute_good_on_parent(isolation_strategy: IsolationStrategy) {
|
||||
ValidationParams {
|
||||
parent_head: GenericHeadData(parent_head.encode()),
|
||||
block_data: GenericBlockData(block_data.encode()),
|
||||
relay_chain_height: 1,
|
||||
relay_storage_root: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: 1,
|
||||
relay_parent_storage_root: Default::default(),
|
||||
},
|
||||
&isolation_strategy,
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
@@ -107,10 +105,8 @@ fn execute_good_chain_on_parent() {
|
||||
ValidationParams {
|
||||
parent_head: GenericHeadData(parent_head.encode()),
|
||||
block_data: GenericBlockData(block_data.encode()),
|
||||
relay_chain_height: number as RelayChainBlockNumber + 1,
|
||||
relay_storage_root: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: number as RelayChainBlockNumber + 1,
|
||||
relay_parent_storage_root: Default::default(),
|
||||
},
|
||||
&isolation_strategy,
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
@@ -148,10 +144,8 @@ fn execute_bad_on_parent() {
|
||||
ValidationParams {
|
||||
parent_head: GenericHeadData(parent_head.encode()),
|
||||
block_data: GenericBlockData(block_data.encode()),
|
||||
relay_chain_height: 1,
|
||||
relay_storage_root: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: 1,
|
||||
relay_parent_storage_root: Default::default(),
|
||||
},
|
||||
&isolation_strategy,
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
|
||||
@@ -41,10 +41,8 @@ fn terminates_on_timeout() {
|
||||
ValidationParams {
|
||||
block_data: BlockData(Vec::new()),
|
||||
parent_head: Default::default(),
|
||||
relay_chain_height: 1,
|
||||
relay_storage_root: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: 1,
|
||||
relay_parent_storage_root: Default::default(),
|
||||
},
|
||||
&isolation_strategy,
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
@@ -70,10 +68,8 @@ fn parallel_execution() {
|
||||
ValidationParams {
|
||||
block_data: BlockData(Vec::new()),
|
||||
parent_head: Default::default(),
|
||||
relay_chain_height: 1,
|
||||
relay_storage_root: Default::default(),
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_number: 1,
|
||||
relay_parent_storage_root: Default::default(),
|
||||
},
|
||||
&isolation_strategy,
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
@@ -83,10 +79,8 @@ fn parallel_execution() {
|
||||
ValidationParams {
|
||||
block_data: BlockData(Vec::new()),
|
||||
parent_head: Default::default(),
|
||||
relay_storage_root: Default::default(),
|
||||
relay_chain_height: 1,
|
||||
hrmp_mqc_heads: Vec::new(),
|
||||
dmq_mqc_head: Default::default(),
|
||||
relay_parent_storage_root: Default::default(),
|
||||
relay_parent_number: 1,
|
||||
},
|
||||
&isolation_strategy_clone,
|
||||
sp_core::testing::TaskExecutor::new(),
|
||||
|
||||
@@ -119,6 +119,22 @@ pub mod well_known_keys {
|
||||
})
|
||||
}
|
||||
|
||||
/// The list of inbound channels for the given para.
|
||||
///
|
||||
/// The storage entry stores a `Vec<ParaId>`
|
||||
pub fn hrmp_ingress_channel_index(para_id: Id) -> Vec<u8> {
|
||||
let prefix = hex!["6a0da05ca59913bc38a8630590f2627c1d3719f5b0b12c7105c073c507445948"];
|
||||
|
||||
para_id.using_encoded(|para_id: &[u8]| {
|
||||
prefix.as_ref()
|
||||
.iter()
|
||||
.chain(twox_64(para_id).iter())
|
||||
.chain(para_id.iter())
|
||||
.cloned()
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
/// The list of outbound channels for the given para.
|
||||
///
|
||||
/// The storage entry stores a `Vec<ParaId>`
|
||||
@@ -134,6 +150,23 @@ pub mod well_known_keys {
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
/// The MQC head for the downward message queue of the given para. See more in the `Dmp` module.
|
||||
///
|
||||
/// The storage entry stores a `Hash`. This is polkadot hash which is at the moment
|
||||
/// `blake2b-256`.
|
||||
pub fn dmq_mqc_head(para_id: Id) -> Vec<u8> {
|
||||
let prefix = hex!["63f78c98723ddc9073523ef3beefda0c4d7fefc408aac59dbfe80a72ac8e3ce5"];
|
||||
|
||||
para_id.using_encoded(|para_id: &[u8]| {
|
||||
prefix.as_ref()
|
||||
.iter()
|
||||
.chain(twox_64(para_id).iter())
|
||||
.chain(para_id.iter())
|
||||
.cloned()
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Unique identifier for the Inclusion Inherent
|
||||
@@ -360,18 +393,9 @@ pub struct PersistedValidationData<N = BlockNumber> {
|
||||
/// The parent head-data.
|
||||
pub parent_head: HeadData,
|
||||
/// The relay-chain block number this is in the context of.
|
||||
pub block_number: N,
|
||||
pub relay_parent_number: N,
|
||||
/// The relay-chain block storage root this is in the context of.
|
||||
pub relay_storage_root: Hash,
|
||||
/// The list of MQC heads for the inbound channels paired with the sender para ids. This
|
||||
/// vector is sorted ascending by the para id and doesn't contain multiple entries with the same
|
||||
/// sender.
|
||||
pub hrmp_mqc_heads: Vec<(Id, Hash)>,
|
||||
/// The MQC head for the DMQ.
|
||||
///
|
||||
/// The DMQ MQC head will be used by the validation function to authorize the downward messages
|
||||
/// passed by the collator.
|
||||
pub dmq_mqc_head: Hash,
|
||||
pub relay_parent_storage_root: Hash,
|
||||
/// The maximum legal size of a POV block, in bytes.
|
||||
pub max_pov_size: u32,
|
||||
}
|
||||
|
||||
@@ -93,17 +93,12 @@ digraph {
|
||||
<tr><td border="0" colspan="2" port="name">PersistedValidationData<N = BlockNumber></td></tr>
|
||||
<tr><td>parent_head</td><td port="parent_head">HeadData</td></tr>
|
||||
<tr><td>block_number</td><td port="block_number">N</td></tr>
|
||||
<tr><td>relay_storage_root</td><td port="relay_storage_root">Hash</td></tr>
|
||||
<tr><td>hrmp_mqc_heads</td><td port="hrmp_mqc_heads">Vec<(Id, Hash)></td></tr>
|
||||
<tr><td>dmq_mqc_head</td><td port="dmq_mqc_head">Hash</td></tr>
|
||||
<tr><td>relay_parent_storage_root</td><td port="relay_parent_storage_root">Hash</td></tr>
|
||||
<tr><td>max_pov_size</td><td port="max_pov_size">u32</td></tr>
|
||||
</table>
|
||||
>]
|
||||
|
||||
PersistedValidationData:parent_head -> HeadData:w
|
||||
PersistedValidationData:hrmp_mqc_heads -> Id:w
|
||||
PersistedValidationData:hrmp_mqc_heads -> MQCHash
|
||||
PersistedValidationData:dmq_mqc_head -> MQCHash
|
||||
|
||||
PersistedValidationDataHash [label = "Hash", shape="doublecircle", fill="gray90"]
|
||||
PersistedValidationDataHash -> PersistedValidationData:name
|
||||
@@ -401,16 +396,14 @@ digraph {
|
||||
<tr><td border="0" colspan="2" port="name">ValidationParams</td></tr>
|
||||
<tr><td>parent_head</td><td port="parent_head">HeadData</td></tr>
|
||||
<tr><td>block_data</td><td port="block_data">BlockData</td></tr>
|
||||
<tr><td>relay_chain_height</td><td port="relay_chain_height">RelayChainBlockNumber</td></tr>
|
||||
<tr><td>relay_storage_root</td><td port="relay_storage_root">Hash</td></tr>
|
||||
<tr><td>dmq_mqc_head</td><td port="dmq_mqc_head">Hash</td></tr>
|
||||
<tr><td>hrmp_mqc_heads</td><td port="hrmp_mqc_heads">Vec<(Id, Hash)></td></tr>
|
||||
<tr><td>relay_parent_number</td><td port="relay_parent_number">RelayChainBlockNumber</td></tr>
|
||||
<tr><td>relay_parent_storage_root</td><td port="relay_parent_storage_root">Hash</td></tr>
|
||||
</table>
|
||||
>]
|
||||
|
||||
ValidationParams:parent_head -> HeadData:name
|
||||
ValidationParams:block_data -> BlockData:name
|
||||
ValidationParams:relay_chain_height -> RelayChainBlockNumber:w
|
||||
ValidationParams:relay_parent_number -> RelayChainBlockNumber:w
|
||||
|
||||
RelayChainBlockNumber [label = "polkadot_core_primitives::BlockNumber"]
|
||||
|
||||
|
||||
@@ -107,14 +107,9 @@ struct PersistedValidationData {
|
||||
/// The parent head-data.
|
||||
parent_head: HeadData,
|
||||
/// The relay-chain block number this is in the context of. This informs the collator.
|
||||
block_number: BlockNumber,
|
||||
relay_parent_number: BlockNumber,
|
||||
/// The relay-chain block storage root this is in the context of.
|
||||
relay_storage_root: Hash,
|
||||
/// The MQC head for the DMQ.
|
||||
///
|
||||
/// The DMQ MQC head will be used by the validation function to authorize the downward messages
|
||||
/// passed by the collator.
|
||||
dmq_mqc_head: Hash,
|
||||
relay_parent_storage_root: Hash,
|
||||
/// The list of MQC heads for the inbound channels paired with the sender para ids. This
|
||||
/// vector is sorted ascending by the para id and doesn't contain multiple entries with the same
|
||||
/// sender.
|
||||
|
||||
@@ -202,7 +202,8 @@ impl<T: Config> Module<T> {
|
||||
|
||||
/// Returns the Head of Message Queue Chain for the given para or `None` if there is none
|
||||
/// associated with it.
|
||||
pub(crate) fn dmq_mqc_head(para: ParaId) -> Hash {
|
||||
#[cfg(test)]
|
||||
fn dmq_mqc_head(para: ParaId) -> Hash {
|
||||
<Self as Store>::DownwardMessageQueueHeads::get(¶)
|
||||
}
|
||||
|
||||
@@ -406,4 +407,25 @@ mod tests {
|
||||
assert!(queue_downward_message(a, big).is_err());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_dmq_mqc_head_is_externally_accessible() {
|
||||
use primitives::v1::well_known_keys;
|
||||
use hex_literal::hex;
|
||||
|
||||
let a = ParaId::from(2020);
|
||||
|
||||
new_test_ext(default_genesis_config()).execute_with(|| {
|
||||
let head = sp_io::storage::get(&well_known_keys::dmq_mqc_head(a));
|
||||
assert_eq!(head, None);
|
||||
|
||||
queue_downward_message(a, vec![1, 2, 3]).unwrap();
|
||||
|
||||
let head = sp_io::storage::get(&well_known_keys::dmq_mqc_head(a));
|
||||
assert_eq!(
|
||||
head,
|
||||
Some(hex!["434f8579a2297dfea851bf6be33093c83a78b655a53ae141a7894494c0010589"].to_vec())
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,7 +1084,8 @@ impl<T: Config> Module<T> {
|
||||
/// Returns the list of MQC heads for the inbound channels of the given recipient para paired
|
||||
/// with the sender para ids. This vector is sorted ascending by the para id and doesn't contain
|
||||
/// multiple entries with the same sender.
|
||||
pub(crate) fn hrmp_mqc_heads(recipient: ParaId) -> Vec<(ParaId, Hash)> {
|
||||
#[cfg(test)]
|
||||
fn hrmp_mqc_heads(recipient: ParaId) -> Vec<(ParaId, Hash)> {
|
||||
let sender_set = <Self as Store>::HrmpIngressChannelsIndex::get(&recipient);
|
||||
|
||||
// The ingress channels vector is sorted, thus `mqc_heads` is sorted as well.
|
||||
@@ -1706,6 +1707,18 @@ mod tests {
|
||||
},
|
||||
);
|
||||
|
||||
let raw_ingress_index =
|
||||
sp_io::storage::get(
|
||||
&well_known_keys::hrmp_ingress_channel_index(para_b),
|
||||
)
|
||||
.expect("the ingress index must be present for para_b");
|
||||
let ingress_index = <Vec<ParaId>>::decode(&mut &raw_ingress_index[..])
|
||||
.expect("ingress indexx should be decodable as a list of para ids");
|
||||
assert_eq!(
|
||||
ingress_index,
|
||||
vec![para_a],
|
||||
);
|
||||
|
||||
// Now, verify that we can access and decode the egress index.
|
||||
let raw_egress_index =
|
||||
sp_io::storage::get(
|
||||
|
||||
@@ -200,13 +200,13 @@ pub fn persisted_validation_data<T: initializer::Config>(
|
||||
) -> Option<PersistedValidationData<T::BlockNumber>> {
|
||||
use parity_scale_codec::Decode as _;
|
||||
let relay_parent_number = <frame_system::Module<T>>::block_number();
|
||||
let relay_storage_root = Hash::decode(&mut &sp_io::storage::root()[..])
|
||||
let relay_parent_storage_root = Hash::decode(&mut &sp_io::storage::root()[..])
|
||||
.expect("storage root must decode to the Hash type; qed");
|
||||
with_assumption::<T, _, _>(para_id, assumption, || {
|
||||
crate::util::make_persisted_validation_data::<T>(
|
||||
para_id,
|
||||
relay_parent_number,
|
||||
relay_storage_root,
|
||||
relay_parent_storage_root,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
use primitives::v1::{Id as ParaId, PersistedValidationData, Hash};
|
||||
|
||||
use crate::{configuration, paras, dmp, hrmp};
|
||||
use crate::{configuration, paras, hrmp};
|
||||
|
||||
/// Make the persisted validation data for a particular parachain, a specified relay-parent and it's
|
||||
/// storage root.
|
||||
@@ -28,16 +28,14 @@ use crate::{configuration, paras, dmp, hrmp};
|
||||
pub fn make_persisted_validation_data<T: paras::Config + hrmp::Config>(
|
||||
para_id: ParaId,
|
||||
relay_parent_number: T::BlockNumber,
|
||||
relay_storage_root: Hash,
|
||||
relay_parent_storage_root: Hash,
|
||||
) -> Option<PersistedValidationData<T::BlockNumber>> {
|
||||
let config = <configuration::Module<T>>::config();
|
||||
|
||||
Some(PersistedValidationData {
|
||||
parent_head: <paras::Module<T>>::para_head(¶_id)?,
|
||||
block_number: relay_parent_number,
|
||||
relay_storage_root,
|
||||
hrmp_mqc_heads: <hrmp::Module<T>>::hrmp_mqc_heads(para_id),
|
||||
dmq_mqc_head: <dmp::Module<T>>::dmq_mqc_head(para_id),
|
||||
relay_parent_number,
|
||||
relay_parent_storage_root,
|
||||
max_pov_size: config.max_pov_size,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user