ab_client_block_authoring/
beacon_chain.rs1use crate::{BlockProducer, ClaimedSlot};
2use ab_client_api::{BlockOrigin, ChainInfo};
3use ab_client_block_builder::BlockBuilder;
4use ab_client_block_import::BlockImport;
5use ab_core_primitives::block::header::{BeaconChainHeader, OwnedBlockHeaderSeal};
6use ab_core_primitives::block::owned::{GenericOwnedBlock, OwnedBeaconChainBlock};
7use ab_core_primitives::hashes::Blake3Hash;
8use tracing::{error, info};
9
10#[derive(Debug)]
12pub struct BeaconChainBlockProducer<BB, BI, CI> {
13 block_builder: BB,
14 block_import: BI,
15 chain_info: CI,
16}
17
18impl<BB, BI, CI> BlockProducer for BeaconChainBlockProducer<BB, BI, CI>
19where
20 BB: BlockBuilder<OwnedBeaconChainBlock>,
21 BI: BlockImport<OwnedBeaconChainBlock>,
22 CI: ChainInfo<OwnedBeaconChainBlock>,
23{
24 async fn produce_block<SealBlock>(
25 &mut self,
26 claimed_slot: ClaimedSlot,
27 best_beacon_chain_header: &BeaconChainHeader<'_>,
28 seal_block: SealBlock,
29 ) where
30 SealBlock: AsyncFnOnce<(Blake3Hash,), Output = Option<OwnedBlockHeaderSeal>, CallOnceFuture: Send>
31 + Send,
32 {
33 let slot = claimed_slot.consensus_info.slot;
34
35 let best_header = best_beacon_chain_header;
36 let parent_block_root = &*best_header.root();
37 let (_, best_block_details) = self
38 .chain_info
39 .header_with_details(parent_block_root)
40 .expect("Best beacon chain block is never missing during block production; qed");
41
42 let block_builder_result = match self
43 .block_builder
44 .build(
45 parent_block_root,
46 best_header,
47 &best_block_details,
48 &claimed_slot.consensus_info,
49 &claimed_slot.checkpoints,
50 seal_block,
51 )
52 .await
53 {
54 Ok(block_builder_result) => block_builder_result,
55 Err(error) => {
56 error!(%slot, %parent_block_root, %error, "Failed to build a block");
57 return;
58 }
59 };
60
61 let header = block_builder_result.block.header().header();
62 info!(
63 slot = %header.consensus_info.slot,
64 number = %header.prefix.number,
65 root = %&*header.root(),
66 pre_seal_hash = %header.pre_seal_hash(),
67 "🔖 Built new block",
68 );
69
70 let block_import_fut = match self.block_import.import(
71 block_builder_result.block,
72 BlockOrigin::LocalBlockBuilder {
73 block_details: block_builder_result.block_details,
74 },
75 ) {
76 Ok(block_import_fut) => block_import_fut,
77 Err(error) => {
78 error!(
79 best_root = %*best_header.root(),
80 %error,
81 "Failed to queue a newly produced block for import"
82 );
83 return;
84 }
85 };
86
87 match block_import_fut.await {
88 Ok(()) => {
89 }
91 Err(error) => {
92 error!(
93 best_root = %*best_header.root(),
94 %error,
95 "Failed to import a newly produced block"
96 );
97 }
98 }
99 }
100}
101
102impl<BB, BI, CI> BeaconChainBlockProducer<BB, BI, CI>
103where
104 BB: BlockBuilder<OwnedBeaconChainBlock>,
105 BI: BlockImport<OwnedBeaconChainBlock>,
106 CI: ChainInfo<OwnedBeaconChainBlock>,
107{
108 pub fn new(block_builder: BB, block_import: BI, chain_info: CI) -> Self {
110 Self {
111 block_builder,
112 block_import,
113 chain_info,
114 }
115 }
116}