diff --git a/zebra-chain/src/block.rs b/zebra-chain/src/block.rs index 15ee3c202..e2058fc46 100644 --- a/zebra-chain/src/block.rs +++ b/zebra-chain/src/block.rs @@ -145,6 +145,8 @@ impl ZcashSerialize for BlockHeader { self.previous_block_hash.zcash_serialize(&mut writer)?; writer.write_all(&self.merkle_root_hash.0[..])?; writer.write_all(&self.final_sapling_root_hash.0[..])?; + // this is a truncating cast, rather than a saturating cast + // but u32 times are valid until 2106 writer.write_u32::(self.time.timestamp() as u32)?; writer.write_u32::(self.bits)?; writer.write_all(&self.nonce[..])?; @@ -190,6 +192,7 @@ impl ZcashDeserialize for BlockHeader { previous_block_hash: BlockHeaderHash::zcash_deserialize(&mut reader)?, merkle_root_hash: MerkleTreeRootHash(reader.read_32_bytes()?), final_sapling_root_hash: SaplingNoteTreeRootHash(reader.read_32_bytes()?), + // This can't panic, because all u32 values are valid `Utc.timestamp`s time: Utc.timestamp(reader.read_u32::()? as i64, 0), bits: reader.read_u32::()?, nonce: reader.read_32_bytes()?, diff --git a/zebra-chain/src/block/tests.rs b/zebra-chain/src/block/tests.rs index 7c633b9f1..98c2fd776 100644 --- a/zebra-chain/src/block/tests.rs +++ b/zebra-chain/src/block/tests.rs @@ -16,11 +16,13 @@ impl Arbitrary for BlockHeader { fn arbitrary_with(_args: ()) -> Self::Strategy { ( - (4u32..2_147_483_647u32), + // version is interpreted as i32 in the spec, so we are limited to i32::MAX here + (4u32..(i32::MAX as u32)), any::(), any::(), any::(), - (0i64..4_294_967_296i64), + // time is interpreted as u32 in the spec, but rust timestamps are i64 + (0i64..(u32::MAX as i64)), any::(), any::<[u8; 32]>(), any::(),