cumulus_client_consensus_proposer/
lib.rs1use async_trait::async_trait;
24use cumulus_primitives_parachain_inherent::ParachainInherentData;
25use sc_basic_authorship::{ProposeArgs, ProposerFactory};
26use sc_block_builder::BlockBuilderApi;
27use sc_transaction_pool_api::TransactionPool;
28use sp_api::{ApiExt, CallApiAt, ProvideRuntimeApi};
29use sp_blockchain::HeaderBackend;
30use sp_consensus::{EnableProofRecording, Environment, Proposal};
31use sp_inherents::{InherentData, InherentDataProvider};
32use sp_runtime::{traits::Block as BlockT, Digest};
33use sp_state_machine::StorageProof;
34use std::{fmt::Debug, time::Duration};
35
36#[derive(thiserror::Error, Debug)]
38#[error(transparent)]
39pub struct Error {
40 inner: anyhow::Error,
41}
42
43impl Error {
44 pub fn proposer_creation(err: impl Into<anyhow::Error>) -> Self {
46 Error { inner: err.into().context("Proposer Creation") }
47 }
48
49 pub fn proposing(err: impl Into<anyhow::Error>) -> Self {
51 Error { inner: err.into().context("Proposing") }
52 }
53}
54
55pub type ProposalOf<B> = Proposal<B, StorageProof>;
58
59#[async_trait]
61pub trait ProposerInterface<Block: BlockT> {
62 async fn propose(
76 &mut self,
77 parent_header: &Block::Header,
78 paras_inherent_data: &ParachainInherentData,
79 other_inherent_data: InherentData,
80 inherent_digests: Digest,
81 max_duration: Duration,
82 block_size_limit: Option<usize>,
83 ) -> Result<Option<Proposal<Block, StorageProof>>, Error>;
84}
85
86#[async_trait]
87impl<Block, A, C> ProposerInterface<Block> for ProposerFactory<A, C, EnableProofRecording>
88where
89 A: TransactionPool<Block = Block> + 'static,
90 C: HeaderBackend<Block> + ProvideRuntimeApi<Block> + CallApiAt<Block> + Send + Sync + 'static,
91 C::Api: ApiExt<Block> + BlockBuilderApi<Block>,
92 Block: sp_runtime::traits::Block,
93{
94 async fn propose(
95 &mut self,
96 parent_header: &Block::Header,
97 paras_inherent_data: &ParachainInherentData,
98 other_inherent_data: InherentData,
99 inherent_digests: Digest,
100 max_duration: Duration,
101 block_size_limit: Option<usize>,
102 ) -> Result<Option<Proposal<Block, StorageProof>>, Error> {
103 let proposer = self
104 .init(parent_header)
105 .await
106 .map_err(|e| Error::proposer_creation(anyhow::Error::new(e)))?;
107
108 let mut inherent_data = other_inherent_data;
109 paras_inherent_data
110 .provide_inherent_data(&mut inherent_data)
111 .await
112 .map_err(|e| Error::proposing(anyhow::Error::new(e)))?;
113
114 proposer
115 .propose_block(ProposeArgs {
116 inherent_data,
117 inherent_digests,
118 max_duration,
119 block_size_limit,
120 ignored_nodes_by_proof_recording: None,
121 })
122 .await
123 .map(Some)
124 .map_err(|e| Error::proposing(anyhow::Error::new(e)).into())
125 }
126}