reth_seismic_node/
engine.rs1use std::sync::Arc;
4
5use alloy_rpc_types_engine::{ExecutionData, ExecutionPayload, ExecutionPayloadEnvelopeV5};
6pub use alloy_rpc_types_engine::{
7 ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadEnvelopeV4,
8 ExecutionPayloadV1, PayloadAttributes,
9};
10use reth_chainspec::ChainSpec;
11use reth_engine_primitives::EngineTypes;
12use reth_ethereum_payload_builder::EthereumExecutionPayloadValidator;
13use reth_node_api::{
14 validate_execution_requests, validate_version_specific_fields, EngineApiMessageVersion,
15 EngineObjectValidationError, EngineValidator, NewPayloadError, PayloadOrAttributes,
16 PayloadValidator,
17};
18use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes};
19use reth_payload_primitives::{BuiltPayload, PayloadTypes};
20use reth_primitives_traits::{NodePrimitives, RecoveredBlock, SealedBlock};
21use reth_seismic_primitives::SeismicPrimitives;
22
23#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
25#[non_exhaustive]
26pub struct SeismicEngineTypes<T: PayloadTypes = SeismicPayloadTypes> {
27 _marker: core::marker::PhantomData<T>,
28}
29
30impl<
31 T: PayloadTypes<
32 ExecutionData = ExecutionData,
33 BuiltPayload: BuiltPayload<
34 Primitives: NodePrimitives<Block = reth_seismic_primitives::SeismicBlock>,
35 >,
36 >,
37 > PayloadTypes for SeismicEngineTypes<T>
38{
39 type ExecutionData = T::ExecutionData;
40 type BuiltPayload = T::BuiltPayload;
41 type PayloadAttributes = T::PayloadAttributes;
42 type PayloadBuilderAttributes = T::PayloadBuilderAttributes;
43
44 fn block_to_payload(
45 block: SealedBlock<
46 <<Self::BuiltPayload as BuiltPayload>::Primitives as NodePrimitives>::Block,
47 >,
48 ) -> Self::ExecutionData {
49 let (payload, sidecar) =
50 ExecutionPayload::from_block_unchecked(block.hash(), &block.into_block());
51 ExecutionData { payload, sidecar }
52 }
53}
54
55impl<T> EngineTypes for SeismicEngineTypes<T>
56where
57 T: PayloadTypes<ExecutionData = ExecutionData>,
58 T::BuiltPayload: BuiltPayload<Primitives: NodePrimitives<Block = reth_seismic_primitives::SeismicBlock>>
59 + TryInto<ExecutionPayloadV1>
60 + TryInto<ExecutionPayloadEnvelopeV2>
61 + TryInto<ExecutionPayloadEnvelopeV3>
62 + TryInto<ExecutionPayloadEnvelopeV4>
63 + TryInto<ExecutionPayloadEnvelopeV5>,
64{
65 type ExecutionPayloadEnvelopeV1 = ExecutionPayloadV1;
66 type ExecutionPayloadEnvelopeV2 = ExecutionPayloadEnvelopeV2;
67 type ExecutionPayloadEnvelopeV3 = ExecutionPayloadEnvelopeV3;
68 type ExecutionPayloadEnvelopeV4 = ExecutionPayloadEnvelopeV4;
69 type ExecutionPayloadEnvelopeV5 = ExecutionPayloadEnvelopeV5;
70}
71
72#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
74#[non_exhaustive]
75pub struct SeismicPayloadTypes;
76
77impl PayloadTypes for SeismicPayloadTypes {
78 type BuiltPayload = EthBuiltPayload<SeismicPrimitives>;
79 type PayloadAttributes = PayloadAttributes;
80 type PayloadBuilderAttributes = EthPayloadBuilderAttributes;
81 type ExecutionData = ExecutionData;
82
83 fn block_to_payload(
84 block: SealedBlock<
85 <<Self::BuiltPayload as BuiltPayload>::Primitives as NodePrimitives>::Block,
86 >,
87 ) -> Self::ExecutionData {
88 let (payload, sidecar) =
89 ExecutionPayload::from_block_unchecked(block.hash(), &block.into_block());
90 ExecutionData { payload, sidecar }
91 }
92}
93
94#[derive(Debug, Clone)]
96pub struct SeismicEngineValidator {
97 inner: EthereumExecutionPayloadValidator<ChainSpec>,
98}
99
100impl SeismicEngineValidator {
101 pub const fn new(chain_spec: Arc<ChainSpec>) -> Self {
103 Self { inner: EthereumExecutionPayloadValidator::new(chain_spec) }
104 }
105
106 #[inline]
108 fn chain_spec(&self) -> &ChainSpec {
109 self.inner.chain_spec()
110 }
111}
112
113impl PayloadValidator for SeismicEngineValidator {
114 type Block = reth_seismic_primitives::SeismicBlock;
115 type ExecutionData = ExecutionData;
116
117 fn ensure_well_formed_payload(
118 &self,
119 payload: ExecutionData,
120 ) -> Result<RecoveredBlock<Self::Block>, NewPayloadError> {
121 let sealed_block = self.inner.ensure_well_formed_payload(payload)?;
122 sealed_block.try_recover().map_err(|e| NewPayloadError::Other(e.into()))
123 }
124}
125
126impl<Types> EngineValidator<Types> for SeismicEngineValidator
127where
128 Types: PayloadTypes<PayloadAttributes = PayloadAttributes, ExecutionData = ExecutionData>,
129{
130 fn validate_version_specific_fields(
131 &self,
132 version: EngineApiMessageVersion,
133 payload_or_attrs: PayloadOrAttributes<'_, Self::ExecutionData, PayloadAttributes>,
134 ) -> Result<(), EngineObjectValidationError> {
135 payload_or_attrs
136 .execution_requests()
137 .map(|requests| validate_execution_requests(requests))
138 .transpose()?;
139
140 validate_version_specific_fields(self.chain_spec(), version, payload_or_attrs)
141 }
142
143 fn ensure_well_formed_attributes(
144 &self,
145 version: EngineApiMessageVersion,
146 attributes: &PayloadAttributes,
147 ) -> Result<(), EngineObjectValidationError> {
148 validate_version_specific_fields(
149 self.chain_spec(),
150 version,
151 PayloadOrAttributes::<Self::ExecutionData, PayloadAttributes>::PayloadAttributes(
152 attributes,
153 ),
154 )
155 }
156}