Do not skip Block::id during ser/de (#505)
Block.id is a necessary piece of information in the context of the consensus engine since there it's not possible to recover the id of the block since the contents are not available. Instead, we should only skip that field when serializing/deserializing a full block.
This commit is contained in:
parent
e8310e3ea8
commit
350620b829
@ -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,
|
||||
|
@ -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<Tx: Clone + Eq + Hash, BlobCertificate: Clone + Eq + Hash> {
|
||||
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<Tx: Clone + Eq + Hash, BlobCertificate: Clone + Eq + Hash> {
|
||||
header: StrippedHeader,
|
||||
beacon: RandomBeaconState,
|
||||
cl_transactions: IndexSet<Tx>,
|
||||
bl_blobs: IndexSet<BlobCertificate>,
|
||||
}
|
||||
|
||||
impl<
|
||||
'de,
|
||||
Tx: Clone + Eq + Hash + Serialize + DeserializeOwned,
|
||||
BlobCertificate: Clone + Eq + Hash + Serialize + DeserializeOwned,
|
||||
> Deserialize<'de> for Block<Tx, BlobCertificate>
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
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<Tx, BlobCertificate>
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user