reth_payload_builder/
test_utils.rs

1//! Utils for testing purposes.
2
3use crate::{
4    traits::KeepPayloadJobAlive, EthBuiltPayload, EthPayloadBuilderAttributes,
5    PayloadBuilderHandle, PayloadBuilderService, PayloadJob, PayloadJobGenerator,
6};
7
8use alloy_primitives::U256;
9use reth_chain_state::CanonStateNotification;
10use reth_payload_builder_primitives::PayloadBuilderError;
11use reth_payload_primitives::{PayloadKind, PayloadTypes};
12use reth_primitives::Block;
13use reth_primitives_traits::Block as _;
14use std::{
15    future::Future,
16    pin::Pin,
17    sync::Arc,
18    task::{Context, Poll},
19};
20
21/// Creates a new [`PayloadBuilderService`] for testing purposes.
22pub fn test_payload_service<T>() -> (
23    PayloadBuilderService<
24        TestPayloadJobGenerator,
25        futures_util::stream::Empty<CanonStateNotification>,
26        T,
27    >,
28    PayloadBuilderHandle<T>,
29)
30where
31    T: PayloadTypes<
32            PayloadBuilderAttributes = EthPayloadBuilderAttributes,
33            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<
43            PayloadBuilderAttributes = EthPayloadBuilderAttributes,
44            BuiltPayload = EthBuiltPayload,
45        > + 'static,
46{
47    let (service, handle) = test_payload_service();
48    tokio::spawn(service);
49    handle
50}
51
52/// A [`PayloadJobGenerator`] for testing purposes
53#[derive(Debug, Default)]
54#[non_exhaustive]
55pub struct TestPayloadJobGenerator;
56
57impl PayloadJobGenerator for TestPayloadJobGenerator {
58    type Job = TestPayloadJob;
59
60    fn new_payload_job(
61        &self,
62        attr: EthPayloadBuilderAttributes,
63    ) -> Result<Self::Job, PayloadBuilderError> {
64        Ok(TestPayloadJob { attr })
65    }
66}
67
68/// A [`PayloadJobGenerator`] for testing purposes
69#[derive(Debug)]
70pub struct TestPayloadJob {
71    attr: EthPayloadBuilderAttributes,
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 = EthPayloadBuilderAttributes;
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            self.attr.payload_id(),
91            Arc::new(Block::<_>::default().seal_slow()),
92            U256::ZERO,
93            Some(Default::default()),
94        ))
95    }
96
97    fn payload_attributes(&self) -> Result<EthPayloadBuilderAttributes, PayloadBuilderError> {
98        Ok(self.attr.clone())
99    }
100
101    fn resolve_kind(
102        &mut self,
103        _kind: PayloadKind,
104    ) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive) {
105        let fut = futures_util::future::ready(self.best_payload());
106        (fut, KeepPayloadJobAlive::No)
107    }
108}