mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 09:21:04 +00:00
Migrate from MQCs in persisted validation data to merkle proofs (#317)
* Update polkadot * Migrate all uses of MQC heads to merkle proofs * Mass rename `relay_parent_storage_root` * Restore parachain-system tests * Update polkadot and libp2p swarm for testing * Collapse match into an if let Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Fix compilation error in test-service Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Generated
+318
-283
File diff suppressed because it is too large
Load Diff
@@ -219,6 +219,31 @@ where
|
|||||||
})
|
})
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
|
let ingress_channels = relay_parent_state_backend
|
||||||
|
.storage(&relay_well_known_keys::hrmp_ingress_channel_index(
|
||||||
|
self.para_id,
|
||||||
|
))
|
||||||
|
.map_err(|e| {
|
||||||
|
error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"Cannot obtain the hrmp ingress channel index: {:?}",
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()?;
|
||||||
|
let ingress_channels = ingress_channels
|
||||||
|
.map(|raw| <Vec<ParaId>>::decode(&mut &raw[..]))
|
||||||
|
.transpose()
|
||||||
|
.map_err(|e| {
|
||||||
|
error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"Cannot decode the hrmp ingress channel index: {:?}",
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok()?
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
let egress_channels = relay_parent_state_backend
|
let egress_channels = relay_parent_state_backend
|
||||||
.storage(&relay_well_known_keys::hrmp_egress_channel_index(
|
.storage(&relay_well_known_keys::hrmp_egress_channel_index(
|
||||||
self.para_id,
|
self.para_id,
|
||||||
@@ -246,12 +271,22 @@ where
|
|||||||
|
|
||||||
let mut relevant_keys = vec![];
|
let mut relevant_keys = vec![];
|
||||||
relevant_keys.push(relay_well_known_keys::ACTIVE_CONFIG.to_vec());
|
relevant_keys.push(relay_well_known_keys::ACTIVE_CONFIG.to_vec());
|
||||||
|
relevant_keys.push(relay_well_known_keys::dmq_mqc_head(self.para_id));
|
||||||
relevant_keys.push(relay_well_known_keys::relay_dispatch_queue_size(
|
relevant_keys.push(relay_well_known_keys::relay_dispatch_queue_size(
|
||||||
self.para_id,
|
self.para_id,
|
||||||
));
|
));
|
||||||
|
relevant_keys.push(relay_well_known_keys::hrmp_ingress_channel_index(
|
||||||
|
self.para_id,
|
||||||
|
));
|
||||||
relevant_keys.push(relay_well_known_keys::hrmp_egress_channel_index(
|
relevant_keys.push(relay_well_known_keys::hrmp_egress_channel_index(
|
||||||
self.para_id,
|
self.para_id,
|
||||||
));
|
));
|
||||||
|
relevant_keys.extend(ingress_channels.into_iter().map(|sender| {
|
||||||
|
relay_well_known_keys::hrmp_channels(HrmpChannelId {
|
||||||
|
sender,
|
||||||
|
recipient: self.para_id,
|
||||||
|
})
|
||||||
|
}));
|
||||||
relevant_keys.extend(egress_channels.into_iter().map(|recipient| {
|
relevant_keys.extend(egress_channels.into_iter().map(|recipient| {
|
||||||
relay_well_known_keys::hrmp_channels(HrmpChannelId {
|
relay_well_known_keys::hrmp_channels(HrmpChannelId {
|
||||||
sender: self.para_id,
|
sender: self.para_id,
|
||||||
@@ -586,7 +621,7 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
let collation =
|
let collation =
|
||||||
self.build_collation(b, block_hash, validation_data.block_number)?;
|
self.build_collation(b, block_hash, validation_data.relay_parent_number)?;
|
||||||
let pov_hash = collation.proof_of_validity.hash();
|
let pov_hash = collation.proof_of_validity.hash();
|
||||||
|
|
||||||
self.wait_to_announce
|
self.wait_to_announce
|
||||||
|
|||||||
@@ -179,18 +179,18 @@ decl_module! {
|
|||||||
// which means we can put the initialization logic here to remove the
|
// which means we can put the initialization logic here to remove the
|
||||||
// sequencing problem.
|
// sequencing problem.
|
||||||
if let Some((apply_block, validation_function)) = PendingValidationFunction::get() {
|
if let Some((apply_block, validation_function)) = PendingValidationFunction::get() {
|
||||||
if vfp.block_number >= apply_block {
|
if vfp.relay_parent_number >= apply_block {
|
||||||
PendingValidationFunction::kill();
|
PendingValidationFunction::kill();
|
||||||
LastUpgrade::put(&apply_block);
|
LastUpgrade::put(&apply_block);
|
||||||
Self::put_parachain_code(&validation_function);
|
Self::put_parachain_code(&validation_function);
|
||||||
Self::deposit_event(Event::ValidationFunctionApplied(vfp.block_number));
|
Self::deposit_event(Event::ValidationFunctionApplied(vfp.relay_parent_number));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (host_config, relevant_messaging_state) =
|
let (host_config, relevant_messaging_state) =
|
||||||
relay_state_snapshot::extract_from_proof(
|
relay_state_snapshot::extract_from_proof(
|
||||||
T::SelfParaId::get(),
|
T::SelfParaId::get(),
|
||||||
vfp.relay_storage_root,
|
vfp.relay_parent_storage_root,
|
||||||
relay_chain_state
|
relay_chain_state
|
||||||
)
|
)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -200,13 +200,19 @@ decl_module! {
|
|||||||
|
|
||||||
storage::unhashed::put(VALIDATION_DATA, &vfp);
|
storage::unhashed::put(VALIDATION_DATA, &vfp);
|
||||||
DidUpdateValidationData::put(true);
|
DidUpdateValidationData::put(true);
|
||||||
RelevantMessagingState::put(relevant_messaging_state);
|
RelevantMessagingState::put(relevant_messaging_state.clone());
|
||||||
HostConfiguration::put(host_config);
|
HostConfiguration::put(host_config);
|
||||||
|
|
||||||
<T::OnValidationData as OnValidationData>::on_validation_data(&vfp);
|
<T::OnValidationData as OnValidationData>::on_validation_data(&vfp);
|
||||||
|
|
||||||
Self::process_inbound_downward_messages(&vfp, downward_messages)?;
|
Self::process_inbound_downward_messages(
|
||||||
Self::process_inbound_horizontal_messages(&vfp, horizontal_messages)?;
|
relevant_messaging_state.dmq_mqc_head,
|
||||||
|
downward_messages,
|
||||||
|
)?;
|
||||||
|
Self::process_inbound_horizontal_messages(
|
||||||
|
&relevant_messaging_state.ingress_channels,
|
||||||
|
horizontal_messages,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -437,7 +443,7 @@ impl<T: Config> Module<T> {
|
|||||||
/// Checks if the sequence of the messages is valid, dispatches them and communicates the number
|
/// Checks if the sequence of the messages is valid, dispatches them and communicates the number
|
||||||
/// of processed messages to the collator via a storage update.
|
/// of processed messages to the collator via a storage update.
|
||||||
fn process_inbound_downward_messages(
|
fn process_inbound_downward_messages(
|
||||||
vfp: &PersistedValidationData,
|
expected_dmq_mqc_head: relay_chain::Hash,
|
||||||
downward_messages: Vec<InboundDownwardMessage>,
|
downward_messages: Vec<InboundDownwardMessage>,
|
||||||
) -> DispatchResult {
|
) -> DispatchResult {
|
||||||
let dm_count = downward_messages.len() as u32;
|
let dm_count = downward_messages.len() as u32;
|
||||||
@@ -453,7 +459,7 @@ impl<T: Config> Module<T> {
|
|||||||
// After hashing each message in the message queue chain submitted by the collator, we should
|
// After hashing each message in the message queue chain submitted by the collator, we should
|
||||||
// arrive to the MQC head provided by the relay chain.
|
// arrive to the MQC head provided by the relay chain.
|
||||||
ensure!(
|
ensure!(
|
||||||
result_mqc_head == vfp.dmq_mqc_head,
|
result_mqc_head == expected_dmq_mqc_head,
|
||||||
Error::<T>::DmpMqcMismatch
|
Error::<T>::DmpMqcMismatch
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -469,14 +475,14 @@ impl<T: Config> Module<T> {
|
|||||||
/// This is similar to [`process_inbound_downward_messages`], but works on multiple inbound
|
/// This is similar to [`process_inbound_downward_messages`], but works on multiple inbound
|
||||||
/// channels.
|
/// channels.
|
||||||
fn process_inbound_horizontal_messages(
|
fn process_inbound_horizontal_messages(
|
||||||
vfp: &PersistedValidationData,
|
ingress_channels: &[(ParaId, cumulus_primitives::AbridgedHrmpChannel)],
|
||||||
horizontal_messages: BTreeMap<ParaId, Vec<InboundHrmpMessage>>,
|
horizontal_messages: BTreeMap<ParaId, Vec<InboundHrmpMessage>>,
|
||||||
) -> DispatchResult {
|
) -> DispatchResult {
|
||||||
// First, check that all submitted messages are sent from channels that exist. The channel
|
// First, check that all submitted messages are sent from channels that exist. The channel
|
||||||
// exists if its MQC head is present in `vfp.hrmp_mqc_heads`.
|
// exists if its MQC head is present in `vfp.hrmp_mqc_heads`.
|
||||||
for sender in horizontal_messages.keys() {
|
for sender in horizontal_messages.keys() {
|
||||||
ensure!(
|
ensure!(
|
||||||
vfp.hrmp_mqc_heads
|
ingress_channels
|
||||||
.binary_search_by_key(sender, |&(s, _)| s)
|
.binary_search_by_key(sender, |&(s, _)| s)
|
||||||
.is_ok(),
|
.is_ok(),
|
||||||
Error::<T>::HrmpNoMqc,
|
Error::<T>::HrmpNoMqc,
|
||||||
@@ -533,13 +539,14 @@ impl<T: Config> Module<T> {
|
|||||||
// `running_mqc_heads`. Otherwise, in a block where no messages were sent in a channel
|
// `running_mqc_heads`. Otherwise, in a block where no messages were sent in a channel
|
||||||
// it won't get into next block's `last_mqc_heads` and thus will be all zeros, which
|
// it won't get into next block's `last_mqc_heads` and thus will be all zeros, which
|
||||||
// would corrupt the message queue chain.
|
// would corrupt the message queue chain.
|
||||||
for &(ref sender, ref target_head) in &vfp.hrmp_mqc_heads {
|
for &(ref sender, ref channel) in ingress_channels {
|
||||||
let cur_head = running_mqc_heads
|
let cur_head = running_mqc_heads
|
||||||
.entry(*sender)
|
.entry(*sender)
|
||||||
.or_insert_with(|| last_mqc_heads.get(&sender).cloned().unwrap_or_default())
|
.or_insert_with(|| last_mqc_heads.get(&sender).cloned().unwrap_or_default())
|
||||||
.head();
|
.head();
|
||||||
|
let target_head = channel.mqc_head.unwrap_or_default();
|
||||||
|
|
||||||
ensure!(&cur_head == target_head, Error::<T>::HrmpMqcMismatch);
|
ensure!(cur_head == target_head, Error::<T>::HrmpMqcMismatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
LastHrmpMqcHeads::put(running_mqc_heads);
|
LastHrmpMqcHeads::put(running_mqc_heads);
|
||||||
@@ -592,7 +599,7 @@ impl<T: Config> Module<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let relay_blocks_since_last_upgrade = vfp
|
let relay_blocks_since_last_upgrade = vfp
|
||||||
.block_number
|
.relay_parent_number
|
||||||
.saturating_sub(LastUpgrade::get());
|
.saturating_sub(LastUpgrade::get());
|
||||||
|
|
||||||
if relay_blocks_since_last_upgrade <= cfg.validation_upgrade_frequency {
|
if relay_blocks_since_last_upgrade <= cfg.validation_upgrade_frequency {
|
||||||
@@ -600,7 +607,7 @@ impl<T: Config> Module<T> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(vfp.block_number + cfg.validation_upgrade_delay)
|
Some(vfp.relay_parent_number + cfg.validation_upgrade_delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The implementation of the runtime upgrade scheduling.
|
/// The implementation of the runtime upgrade scheduling.
|
||||||
@@ -1072,6 +1079,7 @@ mod tests {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)] // might come in handy in future. If now is future and it still hasn't - feel free.
|
||||||
fn with_validation_data<F>(mut self, f: F) -> Self
|
fn with_validation_data<F>(mut self, f: F) -> Self
|
||||||
where
|
where
|
||||||
F: 'static + Fn(&BlockTests, RelayChainBlockNumber, &mut PersistedValidationData),
|
F: 'static + Fn(&BlockTests, RelayChainBlockNumber, &mut PersistedValidationData),
|
||||||
@@ -1117,11 +1125,11 @@ mod tests {
|
|||||||
if let Some(ref hook) = self.relay_sproof_builder_hook {
|
if let Some(ref hook) = self.relay_sproof_builder_hook {
|
||||||
hook(self, *n as RelayChainBlockNumber, &mut sproof_builder);
|
hook(self, *n as RelayChainBlockNumber, &mut sproof_builder);
|
||||||
}
|
}
|
||||||
let (relay_storage_root, relay_chain_state) =
|
let (relay_parent_storage_root, relay_chain_state) =
|
||||||
sproof_builder.into_state_root_and_proof();
|
sproof_builder.into_state_root_and_proof();
|
||||||
let mut vfp = PersistedValidationData {
|
let mut vfp = PersistedValidationData {
|
||||||
block_number: *n as RelayChainBlockNumber,
|
relay_parent_number: *n as RelayChainBlockNumber,
|
||||||
relay_storage_root,
|
relay_parent_storage_root,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
if let Some(ref hook) = self.persisted_validation_data_hook {
|
if let Some(ref hook) = self.persisted_validation_data_hook {
|
||||||
@@ -1612,11 +1620,11 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BlockTests::new()
|
BlockTests::new()
|
||||||
.with_validation_data(
|
.with_relay_sproof_builder(
|
||||||
|_, relay_block_num, validation_data| match relay_block_num {
|
|_, relay_block_num, sproof| match relay_block_num {
|
||||||
1 => {
|
1 => {
|
||||||
validation_data.dmq_mqc_head =
|
sproof.dmq_mqc_head =
|
||||||
MessageQueueChain::default().extend_downward(&MSG).head();
|
Some(MessageQueueChain::default().extend_downward(&MSG).head());
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
@@ -1661,39 +1669,31 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BlockTests::new()
|
BlockTests::new()
|
||||||
.with_validation_data(
|
.with_relay_sproof_builder(
|
||||||
|_, relay_block_num, validation_data| match relay_block_num {
|
|_, relay_block_num, sproof| match relay_block_num {
|
||||||
1 => {
|
1 => {
|
||||||
// 200 - doesn't exist yet
|
// 200 - doesn't exist yet
|
||||||
// 300 - one new message
|
// 300 - one new message
|
||||||
validation_data.hrmp_mqc_heads.push((
|
sproof.upsert_inbound_channel(ParaId::from(300)).mqc_head =
|
||||||
ParaId::from(300),
|
Some(MessageQueueChain::default().extend_hrmp(&MSG_1).head());
|
||||||
MessageQueueChain::default().extend_hrmp(&MSG_1).head(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
// 200 - two new messages
|
// 200 - two new messages
|
||||||
// 300 - now present with one message.
|
// 300 - now present with one message.
|
||||||
validation_data.hrmp_mqc_heads.push((
|
sproof.upsert_inbound_channel(ParaId::from(200)).mqc_head =
|
||||||
ParaId::from(200),
|
Some(MessageQueueChain::default().extend_hrmp(&MSG_4).head());
|
||||||
MessageQueueChain::default().extend_hrmp(&MSG_4).head(),
|
sproof.upsert_inbound_channel(ParaId::from(300)).mqc_head =
|
||||||
));
|
Some(MessageQueueChain::default()
|
||||||
validation_data.hrmp_mqc_heads.push((
|
|
||||||
ParaId::from(300),
|
|
||||||
MessageQueueChain::default()
|
|
||||||
.extend_hrmp(&MSG_1)
|
.extend_hrmp(&MSG_1)
|
||||||
.extend_hrmp(&MSG_2)
|
.extend_hrmp(&MSG_2)
|
||||||
.extend_hrmp(&MSG_3)
|
.extend_hrmp(&MSG_3)
|
||||||
.head(),
|
.head());
|
||||||
));
|
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
// 200 - no new messages
|
// 200 - no new messages
|
||||||
// 300 - is gone
|
// 300 - is gone
|
||||||
validation_data.hrmp_mqc_heads.push((
|
sproof.upsert_inbound_channel(ParaId::from(200)).mqc_head =
|
||||||
ParaId::from(200),
|
Some(MessageQueueChain::default().extend_hrmp(&MSG_4).head());
|
||||||
MessageQueueChain::default().extend_hrmp(&MSG_4).head(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
@@ -1747,21 +1747,17 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn receive_hrmp_empty_channel() {
|
fn receive_hrmp_empty_channel() {
|
||||||
BlockTests::new()
|
BlockTests::new()
|
||||||
.with_validation_data(
|
.with_relay_sproof_builder(|_, relay_block_num, sproof| match relay_block_num {
|
||||||
|_, relay_block_num, validation_data| match relay_block_num {
|
1 => {
|
||||||
1 => {
|
// no channels
|
||||||
// no channels
|
}
|
||||||
}
|
2 => {
|
||||||
2 => {
|
// one new channel
|
||||||
// one new channel
|
sproof.upsert_inbound_channel(ParaId::from(300)).mqc_head =
|
||||||
validation_data.hrmp_mqc_heads.push((
|
Some(MessageQueueChain::default().head());
|
||||||
ParaId::from(300),
|
}
|
||||||
MessageQueueChain::default().head(),
|
_ => unreachable!(),
|
||||||
));
|
})
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.add(1, || {})
|
.add(1, || {})
|
||||||
.add(2, || {});
|
.add(2, || {});
|
||||||
}
|
}
|
||||||
@@ -1783,30 +1779,24 @@ mod tests {
|
|||||||
const ALICE: ParaId = ParaId::new(300);
|
const ALICE: ParaId = ParaId::new(300);
|
||||||
|
|
||||||
BlockTests::new()
|
BlockTests::new()
|
||||||
.with_validation_data(
|
.with_relay_sproof_builder(
|
||||||
|_, relay_block_num, validation_data| match relay_block_num {
|
|_, relay_block_num, sproof| match relay_block_num {
|
||||||
1 => {
|
1 => {
|
||||||
validation_data.hrmp_mqc_heads.push((
|
sproof.upsert_inbound_channel(ALICE).mqc_head
|
||||||
ALICE,
|
= Some(MessageQueueChain::default().extend_hrmp(&MSG_1).head());
|
||||||
MessageQueueChain::default().extend_hrmp(&MSG_1).head(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
// 300 - no new messages, mqc stayed the same.
|
// 300 - no new messages, mqc stayed the same.
|
||||||
validation_data.hrmp_mqc_heads.push((
|
sproof.upsert_inbound_channel(ALICE).mqc_head
|
||||||
ALICE,
|
= Some(MessageQueueChain::default().extend_hrmp(&MSG_1).head());
|
||||||
MessageQueueChain::default().extend_hrmp(&MSG_1).head(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
// 300 - new message.
|
// 300 - new message.
|
||||||
validation_data.hrmp_mqc_heads.push((
|
sproof.upsert_inbound_channel(ALICE).mqc_head
|
||||||
ALICE,
|
= Some(MessageQueueChain::default()
|
||||||
MessageQueueChain::default()
|
.extend_hrmp(&MSG_1)
|
||||||
.extend_hrmp(&MSG_1)
|
.extend_hrmp(&MSG_2)
|
||||||
.extend_hrmp(&MSG_2)
|
.head());
|
||||||
.head(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,14 +27,27 @@ use sp_std::vec::Vec;
|
|||||||
/// This data is essential for making sure that the parachain is aware of current resource use on
|
/// This data is essential for making sure that the parachain is aware of current resource use on
|
||||||
/// the relay chain and that the candidates produced for this parachain do not exceed any of these
|
/// the relay chain and that the candidates produced for this parachain do not exceed any of these
|
||||||
/// limits.
|
/// limits.
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Clone, Encode, Decode)]
|
||||||
pub struct MessagingStateSnapshot {
|
pub struct MessagingStateSnapshot {
|
||||||
|
/// The current message queue chain head for downward message queue.
|
||||||
|
///
|
||||||
|
/// If the value is absent on the relay chain this will be set to all zeros.
|
||||||
|
pub dmq_mqc_head: relay_chain::Hash,
|
||||||
|
|
||||||
/// The current capacity of the upward message queue of the current parachain on the relay chain.
|
/// The current capacity of the upward message queue of the current parachain on the relay chain.
|
||||||
///
|
///
|
||||||
/// The capacity is represented by a tuple that consist of the `count` of the messages and the
|
/// The capacity is represented by a tuple that consist of the `count` of the messages and the
|
||||||
/// `total_size` expressed as the sum of byte sizes of all messages in the queue.
|
/// `total_size` expressed as the sum of byte sizes of all messages in the queue.
|
||||||
pub relay_dispatch_queue_size: (u32, u32),
|
pub relay_dispatch_queue_size: (u32, u32),
|
||||||
|
|
||||||
|
/// Information about all the inbound HRMP channels.
|
||||||
|
///
|
||||||
|
/// These are structured as a list of tuples. The para id in the tuple specifies the sender
|
||||||
|
/// of the channel. Obviously, the recipient is the current parachain.
|
||||||
|
///
|
||||||
|
/// The channels are sorted by the sender para id ascension.
|
||||||
|
pub ingress_channels: Vec<(ParaId, AbridgedHrmpChannel)>,
|
||||||
|
|
||||||
/// Information about all the outbound HRMP channels.
|
/// Information about all the outbound HRMP channels.
|
||||||
///
|
///
|
||||||
/// These are structured as a list of tuples. The para id in the tuple specifies the recipient
|
/// These are structured as a list of tuples. The para id in the tuple specifies the recipient
|
||||||
@@ -50,12 +63,16 @@ pub enum Error {
|
|||||||
RootMismatch,
|
RootMismatch,
|
||||||
/// The host configuration cannot be extracted.
|
/// The host configuration cannot be extracted.
|
||||||
Config(ReadEntryErr),
|
Config(ReadEntryErr),
|
||||||
|
/// The DMQ MQC head cannot be extracted.
|
||||||
|
DmqMqcHead(ReadEntryErr),
|
||||||
/// Relay dispatch queue cannot be extracted.
|
/// Relay dispatch queue cannot be extracted.
|
||||||
RelayDispatchQueueSize(ReadEntryErr),
|
RelayDispatchQueueSize(ReadEntryErr),
|
||||||
|
/// The hrmp inress channel index cannot be extracted.
|
||||||
|
HrmpIngressChannelIndex(ReadEntryErr),
|
||||||
/// The hrmp egress channel index cannot be extracted.
|
/// The hrmp egress channel index cannot be extracted.
|
||||||
HrmpEgressChannelIndex(ReadEntryErr),
|
HrmpEgressChannelIndex(ReadEntryErr),
|
||||||
/// The hrmp channel for the given recipient cannot be extracted.
|
/// The channel identified by the sender and receiver cannot be extracted.
|
||||||
HrmpChannel(ParaId, ReadEntryErr),
|
HrmpChannel(ParaId, ParaId, ReadEntryErr),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -92,14 +109,14 @@ where
|
|||||||
/// of the current parachain and the expected storage root the proof should stem from.
|
/// of the current parachain and the expected storage root the proof should stem from.
|
||||||
pub fn extract_from_proof(
|
pub fn extract_from_proof(
|
||||||
para_id: ParaId,
|
para_id: ParaId,
|
||||||
relay_storage_root: relay_chain::v1::Hash,
|
relay_parent_storage_root: relay_chain::v1::Hash,
|
||||||
proof: StorageProof,
|
proof: StorageProof,
|
||||||
) -> Result<(AbridgedHostConfiguration, MessagingStateSnapshot), Error> {
|
) -> Result<(AbridgedHostConfiguration, MessagingStateSnapshot), Error> {
|
||||||
let db = proof.into_memory_db::<HashFor<relay_chain::Block>>();
|
let db = proof.into_memory_db::<HashFor<relay_chain::Block>>();
|
||||||
if !db.contains(&relay_storage_root, EMPTY_PREFIX) {
|
if !db.contains(&relay_parent_storage_root, EMPTY_PREFIX) {
|
||||||
return Err(Error::RootMismatch);
|
return Err(Error::RootMismatch);
|
||||||
}
|
}
|
||||||
let backend = TrieBackend::new(db, relay_storage_root);
|
let backend = TrieBackend::new(db, relay_parent_storage_root);
|
||||||
|
|
||||||
let host_config: AbridgedHostConfiguration = read_entry(
|
let host_config: AbridgedHostConfiguration = read_entry(
|
||||||
&backend,
|
&backend,
|
||||||
@@ -108,6 +125,13 @@ pub fn extract_from_proof(
|
|||||||
)
|
)
|
||||||
.map_err(Error::Config)?;
|
.map_err(Error::Config)?;
|
||||||
|
|
||||||
|
let dmq_mqc_head: relay_chain::Hash = read_entry(
|
||||||
|
&backend,
|
||||||
|
&relay_chain::well_known_keys::dmq_mqc_head(para_id),
|
||||||
|
Some(Default::default()),
|
||||||
|
)
|
||||||
|
.map_err(Error::DmqMqcHead)?;
|
||||||
|
|
||||||
let relay_dispatch_queue_size: (u32, u32) = read_entry(
|
let relay_dispatch_queue_size: (u32, u32) = read_entry(
|
||||||
&backend,
|
&backend,
|
||||||
&relay_chain::well_known_keys::relay_dispatch_queue_size(para_id),
|
&relay_chain::well_known_keys::relay_dispatch_queue_size(para_id),
|
||||||
@@ -115,6 +139,13 @@ pub fn extract_from_proof(
|
|||||||
)
|
)
|
||||||
.map_err(Error::RelayDispatchQueueSize)?;
|
.map_err(Error::RelayDispatchQueueSize)?;
|
||||||
|
|
||||||
|
let ingress_channel_index: Vec<ParaId> = read_entry(
|
||||||
|
&backend,
|
||||||
|
&relay_chain::well_known_keys::hrmp_ingress_channel_index(para_id),
|
||||||
|
Some(Vec::new()),
|
||||||
|
)
|
||||||
|
.map_err(Error::HrmpIngressChannelIndex)?;
|
||||||
|
|
||||||
let egress_channel_index: Vec<ParaId> = read_entry(
|
let egress_channel_index: Vec<ParaId> = read_entry(
|
||||||
&backend,
|
&backend,
|
||||||
&relay_chain::well_known_keys::hrmp_egress_channel_index(para_id),
|
&relay_chain::well_known_keys::hrmp_egress_channel_index(para_id),
|
||||||
@@ -122,6 +153,21 @@ pub fn extract_from_proof(
|
|||||||
)
|
)
|
||||||
.map_err(Error::HrmpEgressChannelIndex)?;
|
.map_err(Error::HrmpEgressChannelIndex)?;
|
||||||
|
|
||||||
|
let mut ingress_channels = Vec::with_capacity(ingress_channel_index.len());
|
||||||
|
for sender in ingress_channel_index {
|
||||||
|
let channel_id = relay_chain::v1::HrmpChannelId {
|
||||||
|
sender,
|
||||||
|
recipient: para_id,
|
||||||
|
};
|
||||||
|
let hrmp_channel: AbridgedHrmpChannel = read_entry(
|
||||||
|
&backend,
|
||||||
|
&relay_chain::well_known_keys::hrmp_channels(channel_id),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.map_err(|read_err| Error::HrmpChannel(sender, para_id, read_err))?;
|
||||||
|
ingress_channels.push((sender, hrmp_channel));
|
||||||
|
}
|
||||||
|
|
||||||
let mut egress_channels = Vec::with_capacity(egress_channel_index.len());
|
let mut egress_channels = Vec::with_capacity(egress_channel_index.len());
|
||||||
for recipient in egress_channel_index {
|
for recipient in egress_channel_index {
|
||||||
let channel_id = relay_chain::v1::HrmpChannelId {
|
let channel_id = relay_chain::v1::HrmpChannelId {
|
||||||
@@ -133,17 +179,19 @@ pub fn extract_from_proof(
|
|||||||
&relay_chain::well_known_keys::hrmp_channels(channel_id),
|
&relay_chain::well_known_keys::hrmp_channels(channel_id),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.map_err(|read_err| Error::HrmpChannel(recipient, read_err))?;
|
.map_err(|read_err| Error::HrmpChannel(para_id, recipient, read_err))?;
|
||||||
egress_channels.push((recipient, hrmp_channel));
|
egress_channels.push((recipient, hrmp_channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE that egress_channels promises to be sorted. We satisfy this property by relying on
|
// NOTE that ingress_channels and egress_channels promise to be sorted. We satisfy this property
|
||||||
// the fact that `egress_channel_index` is itself sorted.
|
// by relying on the fact that `ingress_channel_index` and `egress_channel_index` are themselves sorted.
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
host_config,
|
host_config,
|
||||||
MessagingStateSnapshot {
|
MessagingStateSnapshot {
|
||||||
|
dmq_mqc_head,
|
||||||
relay_dispatch_queue_size,
|
relay_dispatch_queue_size,
|
||||||
|
ingress_channels,
|
||||||
egress_channels,
|
egress_channels,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ pub fn new_partial(
|
|||||||
|
|
||||||
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
|
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
|
||||||
config.transaction_pool.clone(),
|
config.transaction_pool.clone(),
|
||||||
|
config.role.is_authority().into(),
|
||||||
config.prometheus_registry(),
|
config.prometheus_registry(),
|
||||||
task_manager.spawn_handle(),
|
task_manager.spawn_handle(),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ pub fn validate_block<B: BlockT, E: ExecuteBlock<B>>(params: ValidationParams) -
|
|||||||
.storage(HRMP_WATERMARK)
|
.storage(HRMP_WATERMARK)
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|v| Decode::decode(&mut &v[..]).expect("HRMP watermark is not encoded correctly"))
|
.map(|v| Decode::decode(&mut &v[..]).expect("HRMP watermark is not encoded correctly"))
|
||||||
.unwrap_or(validation_data.block_number);
|
.unwrap_or(validation_data.relay_parent_number);
|
||||||
|
|
||||||
ValidationResult {
|
ValidationResult {
|
||||||
head_data,
|
head_data,
|
||||||
@@ -210,23 +210,15 @@ impl<'a, B: BlockT> WitnessExt<'a, B> {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.params.parent_head,
|
self.params.parent_head,
|
||||||
validation_data.parent_head
|
validation_data.parent_head,
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.params.relay_chain_height,
|
self.params.relay_parent_number,
|
||||||
validation_data.block_number
|
validation_data.relay_parent_number,
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.params.hrmp_mqc_heads,
|
self.params.relay_parent_storage_root,
|
||||||
validation_data.hrmp_mqc_heads
|
validation_data.relay_parent_storage_root,
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
self.params.dmq_mqc_head,
|
|
||||||
validation_data.dmq_mqc_head,
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
self.params.relay_storage_root,
|
|
||||||
validation_data.relay_storage_root,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,17 +42,15 @@ use codec::{Decode, Encode};
|
|||||||
fn call_validate_block(
|
fn call_validate_block(
|
||||||
parent_head: Header,
|
parent_head: Header,
|
||||||
block_data: ParachainBlockData<Block>,
|
block_data: ParachainBlockData<Block>,
|
||||||
relay_storage_root: Hash,
|
relay_parent_storage_root: Hash,
|
||||||
) -> Result<Header> {
|
) -> Result<Header> {
|
||||||
let mut ext = TestExternalities::default();
|
let mut ext = TestExternalities::default();
|
||||||
let mut ext_ext = ext.ext();
|
let mut ext_ext = ext.ext();
|
||||||
let params = ValidationParams {
|
let params = ValidationParams {
|
||||||
block_data: BlockData(block_data.encode()),
|
block_data: BlockData(block_data.encode()),
|
||||||
parent_head: HeadData(parent_head.encode()),
|
parent_head: HeadData(parent_head.encode()),
|
||||||
relay_chain_height: 1,
|
relay_parent_number: 1,
|
||||||
relay_storage_root,
|
relay_parent_storage_root,
|
||||||
hrmp_mqc_heads: Vec::new(),
|
|
||||||
dmq_mqc_head: Default::default(),
|
|
||||||
}
|
}
|
||||||
.encode();
|
.encode();
|
||||||
|
|
||||||
@@ -87,7 +85,7 @@ fn create_test_client() -> (Client, LongestChain) {
|
|||||||
struct TestBlockData {
|
struct TestBlockData {
|
||||||
block: Block,
|
block: Block,
|
||||||
witness: sp_trie::StorageProof,
|
witness: sp_trie::StorageProof,
|
||||||
relay_storage_root: Hash,
|
relay_parent_storage_root: Hash,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_block_with_witness(
|
fn build_block_with_witness(
|
||||||
@@ -96,12 +94,12 @@ fn build_block_with_witness(
|
|||||||
parent_head: Header,
|
parent_head: Header,
|
||||||
) -> TestBlockData {
|
) -> TestBlockData {
|
||||||
let sproof_builder = RelayStateSproofBuilder::default();
|
let sproof_builder = RelayStateSproofBuilder::default();
|
||||||
let (relay_storage_root, _) = sproof_builder.clone().into_state_root_and_proof();
|
let (relay_parent_storage_root, _) = sproof_builder.clone().into_state_root_and_proof();
|
||||||
let block_id = BlockId::Hash(client.info().best_hash);
|
let block_id = BlockId::Hash(client.info().best_hash);
|
||||||
let mut builder = client.init_block_builder_at(
|
let mut builder = client.init_block_builder_at(
|
||||||
&block_id,
|
&block_id,
|
||||||
Some(PersistedValidationData {
|
Some(PersistedValidationData {
|
||||||
block_number: 1,
|
relay_parent_number: 1,
|
||||||
parent_head: parent_head.encode().into(),
|
parent_head: parent_head.encode().into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
@@ -119,7 +117,7 @@ fn build_block_with_witness(
|
|||||||
witness: built_block
|
witness: built_block
|
||||||
.proof
|
.proof
|
||||||
.expect("We enabled proof recording before."),
|
.expect("We enabled proof recording before."),
|
||||||
relay_storage_root,
|
relay_parent_storage_root,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,13 +130,13 @@ fn validate_block_no_extra_extrinsics() {
|
|||||||
let TestBlockData {
|
let TestBlockData {
|
||||||
block,
|
block,
|
||||||
witness,
|
witness,
|
||||||
relay_storage_root,
|
relay_parent_storage_root,
|
||||||
} = build_block_with_witness(&client, vec![], parent_head.clone());
|
} = build_block_with_witness(&client, vec![], parent_head.clone());
|
||||||
let (header, extrinsics) = block.deconstruct();
|
let (header, extrinsics) = block.deconstruct();
|
||||||
|
|
||||||
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness);
|
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness);
|
||||||
|
|
||||||
let res_header = call_validate_block(parent_head, block_data, relay_storage_root)
|
let res_header = call_validate_block(parent_head, block_data, relay_parent_storage_root)
|
||||||
.expect("Calls `validate_block`");
|
.expect("Calls `validate_block`");
|
||||||
assert_eq!(header, res_header);
|
assert_eq!(header, res_header);
|
||||||
}
|
}
|
||||||
@@ -158,13 +156,13 @@ fn validate_block_with_extra_extrinsics() {
|
|||||||
let TestBlockData {
|
let TestBlockData {
|
||||||
block,
|
block,
|
||||||
witness,
|
witness,
|
||||||
relay_storage_root,
|
relay_parent_storage_root,
|
||||||
} = build_block_with_witness(&client, extra_extrinsics, parent_head.clone());
|
} = build_block_with_witness(&client, extra_extrinsics, parent_head.clone());
|
||||||
let (header, extrinsics) = block.deconstruct();
|
let (header, extrinsics) = block.deconstruct();
|
||||||
|
|
||||||
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness);
|
let block_data = ParachainBlockData::new(header.clone(), extrinsics, witness);
|
||||||
|
|
||||||
let res_header = call_validate_block(parent_head, block_data, relay_storage_root)
|
let res_header = call_validate_block(parent_head, block_data, relay_parent_storage_root)
|
||||||
.expect("Calls `validate_block`");
|
.expect("Calls `validate_block`");
|
||||||
assert_eq!(header, res_header);
|
assert_eq!(header, res_header);
|
||||||
}
|
}
|
||||||
@@ -179,12 +177,12 @@ fn validate_block_invalid_parent_hash() {
|
|||||||
let TestBlockData {
|
let TestBlockData {
|
||||||
block,
|
block,
|
||||||
witness,
|
witness,
|
||||||
relay_storage_root,
|
relay_parent_storage_root,
|
||||||
} = build_block_with_witness(&client, vec![], parent_head.clone());
|
} = build_block_with_witness(&client, vec![], parent_head.clone());
|
||||||
let (mut header, extrinsics) = block.deconstruct();
|
let (mut header, extrinsics) = block.deconstruct();
|
||||||
header.set_parent_hash(Hash::from_low_u64_be(1));
|
header.set_parent_hash(Hash::from_low_u64_be(1));
|
||||||
|
|
||||||
let block_data = ParachainBlockData::new(header, extrinsics, witness);
|
let block_data = ParachainBlockData::new(header, extrinsics, witness);
|
||||||
call_validate_block(parent_head, block_data, relay_storage_root)
|
call_validate_block(parent_head, block_data, relay_parent_storage_root)
|
||||||
.expect("Calls `validate_block`");
|
.expect("Calls `validate_block`");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,16 +88,16 @@ impl InitBlockBuilder for Client {
|
|||||||
.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp)
|
.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp)
|
||||||
.expect("Put timestamp failed");
|
.expect("Put timestamp failed");
|
||||||
|
|
||||||
let (relay_storage_root, relay_chain_state) =
|
let (relay_parent_storage_root, relay_chain_state) =
|
||||||
relay_sproof_builder.into_state_root_and_proof();
|
relay_sproof_builder.into_state_root_and_proof();
|
||||||
|
|
||||||
let mut validation_data = validation_data.unwrap_or_default();
|
let mut validation_data = validation_data.unwrap_or_default();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
validation_data.relay_storage_root,
|
validation_data.relay_parent_storage_root,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
"Overriding the relay storage root is not implemented",
|
"Overriding the relay storage root is not implemented",
|
||||||
);
|
);
|
||||||
validation_data.relay_storage_root = relay_storage_root;
|
validation_data.relay_parent_storage_root = relay_parent_storage_root;
|
||||||
|
|
||||||
inherent_data
|
inherent_data
|
||||||
.put_data(
|
.put_data(
|
||||||
|
|||||||
@@ -22,9 +22,20 @@ use sp_std::collections::btree_map::BTreeMap;
|
|||||||
/// Builds a sproof (portmanteau of 'spoof' and 'proof') of the relay chain state.
|
/// Builds a sproof (portmanteau of 'spoof' and 'proof') of the relay chain state.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RelayStateSproofBuilder {
|
pub struct RelayStateSproofBuilder {
|
||||||
|
/// The para id of the current parachain.
|
||||||
|
///
|
||||||
|
/// This doesn't get into the storage proof produced by the builder, however, it is used for
|
||||||
|
/// generation of the storage image and by auxilary methods.
|
||||||
|
///
|
||||||
|
/// It's recommended to change this value once in the very beginning of usage.
|
||||||
|
///
|
||||||
|
/// The default value is 200.
|
||||||
pub para_id: ParaId,
|
pub para_id: ParaId,
|
||||||
|
|
||||||
pub host_config: AbridgedHostConfiguration,
|
pub host_config: AbridgedHostConfiguration,
|
||||||
|
pub dmq_mqc_head: Option<relay_chain::Hash>,
|
||||||
pub relay_dispatch_queue_size: Option<(u32, u32)>,
|
pub relay_dispatch_queue_size: Option<(u32, u32)>,
|
||||||
|
pub hrmp_ingress_channel_index: Option<Vec<ParaId>>,
|
||||||
pub hrmp_egress_channel_index: Option<Vec<ParaId>>,
|
pub hrmp_egress_channel_index: Option<Vec<ParaId>>,
|
||||||
pub hrmp_channels: BTreeMap<relay_chain::v1::HrmpChannelId, AbridgedHrmpChannel>,
|
pub hrmp_channels: BTreeMap<relay_chain::v1::HrmpChannelId, AbridgedHrmpChannel>,
|
||||||
}
|
}
|
||||||
@@ -44,7 +55,9 @@ impl Default for RelayStateSproofBuilder {
|
|||||||
validation_upgrade_frequency: 6,
|
validation_upgrade_frequency: 6,
|
||||||
validation_upgrade_delay: 6,
|
validation_upgrade_delay: 6,
|
||||||
},
|
},
|
||||||
|
dmq_mqc_head: None,
|
||||||
relay_dispatch_queue_size: None,
|
relay_dispatch_queue_size: None,
|
||||||
|
hrmp_ingress_channel_index: None,
|
||||||
hrmp_egress_channel_index: None,
|
hrmp_egress_channel_index: None,
|
||||||
hrmp_channels: BTreeMap::new(),
|
hrmp_channels: BTreeMap::new(),
|
||||||
}
|
}
|
||||||
@@ -52,6 +65,32 @@ impl Default for RelayStateSproofBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RelayStateSproofBuilder {
|
impl RelayStateSproofBuilder {
|
||||||
|
/// Returns a mutable reference to HRMP channel metadata for a channel (`sender`, `self.para_id`).
|
||||||
|
///
|
||||||
|
/// If there is no channel, a new default one is created.
|
||||||
|
///
|
||||||
|
/// It also updates the `hrmp_ingress_channel_index`, creating it if needed.
|
||||||
|
pub fn upsert_inbound_channel(&mut self, sender: ParaId) -> &mut AbridgedHrmpChannel {
|
||||||
|
let in_index = self.hrmp_ingress_channel_index.get_or_insert_with(Vec::new);
|
||||||
|
if let Err(idx) = in_index.binary_search(&sender) {
|
||||||
|
in_index.insert(idx, sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.hrmp_channels
|
||||||
|
.entry(relay_chain::v1::HrmpChannelId {
|
||||||
|
sender,
|
||||||
|
recipient: self.para_id,
|
||||||
|
})
|
||||||
|
.or_insert_with(|| AbridgedHrmpChannel {
|
||||||
|
max_capacity: 0,
|
||||||
|
max_total_size: 0,
|
||||||
|
max_message_size: 0,
|
||||||
|
msg_count: 0,
|
||||||
|
total_size: 0,
|
||||||
|
mqc_head: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn into_state_root_and_proof(
|
pub fn into_state_root_and_proof(
|
||||||
self,
|
self,
|
||||||
) -> (
|
) -> (
|
||||||
@@ -74,16 +113,32 @@ impl RelayStateSproofBuilder {
|
|||||||
relay_chain::well_known_keys::ACTIVE_CONFIG.to_vec(),
|
relay_chain::well_known_keys::ACTIVE_CONFIG.to_vec(),
|
||||||
self.host_config.encode(),
|
self.host_config.encode(),
|
||||||
);
|
);
|
||||||
|
if let Some(dmq_mqc_head) = self.dmq_mqc_head {
|
||||||
|
insert(
|
||||||
|
relay_chain::well_known_keys::dmq_mqc_head(self.para_id),
|
||||||
|
dmq_mqc_head.encode(),
|
||||||
|
);
|
||||||
|
}
|
||||||
if let Some(relay_dispatch_queue_size) = self.relay_dispatch_queue_size {
|
if let Some(relay_dispatch_queue_size) = self.relay_dispatch_queue_size {
|
||||||
insert(
|
insert(
|
||||||
relay_chain::well_known_keys::relay_dispatch_queue_size(self.para_id),
|
relay_chain::well_known_keys::relay_dispatch_queue_size(self.para_id),
|
||||||
relay_dispatch_queue_size.encode(),
|
relay_dispatch_queue_size.encode(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if let Some(hrmp_ingress_channel_index) = self.hrmp_ingress_channel_index {
|
||||||
|
let mut sorted = hrmp_ingress_channel_index.clone();
|
||||||
|
sorted.sort();
|
||||||
|
assert_eq!(sorted, hrmp_ingress_channel_index);
|
||||||
|
|
||||||
|
insert(
|
||||||
|
relay_chain::well_known_keys::hrmp_ingress_channel_index(self.para_id),
|
||||||
|
hrmp_ingress_channel_index.encode(),
|
||||||
|
);
|
||||||
|
}
|
||||||
if let Some(hrmp_egress_channel_index) = self.hrmp_egress_channel_index {
|
if let Some(hrmp_egress_channel_index) = self.hrmp_egress_channel_index {
|
||||||
let mut sorted = hrmp_egress_channel_index.clone();
|
let mut sorted = hrmp_egress_channel_index.clone();
|
||||||
sorted.sort();
|
sorted.sort();
|
||||||
assert_eq!(sorted, hrmp_egress_channel_index,);
|
assert_eq!(sorted, hrmp_egress_channel_index);
|
||||||
|
|
||||||
insert(
|
insert(
|
||||||
relay_chain::well_known_keys::hrmp_egress_channel_index(self.para_id),
|
relay_chain::well_known_keys::hrmp_egress_channel_index(self.para_id),
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ pub fn new_partial(
|
|||||||
|
|
||||||
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
|
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
|
||||||
config.transaction_pool.clone(),
|
config.transaction_pool.clone(),
|
||||||
|
config.role.is_authority().into(),
|
||||||
config.prometheus_registry(),
|
config.prometheus_registry(),
|
||||||
task_manager.spawn_handle(),
|
task_manager.spawn_handle(),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
|
|||||||
Reference in New Issue
Block a user