chain: rename LightClientRootHash to RootHash

It's not accurate to call it a LightClientRootHash, because it's not
always a root has for a light client -- sometimes it's a different kind
of root hash.
This commit is contained in:
Henry de Valence 2020-08-15 16:12:26 -07:00
parent b296d1e2a3
commit 196e841cd9
7 changed files with 35 additions and 40 deletions

View File

@ -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 // block::block is done on purpose and is the most representative name
#![allow(clippy::module_inception)] #![allow(clippy::module_inception)]
@ -7,7 +7,7 @@ mod block;
mod hash; mod hash;
mod header; mod header;
mod height; mod height;
mod light_client; mod root_hash;
mod serialize; mod serialize;
#[cfg(test)] #[cfg(test)]
@ -17,7 +17,7 @@ pub use block::Block;
pub use hash::BlockHeaderHash; pub use hash::BlockHeaderHash;
pub use header::BlockHeader; pub use header::BlockHeader;
pub use height::BlockHeight; pub use height::BlockHeight;
pub use light_client::LightClientRootHash; pub use root_hash::RootHash;
/// The error type for Block checks. /// The error type for Block checks.
// XXX try to remove this -- block checks should be done in zebra-consensus // XXX try to remove this -- block checks should be done in zebra-consensus

View File

@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use crate::parameters::Network; use crate::parameters::Network;
use crate::transaction::Transaction; use crate::transaction::Transaction;
use super::{BlockHeader, BlockHeaderHash, BlockHeight, Error, LightClientRootHash}; use super::{BlockHeader, BlockHeaderHash, BlockHeight, Error, RootHash};
#[cfg(test)] #[cfg(test)]
use proptest_derive::Arbitrary; use proptest_derive::Arbitrary;
@ -66,16 +66,16 @@ impl Block {
BlockHeaderHash::from(self) 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. /// configured `network`, and this block's height.
/// ///
/// Returns None if this block does not have a block height. /// Returns None if this block does not have a block height.
pub fn light_client_root_hash(&self, network: Network) -> Option<LightClientRootHash> { pub fn root_hash(&self, network: Network) -> Option<RootHash> {
match self.coinbase_height() { match self.coinbase_height() {
Some(height) => Some(LightClientRootHash::from_bytes( Some(height) => Some(RootHash::from_bytes(
self.header.light_client_root_bytes, self.header.root_bytes,
network, network,
height, height,
)), )),

View File

@ -36,14 +36,13 @@ pub struct BlockHeader {
/// header. /// header.
pub merkle_root_hash: MerkleTreeRootHash, pub merkle_root_hash: MerkleTreeRootHash,
/// The light client root hash. /// Some kind of root hash.
/// ///
/// Unfortunately, the interpretation of this field was changed without /// Unfortunately, the interpretation of this field was changed without
/// incrementing the version, so it cannot be parsed without the block height /// incrementing the version, so it cannot be parsed without the block height
/// and network. Use /// and network. Use [`Block::root_hash`](super::Block::root_hash) to get the
/// [`Block::light_client_root_hash`](super::Block::light_client_root_hash) /// parsed [`RootHash`](super::RootHash).
/// to get the parsed [`LightClientRootHash`](super::LightClientRootHash). pub root_bytes: [u8; 32],
pub light_client_root_bytes: [u8; 32],
/// The block timestamp is a Unix epoch time (UTC) when the miner /// The block timestamp is a Unix epoch time (UTC) when the miner
/// started hashing the header (according to the miner). /// started hashing the header (according to the miner).

View File

@ -5,13 +5,13 @@ use crate::treestate::note_commitment_tree::SaplingNoteTreeRootHash;
use super::BlockHeight; 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 /// based on the current block height. The interpretation changes at or after
/// network upgrades. /// network upgrades.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum LightClientRootHash { pub enum RootHash {
/// [Pre-Sapling] Reserved field. /// [Pre-Sapling] Reserved field.
/// ///
/// All zeroes. /// All zeroes.
@ -43,15 +43,11 @@ pub enum LightClientRootHash {
ChainHistoryRoot(ChainHistoryMmrRootHash), ChainHistoryRoot(ChainHistoryMmrRootHash),
} }
impl LightClientRootHash { impl RootHash {
/// Returns `bytes` as the LightClientRootHash variant for `network` and /// Returns `bytes` as the LightClientRootHash variant for `network` and
/// `height`. /// `height`.
pub(super) fn from_bytes( pub(super) fn from_bytes(bytes: [u8; 32], network: Network, height: BlockHeight) -> RootHash {
bytes: [u8; 32], use RootHash::*;
network: Network,
height: BlockHeight,
) -> LightClientRootHash {
use LightClientRootHash::*;
match NetworkUpgrade::current(network, height) { match NetworkUpgrade::current(network, height) {
Genesis | BeforeOverwinter | Overwinter => PreSaplingReserved(bytes), Genesis | BeforeOverwinter | Overwinter => PreSaplingReserved(bytes),
@ -66,7 +62,7 @@ impl LightClientRootHash {
/// Returns the serialized bytes for this LightClientRootHash. /// Returns the serialized bytes for this LightClientRootHash.
#[allow(dead_code)] #[allow(dead_code)]
pub(super) fn to_bytes(self) -> [u8; 32] { pub(super) fn to_bytes(self) -> [u8; 32] {
use LightClientRootHash::*; use RootHash::*;
match self { match self {
PreSaplingReserved(b) => b, PreSaplingReserved(b) => b,

View File

@ -24,7 +24,7 @@ impl ZcashSerialize for BlockHeader {
writer.write_u32::<LittleEndian>(self.version)?; writer.write_u32::<LittleEndian>(self.version)?;
self.previous_block_hash.zcash_serialize(&mut writer)?; self.previous_block_hash.zcash_serialize(&mut writer)?;
writer.write_all(&self.merkle_root_hash.0[..])?; 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 // this is a truncating cast, rather than a saturating cast
// but u32 times are valid until 2106, and our block verification time // but u32 times are valid until 2106, and our block verification time
// checks should detect any truncation. // checks should detect any truncation.
@ -72,7 +72,7 @@ impl ZcashDeserialize for BlockHeader {
version, version,
previous_block_hash: BlockHeaderHash::zcash_deserialize(&mut reader)?, previous_block_hash: BlockHeaderHash::zcash_deserialize(&mut reader)?,
merkle_root_hash: MerkleTreeRootHash(reader.read_32_bytes()?), 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 // This can't panic, because all u32 values are valid `Utc.timestamp`s
time: Utc.timestamp(reader.read_u32::<LittleEndian>()? as i64, 0), time: Utc.timestamp(reader.read_u32::<LittleEndian>()? as i64, 0),
difficulty_threshold: CompactDifficulty(reader.read_u32::<LittleEndian>()?), difficulty_threshold: CompactDifficulty(reader.read_u32::<LittleEndian>()?),

View File

@ -10,13 +10,13 @@ use proptest::{
prelude::*, prelude::*,
}; };
impl Arbitrary for LightClientRootHash { impl Arbitrary for RootHash {
type Parameters = (); type Parameters = ();
fn arbitrary_with(_args: ()) -> Self::Strategy { fn arbitrary_with(_args: ()) -> Self::Strategy {
(any::<[u8; 32]>(), any::<Network>(), any::<BlockHeight>()) (any::<[u8; 32]>(), any::<Network>(), any::<BlockHeight>())
.prop_map(|(light_client_root_bytes, network, block_height)| { .prop_map(|(root_bytes, network, block_height)| {
LightClientRootHash::from_bytes(light_client_root_bytes, network, block_height) RootHash::from_bytes(root_bytes, network, block_height)
}) })
.boxed() .boxed()
} }
@ -45,7 +45,7 @@ impl Arbitrary for BlockHeader {
version, version,
previous_block_hash, previous_block_hash,
merkle_root_hash, merkle_root_hash,
light_client_root_bytes, root_bytes,
timestamp, timestamp,
difficulty_threshold, difficulty_threshold,
nonce, nonce,
@ -54,7 +54,7 @@ impl Arbitrary for BlockHeader {
version, version,
previous_block_hash, previous_block_hash,
merkle_root_hash, merkle_root_hash,
light_client_root_bytes, root_bytes,
time: Utc.timestamp(timestamp, 0), time: Utc.timestamp(timestamp, 0),
difficulty_threshold, difficulty_threshold,
nonce, nonce,

View File

@ -26,9 +26,9 @@ proptest! {
} }
#[test] #[test]
fn light_client_roundtrip(bytes in any::<[u8; 32]>(), network in any::<Network>(), block_height in any::<BlockHeight>()) { fn root_hash_roundtrip(bytes in any::<[u8; 32]>(), network in any::<Network>(), block_height in any::<BlockHeight>()) {
let light_hash = LightClientRootHash::from_bytes(bytes, network, block_height); let root_hash = RootHash::from_bytes(bytes, network, block_height);
let other_bytes = light_hash.to_bytes(); let other_bytes = root_hash.to_bytes();
prop_assert_eq![bytes, other_bytes]; prop_assert_eq![bytes, other_bytes];
} }
@ -47,11 +47,11 @@ proptest! {
let bytes = block.zcash_serialize_to_vec()?; let bytes = block.zcash_serialize_to_vec()?;
let bytes = &mut bytes.as_slice(); let bytes = &mut bytes.as_slice();
// Check the light client root hash // Check the root hash
let light_hash = block.light_client_root_hash(network); let root_hash = block.root_hash(network);
if let Some(light_hash) = light_hash { if let Some(root_hash) = root_hash {
let light_hash_bytes = light_hash.to_bytes(); let root_hash_bytes = root_hash.to_bytes();
prop_assert_eq![block.header.light_client_root_bytes, light_hash_bytes]; prop_assert_eq![block.header.root_bytes, root_hash_bytes];
} else { } else {
prop_assert_eq![block.coinbase_height(), None]; prop_assert_eq![block.coinbase_height(), None];
} }