diff --git a/consensus-engine/src/types.rs b/consensus-engine/src/types.rs index d165ef32..698c2c95 100644 --- a/consensus-engine/src/types.rs +++ b/consensus-engine/src/types.rs @@ -103,7 +103,6 @@ impl TimeoutQc { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct Block { - #[cfg_attr(feature = "serde", serde(skip))] pub id: BlockId, pub view: View, pub parent_qc: Qc, diff --git a/nomos-core/src/block/mod.rs b/nomos-core/src/block/mod.rs index f8f8f92a..b88a70e4 100644 --- a/nomos-core/src/block/mod.rs +++ b/nomos-core/src/block/mod.rs @@ -6,17 +6,19 @@ use indexmap::IndexSet; use core::hash::Hash; // crates use crate::wire; +use ::serde::{ + de::{DeserializeOwned, Deserializer}, + Deserialize, Serialize, Serializer, +}; use bytes::Bytes; pub use consensus_engine::BlockId; use consensus_engine::{LeaderProof, NodeId, Qc, View}; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; // internal pub type TxHash = [u8; 32]; /// A block -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug)] pub struct Block { header: consensus_engine::Block, beacon: RandomBeaconState, @@ -107,3 +109,82 @@ impl< result } } + +mod serde { + use super::*; + // use ::serde::{de::Deserializer, Deserialize, Serialize}; + + /// consensus_engine::Block but without the id field, which will be computed + /// from the rest of the block. + #[derive(Serialize, Deserialize)] + struct StrippedHeader { + pub view: View, + pub parent_qc: Qc, + pub leader_proof: LeaderProof, + } + + #[derive(Serialize, Deserialize)] + struct StrippedBlock { + header: StrippedHeader, + beacon: RandomBeaconState, + cl_transactions: IndexSet, + bl_blobs: IndexSet, + } + + impl< + 'de, + Tx: Clone + Eq + Hash + Serialize + DeserializeOwned, + BlobCertificate: Clone + Eq + Hash + Serialize + DeserializeOwned, + > Deserialize<'de> for Block + { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let StrippedBlock { + header, + beacon, + cl_transactions, + bl_blobs, + } = StrippedBlock::deserialize(deserializer)?; + let header = consensus_engine::Block { + id: BlockId::zeros(), + view: header.view, + parent_qc: header.parent_qc, + leader_proof: header.leader_proof, + }; + let mut block = Block { + beacon, + cl_transactions, + bl_blobs, + header, + }; + block.header.id = block_id_from_wire_content(&block); + Ok(block) + } + } + + impl< + Tx: Clone + Eq + Hash + Serialize + DeserializeOwned, + BlobCertificate: Clone + Eq + Hash + Serialize + DeserializeOwned, + > Serialize for Block + { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + // TODO: zero copy serialization + let block = StrippedBlock { + header: StrippedHeader { + view: self.header.view, + parent_qc: self.header.parent_qc.clone(), + leader_proof: self.header.leader_proof.clone(), + }, + beacon: self.beacon.clone(), + cl_transactions: self.cl_transactions.clone(), + bl_blobs: self.bl_blobs.clone(), + }; + block.serialize(serializer) + } + } +} diff --git a/nomos-services/consensus/src/lib.rs b/nomos-services/consensus/src/lib.rs index c2d08be6..a0925bdb 100644 --- a/nomos-services/consensus/src/lib.rs +++ b/nomos-services/consensus/src/lib.rs @@ -1160,7 +1160,7 @@ mod tests { eprintln!("{serialized}"); assert_eq!( serialized, - r#"{"id":"0x0000000000000000000000000000000000000000000000000000000000000000","current_view":1,"highest_voted_view":-1,"local_high_qc":{"view":0,"id":"0x0000000000000000000000000000000000000000000000000000000000000000"},"safe_blocks":[["0x0000000000000000000000000000000000000000000000000000000000000000",{"view":0,"parent_qc":{"Standard":{"view":0,"id":"0x0000000000000000000000000000000000000000000000000000000000000000"}},"leader_proof":{"LeaderId":{"leader_id":"0x0000000000000000000000000000000000000000000000000000000000000000"}}}]],"last_view_timeout_qc":null,"committed_blocks":["0x0000000000000000000000000000000000000000000000000000000000000000"]}"# + r#"{"id":"0x0000000000000000000000000000000000000000000000000000000000000000","current_view":1,"highest_voted_view":-1,"local_high_qc":{"view":0,"id":"0x0000000000000000000000000000000000000000000000000000000000000000"},"safe_blocks":[["0x0000000000000000000000000000000000000000000000000000000000000000",{"id":"0x0000000000000000000000000000000000000000000000000000000000000000","view":0,"parent_qc":{"Standard":{"view":0,"id":"0x0000000000000000000000000000000000000000000000000000000000000000"}},"leader_proof":{"LeaderId":{"leader_id":"0x0000000000000000000000000000000000000000000000000000000000000000"}}}]],"last_view_timeout_qc":null,"committed_blocks":["0x0000000000000000000000000000000000000000000000000000000000000000"]}"# ); let deserialized: CarnotInfo = serde_json::from_str(&serialized).unwrap();