Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 12 additions & 23 deletions crates/prune/prune/src/segments/static_file/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ use std::num::NonZeroUsize;
use tracing::trace;

/// Number of header tables to prune in one step
const HEADER_TABLES_TO_PRUNE: usize = 3;
/// Note: HeaderTerminalDifficulties is no longer pruned after Paris/Merge as it's read-only
const HEADER_TABLES_TO_PRUNE: usize = 2;

#[derive(Debug)]
pub struct Headers<N> {
Expand Down Expand Up @@ -64,11 +65,12 @@ impl<Provider: StaticFileProviderFactory + DBProvider<Tx: DbTxMut>> Segment<Prov
let range = last_pruned_block.map_or(0, |block| block + 1)..=block_range_end;

let mut headers_cursor = provider.tx_ref().cursor_write::<tables::Headers>()?;
let mut header_tds_cursor =
provider.tx_ref().cursor_write::<tables::HeaderTerminalDifficulties>()?;
let mut canonical_headers_cursor =
provider.tx_ref().cursor_write::<tables::CanonicalHeaders>()?;

// Note: We no longer prune HeaderTerminalDifficulties table after Paris/Merge
// as it's read-only and kept for backward compatibility

let mut limiter = input.limiter.floor_deleted_entries_limit_to_multiple_of(
NonZeroUsize::new(HEADER_TABLES_TO_PRUNE).unwrap(),
);
Expand All @@ -77,7 +79,6 @@ impl<Provider: StaticFileProviderFactory + DBProvider<Tx: DbTxMut>> Segment<Prov
provider,
&mut limiter,
headers_cursor.walk_range(range.clone())?,
header_tds_cursor.walk_range(range.clone())?,
canonical_headers_cursor.walk_range(range)?,
);

Expand All @@ -102,6 +103,7 @@ impl<Provider: StaticFileProviderFactory + DBProvider<Tx: DbTxMut>> Segment<Prov
})
}
}

type Walker<'a, Provider, T> =
RangeWalker<'a, T, <<Provider as DBProvider>::Tx as DbTxMut>::CursorMut<T>>;

Expand All @@ -113,7 +115,6 @@ where
provider: &'a Provider,
limiter: &'a mut PruneLimiter,
headers_walker: Walker<'a, Provider, tables::Headers>,
header_tds_walker: Walker<'a, Provider, tables::HeaderTerminalDifficulties>,
canonical_headers_walker: Walker<'a, Provider, tables::CanonicalHeaders>,
}

Expand All @@ -130,10 +131,9 @@ where
provider: &'a Provider,
limiter: &'a mut PruneLimiter,
headers_walker: Walker<'a, Provider, tables::Headers>,
header_tds_walker: Walker<'a, Provider, tables::HeaderTerminalDifficulties>,
canonical_headers_walker: Walker<'a, Provider, tables::CanonicalHeaders>,
) -> Self {
Self { provider, limiter, headers_walker, header_tds_walker, canonical_headers_walker }
Self { provider, limiter, headers_walker, canonical_headers_walker }
}
}

Expand All @@ -148,7 +148,6 @@ where
}

let mut pruned_block_headers = None;
let mut pruned_block_td = None;
let mut pruned_block_canonical = None;

if let Err(err) = self.provider.tx_ref().prune_table_with_range_step(
Expand All @@ -160,15 +159,6 @@ where
return Some(Err(err.into()))
}

if let Err(err) = self.provider.tx_ref().prune_table_with_range_step(
&mut self.header_tds_walker,
self.limiter,
&mut |_| false,
&mut |row| pruned_block_td = Some(row.0),
) {
return Some(Err(err.into()))
}

if let Err(err) = self.provider.tx_ref().prune_table_with_range_step(
&mut self.canonical_headers_walker,
self.limiter,
Expand All @@ -178,7 +168,7 @@ where
return Some(Err(err.into()))
}

if ![pruned_block_headers, pruned_block_td, pruned_block_canonical].iter().all_equal() {
if ![pruned_block_headers, pruned_block_canonical].iter().all_equal() {
return Some(Err(PrunerError::InconsistentData(
"All headers-related tables should be pruned up to the same height",
)))
Expand Down Expand Up @@ -227,7 +217,8 @@ mod tests {

assert_eq!(db.table::<tables::CanonicalHeaders>().unwrap().len(), headers.len());
assert_eq!(db.table::<tables::Headers>().unwrap().len(), headers.len());
assert_eq!(db.table::<tables::HeaderTerminalDifficulties>().unwrap().len(), headers.len());
// Note: HeaderTerminalDifficulties table is read-only in live database after Paris/Merge
// so we don't check its length as it's not being written to

let test_prune = |to_block: BlockNumber, expected_result: (PruneProgress, usize)| {
let segment = super::Headers::new(db.factory.static_file_provider());
Expand Down Expand Up @@ -291,10 +282,8 @@ mod tests {
db.table::<tables::Headers>().unwrap().len(),
headers.len() - (last_pruned_block_number + 1) as usize
);
assert_eq!(
db.table::<tables::HeaderTerminalDifficulties>().unwrap().len(),
headers.len() - (last_pruned_block_number + 1) as usize
);
// Note: HeaderTerminalDifficulties table is read-only in live database after
// Paris/Merge so we don't check its length as it's not being written to
assert_eq!(
db.factory.provider().unwrap().get_prune_checkpoint(PruneSegment::Headers).unwrap(),
Some(PruneCheckpoint {
Expand Down
5 changes: 2 additions & 3 deletions crates/stages/stages/src/stages/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,8 @@ where
(input.unwind_to + 1)..,
)?;
provider.tx_ref().unwind_table_by_num::<tables::CanonicalHeaders>(input.unwind_to)?;
provider
.tx_ref()
.unwind_table_by_num::<tables::HeaderTerminalDifficulties>(input.unwind_to)?;
// Note: We no longer prune HeaderTerminalDifficulties table after Paris/Merge
// as it's read-only and kept for backward compatibility
let unfinalized_headers_unwound =
provider.tx_ref().unwind_table_by_num::<tables::Headers>(input.unwind_to)?;

Expand Down
3 changes: 2 additions & 1 deletion crates/stages/stages/src/test_utils/test_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ impl TestStageDB {
writer.append_header(header.header(), td, &header.hash())?;
} else {
tx.put::<tables::CanonicalHeaders>(header.number, header.hash())?;
tx.put::<tables::HeaderTerminalDifficulties>(header.number, td.into())?;
// Note: HeaderTerminalDifficulties table is read-only in live database after
// Paris/Merge but still written to static files for historical data
tx.put::<tables::Headers>(header.number, header.header().clone())?;
}

Expand Down
7 changes: 6 additions & 1 deletion crates/storage/db-api/src/tables/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,12 @@ tables! {
type Value = HeaderHash;
}

/// Stores the total difficulty from a block header.
/// Stores the total difficulty from block headers.
///
/// Note: This table is no longer written to after the Paris/Merge transition
/// as total difficulty is no longer used for consensus. Read operations are
/// maintained for backward compatibility. Total difficulty values are still
/// written to static files for historical record.
table HeaderTerminalDifficulties {
type Key = BlockNumber;
type Value = CompactU256;
Expand Down
3 changes: 2 additions & 1 deletion crates/storage/provider/src/providers/database/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ struct DatabaseProviderMetrics {
insert_headers: Histogram,
/// Duration of insert header numbers
insert_header_numbers: Histogram,
/// Duration of insert header TD
/// Duration of insert header TD (deprecated after Paris/Merge)
#[deprecated(note = "No longer used after Paris/Merge")]
insert_header_td: Histogram,
/// Duration of insert block body indices
insert_block_body_indices: Histogram,
Expand Down
6 changes: 2 additions & 4 deletions crates/storage/provider/src/providers/database/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2842,9 +2842,6 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
// Put header with canonical hashes.
self.tx.put::<tables::Headers<HeaderTy<N>>>(block_number, block.header().clone())?;
durations_recorder.record_relative(metrics::Action::InsertHeaders);

self.tx.put::<tables::HeaderTerminalDifficulties>(block_number, ttd.into())?;
durations_recorder.record_relative(metrics::Action::InsertHeaderTerminalDifficulties);
}

if write_to.static_files() {
Expand Down Expand Up @@ -2983,7 +2980,8 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
// this table in `canonical_hashes_range`.
self.remove::<tables::CanonicalHeaders>(block + 1..)?;
self.remove::<tables::Headers<HeaderTy<N>>>(block + 1..)?;
self.remove::<tables::HeaderTerminalDifficulties>(block + 1..)?;
// Note: HeaderTerminalDifficulties table is read-only in the live database after
// Paris/Merge, so we do not remove entries from it here.

// First transaction to be removed
let unwind_tx_from = self
Expand Down
Loading