Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit e065c57

Browse files
pepyakinbkchr
andauthored
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>
1 parent b32ce07 commit e065c57

File tree

10 files changed

+553
-398
lines changed

10 files changed

+553
-398
lines changed

Cargo.lock

Lines changed: 318 additions & 283 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

collator/src/lib.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,31 @@ where
219219
})
220220
.ok()?;
221221

222+
let ingress_channels = relay_parent_state_backend
223+
.storage(&relay_well_known_keys::hrmp_ingress_channel_index(
224+
self.para_id,
225+
))
226+
.map_err(|e| {
227+
error!(
228+
target: LOG_TARGET,
229+
"Cannot obtain the hrmp ingress channel index: {:?}",
230+
e,
231+
)
232+
})
233+
.ok()?;
234+
let ingress_channels = ingress_channels
235+
.map(|raw| <Vec<ParaId>>::decode(&mut &raw[..]))
236+
.transpose()
237+
.map_err(|e| {
238+
error!(
239+
target: LOG_TARGET,
240+
"Cannot decode the hrmp ingress channel index: {:?}",
241+
e,
242+
)
243+
})
244+
.ok()?
245+
.unwrap_or_default();
246+
222247
let egress_channels = relay_parent_state_backend
223248
.storage(&relay_well_known_keys::hrmp_egress_channel_index(
224249
self.para_id,
@@ -246,12 +271,22 @@ where
246271

247272
let mut relevant_keys = vec![];
248273
relevant_keys.push(relay_well_known_keys::ACTIVE_CONFIG.to_vec());
274+
relevant_keys.push(relay_well_known_keys::dmq_mqc_head(self.para_id));
249275
relevant_keys.push(relay_well_known_keys::relay_dispatch_queue_size(
250276
self.para_id,
251277
));
278+
relevant_keys.push(relay_well_known_keys::hrmp_ingress_channel_index(
279+
self.para_id,
280+
));
252281
relevant_keys.push(relay_well_known_keys::hrmp_egress_channel_index(
253282
self.para_id,
254283
));
284+
relevant_keys.extend(ingress_channels.into_iter().map(|sender| {
285+
relay_well_known_keys::hrmp_channels(HrmpChannelId {
286+
sender,
287+
recipient: self.para_id,
288+
})
289+
}));
255290
relevant_keys.extend(egress_channels.into_iter().map(|recipient| {
256291
relay_well_known_keys::hrmp_channels(HrmpChannelId {
257292
sender: self.para_id,
@@ -586,7 +621,7 @@ where
586621
);
587622

588623
let collation =
589-
self.build_collation(b, block_hash, validation_data.block_number)?;
624+
self.build_collation(b, block_hash, validation_data.relay_parent_number)?;
590625
let pov_hash = collation.proof_of_validity.hash();
591626

592627
self.wait_to_announce

parachain-system/src/lib.rs

Lines changed: 62 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -179,18 +179,18 @@ decl_module! {
179179
// which means we can put the initialization logic here to remove the
180180
// sequencing problem.
181181
if let Some((apply_block, validation_function)) = PendingValidationFunction::get() {
182-
if vfp.block_number >= apply_block {
182+
if vfp.relay_parent_number >= apply_block {
183183
PendingValidationFunction::kill();
184184
LastUpgrade::put(&apply_block);
185185
Self::put_parachain_code(&validation_function);
186-
Self::deposit_event(Event::ValidationFunctionApplied(vfp.block_number));
186+
Self::deposit_event(Event::ValidationFunctionApplied(vfp.relay_parent_number));
187187
}
188188
}
189189

190190
let (host_config, relevant_messaging_state) =
191191
relay_state_snapshot::extract_from_proof(
192192
T::SelfParaId::get(),
193-
vfp.relay_storage_root,
193+
vfp.relay_parent_storage_root,
194194
relay_chain_state
195195
)
196196
.map_err(|err| {
@@ -200,13 +200,19 @@ decl_module! {
200200

201201
storage::unhashed::put(VALIDATION_DATA, &vfp);
202202
DidUpdateValidationData::put(true);
203-
RelevantMessagingState::put(relevant_messaging_state);
203+
RelevantMessagingState::put(relevant_messaging_state.clone());
204204
HostConfiguration::put(host_config);
205205

206206
<T::OnValidationData as OnValidationData>::on_validation_data(&vfp);
207207

208-
Self::process_inbound_downward_messages(&vfp, downward_messages)?;
209-
Self::process_inbound_horizontal_messages(&vfp, horizontal_messages)?;
208+
Self::process_inbound_downward_messages(
209+
relevant_messaging_state.dmq_mqc_head,
210+
downward_messages,
211+
)?;
212+
Self::process_inbound_horizontal_messages(
213+
&relevant_messaging_state.ingress_channels,
214+
horizontal_messages,
215+
)?;
210216

211217
Ok(())
212218
}
@@ -437,7 +443,7 @@ impl<T: Config> Module<T> {
437443
/// Checks if the sequence of the messages is valid, dispatches them and communicates the number
438444
/// of processed messages to the collator via a storage update.
439445
fn process_inbound_downward_messages(
440-
vfp: &PersistedValidationData,
446+
expected_dmq_mqc_head: relay_chain::Hash,
441447
downward_messages: Vec<InboundDownwardMessage>,
442448
) -> DispatchResult {
443449
let dm_count = downward_messages.len() as u32;
@@ -453,7 +459,7 @@ impl<T: Config> Module<T> {
453459
// After hashing each message in the message queue chain submitted by the collator, we should
454460
// arrive to the MQC head provided by the relay chain.
455461
ensure!(
456-
result_mqc_head == vfp.dmq_mqc_head,
462+
result_mqc_head == expected_dmq_mqc_head,
457463
Error::<T>::DmpMqcMismatch
458464
);
459465

@@ -469,14 +475,14 @@ impl<T: Config> Module<T> {
469475
/// This is similar to [`process_inbound_downward_messages`], but works on multiple inbound
470476
/// channels.
471477
fn process_inbound_horizontal_messages(
472-
vfp: &PersistedValidationData,
478+
ingress_channels: &[(ParaId, cumulus_primitives::AbridgedHrmpChannel)],
473479
horizontal_messages: BTreeMap<ParaId, Vec<InboundHrmpMessage>>,
474480
) -> DispatchResult {
475481
// First, check that all submitted messages are sent from channels that exist. The channel
476482
// exists if its MQC head is present in `vfp.hrmp_mqc_heads`.
477483
for sender in horizontal_messages.keys() {
478484
ensure!(
479-
vfp.hrmp_mqc_heads
485+
ingress_channels
480486
.binary_search_by_key(sender, |&(s, _)| s)
481487
.is_ok(),
482488
Error::<T>::HrmpNoMqc,
@@ -533,13 +539,14 @@ impl<T: Config> Module<T> {
533539
// `running_mqc_heads`. Otherwise, in a block where no messages were sent in a channel
534540
// it won't get into next block's `last_mqc_heads` and thus will be all zeros, which
535541
// would corrupt the message queue chain.
536-
for &(ref sender, ref target_head) in &vfp.hrmp_mqc_heads {
542+
for &(ref sender, ref channel) in ingress_channels {
537543
let cur_head = running_mqc_heads
538544
.entry(*sender)
539545
.or_insert_with(|| last_mqc_heads.get(&sender).cloned().unwrap_or_default())
540546
.head();
547+
let target_head = channel.mqc_head.unwrap_or_default();
541548

542-
ensure!(&cur_head == target_head, Error::<T>::HrmpMqcMismatch);
549+
ensure!(cur_head == target_head, Error::<T>::HrmpMqcMismatch);
543550
}
544551

545552
LastHrmpMqcHeads::put(running_mqc_heads);
@@ -592,15 +599,15 @@ impl<T: Config> Module<T> {
592599
}
593600

594601
let relay_blocks_since_last_upgrade = vfp
595-
.block_number
602+
.relay_parent_number
596603
.saturating_sub(LastUpgrade::get());
597604

598605
if relay_blocks_since_last_upgrade <= cfg.validation_upgrade_frequency {
599606
// The cooldown after the last upgrade hasn't elapsed yet. Upgrade is not allowed.
600607
return None;
601608
}
602609

603-
Some(vfp.block_number + cfg.validation_upgrade_delay)
610+
Some(vfp.relay_parent_number + cfg.validation_upgrade_delay)
604611
}
605612

606613
/// The implementation of the runtime upgrade scheduling.
@@ -1072,6 +1079,7 @@ mod tests {
10721079
self
10731080
}
10741081

1082+
#[allow(dead_code)] // might come in handy in future. If now is future and it still hasn't - feel free.
10751083
fn with_validation_data<F>(mut self, f: F) -> Self
10761084
where
10771085
F: 'static + Fn(&BlockTests, RelayChainBlockNumber, &mut PersistedValidationData),
@@ -1117,11 +1125,11 @@ mod tests {
11171125
if let Some(ref hook) = self.relay_sproof_builder_hook {
11181126
hook(self, *n as RelayChainBlockNumber, &mut sproof_builder);
11191127
}
1120-
let (relay_storage_root, relay_chain_state) =
1128+
let (relay_parent_storage_root, relay_chain_state) =
11211129
sproof_builder.into_state_root_and_proof();
11221130
let mut vfp = PersistedValidationData {
1123-
block_number: *n as RelayChainBlockNumber,
1124-
relay_storage_root,
1131+
relay_parent_number: *n as RelayChainBlockNumber,
1132+
relay_parent_storage_root,
11251133
..Default::default()
11261134
};
11271135
if let Some(ref hook) = self.persisted_validation_data_hook {
@@ -1612,11 +1620,11 @@ mod tests {
16121620
}
16131621

16141622
BlockTests::new()
1615-
.with_validation_data(
1616-
|_, relay_block_num, validation_data| match relay_block_num {
1623+
.with_relay_sproof_builder(
1624+
|_, relay_block_num, sproof| match relay_block_num {
16171625
1 => {
1618-
validation_data.dmq_mqc_head =
1619-
MessageQueueChain::default().extend_downward(&MSG).head();
1626+
sproof.dmq_mqc_head =
1627+
Some(MessageQueueChain::default().extend_downward(&MSG).head());
16201628
}
16211629
_ => unreachable!(),
16221630
},
@@ -1661,39 +1669,31 @@ mod tests {
16611669
}
16621670

16631671
BlockTests::new()
1664-
.with_validation_data(
1665-
|_, relay_block_num, validation_data| match relay_block_num {
1672+
.with_relay_sproof_builder(
1673+
|_, relay_block_num, sproof| match relay_block_num {
16661674
1 => {
16671675
// 200 - doesn't exist yet
16681676
// 300 - one new message
1669-
validation_data.hrmp_mqc_heads.push((
1670-
ParaId::from(300),
1671-
MessageQueueChain::default().extend_hrmp(&MSG_1).head(),
1672-
));
1677+
sproof.upsert_inbound_channel(ParaId::from(300)).mqc_head =
1678+
Some(MessageQueueChain::default().extend_hrmp(&MSG_1).head());
16731679
}
16741680
2 => {
16751681
// 200 - two new messages
16761682
// 300 - now present with one message.
1677-
validation_data.hrmp_mqc_heads.push((
1678-
ParaId::from(200),
1679-
MessageQueueChain::default().extend_hrmp(&MSG_4).head(),
1680-
));
1681-
validation_data.hrmp_mqc_heads.push((
1682-
ParaId::from(300),
1683-
MessageQueueChain::default()
1683+
sproof.upsert_inbound_channel(ParaId::from(200)).mqc_head =
1684+
Some(MessageQueueChain::default().extend_hrmp(&MSG_4).head());
1685+
sproof.upsert_inbound_channel(ParaId::from(300)).mqc_head =
1686+
Some(MessageQueueChain::default()
16841687
.extend_hrmp(&MSG_1)
16851688
.extend_hrmp(&MSG_2)
16861689
.extend_hrmp(&MSG_3)
1687-
.head(),
1688-
));
1690+
.head());
16891691
}
16901692
3 => {
16911693
// 200 - no new messages
16921694
// 300 - is gone
1693-
validation_data.hrmp_mqc_heads.push((
1694-
ParaId::from(200),
1695-
MessageQueueChain::default().extend_hrmp(&MSG_4).head(),
1696-
));
1695+
sproof.upsert_inbound_channel(ParaId::from(200)).mqc_head =
1696+
Some(MessageQueueChain::default().extend_hrmp(&MSG_4).head());
16971697
}
16981698
_ => unreachable!(),
16991699
},
@@ -1747,21 +1747,17 @@ mod tests {
17471747
#[test]
17481748
fn receive_hrmp_empty_channel() {
17491749
BlockTests::new()
1750-
.with_validation_data(
1751-
|_, relay_block_num, validation_data| match relay_block_num {
1752-
1 => {
1753-
// no channels
1754-
}
1755-
2 => {
1756-
// one new channel
1757-
validation_data.hrmp_mqc_heads.push((
1758-
ParaId::from(300),
1759-
MessageQueueChain::default().head(),
1760-
));
1761-
}
1762-
_ => unreachable!(),
1763-
},
1764-
)
1750+
.with_relay_sproof_builder(|_, relay_block_num, sproof| match relay_block_num {
1751+
1 => {
1752+
// no channels
1753+
}
1754+
2 => {
1755+
// one new channel
1756+
sproof.upsert_inbound_channel(ParaId::from(300)).mqc_head =
1757+
Some(MessageQueueChain::default().head());
1758+
}
1759+
_ => unreachable!(),
1760+
})
17651761
.add(1, || {})
17661762
.add(2, || {});
17671763
}
@@ -1783,30 +1779,24 @@ mod tests {
17831779
const ALICE: ParaId = ParaId::new(300);
17841780

17851781
BlockTests::new()
1786-
.with_validation_data(
1787-
|_, relay_block_num, validation_data| match relay_block_num {
1782+
.with_relay_sproof_builder(
1783+
|_, relay_block_num, sproof| match relay_block_num {
17881784
1 => {
1789-
validation_data.hrmp_mqc_heads.push((
1790-
ALICE,
1791-
MessageQueueChain::default().extend_hrmp(&MSG_1).head(),
1792-
));
1785+
sproof.upsert_inbound_channel(ALICE).mqc_head
1786+
= Some(MessageQueueChain::default().extend_hrmp(&MSG_1).head());
17931787
}
17941788
2 => {
17951789
// 300 - no new messages, mqc stayed the same.
1796-
validation_data.hrmp_mqc_heads.push((
1797-
ALICE,
1798-
MessageQueueChain::default().extend_hrmp(&MSG_1).head(),
1799-
));
1790+
sproof.upsert_inbound_channel(ALICE).mqc_head
1791+
= Some(MessageQueueChain::default().extend_hrmp(&MSG_1).head());
18001792
}
18011793
3 => {
18021794
// 300 - new message.
1803-
validation_data.hrmp_mqc_heads.push((
1804-
ALICE,
1805-
MessageQueueChain::default()
1806-
.extend_hrmp(&MSG_1)
1807-
.extend_hrmp(&MSG_2)
1808-
.head(),
1809-
));
1795+
sproof.upsert_inbound_channel(ALICE).mqc_head
1796+
= Some(MessageQueueChain::default()
1797+
.extend_hrmp(&MSG_1)
1798+
.extend_hrmp(&MSG_2)
1799+
.head());
18101800
}
18111801
_ => unreachable!(),
18121802
},

0 commit comments

Comments
 (0)