feature: Add a LightClientRootHash type

This commit is contained in:
teor 2020-08-07 19:24:00 +10:00
parent 53ce01fd23
commit c4eb136426
4 changed files with 99 additions and 10 deletions

View File

@ -4,6 +4,7 @@
mod difficulty;
mod hash;
mod header;
mod light_client;
mod serialize;
#[cfg(test)]

View File

@ -34,15 +34,10 @@ pub struct BlockHeader {
/// header.
pub merkle_root_hash: MerkleTreeRootHash,
/// [Pre-Sapling] Reserved. All zeroes.
/// [Sapling and Blossom] The root LEBS2OSP256(rt) of the Sapling note
/// commitment tree corresponding to the final Sapling treestate of
/// this block.
/// [Heartwood activation block] All zeroes. See ZIP-221 for details.
/// [After Heartwood activation block] The root of a Merkle Mountain
/// Range tree, which commits to various features of the chain's
/// history, including the Sapling commitment tree. This commitment
/// supports the FlyClient protocol. See ZIP-221 for details.
/// The light client root hash.
///
/// This field is interpreted differently, based on the current
/// block height. See LightClientRootHash for details.
pub light_client_root_hash: [u8; 32],
/// The block timestamp is a Unix epoch time (UTC) when the miner

View File

@ -0,0 +1,77 @@
//! The LightClientRootHash enum, used for the corresponding block header field.
use crate::note_commitment_tree::SaplingNoteTreeRootHash;
use crate::types::BlockHeight;
use crate::Network;
/// Light client root hashes.
///
/// The `BlockHeader.light_client_root_hash` 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 {
/// [Pre-Sapling] Reserved field.
///
/// All zeroes.
PreSaplingReserved([u8; 32]),
/// [Sapling and Blossom] The final Sapling treestate of this block.
///
/// The root LEBS2OSP256(rt) of the Sapling note commitment tree
/// corresponding to the final Sapling treestate of this block.
FinalSaplingRoot(SaplingNoteTreeRootHash),
/// [Heartwood activation block] Reserved field.
///
/// All zeroes. This MUST NOT be interpreted as a root hash.
/// See ZIP-221 for details.
ChainHistoryActivationReserved([u8; 32]),
/// [After Heartwood activation block] The root of a Merkle Mountain
/// Range chain history tree.
///
/// This root hash commits to various features of the chain's history,
/// including the Sapling commitment tree. This commitment supports the
/// FlyClient protocol. See ZIP-221 for details.
///
/// The commitment in each block covers the chain history from the most
/// recent network upgrade, through to the previous block. In particular,
/// an activation block commits to the entire previous network upgrade, and
/// the block after activation commits only to the activation block.
ChainHistoryRoot(ChainHistoryMmrRootHash),
}
impl LightClientRootHash {
/// Returns `bytes` as the LightClientRootHash variant for `network` and
/// `height`.
pub fn from_bytes(
bytes: [u8; 32],
network: Network,
height: BlockHeight,
) -> LightClientRootHash {
// TODO(teor): use the correct network upgrade here, after moving the
// network upgrades from zebra-consensus to zebra-chain.
LightClientRootHash::PreSaplingReserved(bytes)
}
/// Returns the serialized bytes for this LightClientRootHash.
pub fn to_bytes(self) -> [u8; 32] {
use LightClientRootHash::*;
match self {
PreSaplingReserved(b) => b,
FinalSaplingRoot(v) => v.0,
ChainHistoryActivationReserved(b) => b,
ChainHistoryRoot(v) => v.0,
}
}
}
/// The root hash of a Merkle Mountain Range chain history tree.
// TODO:
// - add methods for maintaining the MMR peaks, and calculating the root
// hash from the current set of peaks.
// - move to a separate file.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct ChainHistoryMmrRootHash([u8; 32]);

View File

@ -1,12 +1,14 @@
use super::*;
use crate::block::difficulty::CompactDifficulty;
use crate::block::{difficulty::CompactDifficulty, light_client::LightClientRootHash};
use crate::equihash_solution::EquihashSolution;
use crate::merkle_tree::MerkleTreeRootHash;
use crate::serialization::{
SerializationError, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize,
};
use crate::types::BlockHeight;
use crate::types::LockTime;
use crate::Network;
use crate::{sha256d_writer::Sha256dWriter, test::generate};
use chrono::{DateTime, Duration, LocalResult, TimeZone, Utc};
@ -18,6 +20,20 @@ use proptest::{
use std::env;
use std::io::{Cursor, ErrorKind, Write};
impl Arbitrary for LightClientRootHash {
type Parameters = ();
fn arbitrary_with(_args: ()) -> Self::Strategy {
(any::<[u8; 32]>(), any::<Network>(), any::<BlockHeight>())
.prop_map(|(light_client_root_hash, network, block_height)| {
LightClientRootHash::from_bytes(light_client_root_hash, network, block_height)
})
.boxed()
}
type Strategy = BoxedStrategy<Self>;
}
impl Arbitrary for BlockHeader {
type Parameters = ();