chain: Tweak the version and time test bounds

Use MAX constants for the block header version and time arbitrary test
ranges. Reduces the block header time arbitrary test range from 2**32 to
2**32-1 (u32::MAX). (2**32 is an invalid time value, which gets
truncated to 0 during serialization.)

Also add some comments about DateTime conversions.

Part of #477.
This commit is contained in:
teor 2020-06-17 21:10:02 +10:00
parent 3c27c11012
commit 3f5e2695e3
2 changed files with 7 additions and 2 deletions

View File

@ -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::<LittleEndian>(self.time.timestamp() as u32)?;
writer.write_u32::<LittleEndian>(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::<LittleEndian>()? as i64, 0),
bits: reader.read_u32::<LittleEndian>()?,
nonce: reader.read_32_bytes()?,

View File

@ -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::<BlockHeaderHash>(),
any::<MerkleTreeRootHash>(),
any::<SaplingNoteTreeRootHash>(),
(0i64..4_294_967_296i64),
// time is interpreted as u32 in the spec, but rust timestamps are i64
(0i64..(u32::MAX as i64)),
any::<u32>(),
any::<[u8; 32]>(),
any::<EquihashSolution>(),