diff --git a/crates/cli/commands/src/test_vectors/compact.rs b/crates/cli/commands/src/test_vectors/compact.rs index 90aafee1e8ab..3d8e7b13f966 100644 --- a/crates/cli/commands/src/test_vectors/compact.rs +++ b/crates/cli/commands/src/test_vectors/compact.rs @@ -17,7 +17,10 @@ use reth_codecs::alloy::{ withdrawal::Withdrawal, }; use reth_db::{ - models::{AccountBeforeTx, StoredBlockBodyIndices, StoredBlockOmmers, StoredBlockWithdrawals}, + models::{ + AccountBeforeTx, StaticFileBlockWithdrawals, StoredBlockBodyIndices, StoredBlockOmmers, + StoredBlockWithdrawals, + }, ClientVersion, }; use reth_fs_util as fs; @@ -110,6 +113,7 @@ compact_types!( StoredBlockOmmers, StoredBlockBodyIndices, StoredBlockWithdrawals, + StaticFileBlockWithdrawals, // Manual implementations TransactionSigned, // Bytecode, // todo revm arbitrary diff --git a/crates/storage/db-api/src/models/mod.rs b/crates/storage/db-api/src/models/mod.rs index 232e257a1dc8..19e3600dbfec 100644 --- a/crates/storage/db-api/src/models/mod.rs +++ b/crates/storage/db-api/src/models/mod.rs @@ -25,7 +25,8 @@ pub use accounts::*; pub use blocks::*; pub use integer_list::IntegerList; pub use reth_db_models::{ - AccountBeforeTx, ClientVersion, StoredBlockBodyIndices, StoredBlockWithdrawals, + blocks::StaticFileBlockWithdrawals, AccountBeforeTx, ClientVersion, StoredBlockBodyIndices, + StoredBlockWithdrawals, }; pub use sharded_key::ShardedKey; @@ -224,6 +225,7 @@ impl_compression_for_compact!( StoredBlockBodyIndices, StoredBlockOmmers, StoredBlockWithdrawals, + StaticFileBlockWithdrawals, Bytecode, AccountBeforeTx, TransactionSigned, diff --git a/crates/storage/db-models/src/blocks.rs b/crates/storage/db-models/src/blocks.rs index be7661c8b123..c87316d0e4e8 100644 --- a/crates/storage/db-models/src/blocks.rs +++ b/crates/storage/db-models/src/blocks.rs @@ -1,9 +1,9 @@ -use std::ops::Range; - use alloy_eips::eip4895::Withdrawals; use alloy_primitives::TxNumber; +use bytes::Buf; use reth_codecs::{add_arbitrary_tests, Compact}; use serde::{Deserialize, Serialize}; +use std::ops::Range; /// Total number of transactions. pub type NumTransactions = u64; @@ -76,6 +76,37 @@ pub struct StoredBlockWithdrawals { 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, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] +#[add_arbitrary_tests(compact)] +pub struct StaticFileBlockWithdrawals { + /// The block withdrawals. A `None` value represents a pre-merge block. + pub withdrawals: Option, +} + +impl Compact for StaticFileBlockWithdrawals { + fn to_compact(&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]) { + 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; diff --git a/crates/storage/db-models/src/lib.rs b/crates/storage/db-models/src/lib.rs index b8595362afc3..fd97574a646c 100644 --- a/crates/storage/db-models/src/lib.rs +++ b/crates/storage/db-models/src/lib.rs @@ -6,7 +6,7 @@ pub use accounts::AccountBeforeTx; /// Blocks pub mod blocks; -pub use blocks::{StoredBlockBodyIndices, StoredBlockWithdrawals}; +pub use blocks::{StaticFileBlockWithdrawals, StoredBlockBodyIndices, StoredBlockWithdrawals}; /// Client Version pub mod client_version; diff --git a/crates/storage/db/src/static_file/masks.rs b/crates/storage/db/src/static_file/masks.rs index f89a0eac1d4e..6dbc384fab86 100644 --- a/crates/storage/db/src/static_file/masks.rs +++ b/crates/storage/db/src/static_file/masks.rs @@ -1,10 +1,13 @@ use crate::{ add_static_file_mask, static_file::mask::{ColumnSelectorOne, ColumnSelectorTwo}, - BlockBodyIndices, BlockWithdrawals, HeaderTerminalDifficulties, + BlockBodyIndices, HeaderTerminalDifficulties, }; use alloy_primitives::BlockHash; -use reth_db_api::{models::StoredBlockOmmers, table::Table}; +use reth_db_api::{ + models::{StaticFileBlockWithdrawals, StoredBlockOmmers}, + table::Table, +}; // HEADER MASKS add_static_file_mask! { @@ -53,6 +56,6 @@ add_static_file_mask! { OmmersMask, StoredBlockOmmers, 0b010 } add_static_file_mask! { - #[doc = "Mask for a `StoredBlockWithdrawals` from BlockMeta static file segment"] - WithdrawalsMask, ::Value, 0b100 + #[doc = "Mask for a `StaticFileBlockWithdrawals` from BlockMeta static file segment"] + WithdrawalsMask, StaticFileBlockWithdrawals, 0b100 } diff --git a/crates/storage/provider/src/providers/static_file/jar.rs b/crates/storage/provider/src/providers/static_file/jar.rs index 4b6525c1d1dc..8a7654470d08 100644 --- a/crates/storage/provider/src/providers/static_file/jar.rs +++ b/crates/storage/provider/src/providers/static_file/jar.rs @@ -362,7 +362,10 @@ impl WithdrawalsProvider for StaticFileJarProvider<'_, N> { _: u64, ) -> ProviderResult> { if let Some(num) = id.as_number() { - return Ok(self.cursor()?.get_one::(num.into())?.map(|s| s.withdrawals)) + return Ok(self + .cursor()? + .get_one::(num.into())? + .and_then(|s| s.withdrawals)) } // Only accepts block number queries Err(ProviderError::UnsupportedProvider)