ab_client_block_authoring/
beacon_chain.rs1use crate::{BlockProducer, ClaimedSlot};
2use ab_client_api::{BlockOrigin, ChainInfo};
3use ab_client_block_builder::{BlockBuilder, BlockBuilderResult};
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 BlockBuilderResult {
43 block,
44 block_details,
45 extra: (),
46 } = match self
47 .block_builder
48 .build(
49 parent_block_root,
50 best_header,
51 &best_block_details,
52 &claimed_slot.consensus_info,
53 &claimed_slot.checkpoints,
54 seal_block,
55 )
56 .await
57 {
58 Ok(block_builder_result) => block_builder_result,
59 Err(error) => {
60 error!(%slot, %parent_block_root, %error, "Failed to build a block");
61 return;
62 }
63 };
64
65 let header = block.header().header();
66 info!(
67 slot = %header.consensus_info.slot,
68 number = %header.prefix.number,
69 root = %&*header.root(),
70 pre_seal_hash = %header.pre_seal_hash(),
71 "🔖 Built new block",
72 );
73
74 let block_import_fut = match self
75 .block_import
76 .import(block, BlockOrigin::LocalBlockBuilder { block_details })
77 {
78 Ok(block_import_fut) => block_import_fut,
79 Err(error) => {
80 error!(
81 best_root = %*best_header.root(),
82 %error,
83 "Failed to queue a newly produced block for import"
84 );
85 return;
86 }
87 };
88
89 match block_import_fut.await {
90 Ok(()) => {
91 }
93 Err(error) => {
94 error!(
95 best_root = %*best_header.root(),
96 %error,
97 "Failed to import a newly produced block"
98 );
99 }
100 }
101 }
102}
103
104impl<BB, BI, CI> BeaconChainBlockProducer<BB, BI, CI>
105where
106 BB: BlockBuilder<OwnedBeaconChainBlock>,
107 BI: BlockImport<OwnedBeaconChainBlock>,
108 CI: ChainInfo<OwnedBeaconChainBlock>,
109{
110 pub fn new(block_builder: BB, block_import: BI, chain_info: CI) -> Self {
112 Self {
113 block_builder,
114 block_import,
115 chain_info,
116 }
117 }
118}