diff --git a/zebra-chain/src/block.rs b/zebra-chain/src/block.rs index 543d43de..d689d966 100644 --- a/zebra-chain/src/block.rs +++ b/zebra-chain/src/block.rs @@ -1,4 +1,4 @@ -//! Definitions of block datastructures. +//! Blocks and block-related structures (heights, headers, etc.) // block::block is done on purpose and is the most representative name #![allow(clippy::module_inception)] @@ -7,7 +7,7 @@ mod block; mod hash; mod header; mod height; -mod light_client; +mod root_hash; mod serialize; #[cfg(test)] @@ -17,7 +17,7 @@ pub use block::Block; pub use hash::BlockHeaderHash; pub use header::BlockHeader; pub use height::BlockHeight; -pub use light_client::LightClientRootHash; +pub use root_hash::RootHash; /// The error type for Block checks. // XXX try to remove this -- block checks should be done in zebra-consensus diff --git a/zebra-chain/src/block/block.rs b/zebra-chain/src/block/block.rs index 4b672f4e..89a077b8 100644 --- a/zebra-chain/src/block/block.rs +++ b/zebra-chain/src/block/block.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use crate::parameters::Network; use crate::transaction::Transaction; -use super::{BlockHeader, BlockHeaderHash, BlockHeight, Error, LightClientRootHash}; +use super::{BlockHeader, BlockHeaderHash, BlockHeight, Error, RootHash}; #[cfg(test)] use proptest_derive::Arbitrary; @@ -66,16 +66,16 @@ impl Block { BlockHeaderHash::from(self) } - /// Get the parsed light client root hash for this block. + /// Get the parsed root hash for this block. /// - /// The interpretation of the light client root hash depends on the + /// The interpretation of the root hash depends on the /// configured `network`, and this block's height. /// /// Returns None if this block does not have a block height. - pub fn light_client_root_hash(&self, network: Network) -> Option { + pub fn root_hash(&self, network: Network) -> Option { match self.coinbase_height() { - Some(height) => Some(LightClientRootHash::from_bytes( - self.header.light_client_root_bytes, + Some(height) => Some(RootHash::from_bytes( + self.header.root_bytes, network, height, )), diff --git a/zebra-chain/src/block/header.rs b/zebra-chain/src/block/header.rs index 9e1adc93..a998299e 100644 --- a/zebra-chain/src/block/header.rs +++ b/zebra-chain/src/block/header.rs @@ -36,14 +36,13 @@ pub struct BlockHeader { /// header. pub merkle_root_hash: MerkleTreeRootHash, - /// The light client root hash. + /// Some kind of root hash. /// /// Unfortunately, the interpretation of this field was changed without /// incrementing the version, so it cannot be parsed without the block height - /// and network. Use - /// [`Block::light_client_root_hash`](super::Block::light_client_root_hash) - /// to get the parsed [`LightClientRootHash`](super::LightClientRootHash). - pub light_client_root_bytes: [u8; 32], + /// and network. Use [`Block::root_hash`](super::Block::root_hash) to get the + /// parsed [`RootHash`](super::RootHash). + pub root_bytes: [u8; 32], /// The block timestamp is a Unix epoch time (UTC) when the miner /// started hashing the header (according to the miner). diff --git a/zebra-chain/src/block/light_client.rs b/zebra-chain/src/block/root_hash.rs similarity index 88% rename from zebra-chain/src/block/light_client.rs rename to zebra-chain/src/block/root_hash.rs index 73f14354..37511ac8 100644 --- a/zebra-chain/src/block/light_client.rs +++ b/zebra-chain/src/block/root_hash.rs @@ -5,13 +5,13 @@ use crate::treestate::note_commitment_tree::SaplingNoteTreeRootHash; use super::BlockHeight; -/// Light client root hashes. +/// Zcash blocks contain different kinds of root hashes, depending on the network upgrade. /// -/// The `BlockHeader.light_client_root_bytes` field is interpreted differently, +/// The `BlockHeader.root_bytes` field is interpreted differently, /// based on the current block height. The interpretation changes at or after /// network upgrades. #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub enum LightClientRootHash { +pub enum RootHash { /// [Pre-Sapling] Reserved field. /// /// All zeroes. @@ -43,15 +43,11 @@ pub enum LightClientRootHash { ChainHistoryRoot(ChainHistoryMmrRootHash), } -impl LightClientRootHash { +impl RootHash { /// Returns `bytes` as the LightClientRootHash variant for `network` and /// `height`. - pub(super) fn from_bytes( - bytes: [u8; 32], - network: Network, - height: BlockHeight, - ) -> LightClientRootHash { - use LightClientRootHash::*; + pub(super) fn from_bytes(bytes: [u8; 32], network: Network, height: BlockHeight) -> RootHash { + use RootHash::*; match NetworkUpgrade::current(network, height) { Genesis | BeforeOverwinter | Overwinter => PreSaplingReserved(bytes), @@ -66,7 +62,7 @@ impl LightClientRootHash { /// Returns the serialized bytes for this LightClientRootHash. #[allow(dead_code)] pub(super) fn to_bytes(self) -> [u8; 32] { - use LightClientRootHash::*; + use RootHash::*; match self { PreSaplingReserved(b) => b, diff --git a/zebra-chain/src/block/serialize.rs b/zebra-chain/src/block/serialize.rs index 471c9fab..4076df91 100644 --- a/zebra-chain/src/block/serialize.rs +++ b/zebra-chain/src/block/serialize.rs @@ -24,7 +24,7 @@ impl ZcashSerialize for BlockHeader { writer.write_u32::(self.version)?; self.previous_block_hash.zcash_serialize(&mut writer)?; writer.write_all(&self.merkle_root_hash.0[..])?; - writer.write_all(&self.light_client_root_bytes[..])?; + writer.write_all(&self.root_bytes[..])?; // this is a truncating cast, rather than a saturating cast // but u32 times are valid until 2106, and our block verification time // checks should detect any truncation. @@ -72,7 +72,7 @@ impl ZcashDeserialize for BlockHeader { version, previous_block_hash: BlockHeaderHash::zcash_deserialize(&mut reader)?, merkle_root_hash: MerkleTreeRootHash(reader.read_32_bytes()?), - light_client_root_bytes: reader.read_32_bytes()?, + root_bytes: 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), difficulty_threshold: CompactDifficulty(reader.read_u32::()?), diff --git a/zebra-chain/src/block/tests/arbitrary.rs b/zebra-chain/src/block/tests/arbitrary.rs index 992355e7..73abc0e7 100644 --- a/zebra-chain/src/block/tests/arbitrary.rs +++ b/zebra-chain/src/block/tests/arbitrary.rs @@ -10,13 +10,13 @@ use proptest::{ prelude::*, }; -impl Arbitrary for LightClientRootHash { +impl Arbitrary for RootHash { type Parameters = (); fn arbitrary_with(_args: ()) -> Self::Strategy { (any::<[u8; 32]>(), any::(), any::()) - .prop_map(|(light_client_root_bytes, network, block_height)| { - LightClientRootHash::from_bytes(light_client_root_bytes, network, block_height) + .prop_map(|(root_bytes, network, block_height)| { + RootHash::from_bytes(root_bytes, network, block_height) }) .boxed() } @@ -45,7 +45,7 @@ impl Arbitrary for BlockHeader { version, previous_block_hash, merkle_root_hash, - light_client_root_bytes, + root_bytes, timestamp, difficulty_threshold, nonce, @@ -54,7 +54,7 @@ impl Arbitrary for BlockHeader { version, previous_block_hash, merkle_root_hash, - light_client_root_bytes, + root_bytes, time: Utc.timestamp(timestamp, 0), difficulty_threshold, nonce, diff --git a/zebra-chain/src/block/tests/prop.rs b/zebra-chain/src/block/tests/prop.rs index aba04068..93edf9ab 100644 --- a/zebra-chain/src/block/tests/prop.rs +++ b/zebra-chain/src/block/tests/prop.rs @@ -26,9 +26,9 @@ proptest! { } #[test] - fn light_client_roundtrip(bytes in any::<[u8; 32]>(), network in any::(), block_height in any::()) { - let light_hash = LightClientRootHash::from_bytes(bytes, network, block_height); - let other_bytes = light_hash.to_bytes(); + fn root_hash_roundtrip(bytes in any::<[u8; 32]>(), network in any::(), block_height in any::()) { + let root_hash = RootHash::from_bytes(bytes, network, block_height); + let other_bytes = root_hash.to_bytes(); prop_assert_eq![bytes, other_bytes]; } @@ -47,11 +47,11 @@ proptest! { let bytes = block.zcash_serialize_to_vec()?; let bytes = &mut bytes.as_slice(); - // Check the light client root hash - let light_hash = block.light_client_root_hash(network); - if let Some(light_hash) = light_hash { - let light_hash_bytes = light_hash.to_bytes(); - prop_assert_eq![block.header.light_client_root_bytes, light_hash_bytes]; + // Check the root hash + let root_hash = block.root_hash(network); + if let Some(root_hash) = root_hash { + let root_hash_bytes = root_hash.to_bytes(); + prop_assert_eq![block.header.root_bytes, root_hash_bytes]; } else { prop_assert_eq![block.coinbase_height(), None]; }