Skip to content

Commit 5dae42b

Browse files
rymncxgreenx
andauthored
chore(compression): merkleized registration table (#2959)
This pull request introduces a new `Registrations` table to the compression service, enabling the tracking and merkleization of registrations for compressed blocks. It includes updates to the database schema, error handling, and tests to support this new functionality. Below is a breakdown of the most important changes: ### Addition of `Registrations` Table * Introduced the `Registrations` table in the compression database, which maps block heights to registrations made for compressing those blocks. This table is merkleized for fault-proofing. (`.changes/added/2959.md`, `crates/services/compression/src/storage/registrations.rs`) [[1]](diffhunk://#diff-473ce0bca28d3684eac4b5a9548eef03dd51630a607890106e3bd85aa0da8101R1) [[2]](diffhunk://#diff-158a54491feb11d974d50f05aaef46446007139e3708e63befe0432312dbd189R1-R54) * Added a type alias `Registrations` for the merkleized `Registrations` table in `crates/services/compression/src/storage.rs`. ### Integration with Compression Service * Updated the `CompressionStorage` implementation to insert data into the `Registrations` table when the `fault-proving` feature is enabled. (`crates/services/compression/src/ports/compression_storage.rs`) * Added a new test to verify that the `Registrations` table is correctly populated and merkleized during compression. (`crates/services/compression/src/service.rs`) ### Error Handling Updates * Added a new `CompressionError` variant, `FailedToWriteRegistrations`, to handle errors related to writing to the `Registrations` table. (`crates/services/compression/src/errors.rs`) ### Schema and Column Updates * Added a new column, `Registrations`, to the `CompressionColumn` enum for tracking registrations per table. (`crates/services/compression/src/storage/column.rs`) * Enabled the `registrations` module in the storage system when the `fault-proving` feature is active. (`crates/services/compression/src/storage.rs`) --------- Co-authored-by: Green Baneling <[email protected]>
1 parent 2bd308b commit 5dae42b

File tree

7 files changed

+120
-2
lines changed

7 files changed

+120
-2
lines changed

.changes/added/2959.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add `Registrations` table to the compression database. This is merkleized.

crates/services/compression/src/errors.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ pub enum CompressionError {
1212
/// Failed to read compressed block from storage
1313
#[error("failed to write compressed block to storage: `{0}`")]
1414
FailedToWriteCompressedBlock(StorageError),
15+
/// Failed to write registrations to storage
16+
#[error("failed to write registrations to storage: `{0}`")]
17+
FailedToWriteRegistrations(StorageError),
1518
/// Failed to get the size of compressed block
1619
#[error("failed to get size of compressed block: `{0}`")]
1720
FailedToGetCompressedBlockSize(StorageError),

crates/services/compression/src/ports/compression_storage.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::{
22
errors::CompressionError,
3-
storage,
4-
storage::CompressedBlocks,
3+
storage::{
4+
self,
5+
CompressedBlocks,
6+
},
57
};
68
use fuel_core_storage::{
79
self,
@@ -65,6 +67,16 @@ where
6567
.insert(&height, compressed_block)
6668
.map_err(CompressionError::FailedToWriteCompressedBlock)?;
6769

70+
#[cfg(feature = "fault-proving")]
71+
self.storage_as_mut::<crate::storage::registrations::Registrations>()
72+
.insert(
73+
&height,
74+
fuel_core_compression::VersionedBlockPayload::registrations(
75+
compressed_block,
76+
),
77+
)
78+
.map_err(CompressionError::FailedToWriteRegistrations)?;
79+
6880
// this should not hit the db, we get it from the transaction
6981
let size = StorageSize::<CompressedBlocks>::size_of_value(self, &height)
7082
.map_err(CompressionError::FailedToGetCompressedBlockSize)?;

crates/services/compression/src/service.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,4 +763,43 @@ mod tests {
763763
assert!(maybe_block.is_some());
764764
service.shutdown().await.unwrap();
765765
}
766+
767+
#[cfg(feature = "fault-proving")]
768+
#[tokio::test]
769+
async fn compression_service__writes_to_registrations_table() {
770+
// given: we create the compression service
771+
let block_with_metadata = BlockWithMetadata::default();
772+
let block_source = MockBlockSource::new(vec![block_with_metadata]);
773+
let storage = test_storage();
774+
let config_provider = MockConfigProvider::default();
775+
let canonical_height_provider = MockCanonicalHeightProvider::default();
776+
777+
let uninit_service = UninitializedCompressionService::new(
778+
block_source,
779+
storage,
780+
config_provider.config(),
781+
canonical_height_provider,
782+
);
783+
let sync_observer = uninit_service.shared_data();
784+
785+
// when: the compression service is started
786+
let mut service = uninit_service
787+
.into_task(&Default::default(), ())
788+
.await
789+
.unwrap();
790+
let _ = service.run(&mut StateWatcher::started()).await;
791+
792+
// then: we ensure we can get the registrations per block + root of that table
793+
let target_block_height = 0;
794+
sync_observer
795+
.await_synced_until(&target_block_height)
796+
.await
797+
.unwrap();
798+
let maybe_registrations = service
799+
.storage
800+
.storage_as_ref::<storage::registrations::Registrations>()
801+
.get(&target_block_height.into())
802+
.unwrap();
803+
assert!(maybe_registrations.is_some());
804+
}
766805
}

crates/services/compression/src/storage.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ pub mod predicate_code;
2020
pub mod registry_index;
2121
pub mod script_code;
2222
// TODO: https://github.com/FuelLabs/fuel-core/issues/2842
23+
#[cfg(feature = "fault-proving")]
24+
pub mod registrations;
2325
pub mod timestamps;
2426

2527
/// Merkleized Address table type alias
@@ -48,3 +50,7 @@ pub type Timestamps = Merkleized<timestamps::Timestamps>;
4850

4951
/// Re-export to match api
5052
pub use compressed_blocks::CompressedBlocks;
53+
54+
/// Merkleized Registrations table type alias
55+
#[cfg(feature = "fault-proving")]
56+
pub type Registrations = Merkleized<registrations::Registrations>;

crates/services/compression/src/storage/column.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ pub enum CompressionColumn {
4040
EvictorCache = 7,
4141
/// Keeps track of timestamps, will be removed eventually, see [`Timestamps`](crate::storage::timestamps::Timestamps)
4242
Timestamps = 8,
43+
#[cfg(feature = "fault-proving")]
44+
/// Keeps track of registrations per table associated with a compressed block, see [`Registrations`](crate::storage::registrations::Registrations)
45+
Registrations = 9,
4346
}
4447

4548
impl AsU32 for CompressionColumn {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//! Registrations table.
2+
//! Maps from block height -> registrations made for compressing that block
3+
4+
use fuel_core_storage::{
5+
Mappable,
6+
blueprint::plain::Plain,
7+
codec::postcard::Postcard,
8+
merkle::sparse::MerkleizedTableColumn,
9+
structured_storage::TableWithBlueprint,
10+
};
11+
12+
use super::column::{
13+
CompressionColumn,
14+
MerkleizedColumnOf,
15+
};
16+
17+
/// Table that indexes the registrations.
18+
pub struct Registrations;
19+
20+
impl MerkleizedTableColumn for Registrations {
21+
type TableColumn = CompressionColumn;
22+
23+
fn table_column() -> Self::TableColumn {
24+
Self::TableColumn::Registrations
25+
}
26+
}
27+
28+
impl Mappable for Registrations {
29+
type Key = Self::OwnedKey;
30+
type OwnedKey = fuel_core_types::fuel_types::BlockHeight;
31+
type Value = Self::OwnedValue;
32+
type OwnedValue = fuel_core_compression::registry::RegistrationsPerTable;
33+
}
34+
35+
impl TableWithBlueprint for Registrations {
36+
type Blueprint = Plain<Postcard, Postcard>;
37+
type Column = MerkleizedColumnOf<Self>;
38+
39+
fn column() -> Self::Column {
40+
Self::Column::TableColumn(Self::table_column())
41+
}
42+
}
43+
44+
#[cfg(test)]
45+
mod tests {
46+
use super::*;
47+
48+
fuel_core_storage::basic_storage_tests!(
49+
Registrations,
50+
<Registrations as Mappable>::Key::default(),
51+
<Registrations as Mappable>::Value::default(),
52+
<Registrations as Mappable>::Value::default()
53+
);
54+
}

0 commit comments

Comments
 (0)