reth_basic_payload_builder/
better_payload_emitter.rs

1use crate::{BuildArguments, BuildOutcome, HeaderForPayload, PayloadBuilder, PayloadConfig};
2use reth_payload_builder::PayloadBuilderError;
3use std::sync::Arc;
4use tokio::sync::broadcast;
5
6/// Emits events when a payload is built (both `Better` and `Freeze` outcomes).
7/// Delegates the actual payload building to an inner [`PayloadBuilder`].
8#[derive(Debug, Clone)]
9pub struct BetterPayloadEmitter<PB: PayloadBuilder> {
10    better_payloads_tx: broadcast::Sender<Arc<PB::BuiltPayload>>,
11    inner: PB,
12}
13
14impl<PB> BetterPayloadEmitter<PB>
15where
16    PB: PayloadBuilder,
17{
18    /// Create a new [`BetterPayloadEmitter`] with the given inner payload builder.
19    /// Owns the sender half of a broadcast channel that emits payloads when they are built
20    /// (for both `Better` and `Freeze` outcomes).
21    pub const fn new(
22        better_payloads_tx: broadcast::Sender<Arc<PB::BuiltPayload>>,
23        inner: PB,
24    ) -> Self {
25        Self { better_payloads_tx, inner }
26    }
27}
28
29impl<PB> PayloadBuilder for BetterPayloadEmitter<PB>
30where
31    PB: PayloadBuilder,
32    <PB as PayloadBuilder>::BuiltPayload: Clone,
33{
34    type Attributes = PB::Attributes;
35    type BuiltPayload = PB::BuiltPayload;
36
37    fn try_build(
38        &self,
39        args: BuildArguments<Self::Attributes, Self::BuiltPayload>,
40    ) -> Result<BuildOutcome<Self::BuiltPayload>, PayloadBuilderError> {
41        match self.inner.try_build(args) {
42            Ok(res) => {
43                // Emit payload for both Better and Freeze outcomes, as both represent valid
44                // payloads that should be available to subscribers (e.g., for
45                // insertion into engine service).
46                if let Some(payload) = res.payload().cloned() {
47                    let _ = self.better_payloads_tx.send(Arc::new(payload));
48                }
49                Ok(res)
50            }
51            res => res,
52        }
53    }
54
55    fn build_empty_payload(
56        &self,
57        config: PayloadConfig<Self::Attributes, HeaderForPayload<Self::BuiltPayload>>,
58    ) -> Result<Self::BuiltPayload, PayloadBuilderError> {
59        self.inner.build_empty_payload(config)
60    }
61}