use std::sync::Arc;
use crate::{
block::{
Block,
Commitment::{self, ChainHistoryActivationReserved},
},
history_tree::NonEmptyHistoryTree,
parameters::{Network, NetworkUpgrade},
sapling,
serialization::ZcashDeserializeInto,
};
use color_eyre::eyre;
use eyre::Result;
#[test]
fn push_and_prune() -> Result<()> {
for network in Network::iter() {
push_and_prune_for_network_upgrade(network.clone(), NetworkUpgrade::Heartwood)?;
push_and_prune_for_network_upgrade(network, NetworkUpgrade::Canopy)?;
}
Ok(())
}
fn push_and_prune_for_network_upgrade(
network: Network,
network_upgrade: NetworkUpgrade,
) -> Result<()> {
let (blocks, sapling_roots) = network.block_sapling_roots_map();
let height = network_upgrade.activation_height(&network).unwrap().0;
let first_block = Arc::new(
blocks
.get(&height)
.expect("test vector exists")
.zcash_deserialize_into::<Block>()
.expect("block is structurally valid"),
);
let first_commitment = first_block.commitment(&network)?;
if network_upgrade == NetworkUpgrade::Heartwood {
assert_eq!(first_commitment, ChainHistoryActivationReserved);
}
let first_sapling_root =
sapling::tree::Root::try_from(**sapling_roots.get(&height).expect("test vector exists"))?;
let mut tree = NonEmptyHistoryTree::from_block(
&network,
first_block,
&first_sapling_root,
&Default::default(),
)?;
assert_eq!(tree.size(), 1);
assert_eq!(tree.peaks().len(), 1);
assert_eq!(tree.current_height().0, height);
let first_root = tree.hash();
let second_block = Arc::new(
blocks
.get(&(height + 1))
.expect("test vector exists")
.zcash_deserialize_into::<Block>()
.expect("block is structurally valid"),
);
let second_commitment = second_block.commitment(&network)?;
assert_eq!(second_commitment, Commitment::ChainHistoryRoot(first_root));
let second_sapling_root = sapling::tree::Root::try_from(
**sapling_roots
.get(&(height + 1))
.expect("test vector exists"),
)?;
tree.push(second_block, &second_sapling_root, &Default::default())
.unwrap();
assert_eq!(tree.size(), 3);
assert_eq!(tree.peaks().len(), 1);
assert_eq!(tree.current_height().0, height + 1);
Ok(())
}
#[test]
fn upgrade() -> Result<()> {
for network in Network::iter() {
upgrade_for_network_upgrade(network, NetworkUpgrade::Canopy)?;
}
Ok(())
}
fn upgrade_for_network_upgrade(network: Network, network_upgrade: NetworkUpgrade) -> Result<()> {
let (blocks, sapling_roots) = network.block_sapling_roots_map();
let height = network_upgrade.activation_height(&network).unwrap().0;
let block_prev = Arc::new(
blocks
.get(&(height - 1))
.expect("test vector exists")
.zcash_deserialize_into::<Block>()
.expect("block is structurally valid"),
);
let sapling_root_prev =
sapling::tree::Root::try_from(**sapling_roots.get(&height).expect("test vector exists"))?;
let mut tree = NonEmptyHistoryTree::from_block(
&network,
block_prev,
&sapling_root_prev,
&Default::default(),
)?;
assert_eq!(tree.size(), 1);
assert_eq!(tree.peaks().len(), 1);
assert_eq!(tree.current_height().0, height - 1);
let activation_block = Arc::new(
blocks
.get(&height)
.expect("test vector exists")
.zcash_deserialize_into::<Block>()
.expect("block is structurally valid"),
);
let activation_sapling_root = sapling::tree::Root::try_from(
**sapling_roots
.get(&(height + 1))
.expect("test vector exists"),
)?;
tree.push(
activation_block,
&activation_sapling_root,
&Default::default(),
)
.unwrap();
assert_eq!(tree.size(), 1);
assert_eq!(tree.peaks().len(), 1);
assert_eq!(tree.current_height().0, height);
Ok(())
}