reth_e2e_test_utils/
payload.rs1use eyre::eyre;
2use futures_util::StreamExt;
3use reth_node_api::{PayloadAttributes, PayloadKind};
4use reth_payload_builder::{PayloadBuilderHandle, PayloadId};
5use reth_payload_builder_primitives::Events;
6use reth_payload_primitives::PayloadTypes;
7use tokio_stream::wrappers::BroadcastStream;
8
9#[derive(derive_more::Debug)]
11pub struct PayloadTestContext<T: PayloadTypes> {
12 pub payload_event_stream: BroadcastStream<Events<T>>,
20 payload_builder: PayloadBuilderHandle<T>,
21 pub timestamp: u64,
29 #[debug(skip)]
30 attributes_generator: Box<dyn Fn(u64) -> T::PayloadAttributes + Send + Sync>,
31}
32
33impl<T: PayloadTypes> PayloadTestContext<T> {
34 pub async fn new(
36 payload_builder: PayloadBuilderHandle<T>,
37 attributes_generator: impl Fn(u64) -> T::PayloadAttributes + Send + Sync + 'static,
38 ) -> eyre::Result<Self> {
39 let payload_events = payload_builder.subscribe().await?;
40 let payload_event_stream = payload_events.into_stream();
41 Ok(Self {
43 payload_event_stream,
44 payload_builder,
45 timestamp: 1710338135,
46 attributes_generator: Box::new(attributes_generator),
47 })
48 }
49
50 pub fn next_attributes(&mut self) -> T::PayloadAttributes {
52 self.timestamp += 1;
53 (self.attributes_generator)(self.timestamp)
54 }
55
56 pub async fn expect_attr_event(&mut self, attrs: T::PayloadAttributes) -> eyre::Result<()> {
58 let first_event = self.payload_event_stream.next().await.unwrap()?;
59 if let Events::Attributes(attr) = first_event {
60 assert_eq!(attrs.timestamp(), attr.timestamp());
61 } else {
62 panic!("Expect first event as payload attributes.")
63 }
64 Ok(())
65 }
66
67 pub async fn wait_for_built_payload(&self, payload_id: PayloadId) {
74 if let Err(err) = self.resolve_payload(payload_id).await {
75 panic!("{err}")
76 }
77 }
78
79 pub async fn expect_built_payload(&mut self) -> eyre::Result<T::BuiltPayload> {
81 let second_event = self.payload_event_stream.next().await.unwrap()?;
82 if let Events::BuiltPayload(payload) = second_event {
83 Ok(payload)
84 } else {
85 panic!("Expect a built payload event.");
86 }
87 }
88
89 pub async fn resolve_payload(&self, payload_id: PayloadId) -> eyre::Result<T::BuiltPayload> {
99 self.payload_builder
100 .resolve_kind(payload_id, PayloadKind::WaitForPending)
101 .await
102 .ok_or_else(|| eyre!("payload builder has no payload job {payload_id}"))?
103 .map_err(|err| eyre!("failed to resolve payload job {payload_id}: {err}"))
104 }
105}