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

Commit 11b8062

Browse files
committed
refactor basic collator to use new collator utility
1 parent 27f3f92 commit 11b8062

File tree

1 file changed

+44
-208
lines changed
  • client/consensus/aura/src/collators

1 file changed

+44
-208
lines changed

client/consensus/aura/src/collators/basic.rs

Lines changed: 44 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
1616

17-
//! This provides the option to run a basic relay-chain driven Aura implementation
17+
//! This provides the option to run a basic relay-chain driven Aura implementation.
18+
//!
19+
//! This collator only builds on top of the most recently included block, limiting the
20+
//! block time to a maximum of two times the relay-chain block time, and requiring the
21+
//! block to be built and distributed to validators between two relay-chain blocks.
1822
//!
1923
//! For more information about AuRa, the Substrate crate should be checked.
2024
@@ -59,6 +63,8 @@ use sp_state_machine::StorageChanges;
5963
use sp_timestamp::Timestamp;
6064
use std::{convert::TryFrom, error::Error, fmt::Debug, hash::Hash, sync::Arc, time::Duration};
6165

66+
use crate::collator as collator_util;
67+
6268
/// Parameters for [`run`].
6369
pub struct Params<BI, CIDP, Client, RClient, SO, Proposer, CS> {
6470
pub create_inherent_data_providers: CIDP,
@@ -110,6 +116,20 @@ pub async fn run<Block, P, BI, CIDP, Client, RClient, SO, Proposer, CS>(
110116
)
111117
.await;
112118

119+
let mut collator = {
120+
let params = collator_util::Params {
121+
create_inherent_data_providers: params.create_inherent_data_providers,
122+
block_import: params.block_import,
123+
relay_client: params.relay_client.clone(),
124+
keystore: params.keystore.clone(),
125+
para_id: params.para_id,
126+
proposer: params.proposer,
127+
collator_service: params.collator_service,
128+
};
129+
130+
collator_util::Collator::<Block, P, _, _, _, _, _>::new(params)
131+
};
132+
113133
while let Some(request) = collation_requests.next().await {
114134
macro_rules! reject_with_error {
115135
($err:expr) => {{
@@ -135,7 +155,7 @@ pub async fn run<Block, P, BI, CIDP, Client, RClient, SO, Proposer, CS>(
135155

136156
let parent_hash = parent_header.hash();
137157

138-
if !params.collator_service.check_block_status(parent_hash, &parent_header) {
158+
if !collator.collator_service().check_block_status(parent_hash, &parent_header) {
139159
continue
140160
}
141161

@@ -145,7 +165,7 @@ pub async fn run<Block, P, BI, CIDP, Client, RClient, SO, Proposer, CS>(
145165
Ok(Some(h)) => h,
146166
};
147167

148-
let claim = match claim_slot::<_, _, P>(
168+
let claim = match collator_util::claim_slot::<_, _, P>(
149169
&*params.para_client,
150170
parent_hash,
151171
&relay_parent_header,
@@ -161,217 +181,33 @@ pub async fn run<Block, P, BI, CIDP, Client, RClient, SO, Proposer, CS>(
161181
};
162182

163183
let (parachain_inherent_data, other_inherent_data) = try_request!(
164-
create_inherent_data(
184+
collator.create_inherent_data(
165185
*request.relay_parent(),
166186
&validation_data,
167187
parent_hash,
168-
params.para_id,
169-
claim.timestamp,
170-
&params.relay_client,
171-
&params.create_inherent_data_providers,
172-
)
173-
.await
188+
claim.timestamp(),
189+
).await
174190
);
175191

176-
let proposal = try_request!(
177-
params
178-
.proposer
179-
.propose(
180-
&parent_header,
181-
&parachain_inherent_data,
182-
other_inherent_data,
183-
Digest { logs: vec![claim.pre_digest] },
184-
// TODO [https://github.com/paritytech/cumulus/issues/2439]
185-
// We should call out to a pluggable interface that provides
186-
// the proposal duration.
187-
Duration::from_millis(500),
188-
// Set the block limit to 50% of the maximum PoV size.
189-
//
190-
// TODO: If we got benchmarking that includes the proof size,
191-
// we should be able to use the maximum pov size.
192-
Some((validation_data.max_pov_size / 2) as usize),
193-
)
194-
.await
192+
let (collation, _, post_hash) = try_request!(
193+
collator.collate(
194+
&parent_header,
195+
&claim,
196+
None,
197+
(parachain_inherent_data, other_inherent_data),
198+
// TODO [https://github.com/paritytech/cumulus/issues/2439]
199+
// We should call out to a pluggable interface that provides
200+
// the proposal duration.
201+
Duration::from_millis(500),
202+
// Set the block limit to 50% of the maximum PoV size.
203+
//
204+
// TODO: If we got benchmarking that includes the proof size,
205+
// we should be able to use the maximum pov size.
206+
(validation_data.max_pov_size / 2) as usize,
207+
).await
195208
);
196209

197-
let sealed_importable = try_request!(seal::<_, _, P>(
198-
proposal.block,
199-
proposal.storage_changes,
200-
&claim.author_pub,
201-
&params.keystore,
202-
));
203-
204-
let post_hash = sealed_importable.post_hash();
205-
let block = Block::new(
206-
sealed_importable.post_header(),
207-
sealed_importable
208-
.body
209-
.as_ref()
210-
.expect("body always created with this `propose` fn; qed")
211-
.clone(),
212-
);
213-
214-
try_request!(params.block_import.import_block(sealed_importable).await);
215-
216-
let response = if let Some((collation, b)) = params.collator_service.build_collation(
217-
&parent_header,
218-
post_hash,
219-
ParachainCandidate { block, proof: proposal.proof },
220-
) {
221-
tracing::info!(
222-
target: crate::LOG_TARGET,
223-
"PoV size {{ header: {}kb, extrinsics: {}kb, storage_proof: {}kb }}",
224-
b.header().encode().len() as f64 / 1024f64,
225-
b.extrinsics().encode().len() as f64 / 1024f64,
226-
b.storage_proof().encode().len() as f64 / 1024f64,
227-
);
228-
229-
if let MaybeCompressedPoV::Compressed(ref pov) = collation.proof_of_validity {
230-
tracing::info!(
231-
target: crate::LOG_TARGET,
232-
"Compressed PoV size: {}kb",
233-
pov.block_data.0.len() as f64 / 1024f64,
234-
);
235-
}
236-
237-
let result_sender = params.collator_service.announce_with_barrier(post_hash);
238-
Some(CollationResult { collation, result_sender: Some(result_sender) })
239-
} else {
240-
None
241-
};
242-
243-
request.complete(response);
210+
let result_sender = Some(collator.collator_service().announce_with_barrier(post_hash));
211+
request.complete(Some(CollationResult { collation, result_sender }));
244212
}
245213
}
246-
247-
/// A claim on an Aura slot.
248-
struct SlotClaim<Pub> {
249-
author_pub: Pub,
250-
pre_digest: sp_runtime::DigestItem,
251-
timestamp: Timestamp,
252-
}
253-
254-
async fn claim_slot<B, C, P>(
255-
client: &C,
256-
parent_hash: B::Hash,
257-
relay_parent_header: &PHeader,
258-
slot_duration: SlotDuration,
259-
relay_chain_slot_duration: SlotDuration,
260-
keystore: &KeystorePtr,
261-
) -> Result<Option<SlotClaim<P::Public>>, Box<dyn Error>>
262-
where
263-
B: BlockT,
264-
C: ProvideRuntimeApi<B> + Send + Sync + 'static,
265-
C::Api: AuraApi<B, P::Public>,
266-
P: Pair,
267-
P::Public: Encode + Decode,
268-
P::Signature: Encode + Decode,
269-
{
270-
// load authorities
271-
let authorities = client.runtime_api().authorities(parent_hash).map_err(Box::new)?;
272-
273-
// Determine the current slot and timestamp based on the relay-parent's.
274-
let (slot_now, timestamp) =
275-
match sc_consensus_babe::find_pre_digest::<PBlock>(relay_parent_header) {
276-
Ok(babe_pre_digest) => {
277-
let t =
278-
Timestamp::new(relay_chain_slot_duration.as_millis() * *babe_pre_digest.slot());
279-
let slot = Slot::from_timestamp(t, slot_duration);
280-
281-
(slot, t)
282-
},
283-
Err(_) => return Ok(None),
284-
};
285-
286-
// Try to claim the slot locally.
287-
let author_pub = {
288-
let res = aura_internal::claim_slot::<P>(slot_now, &authorities, keystore).await;
289-
match res {
290-
Some(p) => p,
291-
None => return Ok(None),
292-
}
293-
};
294-
295-
// Produce the pre-digest.
296-
let pre_digest = aura_internal::pre_digest::<P>(slot_now);
297-
298-
Ok(Some(SlotClaim { author_pub, pre_digest, timestamp }))
299-
}
300-
301-
// This explicitly creates the inherent data for parachains, as well as overriding the
302-
// timestamp based on the slot number.
303-
async fn create_inherent_data<B: BlockT>(
304-
relay_parent: PHash,
305-
validation_data: &PersistedValidationData,
306-
parent_hash: B::Hash,
307-
para_id: ParaId,
308-
timestamp: Timestamp,
309-
relay_chain_interface: &impl RelayChainInterface,
310-
create_inherent_data_providers: &impl CreateInherentDataProviders<B, ()>,
311-
) -> Result<(ParachainInherentData, InherentData), Box<dyn Error>> {
312-
let paras_inherent_data = ParachainInherentData::create_at(
313-
relay_parent,
314-
relay_chain_interface,
315-
validation_data,
316-
para_id,
317-
)
318-
.await;
319-
320-
let paras_inherent_data = match paras_inherent_data {
321-
Some(p) => p,
322-
None =>
323-
return Err(format!("Could not create paras inherent data at {:?}", relay_parent).into()),
324-
};
325-
326-
let mut other_inherent_data = create_inherent_data_providers
327-
.create_inherent_data_providers(parent_hash, ())
328-
.map_err(|e| e as Box<dyn Error>)
329-
.await?
330-
.create_inherent_data()
331-
.await
332-
.map_err(Box::new)?;
333-
334-
other_inherent_data.replace_data(sp_timestamp::INHERENT_IDENTIFIER, &timestamp);
335-
336-
Ok((paras_inherent_data, other_inherent_data))
337-
}
338-
339-
fn seal<B: BlockT, T, P>(
340-
pre_sealed: B,
341-
storage_changes: StorageChanges<T, HashFor<B>>,
342-
author_pub: &P::Public,
343-
keystore: &KeystorePtr,
344-
) -> Result<BlockImportParams<B, T>, Box<dyn Error>>
345-
where
346-
P: Pair,
347-
P::Signature: Encode + Decode + TryFrom<Vec<u8>>,
348-
P::Public: AppPublic,
349-
{
350-
let (pre_header, body) = pre_sealed.deconstruct();
351-
let pre_hash = pre_header.hash();
352-
let block_number = *pre_header.number();
353-
354-
// seal the block.
355-
let block_import_params = {
356-
let seal_digest =
357-
aura_internal::seal::<_, P>(&pre_hash, &author_pub, keystore).map_err(Box::new)?;
358-
let mut block_import_params = BlockImportParams::new(BlockOrigin::Own, pre_header);
359-
block_import_params.post_digests.push(seal_digest);
360-
block_import_params.body = Some(body.clone());
361-
block_import_params.state_action =
362-
StateAction::ApplyChanges(sc_consensus::StorageChanges::Changes(storage_changes));
363-
block_import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain);
364-
block_import_params
365-
};
366-
let post_hash = block_import_params.post_hash();
367-
368-
tracing::info!(
369-
target: crate::LOG_TARGET,
370-
"🔖 Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.",
371-
block_number,
372-
post_hash,
373-
pre_hash,
374-
);
375-
376-
Ok(block_import_params)
377-
}

0 commit comments

Comments
 (0)