feature: Add a LightClientRootHash type
This commit is contained in:
parent
53ce01fd23
commit
c4eb136426
|
|
@ -4,6 +4,7 @@
|
||||||
mod difficulty;
|
mod difficulty;
|
||||||
mod hash;
|
mod hash;
|
||||||
mod header;
|
mod header;
|
||||||
|
mod light_client;
|
||||||
mod serialize;
|
mod serialize;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -34,15 +34,10 @@ pub struct BlockHeader {
|
||||||
/// header.
|
/// header.
|
||||||
pub merkle_root_hash: MerkleTreeRootHash,
|
pub merkle_root_hash: MerkleTreeRootHash,
|
||||||
|
|
||||||
/// [Pre-Sapling] Reserved. All zeroes.
|
/// The light client root hash.
|
||||||
/// [Sapling and Blossom] The root LEBS2OSP256(rt) of the Sapling note
|
///
|
||||||
/// commitment tree corresponding to the final Sapling treestate of
|
/// This field is interpreted differently, based on the current
|
||||||
/// this block.
|
/// block height. See LightClientRootHash for details.
|
||||||
/// [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.
|
|
||||||
pub light_client_root_hash: [u8; 32],
|
pub light_client_root_hash: [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
|
||||||
|
|
|
||||||
|
|
@ -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]);
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::block::difficulty::CompactDifficulty;
|
use crate::block::{difficulty::CompactDifficulty, light_client::LightClientRootHash};
|
||||||
use crate::equihash_solution::EquihashSolution;
|
use crate::equihash_solution::EquihashSolution;
|
||||||
use crate::merkle_tree::MerkleTreeRootHash;
|
use crate::merkle_tree::MerkleTreeRootHash;
|
||||||
use crate::serialization::{
|
use crate::serialization::{
|
||||||
SerializationError, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize,
|
SerializationError, ZcashDeserialize, ZcashDeserializeInto, ZcashSerialize,
|
||||||
};
|
};
|
||||||
|
use crate::types::BlockHeight;
|
||||||
use crate::types::LockTime;
|
use crate::types::LockTime;
|
||||||
|
use crate::Network;
|
||||||
use crate::{sha256d_writer::Sha256dWriter, test::generate};
|
use crate::{sha256d_writer::Sha256dWriter, test::generate};
|
||||||
|
|
||||||
use chrono::{DateTime, Duration, LocalResult, TimeZone, Utc};
|
use chrono::{DateTime, Duration, LocalResult, TimeZone, Utc};
|
||||||
|
|
@ -18,6 +20,20 @@ use proptest::{
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::{Cursor, ErrorKind, Write};
|
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 {
|
impl Arbitrary for BlockHeader {
|
||||||
type Parameters = ();
|
type Parameters = ();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue