/ ledger / block / src / serialize.rs
serialize.rs
  1  // Copyright (c) 2019-2025 Alpha-Delta Network Inc.
  2  // This file is part of the deltavm library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  use super::*;
 17  
 18  impl<N: Network> Serialize for Block<N> {
 19      /// Serializes the block to a JSON-string or buffer.
 20      fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
 21          match serializer.is_human_readable() {
 22              true => {
 23                  let mut block = serializer.serialize_struct("Block", 9)?;
 24                  block.serialize_field("block_hash", &self.block_hash)?;
 25                  block.serialize_field("previous_hash", &self.previous_hash)?;
 26                  block.serialize_field("header", &self.header)?;
 27                  block.serialize_field("authority", &self.authority)?;
 28                  block.serialize_field("ratifications", &self.ratifications)?;
 29                  block.serialize_field("solutions", &self.solutions)?;
 30                  block.serialize_field("aborted_solution_ids", &self.aborted_solution_ids)?;
 31                  block.serialize_field("transactions", &self.transactions)?;
 32                  block.serialize_field("aborted_transaction_ids", &self.aborted_transaction_ids)?;
 33                  block.end()
 34              }
 35              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
 36          }
 37      }
 38  }
 39  
 40  impl<'de, N: Network> Deserialize<'de> for Block<N> {
 41      /// Deserializes the block from a JSON-string or buffer.
 42      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
 43          if deserializer.is_human_readable() {
 44              let mut block = serde_json::Value::deserialize(deserializer)?;
 45              let block_hash: N::BlockHash = DeserializeExt::take_from_value::<D>(&mut block, "block_hash")?;
 46  
 47              // Recover the block.
 48              let block = Self::from(
 49                  DeserializeExt::take_from_value::<D>(&mut block, "previous_hash")?,
 50                  DeserializeExt::take_from_value::<D>(&mut block, "header")?,
 51                  DeserializeExt::take_from_value::<D>(&mut block, "authority")?,
 52                  DeserializeExt::take_from_value::<D>(&mut block, "ratifications")?,
 53                  DeserializeExt::take_from_value::<D>(&mut block, "solutions")?,
 54                  DeserializeExt::take_from_value::<D>(&mut block, "aborted_solution_ids")?,
 55                  DeserializeExt::take_from_value::<D>(&mut block, "transactions")?,
 56                  DeserializeExt::take_from_value::<D>(&mut block, "aborted_transaction_ids")?,
 57              )
 58              .map_err(de::Error::custom)?;
 59  
 60              // Ensure the block hash matches.
 61              match block_hash == block.hash() {
 62                  true => Ok(block),
 63                  false => Err(de::Error::custom(error("Mismatching block hash, possible data corruption"))),
 64              }
 65          } else {
 66              FromBytesUncheckedDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "block")
 67          }
 68      }
 69  }
 70  
 71  #[cfg(test)]
 72  mod tests {
 73      use super::*;
 74      use console::network::MainnetV0;
 75  
 76      type CurrentNetwork = MainnetV0;
 77  
 78      #[test]
 79      fn test_serde_json() -> Result<()> {
 80          let rng = &mut TestRng::default();
 81  
 82          for expected in [crate::test_helpers::sample_genesis_block(rng)].into_iter() {
 83              // Serialize
 84              let expected_string = &expected.to_string();
 85              let candidate_string = serde_json::to_string(&expected)?;
 86  
 87              // Deserialize
 88              assert_eq!(expected, Block::from_str(expected_string)?);
 89              assert_eq!(expected, serde_json::from_str(&candidate_string)?);
 90          }
 91          Ok(())
 92      }
 93  
 94      #[test]
 95      fn test_bincode() -> Result<()> {
 96          let rng = &mut TestRng::default();
 97  
 98          for expected in [crate::test_helpers::sample_genesis_block(rng)].into_iter() {
 99              // Serialize
100              let expected_bytes = expected.to_bytes_le()?;
101              let expected_bytes_with_size_encoding = bincode::serialize(&expected)?;
102              assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]);
103  
104              // Deserialize
105              assert_eq!(expected, Block::read_le(&expected_bytes[..])?);
106              assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..])?);
107          }
108          Ok(())
109      }
110  
111      #[test]
112      fn test_genesis_serde_json() -> Result<()> {
113          // Load the genesis block.
114          let genesis_block = Block::<CurrentNetwork>::read_le(CurrentNetwork::genesis_bytes()).unwrap();
115  
116          // Serialize
117          let expected_string = &genesis_block.to_string();
118          let candidate_string = serde_json::to_string(&genesis_block)?;
119  
120          // Deserialize
121          assert_eq!(genesis_block, Block::from_str(expected_string)?);
122          assert_eq!(genesis_block, serde_json::from_str(&candidate_string)?);
123  
124          Ok(())
125      }
126  
127      #[test]
128      fn test_genesis_bincode() -> Result<()> {
129          // Load the genesis block.
130          let genesis_block = Block::<CurrentNetwork>::read_le(CurrentNetwork::genesis_bytes()).unwrap();
131  
132          // Serialize
133          let expected_bytes = genesis_block.to_bytes_le()?;
134          let expected_bytes_with_size_encoding = bincode::serialize(&genesis_block)?;
135          assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]);
136  
137          // Deserialize
138          assert_eq!(genesis_block, Block::read_le(&expected_bytes[..])?);
139          assert_eq!(genesis_block, bincode::deserialize(&expected_bytes_with_size_encoding[..])?);
140  
141          Ok(())
142      }
143  }