Skip to main content

reth_payload_builder/
test_utils.rs

1//! Utils for testing purposes.
2
3use crate::{
4    traits::KeepPayloadJobAlive, EthBuiltPayload, PayloadBuilderHandle, PayloadBuilderService,
5    PayloadJob, PayloadJobGenerator,
6};
7
8use alloy_consensus::Block;
9use alloy_primitives::{B256, U256};
10use alloy_rpc_types::engine::PayloadId;
11use reth_chain_state::CanonStateNotification;
12use reth_ethereum_engine_primitives::EthPayloadAttributes;
13use reth_payload_builder_primitives::PayloadBuilderError;
14use reth_payload_primitives::{PayloadKind, PayloadTypes};
15use reth_primitives_traits::Block as _;
16use std::{
17    future::Future,
18    pin::Pin,
19    sync::Arc,
20    task::{Context, Poll},
21};
22
23/// Creates a new [`PayloadBuilderService`] for testing purposes.
24pub fn test_payload_service<T>() -> (
25    PayloadBuilderService<
26        TestPayloadJobGenerator,
27        futures_util::stream::Empty<CanonStateNotification>,
28        T,
29    >,
30    PayloadBuilderHandle<T>,
31)
32where
33    T: PayloadTypes<PayloadAttributes = EthPayloadAttributes, BuiltPayload = EthBuiltPayload>
34        + 'static,
35{
36    PayloadBuilderService::new(Default::default(), futures_util::stream::empty())
37}
38
39/// Creates a new [`PayloadBuilderService`] for testing purposes and spawns it in the background.
40pub fn spawn_test_payload_service<T>() -> PayloadBuilderHandle<T>
41where
42    T: PayloadTypes<PayloadAttributes = EthPayloadAttributes, BuiltPayload = EthBuiltPayload>
43        + 'static,
44{
45    let (service, handle) = test_payload_service();
46    tokio::spawn(service);
47    handle
48}
49
50/// A [`PayloadJobGenerator`] for testing purposes
51#[derive(Debug, Default)]
52#[non_exhaustive]
53pub struct TestPayloadJobGenerator;
54
55impl PayloadJobGenerator for TestPayloadJobGenerator {
56    type Job = TestPayloadJob;
57
58    fn new_payload_job(
59        &self,
60        _parent: B256,
61        attr: EthPayloadAttributes,
62        _id: PayloadId,
63    ) -> Result<Self::Job, PayloadBuilderError> {
64        Ok(TestPayloadJob { attr })
65    }
66}
67
68/// A [`PayloadJob`] for testing purposes
69#[derive(Debug)]
70pub struct TestPayloadJob {
71    attr: EthPayloadAttributes,
72}
73
74impl Future for TestPayloadJob {
75    type Output = Result<(), PayloadBuilderError>;
76
77    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
78        Poll::Pending
79    }
80}
81
82impl PayloadJob for TestPayloadJob {
83    type PayloadAttributes = EthPayloadAttributes;
84    type ResolvePayloadFuture =
85        futures_util::future::Ready<Result<EthBuiltPayload, PayloadBuilderError>>;
86    type BuiltPayload = EthBuiltPayload;
87
88    fn best_payload(&self) -> Result<EthBuiltPayload, PayloadBuilderError> {
89        Ok(EthBuiltPayload::new(
90            Arc::new(Block::<_>::default().seal_slow()),
91            U256::ZERO,
92            Some(Default::default()),
93        ))
94    }
95
96    fn payload_attributes(&self) -> Result<EthPayloadAttributes, PayloadBuilderError> {
97        Ok(self.attr.clone())
98    }
99
100    fn payload_timestamp(&self) -> Result<u64, PayloadBuilderError> {
101        Ok(self.attr.timestamp)
102    }
103
104    fn resolve_kind(
105        &mut self,
106        _kind: PayloadKind,
107    ) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive) {
108        let fut = futures_util::future::ready(self.best_payload());
109        (fut, KeepPayloadJobAlive::No)
110    }
111}