cumulus_test_relay_sproof_builder/
lib.rs1extern crate alloc;
18
19use alloc::collections::btree_map::BTreeMap;
20use cumulus_primitives_core::{
21 relay_chain, AbridgedHostConfiguration, AbridgedHrmpChannel, ParaId,
22};
23use polkadot_primitives::UpgradeGoAhead;
24use sp_runtime::traits::HashingFor;
25use sp_trie::PrefixedMemoryDB;
26
27#[derive(Clone)]
29pub struct RelayStateSproofBuilder {
30 pub para_id: ParaId,
39
40 pub host_config: AbridgedHostConfiguration,
41 pub dmq_mqc_head: Option<relay_chain::Hash>,
42 pub upgrade_go_ahead: Option<UpgradeGoAhead>,
43 pub relay_dispatch_queue_remaining_capacity: Option<(u32, u32)>,
44 pub hrmp_ingress_channel_index: Option<Vec<ParaId>>,
45 pub hrmp_egress_channel_index: Option<Vec<ParaId>>,
46 pub hrmp_channels: BTreeMap<relay_chain::HrmpChannelId, AbridgedHrmpChannel>,
47 pub current_slot: relay_chain::Slot,
48 pub current_epoch: u64,
49 pub randomness: relay_chain::Hash,
50 pub additional_key_values: Vec<(Vec<u8>, Vec<u8>)>,
51 pub included_para_head: Option<relay_chain::HeadData>,
52}
53
54impl Default for RelayStateSproofBuilder {
55 fn default() -> Self {
56 RelayStateSproofBuilder {
57 para_id: ParaId::from(200),
58 host_config: cumulus_primitives_core::AbridgedHostConfiguration {
59 max_code_size: 2 * 1024 * 1024,
60 max_head_data_size: 1024 * 1024,
61 max_upward_queue_count: 8,
62 max_upward_queue_size: 1024,
63 max_upward_message_size: 256,
64 max_upward_message_num_per_candidate: 5,
65 hrmp_max_message_num_per_candidate: 5,
66 validation_upgrade_cooldown: 6,
67 validation_upgrade_delay: 6,
68 async_backing_params: relay_chain::AsyncBackingParams {
69 allowed_ancestry_len: 0,
70 max_candidate_depth: 0,
71 },
72 },
73 dmq_mqc_head: None,
74 upgrade_go_ahead: None,
75 relay_dispatch_queue_remaining_capacity: None,
76 hrmp_ingress_channel_index: None,
77 hrmp_egress_channel_index: None,
78 hrmp_channels: BTreeMap::new(),
79 current_slot: 0.into(),
80 current_epoch: 0u64,
81 randomness: relay_chain::Hash::default(),
82 additional_key_values: vec![],
83 included_para_head: None,
84 }
85 }
86}
87
88impl RelayStateSproofBuilder {
89 pub fn upsert_inbound_channel(&mut self, sender: ParaId) -> &mut AbridgedHrmpChannel {
96 let in_index = self.hrmp_ingress_channel_index.get_or_insert_with(Vec::new);
97 if let Err(idx) = in_index.binary_search(&sender) {
98 in_index.insert(idx, sender);
99 }
100
101 self.upsert_channel(relay_chain::HrmpChannelId { sender, recipient: self.para_id })
102 }
103
104 pub fn upsert_outbound_channel(&mut self, recipient: ParaId) -> &mut AbridgedHrmpChannel {
111 let in_index = self.hrmp_egress_channel_index.get_or_insert_with(Vec::new);
112 if let Err(idx) = in_index.binary_search(&recipient) {
113 in_index.insert(idx, recipient);
114 }
115
116 self.upsert_channel(relay_chain::HrmpChannelId { sender: self.para_id, recipient })
117 }
118
119 fn upsert_channel(&mut self, id: relay_chain::HrmpChannelId) -> &mut AbridgedHrmpChannel {
122 self.hrmp_channels.entry(id).or_insert_with(|| AbridgedHrmpChannel {
123 max_capacity: 0,
124 max_total_size: 0,
125 max_message_size: 0,
126 msg_count: 0,
127 total_size: 0,
128 mqc_head: None,
129 })
130 }
131
132 pub fn into_state_root_and_proof(
133 self,
134 ) -> (polkadot_primitives::Hash, sp_state_machine::StorageProof) {
135 let (db, root) =
136 PrefixedMemoryDB::<HashingFor<polkadot_primitives::Block>>::default_with_root();
137 let state_version = Default::default(); let mut backend = sp_state_machine::TrieBackendBuilder::new(db, root).build();
139
140 let mut relevant_keys = Vec::new();
141 {
142 use codec::Encode as _;
143
144 let mut insert = |key: Vec<u8>, value: Vec<u8>| {
145 relevant_keys.push(key.clone());
146 backend.insert(vec![(None, vec![(key, Some(value))])], state_version);
147 };
148
149 insert(relay_chain::well_known_keys::ACTIVE_CONFIG.to_vec(), self.host_config.encode());
150 if let Some(dmq_mqc_head) = self.dmq_mqc_head {
151 insert(
152 relay_chain::well_known_keys::dmq_mqc_head(self.para_id),
153 dmq_mqc_head.encode(),
154 );
155 }
156 if let Some(para_head) = self.included_para_head {
157 insert(relay_chain::well_known_keys::para_head(self.para_id), para_head.encode());
158 }
159 if let Some(relay_dispatch_queue_remaining_capacity) =
160 self.relay_dispatch_queue_remaining_capacity
161 {
162 insert(
163 relay_chain::well_known_keys::relay_dispatch_queue_remaining_capacity(
164 self.para_id,
165 )
166 .key,
167 relay_dispatch_queue_remaining_capacity.encode(),
168 );
169 }
170 if let Some(upgrade_go_ahead) = self.upgrade_go_ahead {
171 insert(
172 relay_chain::well_known_keys::upgrade_go_ahead_signal(self.para_id),
173 upgrade_go_ahead.encode(),
174 );
175 }
176 if let Some(hrmp_ingress_channel_index) = self.hrmp_ingress_channel_index {
177 let mut sorted = hrmp_ingress_channel_index.clone();
178 sorted.sort();
179 assert_eq!(sorted, hrmp_ingress_channel_index);
180
181 insert(
182 relay_chain::well_known_keys::hrmp_ingress_channel_index(self.para_id),
183 hrmp_ingress_channel_index.encode(),
184 );
185 }
186 if let Some(hrmp_egress_channel_index) = self.hrmp_egress_channel_index {
187 let mut sorted = hrmp_egress_channel_index.clone();
188 sorted.sort();
189 assert_eq!(sorted, hrmp_egress_channel_index);
190
191 insert(
192 relay_chain::well_known_keys::hrmp_egress_channel_index(self.para_id),
193 hrmp_egress_channel_index.encode(),
194 );
195 }
196 for (channel, metadata) in self.hrmp_channels {
197 insert(relay_chain::well_known_keys::hrmp_channels(channel), metadata.encode());
198 }
199 insert(relay_chain::well_known_keys::EPOCH_INDEX.to_vec(), self.current_epoch.encode());
200 insert(
201 relay_chain::well_known_keys::ONE_EPOCH_AGO_RANDOMNESS.to_vec(),
202 self.randomness.encode(),
203 );
204 insert(relay_chain::well_known_keys::CURRENT_SLOT.to_vec(), self.current_slot.encode());
205
206 for (key, value) in self.additional_key_values {
207 insert(key, value);
208 }
209 }
210
211 let root = *backend.root();
212 let proof = sp_state_machine::prove_read(backend, relevant_keys).expect("prove read");
213 (root, proof)
214 }
215}