reth_eth_wire_types/primitives.rs
1//! Abstraction over primitive types in network messages.
2
3use crate::NewBlockPayload;
4use alloy_consensus::{RlpDecodableReceipt, RlpEncodableReceipt, TxReceipt};
5use alloy_rlp::{Decodable, Encodable};
6use core::fmt::Debug;
7use reth_ethereum_primitives::{EthPrimitives, PooledTransactionVariant};
8use reth_primitives_traits::{
9 Block, BlockBody, BlockHeader, BlockTy, NodePrimitives, SignedTransaction,
10};
11
12/// Abstraction over primitive types which might appear in network messages.
13///
14/// This trait defines the types used in the Ethereum Wire Protocol (devp2p) for
15/// peer-to-peer communication. While [`NodePrimitives`] defines the core types
16/// used throughout the node (consensus format), `NetworkPrimitives` defines how
17/// these types are represented when transmitted over the network.
18///
19/// The key distinction is in transaction handling:
20/// - [`NodePrimitives`] defines `SignedTx` - the consensus format stored in blocks
21/// - `NetworkPrimitives` defines `BroadcastedTransaction` and `PooledTransaction` - the formats
22/// used for network propagation with additional data like blob sidecars
23///
24/// These traits work together through implementations like [`NetPrimitivesFor`],
25/// which ensures type compatibility between a node's internal representation and
26/// its network representation.
27///
28/// See [`crate::EthMessage`] for more context.
29pub trait NetworkPrimitives: Send + Sync + Unpin + Clone + Debug + 'static {
30 /// The block header type.
31 type BlockHeader: BlockHeader + 'static;
32
33 /// The block body type.
34 type BlockBody: BlockBody + 'static;
35
36 /// Full block type.
37 type Block: Block<Header = Self::BlockHeader, Body = Self::BlockBody>
38 + Encodable
39 + Decodable
40 + 'static;
41
42 /// The transaction type which peers announce in `Transactions` messages.
43 ///
44 /// This is different from `PooledTransactions` to account for the Ethereum case where
45 /// EIP-4844 blob transactions are not announced over the network and can only be
46 /// explicitly requested from peers. This is because blob transactions can be quite
47 /// large and broadcasting them to all peers would cause
48 /// significant bandwidth usage.
49 type BroadcastedTransaction: SignedTransaction + 'static;
50
51 /// The transaction type which peers return in `PooledTransactions` messages.
52 ///
53 /// For EIP-4844 blob transactions, this includes the full blob sidecar with
54 /// KZG commitments and proofs that are needed for validation but are not
55 /// included in the consensus block format.
56 type PooledTransaction: SignedTransaction + TryFrom<Self::BroadcastedTransaction> + 'static;
57
58 /// The transaction type which peers return in `GetReceipts` messages.
59 type Receipt: TxReceipt
60 + RlpEncodableReceipt
61 + RlpDecodableReceipt
62 + Encodable
63 + Decodable
64 + Unpin
65 + 'static;
66
67 /// The payload type for the `NewBlock` message.
68 type NewBlockPayload: NewBlockPayload<Block = Self::Block>;
69}
70
71/// This is a helper trait for use in bounds, where some of the [`NetworkPrimitives`] associated
72/// types must be the same as the [`NodePrimitives`] associated types.
73pub trait NetPrimitivesFor<N: NodePrimitives>:
74 NetworkPrimitives<
75 BlockHeader = N::BlockHeader,
76 BlockBody = N::BlockBody,
77 Block = N::Block,
78 Receipt = N::Receipt,
79>
80{
81}
82
83impl<N, T> NetPrimitivesFor<N> for T
84where
85 N: NodePrimitives,
86 T: NetworkPrimitives<
87 BlockHeader = N::BlockHeader,
88 BlockBody = N::BlockBody,
89 Block = N::Block,
90 Receipt = N::Receipt,
91 >,
92{
93}
94
95/// Basic implementation of [`NetworkPrimitives`] combining [`NodePrimitives`] and a pooled
96/// transaction.
97#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
98pub struct BasicNetworkPrimitives<N: NodePrimitives, Pooled, NewBlock = crate::NewBlock<BlockTy<N>>>(
99 core::marker::PhantomData<(N, Pooled, NewBlock)>,
100);
101
102impl<N, Pooled, NewBlock> NetworkPrimitives for BasicNetworkPrimitives<N, Pooled, NewBlock>
103where
104 N: NodePrimitives,
105 Pooled: SignedTransaction + TryFrom<N::SignedTx> + 'static,
106 NewBlock: NewBlockPayload<Block = N::Block>,
107{
108 type BlockHeader = N::BlockHeader;
109 type BlockBody = N::BlockBody;
110 type Block = N::Block;
111 type BroadcastedTransaction = N::SignedTx;
112 type PooledTransaction = Pooled;
113 type Receipt = N::Receipt;
114 type NewBlockPayload = NewBlock;
115}
116
117/// Network primitive types used by Ethereum networks.
118pub type EthNetworkPrimitives = BasicNetworkPrimitives<EthPrimitives, PooledTransactionVariant>;