diff --git a/Cargo.lock b/Cargo.lock index 9dd90e6a94..81dd826995 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3579,9 +3579,11 @@ name = "fuel-core-compression" version = "0.41.0" dependencies = [ "anyhow", + "derive_more 0.99.18", "enum_dispatch", "fuel-core-compression", "fuel-core-types 0.41.0", + "fuel-crypto 0.59.1", "paste", "postcard", "proptest", diff --git a/crates/compression/Cargo.toml b/crates/compression/Cargo.toml index c47b24e941..8065e9f3f6 100644 --- a/crates/compression/Cargo.toml +++ b/crates/compression/Cargo.toml @@ -18,12 +18,14 @@ description = "Compression and decompression of Fuel blocks for DA storage." [dependencies] anyhow = { workspace = true } +derive_more = { workspace = true, optional = true } enum_dispatch = "0.3.13" fuel-core-types = { workspace = true, features = [ "alloc", "serde", "da-compression", ] } +fuel-crypto = { version = "0.59.1", optional = true } paste = { workspace = true } rand = { workspace = true, optional = true } serde = { version = "1.0", features = ["derive"] } @@ -43,4 +45,4 @@ test-helpers = [ "fuel-core-types/random", "fuel-core-types/std", ] -fault-proving = [] +fault-proving = ["dep:derive_more", "dep:fuel-crypto"] diff --git a/crates/compression/src/compressed_block_payload/mod.rs b/crates/compression/src/compressed_block_payload/mod.rs index eeebe11bfb..aff00c9ffc 100644 --- a/crates/compression/src/compressed_block_payload/mod.rs +++ b/crates/compression/src/compressed_block_payload/mod.rs @@ -1,3 +1,4 @@ pub mod v0; +#[cfg(feature = "fault-proving")] pub mod v1; diff --git a/crates/compression/src/compressed_block_payload/v1.rs b/crates/compression/src/compressed_block_payload/v1.rs index 51e0012a61..363286830b 100644 --- a/crates/compression/src/compressed_block_payload/v1.rs +++ b/crates/compression/src/compressed_block_payload/v1.rs @@ -1,5 +1,8 @@ use crate::{ - registry::RegistrationsPerTable, + registry::{ + RegistrationsPerTable, + RegistryId, + }, VersionedBlockPayload, }; use fuel_core_types::{ @@ -31,10 +34,15 @@ pub struct CompressedBlockHeader { pub consensus: ConsensusHeader, // The block id. pub block_id: BlockId, + // The registry id. + pub registry_id: RegistryId, } -impl From<&BlockHeader> for CompressedBlockHeader { - fn from(header: &BlockHeader) -> Self { +impl CompressedBlockHeader { + fn from_header_and_registry( + header: &BlockHeader, + registry: &RegistrationsPerTable, + ) -> Self { let ConsensusHeader { prev_root, height, @@ -56,6 +64,7 @@ impl From<&BlockHeader> for CompressedBlockHeader { generated: Empty {}, }, block_id: header.id(), + registry_id: registry.id(), } } } @@ -114,7 +123,10 @@ impl CompressedBlockPayloadV1 { transactions: Vec, ) -> Self { Self { - header: CompressedBlockHeader::from(header), + header: CompressedBlockHeader::from_header_and_registry( + header, + ®istrations, + ), registrations, transactions, } diff --git a/crates/compression/src/lib.rs b/crates/compression/src/lib.rs index 681a466e12..61a87ebbce 100644 --- a/crates/compression/src/lib.rs +++ b/crates/compression/src/lib.rs @@ -274,6 +274,7 @@ mod tests { generated: Empty, }, block_id: BlockId::from_str("0xecea85c17070bc2e65f911310dbd01198f4436052ebba96cded9ddf30c58dd1a").unwrap(), + registry_id: registrations.id(), }; @@ -302,6 +303,7 @@ mod tests { if let VersionedCompressedBlock::V1(block) = decompressed { assert_eq!(block.header.block_id, header.block_id); + assert_eq!(block.header.registry_id, header.registry_id); } else { panic!("Expected V1 block, got {:?}", decompressed); } diff --git a/crates/compression/src/registry.rs b/crates/compression/src/registry.rs index 1fd20365d1..116ecc8c91 100644 --- a/crates/compression/src/registry.rs +++ b/crates/compression/src/registry.rs @@ -14,6 +14,47 @@ use fuel_core_types::{ tai64::Tai64, }; +#[cfg(feature = "fault-proving")] +use derive_more::{ + AsRef, + Display, + From, + FromStr, + Into, + LowerHex, + UpperHex, +}; +#[cfg(feature = "fault-proving")] +use fuel_core_types::fuel_tx::Bytes32; + +#[cfg(feature = "fault-proving")] +#[cfg_attr( + feature = "fault-proving", + derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Default, + FromStr, + From, + Into, + LowerHex, + UpperHex, + Display, + AsRef, + serde::Deserialize, + serde::Serialize, + ) +)] +#[cfg_attr(feature = "fault-proving", serde(transparent))] +#[cfg_attr(feature = "fault-proving", repr(transparent))] +pub struct RegistryId(Bytes32); + macro_rules! tables { ($($ident:ty: $type:ty),*) => { paste::paste! { #[doc = "RegistryKey namespaces"] @@ -90,10 +131,25 @@ macro_rules! tables { Ok(()) } + + #[cfg(feature = "fault-proving")] + pub fn id(&self) -> RegistryId { + let mut hasher = fuel_crypto::Hasher::default(); + + $( + for (key, value) in self.$ident.iter() { + hasher.input(key); + hasher.input(value); + } + )* + + RegistryId(hasher.digest()) + } } }}; } +// Don't change the order of these, it will affect the order of hashing tables!( address: Address, asset_id: AssetId,