mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-08 03:01:12 -04:00
Co-authored-by: joshieDo <93316087+joshieDo@users.noreply.github.com> Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
136 lines
5.0 KiB
Rust
136 lines
5.0 KiB
Rust
use alloy_eips::eip4895::Withdrawals;
|
|
use alloy_primitives::TxNumber;
|
|
use core::ops::Range;
|
|
|
|
/// Total number of transactions.
|
|
pub type NumTransactions = u64;
|
|
|
|
/// The storage of the block body indices.
|
|
///
|
|
/// It has the pointer to the transaction Number of the first
|
|
/// transaction in the block and the total number of transactions.
|
|
#[derive(Debug, Default, Eq, PartialEq, Clone, Copy)]
|
|
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
|
|
#[cfg_attr(any(test, feature = "reth-codec"), derive(reth_codecs::Compact))]
|
|
#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
|
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
|
pub struct StoredBlockBodyIndices {
|
|
/// The number of the first transaction in this block
|
|
///
|
|
/// Note: If the block is empty, this is the number of the first transaction
|
|
/// in the next non-empty block.
|
|
pub first_tx_num: TxNumber,
|
|
/// The total number of transactions in the block
|
|
///
|
|
/// NOTE: Number of transitions is equal to number of transactions with
|
|
/// additional transition for block change if block has block reward or withdrawal.
|
|
pub tx_count: NumTransactions,
|
|
}
|
|
|
|
impl StoredBlockBodyIndices {
|
|
/// Return the range of transaction ids for this block.
|
|
pub const fn tx_num_range(&self) -> Range<TxNumber> {
|
|
self.first_tx_num..self.first_tx_num + self.tx_count
|
|
}
|
|
|
|
/// Return the index of last transaction in this block unless the block
|
|
/// is empty in which case it refers to the last transaction in a previous
|
|
/// non-empty block
|
|
pub const fn last_tx_num(&self) -> TxNumber {
|
|
self.first_tx_num.saturating_add(self.tx_count).saturating_sub(1)
|
|
}
|
|
|
|
/// First transaction index.
|
|
///
|
|
/// Caution: If the block is empty, this is the number of the first transaction
|
|
/// in the next non-empty block.
|
|
pub const fn first_tx_num(&self) -> TxNumber {
|
|
self.first_tx_num
|
|
}
|
|
|
|
/// Return the index of the next transaction after this block.
|
|
pub const fn next_tx_num(&self) -> TxNumber {
|
|
self.first_tx_num + self.tx_count
|
|
}
|
|
|
|
/// Return a flag whether the block is empty
|
|
pub const fn is_empty(&self) -> bool {
|
|
self.tx_count == 0
|
|
}
|
|
|
|
/// Return number of transaction inside block
|
|
///
|
|
/// NOTE: This is not the same as the number of transitions.
|
|
pub const fn tx_count(&self) -> NumTransactions {
|
|
self.tx_count
|
|
}
|
|
|
|
/// Returns true if the block contains a transaction with the given number.
|
|
pub const fn contains_tx(&self, tx_num: TxNumber) -> bool {
|
|
tx_num >= self.first_tx_num && tx_num < self.next_tx_num()
|
|
}
|
|
}
|
|
|
|
/// The storage representation of block withdrawals.
|
|
#[derive(Debug, Default, Eq, PartialEq, Clone)]
|
|
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
|
|
#[cfg_attr(any(test, feature = "reth-codec"), derive(reth_codecs::Compact))]
|
|
#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
|
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
|
pub struct StoredBlockWithdrawals {
|
|
/// The block withdrawals.
|
|
pub withdrawals: Withdrawals,
|
|
}
|
|
|
|
/// A storage representation of block withdrawals that is static file friendly. An inner `None`
|
|
/// represents a pre-merge block.
|
|
#[derive(Debug, Default, Eq, PartialEq, Clone)]
|
|
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
|
|
#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
|
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
|
pub struct StaticFileBlockWithdrawals {
|
|
/// The block withdrawals. A `None` value represents a pre-merge block.
|
|
pub withdrawals: Option<Withdrawals>,
|
|
}
|
|
|
|
#[cfg(any(test, feature = "reth-codec"))]
|
|
impl reth_codecs::Compact for StaticFileBlockWithdrawals {
|
|
fn to_compact<B>(&self, buf: &mut B) -> usize
|
|
where
|
|
B: bytes::BufMut + AsMut<[u8]>,
|
|
{
|
|
buf.put_u8(self.withdrawals.is_some() as u8);
|
|
if let Some(withdrawals) = &self.withdrawals {
|
|
return 1 + withdrawals.to_compact(buf);
|
|
}
|
|
1
|
|
}
|
|
fn from_compact(mut buf: &[u8], _: usize) -> (Self, &[u8]) {
|
|
use bytes::Buf;
|
|
if buf.get_u8() == 1 {
|
|
let (w, buf) = Withdrawals::from_compact(buf, buf.len());
|
|
(Self { withdrawals: Some(w) }, buf)
|
|
} else {
|
|
(Self { withdrawals: None }, buf)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::StoredBlockBodyIndices;
|
|
|
|
#[test]
|
|
fn block_indices() {
|
|
let first_tx_num = 10;
|
|
let tx_count = 6;
|
|
let block_indices = StoredBlockBodyIndices { first_tx_num, tx_count };
|
|
|
|
assert_eq!(block_indices.first_tx_num(), first_tx_num);
|
|
assert_eq!(block_indices.last_tx_num(), first_tx_num + tx_count - 1);
|
|
assert_eq!(block_indices.next_tx_num(), first_tx_num + tx_count);
|
|
assert_eq!(block_indices.tx_count(), tx_count);
|
|
assert_eq!(block_indices.tx_num_range(), first_tx_num..first_tx_num + tx_count);
|
|
}
|
|
}
|