83 lines
3.1 KiB
Rust
83 lines
3.1 KiB
Rust
//! The LightClientRootHash enum, used for the corresponding block header field.
|
|
|
|
use crate::parameters::{Network, NetworkUpgrade, NetworkUpgrade::*};
|
|
use crate::sapling::tree::Root;
|
|
|
|
use super::Height;
|
|
|
|
/// Zcash blocks contain different kinds of root hashes, depending on the network upgrade.
|
|
///
|
|
/// 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 RootHash {
|
|
/// [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(Root),
|
|
|
|
/// [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 RootHash {
|
|
/// Returns `bytes` as the LightClientRootHash variant for `network` and
|
|
/// `height`.
|
|
pub(super) fn from_bytes(bytes: [u8; 32], network: Network, height: Height) -> RootHash {
|
|
use RootHash::*;
|
|
|
|
match NetworkUpgrade::current(network, height) {
|
|
Genesis | BeforeOverwinter | Overwinter => PreSaplingReserved(bytes),
|
|
Sapling | Blossom => FinalSaplingRoot(Root(bytes)),
|
|
Heartwood if Some(height) == Heartwood.activation_height(network) => {
|
|
ChainHistoryActivationReserved(bytes)
|
|
}
|
|
Heartwood | Canopy => ChainHistoryRoot(ChainHistoryMmrRootHash(bytes)),
|
|
}
|
|
}
|
|
|
|
/// Returns the serialized bytes for this LightClientRootHash.
|
|
#[allow(dead_code)]
|
|
pub(super) fn to_bytes(self) -> [u8; 32] {
|
|
use RootHash::*;
|
|
|
|
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]);
|