reth_seismic_node/
node.rs

1//! Seismic Node types config.
2
3use crate::{
4    engine::{SeismicEngineTypes, SeismicEngineValidator},
5    txpool::SeismicTransactionPool,
6};
7use alloy_eips::merge::EPOCH_SLOTS;
8use reth_chainspec::{ChainSpec, EthChainSpec};
9use reth_consensus::{ConsensusError, FullConsensus};
10use reth_evm::{ConfigureEvm, EvmFactory, EvmFactoryFor, NextBlockEnvAttributes};
11use reth_network::{NetworkHandle, NetworkPrimitives};
12use reth_node_api::{AddOnsContext, FullNodeComponents, NodeAddOns, PrimitivesTy, TxTy};
13use reth_node_builder::{
14    components::{
15        BasicPayloadServiceBuilder, ComponentsBuilder, ConsensusBuilder, ExecutorBuilder,
16        NetworkBuilder, PayloadBuilderBuilder, PoolBuilder,
17    },
18    node::{FullNodeTypes, NodeTypes},
19    rpc::{
20        EngineValidatorAddOn, EngineValidatorBuilder, EthApiBuilder, RethRpcAddOns, RpcAddOns,
21        RpcHandle,
22    },
23    BuilderContext, DebugNode, Node, NodeAdapter, NodeComponentsBuilder, PayloadBuilderConfig,
24};
25use reth_node_ethereum::consensus::EthBeaconConsensus;
26use reth_provider::{providers::ProviderFactoryBuilder, CanonStateSubscriptions, EthStorage};
27use reth_rpc::ValidationApi;
28use reth_rpc_api::BlockSubmissionValidationApiServer;
29use reth_rpc_builder::config::RethRpcServerConfig;
30use reth_rpc_eth_api::FullEthApiServer;
31use reth_rpc_eth_types::{error::FromEvmError, EthApiError};
32use reth_rpc_server_types::RethRpcModule;
33use reth_seismic_evm::SeismicEvmConfig;
34use reth_seismic_payload_builder::SeismicBuilderConfig;
35use reth_seismic_primitives::{SeismicPrimitives, SeismicReceipt, SeismicTransactionSigned};
36use reth_seismic_rpc::{SeismicEthApi, SeismicEthApiBuilder};
37use reth_transaction_pool::{
38    blobstore::{DiskFileBlobStore, DiskFileBlobStoreConfig},
39    CoinbaseTipOrdering, PoolTransaction, TransactionPool, TransactionValidationTaskExecutor,
40};
41use reth_trie_db::MerklePatriciaTrie;
42use revm::context::TxEnv;
43use seismic_alloy_consensus::SeismicTxEnvelope;
44use seismic_enclave::rpc::SyncEnclaveApiClientBuilder;
45use std::{sync::Arc, time::SystemTime};
46
47use crate::{real_seismic_evm_config, RealSeismicEvmConfig};
48
49/// Storage implementation for Optimism.
50pub type SeismicStorage = EthStorage<SeismicTransactionSigned>;
51
52#[derive(Debug, Default, Clone)]
53#[non_exhaustive]
54/// Type configuration for a regular Seismic node.
55pub struct SeismicNode;
56
57impl SeismicNode {
58    /// Returns the components for the given [`EnclaveArgs`].
59    pub fn components<Node>(
60        &self,
61    ) -> ComponentsBuilder<
62        Node,
63        SeismicPoolBuilder,
64        BasicPayloadServiceBuilder<SeismicPayloadBuilder>,
65        SeismicNetworkBuilder,
66        SeismicExecutorBuilder,
67        SeismicConsensusBuilder,
68    >
69    where
70        Node: FullNodeTypes<
71            Types: NodeTypes<
72                Payload = SeismicEngineTypes,
73                ChainSpec = ChainSpec,
74                Primitives = SeismicPrimitives,
75            >,
76        >,
77    {
78        ComponentsBuilder::default()
79            .node_types::<Node>()
80            .pool(SeismicPoolBuilder::default())
81            .executor(SeismicExecutorBuilder::default())
82            .payload(BasicPayloadServiceBuilder::<SeismicPayloadBuilder>::default())
83            .network(SeismicNetworkBuilder::default())
84            .executor(SeismicExecutorBuilder::default())
85            .consensus(SeismicConsensusBuilder::default())
86    }
87
88    /// Instantiates the [`ProviderFactoryBuilder`] for an opstack node.
89    ///
90    /// # Open a Providerfactory in read-only mode from a datadir
91    ///
92    /// See also: [`ProviderFactoryBuilder`] and
93    /// [`ReadOnlyConfig`](reth_provider::providers::ReadOnlyConfig).
94    ///
95    /// ```no_run
96    /// use reth_chainspec::BASE_MAINNET;
97    /// use reth_seismic_node::SeismicNode;
98    ///
99    /// let factory = SeismicNode::provider_factory_builder()
100    ///     .open_read_only(BASE_MAINNET.clone(), "datadir")
101    ///     .unwrap();
102    /// ```
103    ///
104    /// # Open a Providerfactory manually with with all required components
105    ///
106    /// ```no_run
107    /// use reth_chainspec::ChainSpecBuilder;
108    /// use reth_db::open_db_read_only;
109    /// use reth_provider::providers::StaticFileProvider;
110    /// use reth_seismic_node::SeismicNode;
111    /// use std::sync::Arc;
112    ///
113    /// let factory = SeismicNode::provider_factory_builder()
114    ///     .db(Arc::new(open_db_read_only("db", Default::default()).unwrap()))
115    ///     .chainspec(ChainSpecBuilder::base_mainnet().build().into())
116    ///     .static_file(StaticFileProvider::read_only("db/static_files", false).unwrap())
117    ///     .build_provider_factory();
118    /// ```
119    pub fn provider_factory_builder() -> ProviderFactoryBuilder<Self> {
120        ProviderFactoryBuilder::default()
121    }
122}
123
124impl<N> Node<N> for SeismicNode
125where
126    N: FullNodeTypes<
127        Types: NodeTypes<
128            Payload = SeismicEngineTypes,
129            ChainSpec = ChainSpec,
130            Primitives = SeismicPrimitives,
131            Storage = SeismicStorage,
132        >,
133    >,
134{
135    type ComponentsBuilder = ComponentsBuilder<
136        N,
137        SeismicPoolBuilder,
138        BasicPayloadServiceBuilder<SeismicPayloadBuilder>,
139        SeismicNetworkBuilder,
140        SeismicExecutorBuilder,
141        SeismicConsensusBuilder,
142    >;
143
144    type AddOns = SeismicAddOns<
145        NodeAdapter<N, <Self::ComponentsBuilder as NodeComponentsBuilder<N>>::Components>,
146    >;
147
148    fn components_builder(&self) -> Self::ComponentsBuilder {
149        Self::components(self)
150    }
151
152    fn add_ons(&self) -> Self::AddOns {
153        Self::AddOns::builder().build()
154    }
155}
156
157impl NodeTypes for SeismicNode {
158    type Primitives = SeismicPrimitives;
159    type ChainSpec = ChainSpec;
160    type StateCommitment = MerklePatriciaTrie;
161    type Storage = SeismicStorage;
162    type Payload = SeismicEngineTypes;
163}
164
165impl<N> DebugNode<N> for SeismicNode
166where
167    N: FullNodeComponents<Types = Self>,
168{
169    type RpcBlock = alloy_rpc_types_eth::Block<seismic_alloy_consensus::SeismicTxEnvelope>;
170
171    fn rpc_to_primitive_block(rpc_block: Self::RpcBlock) -> reth_node_api::BlockTy<Self> {
172        let alloy_rpc_types_eth::Block { header, transactions, .. } = rpc_block;
173        reth_seismic_primitives::SeismicBlock {
174            header: header.inner,
175            body: reth_seismic_primitives::SeismicBlockBody {
176                transactions: transactions.into_transactions().map(Into::into).collect(),
177                ..Default::default()
178            },
179        }
180    }
181}
182
183/// Add-ons w.r.t. seismic
184#[derive(Debug)]
185pub struct SeismicAddOns<N: FullNodeComponents>
186where
187    N: FullNodeComponents,
188    SeismicEthApiBuilder: EthApiBuilder<N>,
189{
190    inner: RpcAddOns<
191        N,                             // Node:
192        SeismicEthApiBuilder,          // EthB:
193        SeismicEngineValidatorBuilder, // EV:
194    >,
195}
196
197impl<N> SeismicAddOns<N>
198where
199    N: FullNodeComponents<
200        Types: NodeTypes<
201            ChainSpec = ChainSpec,
202            Primitives = SeismicPrimitives,
203            Storage = SeismicStorage,
204            Payload = SeismicEngineTypes,
205        >,
206    >,
207    SeismicEthApiBuilder: EthApiBuilder<N>,
208{
209    /// Build a [`SeismicAddOns`] using [`SeismicAddOnsBuilder`].
210    pub fn builder() -> SeismicAddOnsBuilder {
211        SeismicAddOnsBuilder::default()
212    }
213}
214
215/// A regular seismic evm and executor builder.
216#[derive(Debug, Default, Clone)]
217pub struct SeismicAddOnsBuilder {}
218
219impl SeismicAddOnsBuilder {
220    /// Builds an instance of [`OpAddOns`].
221    pub fn build<N>(self) -> SeismicAddOns<N>
222    where
223        N: FullNodeComponents<
224            Types: NodeTypes<
225                ChainSpec = ChainSpec,
226                Primitives = SeismicPrimitives,
227                Storage = SeismicStorage,
228                Payload = SeismicEngineTypes,
229            >,
230            Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>,
231        >,
232        SeismicEthApiBuilder: EthApiBuilder<N>,
233    {
234        SeismicAddOns { inner: Default::default() }
235    }
236}
237
238impl<N: FullNodeComponents> Default for SeismicAddOns<N>
239where
240    N: FullNodeComponents<
241        Types: NodeTypes<
242            ChainSpec = ChainSpec,
243            Primitives = SeismicPrimitives,
244            Storage = SeismicStorage,
245            Payload = SeismicEngineTypes,
246        >,
247        Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>,
248    >,
249    SeismicEthApiBuilder: EthApiBuilder<N>,
250{
251    fn default() -> Self {
252        Self::builder().build()
253    }
254}
255
256impl<N> NodeAddOns<N> for SeismicAddOns<N>
257where
258    N: FullNodeComponents<
259        Types: NodeTypes<
260            ChainSpec = ChainSpec,
261            Primitives = SeismicPrimitives,
262            Storage = SeismicStorage,
263            Payload = SeismicEngineTypes,
264        >,
265        Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>,
266    >,
267    EthApiError: FromEvmError<N::Evm>,
268    EvmFactoryFor<N::Evm>: EvmFactory<Tx = seismic_revm::SeismicTransaction<TxEnv>>,
269{
270    type Handle = RpcHandle<N, SeismicEthApi<N>>;
271
272    async fn launch_add_ons(
273        self,
274        ctx: reth_node_api::AddOnsContext<'_, N>,
275    ) -> eyre::Result<Self::Handle> {
276        let validation_api = ValidationApi::new(
277            ctx.node.provider().clone(),
278            Arc::new(ctx.node.consensus().clone()),
279            ctx.node.evm_config().clone(),
280            ctx.config.rpc.flashbots_config(),
281            Box::new(ctx.node.task_executor().clone()),
282            Arc::new(SeismicEngineValidator::new(ctx.config.chain.clone())),
283        );
284
285        self.inner
286            .launch_add_ons_with(ctx, move |modules, _, _| {
287                modules.merge_if_module_configured(
288                    RethRpcModule::Flashbots,
289                    validation_api.into_rpc(),
290                )?;
291
292                Ok(())
293            })
294            .await
295    }
296}
297
298impl<N> RethRpcAddOns<N> for SeismicAddOns<N>
299where
300    N: FullNodeComponents<
301        Types: NodeTypes<
302            ChainSpec = ChainSpec,
303            Primitives = SeismicPrimitives,
304            Storage = SeismicStorage,
305            Payload = SeismicEngineTypes,
306        >,
307        Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>,
308    >,
309    EthApiError: FromEvmError<N::Evm>,
310    EvmFactoryFor<N::Evm>: EvmFactory<Tx = seismic_revm::SeismicTransaction<TxEnv>>,
311    SeismicEthApi<N>: FullEthApiServer<Provider = N::Provider, Pool = N::Pool>, /* Needed to
312                                                                                compile, but why? */
313{
314    type EthApi = SeismicEthApi<N>;
315
316    fn hooks_mut(&mut self) -> &mut reth_node_builder::rpc::RpcHooks<N, Self::EthApi> {
317        self.inner.hooks_mut()
318    }
319}
320
321impl<N> EngineValidatorAddOn<N> for SeismicAddOns<N>
322where
323    N: FullNodeComponents<
324        Types: NodeTypes<
325            ChainSpec = ChainSpec,
326            Primitives = SeismicPrimitives,
327            Storage = SeismicStorage,
328            Payload = SeismicEngineTypes,
329        >,
330        Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>,
331    >,
332    SeismicEthApi<N>: FullEthApiServer<Provider = N::Provider, Pool = N::Pool>, /* Needed to
333                                                                                compile, but why? */
334{
335    type Validator = SeismicEngineValidator;
336
337    async fn engine_validator(&self, ctx: &AddOnsContext<'_, N>) -> eyre::Result<Self::Validator> {
338        SeismicEngineValidatorBuilder::default().build(ctx).await
339    }
340}
341
342/// A regular seismic evm and executor builder.
343#[derive(Debug, Default, Clone, Copy)]
344#[non_exhaustive]
345pub struct SeismicExecutorBuilder;
346
347impl<Node> ExecutorBuilder<Node> for SeismicExecutorBuilder
348where
349    Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = SeismicPrimitives>>,
350{
351    type EVM = RealSeismicEvmConfig;
352
353    async fn build_evm(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::EVM> {
354        let evm_config = real_seismic_evm_config(ctx.chain_spec());
355
356        Ok(evm_config)
357    }
358}
359
360/// A basic ethereum transaction pool.
361///
362/// This contains various settings that can be configured and take precedence over the node's
363/// config.
364#[derive(Debug, Default, Clone, Copy)]
365#[non_exhaustive]
366pub struct SeismicPoolBuilder;
367
368impl<Node> PoolBuilder<Node> for SeismicPoolBuilder
369where
370    Node: FullNodeTypes<
371        Types: NodeTypes<
372            Payload = SeismicEngineTypes,
373            ChainSpec = ChainSpec,
374            Primitives = SeismicPrimitives,
375        >,
376    >,
377    // T: EthPoolTransaction<Consensus = TxTy<Node::Types>>
378    // + MaybeConditionalTransaction
379    // + MaybeInteropTransaction,
380{
381    type Pool = SeismicTransactionPool<Node::Provider, DiskFileBlobStore>;
382
383    async fn build_pool(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Pool> {
384        let data_dir = ctx.config().datadir();
385        let pool_config = ctx.pool_config();
386
387        let blob_cache_size = if let Some(blob_cache_size) = pool_config.blob_cache_size {
388            blob_cache_size
389        } else {
390            // get the current blob params for the current timestamp
391            let current_timestamp =
392                SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_secs();
393            let blob_params = ctx
394                .chain_spec()
395                .blob_params_at_timestamp(current_timestamp)
396                .unwrap_or(ctx.chain_spec().blob_params.cancun);
397
398            // Derive the blob cache size from the target blob count, to auto scale it by
399            // multiplying it with the slot count for 2 epochs: 384 for pectra
400            (blob_params.target_blob_count * EPOCH_SLOTS * 2) as u32
401        };
402
403        let custom_config =
404            DiskFileBlobStoreConfig::default().with_max_cached_entries(blob_cache_size);
405
406        let blob_store = DiskFileBlobStore::open(data_dir.blobstore(), custom_config)?;
407        let validator = TransactionValidationTaskExecutor::eth_builder(ctx.provider().clone())
408            .with_head_timestamp(ctx.head().timestamp)
409            .kzg_settings(ctx.kzg_settings()?)
410            .with_local_transactions_config(pool_config.local_transactions_config.clone())
411            .with_additional_tasks(ctx.config().txpool.additional_validation_tasks)
412            .build_with_tasks(ctx.task_executor().clone(), blob_store.clone());
413
414        let transaction_pool = reth_transaction_pool::Pool::new(
415            validator,
416            CoinbaseTipOrdering::default(),
417            blob_store,
418            pool_config,
419        );
420        // info!(target: "reth::cli", "Transaction pool initialized");
421        let transactions_path = data_dir.txpool_transactions();
422
423        // spawn txpool maintenance task
424        {
425            let pool = transaction_pool.clone();
426            let chain_events = ctx.provider().canonical_state_stream();
427            let client = ctx.provider().clone();
428            let transactions_backup_config =
429
430reth_transaction_pool::maintain::LocalTransactionBackupConfig::with_local_txs_backup(transactions_path);
431
432            ctx.task_executor().spawn_critical_with_graceful_shutdown_signal(
433                "local transactions backup task",
434                |shutdown| {
435                    reth_transaction_pool::maintain::backup_local_transactions_task(
436                        shutdown,
437                        pool.clone(),
438                        transactions_backup_config,
439                    )
440                },
441            );
442
443            // spawn the maintenance task
444            ctx.task_executor().spawn_critical(
445                "txpool maintenance task",
446                reth_transaction_pool::maintain::maintain_transaction_pool_future(
447                    client,
448                    pool,
449                    chain_events,
450                    ctx.task_executor().clone(),
451                    reth_transaction_pool::maintain::MaintainPoolConfig {
452                        max_tx_lifetime: transaction_pool.config().max_queued_lifetime,
453                        ..Default::default()
454                    },
455                ),
456            );
457            // debug!(target: "reth::cli", "Spawned txpool maintenance task");
458        }
459
460        Ok(transaction_pool)
461    }
462}
463
464/// A basic seismic payload service builder
465#[derive(Debug, Default, Clone)]
466pub struct SeismicPayloadBuilder;
467
468impl SeismicPayloadBuilder {
469    /// A helper method initializing [`reth_ethereum_payload_builder::EthereumPayloadBuilder`]
470    /// with the given EVM config.
471    pub fn build<Types, Node, Evm, Pool>(
472        self,
473        evm_config: Evm,
474        ctx: &BuilderContext<Node>,
475        pool: Pool,
476    ) -> eyre::Result<reth_seismic_payload_builder::SeismicPayloadBuilder<Pool, Node::Provider, Evm>>
477    where
478        Node: FullNodeTypes<
479            Types: NodeTypes<
480                Payload = SeismicEngineTypes,
481                ChainSpec = ChainSpec,
482                Primitives = SeismicPrimitives,
483            >,
484        >,
485        Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TxTy<Node::Types>>>
486            + Unpin
487            + 'static,
488        Evm: ConfigureEvm<Primitives = PrimitivesTy<Node::Types>>,
489        // Txs: SeismicPayloadTransactions<Pool::Transaction>,
490    {
491        let conf = ctx.payload_builder_config();
492        let chain = ctx.chain_spec().chain();
493        let gas_limit = conf.gas_limit_for(chain);
494
495        Ok(reth_seismic_payload_builder::SeismicPayloadBuilder::new(
496            ctx.provider().clone(),
497            pool,
498            evm_config,
499            SeismicBuilderConfig::new().with_gas_limit(gas_limit),
500        ))
501    }
502}
503
504impl<Node, Pool, CB> PayloadBuilderBuilder<Node, Pool, SeismicEvmConfig<CB>>
505    for SeismicPayloadBuilder
506where
507    Node: FullNodeTypes<
508        Types: NodeTypes<
509            Payload = SeismicEngineTypes,
510            ChainSpec = ChainSpec,
511            Primitives = SeismicPrimitives,
512        >,
513    >,
514    Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TxTy<Node::Types>>>
515        + Unpin
516        + 'static,
517
518    CB: SyncEnclaveApiClientBuilder + 'static,
519{
520    type PayloadBuilder = reth_seismic_payload_builder::SeismicPayloadBuilder<
521        Pool,
522        Node::Provider,
523        SeismicEvmConfig<CB>,
524    >;
525
526    async fn build_payload_builder(
527        self,
528        ctx: &BuilderContext<Node>,
529        pool: Pool,
530        evm_config: SeismicEvmConfig<CB>,
531    ) -> eyre::Result<Self::PayloadBuilder> {
532        let conf = ctx.payload_builder_config();
533        let chain = ctx.chain_spec().chain();
534        let gas_limit = conf.gas_limit_for(chain);
535
536        let payload_builder = reth_seismic_payload_builder::SeismicPayloadBuilder::new(
537            ctx.provider().clone(),
538            pool,
539            evm_config,
540            SeismicBuilderConfig::new().with_gas_limit(gas_limit),
541        );
542        Ok(payload_builder)
543    }
544}
545
546/// A basic ethereum payload service.
547#[derive(Debug, Default, Clone, Copy)]
548pub struct SeismicNetworkBuilder {
549    // TODO add closure to modify network
550}
551
552impl<Node, Pool> NetworkBuilder<Node, Pool> for SeismicNetworkBuilder
553where
554    Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = SeismicPrimitives>>,
555    Pool: TransactionPool<
556            Transaction: PoolTransaction<Consensus = TxTy<Node::Types>, Pooled = SeismicTxEnvelope>, /* equiv to op_alloy_consensus::OpPooledTransaction>, */
557        > + Unpin
558        + 'static,
559{
560    type Network = NetworkHandle<SeismicNetworkPrimitives>;
561
562    async fn build_network(
563        self,
564        ctx: &BuilderContext<Node>,
565        pool: Pool,
566    ) -> eyre::Result<NetworkHandle<SeismicNetworkPrimitives>> {
567        let network = ctx.network_builder().await?;
568        let handle = ctx.start_network(network, pool);
569        // info!(target: "reth::cli", enode=%handle.local_node_record(), "P2P networking
570        // initialized");
571        Ok(handle)
572    }
573}
574
575/// A basic seismic consensus builder.
576#[derive(Debug, Default, Clone)]
577#[non_exhaustive]
578pub struct SeismicConsensusBuilder;
579
580impl<Node> ConsensusBuilder<Node> for SeismicConsensusBuilder
581where
582    Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = SeismicPrimitives>>,
583{
584    type Consensus = Arc<dyn FullConsensus<SeismicPrimitives, Error = ConsensusError>>;
585
586    async fn build_consensus(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Consensus> {
587        Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec())))
588    }
589}
590
591/// Builder for [`EthereumEngineValidator`].
592#[derive(Debug, Default, Clone)]
593#[non_exhaustive]
594pub struct SeismicEngineValidatorBuilder;
595
596impl<Node, Types> EngineValidatorBuilder<Node> for SeismicEngineValidatorBuilder
597where
598    Types: NodeTypes<
599        ChainSpec = ChainSpec,
600        Primitives = SeismicPrimitives,
601        Payload = SeismicEngineTypes,
602    >,
603    Node: FullNodeComponents<Types = Types>,
604{
605    type Validator = SeismicEngineValidator;
606
607    async fn build(self, ctx: &AddOnsContext<'_, Node>) -> eyre::Result<Self::Validator> {
608        Ok(SeismicEngineValidator::new(ctx.config.chain.clone()))
609    }
610}
611/// Network primitive types used by Optimism networks.
612#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
613#[non_exhaustive]
614pub struct SeismicNetworkPrimitives;
615
616impl NetworkPrimitives for SeismicNetworkPrimitives {
617    type BlockHeader = alloy_consensus::Header;
618    type BlockBody = alloy_consensus::BlockBody<SeismicTransactionSigned>;
619    type Block = alloy_consensus::Block<SeismicTransactionSigned>;
620    type BroadcastedTransaction = SeismicTransactionSigned;
621    type PooledTransaction = SeismicTxEnvelope;
622    type Receipt = SeismicReceipt;
623}