mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
chore(sdk): incorporate block module into reth-primitives-traits (#11835)
This commit is contained in:
@ -1,99 +0,0 @@
|
|||||||
//! Block abstraction.
|
|
||||||
|
|
||||||
pub mod body;
|
|
||||||
|
|
||||||
use alloc::fmt;
|
|
||||||
use core::ops;
|
|
||||||
|
|
||||||
use alloy_consensus::BlockHeader;
|
|
||||||
use alloy_primitives::{Address, Sealable, B256};
|
|
||||||
|
|
||||||
use crate::{traits::BlockBody, BlockWithSenders, SealedBlock, SealedHeader};
|
|
||||||
|
|
||||||
/// Abstraction of block data type.
|
|
||||||
pub trait Block:
|
|
||||||
fmt::Debug
|
|
||||||
+ Clone
|
|
||||||
+ PartialEq
|
|
||||||
+ Eq
|
|
||||||
+ Default
|
|
||||||
+ serde::Serialize
|
|
||||||
+ for<'a> serde::Deserialize<'a>
|
|
||||||
+ From<(Self::Header, Self::Body)>
|
|
||||||
+ Into<(Self::Header, Self::Body)>
|
|
||||||
{
|
|
||||||
/// Header part of the block.
|
|
||||||
type Header: BlockHeader + Sealable;
|
|
||||||
|
|
||||||
/// The block's body contains the transactions in the block.
|
|
||||||
type Body: BlockBody;
|
|
||||||
|
|
||||||
/// A block and block hash.
|
|
||||||
type SealedBlock<H = Self::Header, B = Self::Body>;
|
|
||||||
|
|
||||||
/// A block and addresses of senders of transactions in it.
|
|
||||||
type BlockWithSenders<T = Self>;
|
|
||||||
|
|
||||||
/// Returns reference to [`BlockHeader`] type.
|
|
||||||
fn header(&self) -> &Self::Header;
|
|
||||||
|
|
||||||
/// Returns reference to [`BlockBody`] type.
|
|
||||||
fn body(&self) -> &Self::Body;
|
|
||||||
|
|
||||||
/// Calculate the header hash and seal the block so that it can't be changed.
|
|
||||||
// todo: can be default impl if sealed block type is made generic over header and body and
|
|
||||||
// migrated to alloy
|
|
||||||
fn seal_slow(self) -> Self::SealedBlock;
|
|
||||||
|
|
||||||
/// Seal the block with a known hash.
|
|
||||||
///
|
|
||||||
/// WARNING: This method does not perform validation whether the hash is correct.
|
|
||||||
// todo: can be default impl if sealed block type is made generic over header and body and
|
|
||||||
// migrated to alloy
|
|
||||||
fn seal(self, hash: B256) -> Self::SealedBlock;
|
|
||||||
|
|
||||||
/// Expensive operation that recovers transaction signer. See
|
|
||||||
/// [`SealedBlockWithSenders`](reth_primitives::SealedBlockWithSenders).
|
|
||||||
fn senders(&self) -> Option<Vec<Address>> {
|
|
||||||
self.body().recover_signers()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transform into a [`BlockWithSenders`].
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// If the number of senders does not match the number of transactions in the block
|
|
||||||
/// and the signer recovery for one of the transactions fails.
|
|
||||||
///
|
|
||||||
/// Note: this is expected to be called with blocks read from disk.
|
|
||||||
#[track_caller]
|
|
||||||
fn with_senders_unchecked(self, senders: Vec<Address>) -> Self::BlockWithSenders {
|
|
||||||
self.try_with_senders_unchecked(senders).expect("stored block is valid")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transform into a [`BlockWithSenders`] using the given senders.
|
|
||||||
///
|
|
||||||
/// If the number of senders does not match the number of transactions in the block, this falls
|
|
||||||
/// back to manually recovery, but _without ensuring that the signature has a low `s` value_.
|
|
||||||
/// See also [`TransactionSigned::recover_signer_unchecked`]
|
|
||||||
///
|
|
||||||
/// Returns an error if a signature is invalid.
|
|
||||||
// todo: can be default impl if block with senders type is made generic over block and migrated
|
|
||||||
// to alloy
|
|
||||||
#[track_caller]
|
|
||||||
fn try_with_senders_unchecked(
|
|
||||||
self,
|
|
||||||
senders: Vec<Address>,
|
|
||||||
) -> Result<Self::BlockWithSenders, Self>;
|
|
||||||
|
|
||||||
/// **Expensive**. Transform into a [`BlockWithSenders`] by recovering senders in the contained
|
|
||||||
/// transactions.
|
|
||||||
///
|
|
||||||
/// Returns `None` if a transaction is invalid.
|
|
||||||
// todo: can be default impl if sealed block type is made generic over header and body and
|
|
||||||
// migrated to alloy
|
|
||||||
fn with_recovered_senders(self) -> Option<Self::BlockWithSenders>;
|
|
||||||
|
|
||||||
/// Calculates a heuristic for the in-memory size of the [`Block`].
|
|
||||||
fn size(&self) -> usize;
|
|
||||||
}
|
|
||||||
@ -1,11 +1,10 @@
|
|||||||
//! Block body abstraction.
|
//! Block body abstraction.
|
||||||
|
|
||||||
use alloc::fmt;
|
use alloc::{fmt, vec::Vec};
|
||||||
use core::ops;
|
|
||||||
|
|
||||||
use alloy_consensus::{BlockHeader,Request, Transaction, TxType};
|
use alloy_consensus::{BlockHeader, Request, Transaction, TxType};
|
||||||
|
use alloy_eips::eip4895::Withdrawal;
|
||||||
use alloy_primitives::{Address, B256};
|
use alloy_primitives::{Address, B256};
|
||||||
use alloy_eips::eip1559::Withdrawal;
|
|
||||||
|
|
||||||
use crate::Block;
|
use crate::Block;
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ pub trait BlockBody:
|
|||||||
/// Returns reference to transactions in block.
|
/// Returns reference to transactions in block.
|
||||||
fn transactions(&self) -> &[Self::SignedTransaction];
|
fn transactions(&self) -> &[Self::SignedTransaction];
|
||||||
|
|
||||||
/// Returns [`Withdrawals`] in the block, if any.
|
/// Returns `Withdrawals` in the block, if any.
|
||||||
// todo: branch out into extension trait
|
// todo: branch out into extension trait
|
||||||
fn withdrawals(&self) -> Option<&Self::Withdrawals>;
|
fn withdrawals(&self) -> Option<&Self::Withdrawals>;
|
||||||
|
|
||||||
@ -60,13 +59,13 @@ pub trait BlockBody:
|
|||||||
|
|
||||||
/// Calculate the withdrawals root for the block body, if withdrawals exist. If there are no
|
/// Calculate the withdrawals root for the block body, if withdrawals exist. If there are no
|
||||||
/// withdrawals, this will return `None`.
|
/// withdrawals, this will return `None`.
|
||||||
// todo: can be default impl if `calculate_withdrawals_root` made into a method on
|
// todo: can be default impl if `calculate_withdrawals_root` made into a method on
|
||||||
// `Withdrawals` and `Withdrawals` moved to alloy
|
// `Withdrawals` and `Withdrawals` moved to alloy
|
||||||
fn calculate_withdrawals_root(&self) -> Option<B256>;
|
fn calculate_withdrawals_root(&self) -> Option<B256>;
|
||||||
|
|
||||||
/// Calculate the requests root for the block body, if requests exist. If there are no
|
/// Calculate the requests root for the block body, if requests exist. If there are no
|
||||||
/// requests, this will return `None`.
|
/// requests, this will return `None`.
|
||||||
// todo: can be default impl if `calculate_requests_root` made into a method on
|
// todo: can be default impl if `calculate_requests_root` made into a method on
|
||||||
// `Requests` and `Requests` moved to alloy
|
// `Requests` and `Requests` moved to alloy
|
||||||
fn calculate_requests_root(&self) -> Option<B256>;
|
fn calculate_requests_root(&self) -> Option<B256>;
|
||||||
|
|
||||||
@ -75,17 +74,17 @@ pub trait BlockBody:
|
|||||||
|
|
||||||
/// Returns whether or not the block body contains any blob transactions.
|
/// Returns whether or not the block body contains any blob transactions.
|
||||||
fn has_blob_transactions(&self) -> bool {
|
fn has_blob_transactions(&self) -> bool {
|
||||||
self.transactions().iter().any(|tx| tx.ty() as u8 == TxType::Eip4844 as u8)
|
self.transactions().iter().any(|tx| tx.ty() == TxType::Eip4844 as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether or not the block body contains any EIP-7702 transactions.
|
/// Returns whether or not the block body contains any EIP-7702 transactions.
|
||||||
fn has_eip7702_transactions(&self) -> bool {
|
fn has_eip7702_transactions(&self) -> bool {
|
||||||
self.transactions().iter().any(|tx| tx.ty() as u8 == TxType::Eip7702 as u8)
|
self.transactions().iter().any(|tx| tx.ty() == TxType::Eip7702 as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all blob transactions of the block
|
/// Returns an iterator over all blob transactions of the block
|
||||||
fn blob_transactions_iter(&self) -> impl Iterator<Item = &Self::SignedTransaction> + '_ {
|
fn blob_transactions_iter(&self) -> impl Iterator<Item = &Self::SignedTransaction> + '_ {
|
||||||
self.transactions().iter().filter(|tx| tx.ty() as u8 == TxType::Eip4844 as u8)
|
self.transactions().iter().filter(|tx| tx.ty() == TxType::Eip4844 as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns only the blob transactions, if any, from the block body.
|
/// Returns only the blob transactions, if any, from the block body.
|
||||||
@ -104,56 +103,3 @@ pub trait BlockBody:
|
|||||||
/// Calculates a heuristic for the in-memory size of the [`BlockBody`].
|
/// Calculates a heuristic for the in-memory size of the [`BlockBody`].
|
||||||
fn size(&self) -> usize;
|
fn size(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> BlockBody for T
|
|
||||||
where
|
|
||||||
T: ops::Deref<Target: BlockBody>
|
|
||||||
+ Clone
|
|
||||||
+ fmt::Debug
|
|
||||||
+ PartialEq
|
|
||||||
+ Eq
|
|
||||||
+ Default
|
|
||||||
+ serde::Serialize
|
|
||||||
+ for<'de> serde::Deserialize<'de>
|
|
||||||
+ alloy_rlp::Encodable
|
|
||||||
+ alloy_rlp::Decodable,
|
|
||||||
{
|
|
||||||
type Header = <T::Target as BlockBody>::Header;
|
|
||||||
type SignedTransaction = <T::Target as BlockBody>::SignedTransaction;
|
|
||||||
|
|
||||||
fn transactions(&self) -> &Vec<Self::SignedTransaction> {
|
|
||||||
self.deref().transactions()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn withdrawals(&self) -> Option<&Withdrawals> {
|
|
||||||
self.deref().withdrawals()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ommers(&self) -> &Vec<Self::Header> {
|
|
||||||
self.deref().ommers()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn requests(&self) -> Option<&Requests> {
|
|
||||||
self.deref().requests()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn calculate_tx_root(&self) -> B256 {
|
|
||||||
self.deref().calculate_tx_root()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn calculate_ommers_root(&self) -> B256 {
|
|
||||||
self.deref().calculate_ommers_root()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn recover_signers(&self) -> Option<Vec<Address>> {
|
|
||||||
self.deref().recover_signers()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn blob_versioned_hashes_iter(&self) -> impl Iterator<Item = &B256> + '_ {
|
|
||||||
self.deref().blob_versioned_hashes_iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size(&self) -> usize {
|
|
||||||
self.deref().size()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -2,15 +2,22 @@
|
|||||||
|
|
||||||
pub mod body;
|
pub mod body;
|
||||||
|
|
||||||
use alloc::fmt;
|
use alloc::{fmt, vec::Vec};
|
||||||
use core::ops;
|
|
||||||
|
|
||||||
use alloy_consensus::BlockHeader;
|
use alloy_consensus::BlockHeader;
|
||||||
use alloy_primitives::{Address, Sealable, B256};
|
use alloy_primitives::{Address, Sealable, B256};
|
||||||
|
|
||||||
use crate::{traits::BlockBody, BlockWithSenders, SealedBlock, SealedHeader};
|
use crate::BlockBody;
|
||||||
|
|
||||||
|
/// Helper trait, unifies behaviour required of a block header.
|
||||||
|
pub trait Header: BlockHeader + Sealable {}
|
||||||
|
|
||||||
|
impl<T> Header for T where T: BlockHeader + Sealable {}
|
||||||
|
|
||||||
/// Abstraction of block data type.
|
/// Abstraction of block data type.
|
||||||
|
// todo: make sealable super-trait, depends on <https://github.com/paradigmxyz/reth/issues/11449>
|
||||||
|
// todo: make with senders extension trait, so block can be impl by block type already containing
|
||||||
|
// senders
|
||||||
pub trait Block:
|
pub trait Block:
|
||||||
fmt::Debug
|
fmt::Debug
|
||||||
+ Clone
|
+ Clone
|
||||||
@ -23,16 +30,16 @@ pub trait Block:
|
|||||||
+ Into<(Self::Header, Self::Body)>
|
+ Into<(Self::Header, Self::Body)>
|
||||||
{
|
{
|
||||||
/// Header part of the block.
|
/// Header part of the block.
|
||||||
type Header: BlockHeader + Sealable;
|
type Header: Header;
|
||||||
|
|
||||||
/// The block's body contains the transactions in the block.
|
/// The block's body contains the transactions in the block.
|
||||||
type Body: BlockBody;
|
type Body: BlockBody;
|
||||||
|
|
||||||
/// A block and block hash.
|
/// A block and block hash.
|
||||||
type SealedBlock<H = Self::Header, B = Self::Body>;
|
type SealedBlock<H, B>;
|
||||||
|
|
||||||
/// A block and addresses of senders of transactions in it.
|
/// A block and addresses of senders of transactions in it.
|
||||||
type BlockWithSenders<T = Self>;
|
type BlockWithSenders<T>;
|
||||||
|
|
||||||
/// Returns reference to [`BlockHeader`] type.
|
/// Returns reference to [`BlockHeader`] type.
|
||||||
fn header(&self) -> &Self::Header;
|
fn header(&self) -> &Self::Header;
|
||||||
@ -41,24 +48,24 @@ pub trait Block:
|
|||||||
fn body(&self) -> &Self::Body;
|
fn body(&self) -> &Self::Body;
|
||||||
|
|
||||||
/// Calculate the header hash and seal the block so that it can't be changed.
|
/// Calculate the header hash and seal the block so that it can't be changed.
|
||||||
// todo: can be default impl if sealed block type is made generic over header and body and
|
// todo: can be default impl if sealed block type is made generic over header and body and
|
||||||
// migrated to alloy
|
// migrated to alloy
|
||||||
fn seal_slow(self) -> Self::SealedBlock;
|
fn seal_slow(self) -> Self::SealedBlock<Self::Header, Self::Body>;
|
||||||
|
|
||||||
/// Seal the block with a known hash.
|
/// Seal the block with a known hash.
|
||||||
///
|
///
|
||||||
/// WARNING: This method does not perform validation whether the hash is correct.
|
/// WARNING: This method does not perform validation whether the hash is correct.
|
||||||
// todo: can be default impl if sealed block type is made generic over header and body and
|
// todo: can be default impl if sealed block type is made generic over header and body and
|
||||||
// migrated to alloy
|
// migrated to alloy
|
||||||
fn seal(self, hash: B256) -> Self::SealedBlock;
|
fn seal(self, hash: B256) -> Self::SealedBlock<Self::Header, Self::Body>;
|
||||||
|
|
||||||
/// Expensive operation that recovers transaction signer. See
|
/// Expensive operation that recovers transaction signer. See
|
||||||
/// [`SealedBlockWithSenders`](reth_primitives::SealedBlockWithSenders).
|
/// `SealedBlockWithSenders`.
|
||||||
fn senders(&self) -> Option<Vec<Address>> {
|
fn senders(&self) -> Option<Vec<Address>> {
|
||||||
self.body().recover_signers()
|
self.body().recover_signers()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform into a [`BlockWithSenders`].
|
/// Transform into a `BlockWithSenders`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
@ -67,32 +74,32 @@ pub trait Block:
|
|||||||
///
|
///
|
||||||
/// Note: this is expected to be called with blocks read from disk.
|
/// Note: this is expected to be called with blocks read from disk.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn with_senders_unchecked(self, senders: Vec<Address>) -> Self::BlockWithSenders {
|
fn with_senders_unchecked(self, senders: Vec<Address>) -> Self::BlockWithSenders<Self> {
|
||||||
self.try_with_senders_unchecked(senders).expect("stored block is valid")
|
self.try_with_senders_unchecked(senders).expect("stored block is valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transform into a [`BlockWithSenders`] using the given senders.
|
/// Transform into a `BlockWithSenders` using the given senders.
|
||||||
///
|
///
|
||||||
/// If the number of senders does not match the number of transactions in the block, this falls
|
/// If the number of senders does not match the number of transactions in the block, this falls
|
||||||
/// back to manually recovery, but _without ensuring that the signature has a low `s` value_.
|
/// back to manually recovery, but _without ensuring that the signature has a low `s` value_.
|
||||||
/// See also [`TransactionSigned::recover_signer_unchecked`]
|
/// See also `SignedTransaction::recover_signer_unchecked`.
|
||||||
///
|
///
|
||||||
/// Returns an error if a signature is invalid.
|
/// Returns an error if a signature is invalid.
|
||||||
// todo: can be default impl if block with senders type is made generic over block and migrated
|
// todo: can be default impl if block with senders type is made generic over block and migrated
|
||||||
// to alloy
|
// to alloy
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn try_with_senders_unchecked(
|
fn try_with_senders_unchecked(
|
||||||
self,
|
self,
|
||||||
senders: Vec<Address>,
|
senders: Vec<Address>,
|
||||||
) -> Result<Self::BlockWithSenders, Self>;
|
) -> Result<Self::BlockWithSenders<Self>, Self>;
|
||||||
|
|
||||||
/// **Expensive**. Transform into a [`BlockWithSenders`] by recovering senders in the contained
|
/// **Expensive**. Transform into a `BlockWithSenders` by recovering senders in the contained
|
||||||
/// transactions.
|
/// transactions.
|
||||||
///
|
///
|
||||||
/// Returns `None` if a transaction is invalid.
|
/// Returns `None` if a transaction is invalid.
|
||||||
// todo: can be default impl if sealed block type is made generic over header and body and
|
// todo: can be default impl if sealed block type is made generic over header and body and
|
||||||
// migrated to alloy
|
// migrated to alloy
|
||||||
fn with_recovered_senders(self) -> Option<Self::BlockWithSenders>;
|
fn with_recovered_senders(self) -> Option<Self::BlockWithSenders<Self>>;
|
||||||
|
|
||||||
/// Calculates a heuristic for the in-memory size of the [`Block`].
|
/// Calculates a heuristic for the in-memory size of the [`Block`].
|
||||||
fn size(&self) -> usize;
|
fn size(&self) -> usize;
|
||||||
|
|||||||
@ -32,6 +32,9 @@ pub use integer_list::{IntegerList, IntegerListError};
|
|||||||
pub mod request;
|
pub mod request;
|
||||||
pub use request::{Request, Requests};
|
pub use request::{Request, Requests};
|
||||||
|
|
||||||
|
pub mod block;
|
||||||
|
pub use block::{body::BlockBody, Block};
|
||||||
|
|
||||||
mod withdrawal;
|
mod withdrawal;
|
||||||
pub use withdrawal::{Withdrawal, Withdrawals};
|
pub use withdrawal::{Withdrawal, Withdrawals};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user