chain: rename BlockHeight to block::Height

This commit is contained in:
Henry de Valence 2020-08-16 11:42:02 -07:00
parent 61dea90e2f
commit 103b663c40
34 changed files with 278 additions and 275 deletions

View File

@ -13,7 +13,7 @@ mod tests;
pub use hash::Hash;
pub use header::BlockHeader;
pub use height::BlockHeight;
pub use height::Height;
pub use root_hash::RootHash;
/// The error type for Block checks.
@ -45,7 +45,7 @@ pub struct Block {
impl Block {
/// Return the block height reported in the coinbase transaction, if any.
pub fn coinbase_height(&self) -> Option<BlockHeight> {
pub fn coinbase_height(&self) -> Option<Height> {
use crate::transaction::TransparentInput;
self.transactions
.get(0)

View File

@ -6,13 +6,13 @@ use crate::serialization::SerializationError;
///
/// Users should not construct block heights greater than `BlockHeight::MAX`.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct BlockHeight(pub u32);
pub struct Height(pub u32);
impl std::str::FromStr for BlockHeight {
impl std::str::FromStr for Height {
type Err = SerializationError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.parse() {
Ok(h) if (BlockHeight(h) <= BlockHeight::MAX) => Ok(BlockHeight(h)),
Ok(h) if (Height(h) <= Height::MAX) => Ok(Height(h)),
Ok(_) => Err(SerializationError::Parse(
"BlockHeight exceeds maximum height",
)),
@ -23,7 +23,7 @@ impl std::str::FromStr for BlockHeight {
}
}
impl BlockHeight {
impl Height {
/// The minimum BlockHeight.
///
/// Due to the underlying type, it is impossible to construct block heights
@ -31,12 +31,12 @@ impl BlockHeight {
///
/// Style note: Sometimes, `BlockHeight::MIN` is less readable than
/// `BlockHeight(0)`. Use whichever makes sense in context.
pub const MIN: BlockHeight = BlockHeight(0);
pub const MIN: Height = Height(0);
/// The maximum BlockHeight.
///
/// Users should not construct block heights greater than `BlockHeight::MAX`.
pub const MAX: BlockHeight = BlockHeight(499_999_999);
pub const MAX: Height = Height(499_999_999);
/// The maximum BlockHeight as a u32, for range patterns.
///
@ -48,13 +48,11 @@ impl BlockHeight {
#[cfg(test)]
use proptest::prelude::*;
#[cfg(test)]
impl Arbitrary for BlockHeight {
impl Arbitrary for Height {
type Parameters = ();
fn arbitrary_with(_args: ()) -> Self::Strategy {
(BlockHeight::MIN.0..=BlockHeight::MAX.0)
.prop_map(BlockHeight)
.boxed()
(Height::MIN.0..=Height::MAX.0).prop_map(Height).boxed()
}
type Strategy = BoxedStrategy<Self>;

View File

@ -3,7 +3,7 @@
use crate::parameters::{Network, NetworkUpgrade, NetworkUpgrade::*};
use crate::sapling::tree::SaplingNoteTreeRootHash;
use super::BlockHeight;
use super::Height;
/// Zcash blocks contain different kinds of root hashes, depending on the network upgrade.
///
@ -46,7 +46,7 @@ pub enum RootHash {
impl RootHash {
/// Returns `bytes` as the LightClientRootHash variant for `network` and
/// `height`.
pub(super) fn from_bytes(bytes: [u8; 32], network: Network, height: BlockHeight) -> RootHash {
pub(super) fn from_bytes(bytes: [u8; 32], network: Network, height: Height) -> RootHash {
use RootHash::*;
match NetworkUpgrade::current(network, height) {

View File

@ -13,7 +13,7 @@ impl Arbitrary for RootHash {
type Parameters = ();
fn arbitrary_with(_args: ()) -> Self::Strategy {
(any::<[u8; 32]>(), any::<Network>(), any::<BlockHeight>())
(any::<[u8; 32]>(), any::<Network>(), any::<Height>())
.prop_map(|(root_bytes, network, block_height)| {
RootHash::from_bytes(root_bytes, network, block_height)
})

View File

@ -26,7 +26,11 @@ proptest! {
}
#[test]
fn root_hash_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::<Height>()
) {
let root_hash = RootHash::from_bytes(bytes, network, block_height);
let other_bytes = root_hash.to_bytes();

View File

@ -2,7 +2,7 @@
use NetworkUpgrade::*;
use crate::block::BlockHeight;
use crate::block;
use crate::parameters::{Network, Network::*};
use std::collections::{BTreeMap, HashMap};
@ -41,30 +41,30 @@ pub enum NetworkUpgrade {
///
/// This is actually a bijective map, but it is const, so we use a vector, and
/// do the uniqueness check in the unit tests.
pub(crate) const MAINNET_ACTIVATION_HEIGHTS: &[(BlockHeight, NetworkUpgrade)] = &[
(BlockHeight(0), Genesis),
(BlockHeight(1), BeforeOverwinter),
(BlockHeight(347_500), Overwinter),
(BlockHeight(419_200), Sapling),
(BlockHeight(653_600), Blossom),
(BlockHeight(903_000), Heartwood),
(BlockHeight(1_046_400), Canopy),
pub(crate) const MAINNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)] = &[
(block::Height(0), Genesis),
(block::Height(1), BeforeOverwinter),
(block::Height(347_500), Overwinter),
(block::Height(419_200), Sapling),
(block::Height(653_600), Blossom),
(block::Height(903_000), Heartwood),
(block::Height(1_046_400), Canopy),
];
/// Testnet network upgrade activation heights.
///
/// This is actually a bijective map, but it is const, so we use a vector, and
/// do the uniqueness check in the unit tests.
pub(crate) const TESTNET_ACTIVATION_HEIGHTS: &[(BlockHeight, NetworkUpgrade)] = &[
(BlockHeight(0), Genesis),
(BlockHeight(1), BeforeOverwinter),
(BlockHeight(207_500), Overwinter),
(BlockHeight(280_000), Sapling),
(BlockHeight(584_000), Blossom),
(BlockHeight(903_800), Heartwood),
pub(crate) const TESTNET_ACTIVATION_HEIGHTS: &[(block::Height, NetworkUpgrade)] = &[
(block::Height(0), Genesis),
(block::Height(1), BeforeOverwinter),
(block::Height(207_500), Overwinter),
(block::Height(280_000), Sapling),
(block::Height(584_000), Blossom),
(block::Height(903_800), Heartwood),
// As of 27 July 2020, the Canopy testnet height is under final review.
// See ZIP 251 for any updates.
(BlockHeight(1_028_500), Canopy),
(block::Height(1_028_500), Canopy),
];
/// The Consensus Branch Id, used to bind transactions and blocks to a
@ -101,7 +101,7 @@ impl NetworkUpgrade {
/// network upgrade does not appear in the list.
///
/// This is actually a bijective map.
pub(crate) fn activation_list(network: Network) -> BTreeMap<BlockHeight, NetworkUpgrade> {
pub(crate) fn activation_list(network: Network) -> BTreeMap<block::Height, NetworkUpgrade> {
match network {
Mainnet => MAINNET_ACTIVATION_HEIGHTS,
Testnet => TESTNET_ACTIVATION_HEIGHTS,
@ -112,7 +112,7 @@ impl NetworkUpgrade {
}
/// Returns the current network upgrade for `network` and `height`.
pub fn current(network: Network, height: BlockHeight) -> NetworkUpgrade {
pub fn current(network: Network, height: block::Height) -> NetworkUpgrade {
NetworkUpgrade::activation_list(network)
.range(..=height)
.map(|(_, nu)| *nu)
@ -123,7 +123,7 @@ impl NetworkUpgrade {
/// Returns the next network upgrade for `network` and `height`.
///
/// Returns None if the name of the next upgrade has not been decided yet.
pub fn next(network: Network, height: BlockHeight) -> Option<NetworkUpgrade> {
pub fn next(network: Network, height: block::Height) -> Option<NetworkUpgrade> {
NetworkUpgrade::activation_list(network)
.range((Excluded(height), Unbounded))
.map(|(_, nu)| *nu)
@ -134,7 +134,7 @@ impl NetworkUpgrade {
///
/// Returns None if this network upgrade is a future upgrade, and its
/// activation height has not been set yet.
pub fn activation_height(&self, network: Network) -> Option<BlockHeight> {
pub fn activation_height(&self, network: Network) -> Option<block::Height> {
NetworkUpgrade::activation_list(network)
.iter()
.filter(|(_, nu)| nu == &self)
@ -166,7 +166,7 @@ impl ConsensusBranchId {
/// Returns the current consensus branch id for `network` and `height`.
///
/// Returns None if the network has no branch id at this height.
pub fn current(network: Network, height: BlockHeight) -> Option<ConsensusBranchId> {
pub fn current(network: Network, height: block::Height) -> Option<ConsensusBranchId> {
NetworkUpgrade::current(network, height).branch_id()
}
}

View File

@ -2,7 +2,7 @@
use std::collections::HashSet;
use crate::block::BlockHeight;
use crate::block;
use super::*;
@ -13,14 +13,14 @@ use NetworkUpgrade::*;
#[test]
fn activation_bijective() {
let mainnet_activations = NetworkUpgrade::activation_list(Mainnet);
let mainnet_heights: HashSet<&BlockHeight> = mainnet_activations.keys().collect();
let mainnet_heights: HashSet<&block::Height> = mainnet_activations.keys().collect();
assert_eq!(MAINNET_ACTIVATION_HEIGHTS.len(), mainnet_heights.len());
let mainnet_nus: HashSet<&NetworkUpgrade> = mainnet_activations.values().collect();
assert_eq!(MAINNET_ACTIVATION_HEIGHTS.len(), mainnet_nus.len());
let testnet_activations = NetworkUpgrade::activation_list(Testnet);
let testnet_heights: HashSet<&BlockHeight> = testnet_activations.keys().collect();
let testnet_heights: HashSet<&block::Height> = testnet_activations.keys().collect();
assert_eq!(TESTNET_ACTIVATION_HEIGHTS.len(), testnet_heights.len());
let testnet_nus: HashSet<&NetworkUpgrade> = testnet_activations.values().collect();
@ -42,41 +42,44 @@ fn activation_extremes_testnet() {
fn activation_extremes(network: Network) {
// The first three upgrades are Genesis, BeforeOverwinter, and Overwinter
assert_eq!(
NetworkUpgrade::activation_list(network).get(&BlockHeight(0)),
NetworkUpgrade::activation_list(network).get(&block::Height(0)),
Some(&Genesis)
);
assert_eq!(Genesis.activation_height(network), Some(BlockHeight(0)));
assert_eq!(NetworkUpgrade::current(network, BlockHeight(0)), Genesis);
assert_eq!(Genesis.activation_height(network), Some(block::Height(0)));
assert_eq!(NetworkUpgrade::current(network, block::Height(0)), Genesis);
assert_eq!(
NetworkUpgrade::next(network, BlockHeight(0)),
NetworkUpgrade::next(network, block::Height(0)),
Some(BeforeOverwinter)
);
assert_eq!(
NetworkUpgrade::activation_list(network).get(&BlockHeight(1)),
NetworkUpgrade::activation_list(network).get(&block::Height(1)),
Some(&BeforeOverwinter)
);
assert_eq!(
BeforeOverwinter.activation_height(network),
Some(BlockHeight(1))
Some(block::Height(1))
);
assert_eq!(
NetworkUpgrade::current(network, BlockHeight(1)),
NetworkUpgrade::current(network, block::Height(1)),
BeforeOverwinter
);
assert_eq!(
NetworkUpgrade::next(network, BlockHeight(1)),
NetworkUpgrade::next(network, block::Height(1)),
Some(Overwinter)
);
// We assume that the last upgrade we know about continues forever
// (even if we suspect that won't be true)
assert_ne!(
NetworkUpgrade::activation_list(network).get(&BlockHeight::MAX),
NetworkUpgrade::activation_list(network).get(&block::Height::MAX),
Some(&Genesis)
);
assert_ne!(NetworkUpgrade::current(network, BlockHeight::MAX), Genesis);
assert_eq!(NetworkUpgrade::next(network, BlockHeight::MAX), None);
assert_ne!(
NetworkUpgrade::current(network, block::Height::MAX),
Genesis
);
assert_eq!(NetworkUpgrade::next(network, block::Height::MAX), None);
}
#[test]
@ -103,11 +106,11 @@ fn activation_consistent(network: Network) {
// Network upgrades don't repeat
assert_ne!(NetworkUpgrade::next(network, height), Some(network_upgrade));
assert_ne!(
NetworkUpgrade::next(network, BlockHeight(height.0 + 1)),
NetworkUpgrade::next(network, block::Height(height.0 + 1)),
Some(network_upgrade)
);
assert_ne!(
NetworkUpgrade::next(network, BlockHeight::MAX),
NetworkUpgrade::next(network, block::Height::MAX),
Some(network_upgrade)
);
}
@ -142,7 +145,7 @@ fn branch_id_extremes(network: Network) {
NetworkUpgrade::branch_id_list().get(&BeforeOverwinter),
None
);
assert_eq!(ConsensusBranchId::current(network, BlockHeight(0)), None);
assert_eq!(ConsensusBranchId::current(network, block::Height(0)), None);
assert_eq!(
NetworkUpgrade::branch_id_list().get(&Overwinter).cloned(),
Overwinter.branch_id()
@ -151,10 +154,13 @@ fn branch_id_extremes(network: Network) {
// We assume that the last upgrade we know about continues forever
// (even if we suspect that won't be true)
assert_ne!(
NetworkUpgrade::branch_id_list().get(&NetworkUpgrade::current(network, BlockHeight::MAX)),
NetworkUpgrade::branch_id_list().get(&NetworkUpgrade::current(network, block::Height::MAX)),
None
);
assert_ne!(
ConsensusBranchId::current(network, block::Height::MAX),
None
);
assert_ne!(ConsensusBranchId::current(network, BlockHeight::MAX), None);
}
#[test]

View File

@ -21,7 +21,7 @@ pub use shielded_data::{Output, ShieldedData, Spend};
pub use transparent::{CoinbaseData, OutPoint, TransparentInput, TransparentOutput};
use crate::amount::Amount;
use crate::block::BlockHeight;
use crate::block;
use crate::primitives::{Bctv14Proof, Groth16Proof};
/// A Zcash transaction.
@ -71,7 +71,7 @@ pub enum Transaction {
/// chain.
lock_time: LockTime,
/// The latest block height that this transaction can be added to the chain.
expiry_height: BlockHeight,
expiry_height: block::Height,
/// The JoinSplit data for this transaction, if any.
joinsplit_data: Option<JoinSplitData<Bctv14Proof>>,
},
@ -85,7 +85,7 @@ pub enum Transaction {
/// chain.
lock_time: LockTime,
/// The latest block height that this transaction can be added to the chain.
expiry_height: BlockHeight,
expiry_height: block::Height,
/// The net value of Sapling spend transfers minus output transfers.
value_balance: Amount,
/// The shielded data for this transaction, if any.
@ -127,7 +127,7 @@ impl Transaction {
}
/// Get this transaction's expiry height, if any.
pub fn expiry_height(&self) -> Option<BlockHeight> {
pub fn expiry_height(&self) -> Option<block::Height> {
match self {
Transaction::V1 { .. } => None,
Transaction::V2 { .. } => None,

View File

@ -3,7 +3,7 @@ use std::io;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use chrono::{DateTime, TimeZone, Utc};
use crate::block::BlockHeight;
use crate::block;
use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
/// A Bitcoin-style `locktime`, representing either a block height or an epoch
@ -20,7 +20,7 @@ use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum LockTime {
/// Unlock at a particular block height.
Height(BlockHeight),
Height(block::Height),
/// Unlock at a particular time.
Time(DateTime<Utc>),
}
@ -63,10 +63,9 @@ impl ZcashSerialize for LockTime {
// This implementation does not check the invariants on `LockTime` so that the
// serialization is fallible only if the underlying writer is. This ensures that
// we can always compute a hash of a transaction object.
use LockTime::*;
match self {
Height(BlockHeight(n)) => writer.write_u32::<LittleEndian>(*n)?,
Time(t) => writer.write_u32::<LittleEndian>(t.timestamp() as u32)?,
LockTime::Height(block::Height(n)) => writer.write_u32::<LittleEndian>(*n)?,
LockTime::Time(t) => writer.write_u32::<LittleEndian>(t.timestamp() as u32)?,
}
Ok(())
}
@ -75,8 +74,8 @@ impl ZcashSerialize for LockTime {
impl ZcashDeserialize for LockTime {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
let n = reader.read_u32::<LittleEndian>()?;
if n <= BlockHeight::MAX.0 {
Ok(LockTime::Height(BlockHeight(n)))
if n <= block::Height::MAX.0 {
Ok(LockTime::Height(block::Height(n)))
} else {
Ok(LockTime::Time(Utc.timestamp(n as i64, 0)))
}

View File

@ -72,35 +72,36 @@ impl ZcashDeserialize for OutPoint {
fn parse_coinbase_height(
mut data: Vec<u8>,
) -> Result<(BlockHeight, CoinbaseData), SerializationError> {
) -> Result<(block::Height, CoinbaseData), SerializationError> {
use block::Height;
match (data.get(0), data.len()) {
// Blocks 1 through 16 inclusive encode block height with OP_N opcodes.
(Some(op_n @ 0x51..=0x60), len) if len >= 1 => Ok((
BlockHeight((op_n - 0x50) as u32),
Height((op_n - 0x50) as u32),
CoinbaseData(data.split_off(1)),
)),
// Blocks 17 through 256 exclusive encode block height with the `0x01` opcode.
(Some(0x01), len) if len >= 2 => {
Ok((BlockHeight(data[1] as u32), CoinbaseData(data.split_off(2))))
Ok((Height(data[1] as u32), CoinbaseData(data.split_off(2))))
}
// Blocks 256 through 65536 exclusive encode block height with the `0x02` opcode.
(Some(0x02), len) if len >= 3 => Ok((
BlockHeight(data[1] as u32 + ((data[2] as u32) << 8)),
Height(data[1] as u32 + ((data[2] as u32) << 8)),
CoinbaseData(data.split_off(3)),
)),
// Blocks 65536 through 2**24 exclusive encode block height with the `0x03` opcode.
(Some(0x03), len) if len >= 4 => Ok((
BlockHeight(data[1] as u32 + ((data[2] as u32) << 8) + ((data[3] as u32) << 16)),
Height(data[1] as u32 + ((data[2] as u32) << 8) + ((data[3] as u32) << 16)),
CoinbaseData(data.split_off(4)),
)),
// The genesis block does not encode the block height by mistake; special case it.
// The first five bytes are [4, 255, 255, 7, 31], the little-endian encoding of
// 520_617_983. This is lucky because it means we can special-case the genesis block
// while remaining below the maximum `BlockHeight` of 500_000_000 forced by `LockTime`.
// while remaining below the maximum `block::Height` of 500_000_000 forced by `LockTime`.
// While it's unlikely this code will ever process a block height that high, this means
// we don't need to maintain a cascade of different invariants for allowable `BlockHeight`s.
// we don't need to maintain a cascade of different invariants for allowable heights.
(Some(0x04), _) if data[..] == GENESIS_COINBASE_DATA[..] => {
Ok((BlockHeight(0), CoinbaseData(data)))
Ok((Height(0), CoinbaseData(data)))
}
// As noted above, this is included for completeness.
(Some(0x04), len) if len >= 5 => {
@ -108,8 +109,8 @@ fn parse_coinbase_height(
+ ((data[2] as u32) << 8)
+ ((data[3] as u32) << 16)
+ ((data[4] as u32) << 24);
if h <= BlockHeight::MAX.0 {
Ok((BlockHeight(h), CoinbaseData(data.split_off(5))))
if h <= Height::MAX.0 {
Ok((Height(h), CoinbaseData(data.split_off(5))))
} else {
Err(SerializationError::Parse("Invalid block height"))
}
@ -120,7 +121,7 @@ fn parse_coinbase_height(
}
}
fn coinbase_height_len(height: BlockHeight) -> usize {
fn coinbase_height_len(height: block::Height) -> usize {
// We can't write this as a match statement on stable until exclusive range
// guards are stabilized.
if let 0 = height.0 {
@ -133,14 +134,14 @@ fn coinbase_height_len(height: BlockHeight) -> usize {
3
} else if let _h @ 65536..=16_777_215 = height.0 {
4
} else if let _h @ 16_777_216..=BlockHeight::MAX_AS_U32 = height.0 {
} else if let _h @ 16_777_216..=block::Height::MAX_AS_U32 = height.0 {
5
} else {
panic!("Invalid coinbase height");
}
}
fn write_coinbase_height<W: io::Write>(height: BlockHeight, mut w: W) -> Result<(), io::Error> {
fn write_coinbase_height<W: io::Write>(height: block::Height, mut w: W) -> Result<(), io::Error> {
// We can't write this as a match statement on stable until exclusive range
// guards are stabilized.
if let 0 = height.0 {
@ -158,7 +159,7 @@ fn write_coinbase_height<W: io::Write>(height: BlockHeight, mut w: W) -> Result<
w.write_u8(h as u8)?;
w.write_u8((h >> 8) as u8)?;
w.write_u8((h >> 16) as u8)?;
} else if let h @ 16_777_216..=BlockHeight::MAX_AS_U32 = height.0 {
} else if let h @ 16_777_216..=block::Height::MAX_AS_U32 = height.0 {
w.write_u8(0x04)?;
w.write_u32::<LittleEndian>(h)?;
} else {
@ -549,7 +550,7 @@ impl ZcashDeserialize for Transaction {
inputs: Vec::zcash_deserialize(&mut reader)?,
outputs: Vec::zcash_deserialize(&mut reader)?,
lock_time: LockTime::zcash_deserialize(&mut reader)?,
expiry_height: BlockHeight(reader.read_u32::<LittleEndian>()?),
expiry_height: block::Height(reader.read_u32::<LittleEndian>()?),
joinsplit_data: OptV3JSD::zcash_deserialize(&mut reader)?,
})
}
@ -574,7 +575,7 @@ impl ZcashDeserialize for Transaction {
let inputs = Vec::zcash_deserialize(&mut reader)?;
let outputs = Vec::zcash_deserialize(&mut reader)?;
let lock_time = LockTime::zcash_deserialize(&mut reader)?;
let expiry_height = BlockHeight(reader.read_u32::<LittleEndian>()?);
let expiry_height = block::Height(reader.read_u32::<LittleEndian>()?);
let value_balance = reader.read_i64::<LittleEndian>()?.try_into()?;
let mut shielded_spends = Vec::zcash_deserialize(&mut reader)?;
let mut shielded_outputs = Vec::zcash_deserialize(&mut reader)?;

View File

@ -4,7 +4,7 @@ use proptest::{arbitrary::any, array, collection::vec, option, prelude::*};
use crate::{
amount::{Amount, NonNegative},
block::BlockHeight,
block,
primitives::{Bctv14Proof, Groth16Proof, Script, ZkSnarkProof},
sapling, sprout,
};
@ -52,7 +52,7 @@ impl Transaction {
vec(any::<TransparentInput>(), 0..10),
vec(any::<TransparentOutput>(), 0..10),
any::<LockTime>(),
any::<BlockHeight>(),
any::<block::Height>(),
option::of(any::<JoinSplitData<Bctv14Proof>>()),
)
.prop_map(
@ -72,7 +72,7 @@ impl Transaction {
vec(any::<TransparentInput>(), 0..10),
vec(any::<TransparentOutput>(), 0..10),
any::<LockTime>(),
any::<BlockHeight>(),
any::<block::Height>(),
any::<Amount>(),
option::of(any::<ShieldedData>()),
option::of(any::<JoinSplitData<Groth16Proof>>()),
@ -121,8 +121,8 @@ impl Arbitrary for LockTime {
fn arbitrary_with(_args: ()) -> Self::Strategy {
prop_oneof![
(BlockHeight::MIN.0..=BlockHeight::MAX.0)
.prop_map(|n| LockTime::Height(BlockHeight(n))),
(block::Height::MIN.0..=block::Height::MAX.0)
.prop_map(|n| LockTime::Height(block::Height(n))),
(LockTime::MIN_TIMESTAMP..=LockTime::MAX_TIMESTAMP)
.prop_map(|n| { LockTime::Time(Utc.timestamp(n as i64, 0)) })
]
@ -326,7 +326,11 @@ impl Arbitrary for TransparentInput {
}
})
.boxed(),
(any::<BlockHeight>(), vec(any::<u8>(), 0..95), any::<u32>())
(
any::<block::Height>(),
vec(any::<u8>(), 0..95),
any::<u32>()
)
.prop_map(|(height, data, sequence)| {
TransparentInput::Coinbase {
height,

View File

@ -6,7 +6,7 @@ use proptest_derive::Arbitrary;
use crate::{
amount::{Amount, NonNegative},
block::BlockHeight,
block,
primitives::Script,
};
@ -59,7 +59,7 @@ pub enum TransparentInput {
/// New coins created by the block reward.
Coinbase {
/// The height of this block.
height: BlockHeight,
height: block::Height,
/// Free data inserted by miners after the block height.
data: CoinbaseData,
/// The sequence number for the output.

View File

@ -25,8 +25,7 @@ use std::{
use tokio::time;
use tower::{buffer::Buffer, Service, ServiceExt};
use zebra_chain::block::BlockHeight;
use zebra_chain::block::{Block, self};
use zebra_chain::block::{self, Block};
/// A service that verifies blocks.
#[derive(Debug)]
@ -84,7 +83,7 @@ where
let height = block
.coinbase_height()
.ok_or("Invalid block: missing block height.")?;
if height > BlockHeight::MAX {
if height > block::Height::MAX {
Err("Invalid block height: greater than the maximum height.")?;
}
@ -126,7 +125,7 @@ where
let previous_block = BlockVerifier::await_block(
&mut state,
previous_block_hash,
BlockHeight(height.0 - 1),
block::Height(height.0 - 1),
)
.await?;
@ -180,7 +179,7 @@ where
async fn await_block(
state: &mut S,
hash: block::Hash,
height: BlockHeight,
height: block::Height,
) -> Result<Arc<Block>, Report> {
loop {
match BlockVerifier::get_block(state, hash).await? {

View File

@ -6,8 +6,8 @@ use chrono::Utc;
use color_eyre::eyre::{eyre, Report};
use once_cell::sync::Lazy;
use zebra_chain::block::{Block, self};
use zebra_chain::block::BlockHeader;
use zebra_chain::block::{self, Block};
use zebra_chain::serialization::{ZcashDeserialize, ZcashDeserializeInto};
use zebra_test::transcript::{TransError, Transcript};

View File

@ -27,8 +27,7 @@ use std::{
use tower::{buffer::Buffer, Service, ServiceExt};
use tracing_futures::Instrument;
use zebra_chain::block::BlockHeight;
use zebra_chain::block::{Block, self};
use zebra_chain::block::{self, Block};
use zebra_chain::parameters::{Network, NetworkUpgrade::Sapling};
/// The maximum expected gap between blocks.
@ -45,7 +44,7 @@ struct ChainCheckpointVerifier {
verifier: Buffer<CheckpointVerifier, Arc<Block>>,
/// The maximum checkpoint height for `checkpoint_verifier`.
max_height: BlockHeight,
max_height: block::Height,
}
/// A service that verifies the chain, using its associated `CheckpointVerifier`
@ -77,7 +76,7 @@ where
/// Used for debugging.
///
/// Updated before verification: the block at this height might not be valid.
last_block_height: Option<BlockHeight>,
last_block_height: Option<block::Height>,
}
/// The error type for the ChainVerifier Service.
@ -125,10 +124,10 @@ where
// Log an info-level message on unexpected high blocks
let is_unexpected_high_block = match (block_height, self.last_block_height) {
(Some(BlockHeight(block_height)), Some(BlockHeight(last_block_height)))
(Some(block::Height(block_height)), Some(block::Height(last_block_height)))
if (block_height > last_block_height + MAX_EXPECTED_BLOCK_GAP) =>
{
self.last_block_height = Some(BlockHeight(block_height));
self.last_block_height = Some(block::Height(block_height));
true
}
(Some(block_height), _) => {
@ -190,8 +189,8 @@ where
///
/// Returns false if the block does not have a height.
fn is_higher_than_max_checkpoint(
block_height: Option<BlockHeight>,
max_checkpoint_height: Option<BlockHeight>,
block_height: Option<block::Height>,
max_checkpoint_height: Option<block::Height>,
) -> bool {
match (block_height, max_checkpoint_height) {
(Some(block_height), Some(max_checkpoint_height)) => block_height > max_checkpoint_height,

View File

@ -11,7 +11,7 @@ use tower::{layer::Layer, timeout::TimeoutLayer, Service, ServiceExt};
use tracing_futures::Instrument;
use zebra_chain::{
block::{Block, BlockHeader},
block::{self, Block, BlockHeader},
parameters::Network,
serialization::ZcashDeserialize,
};
@ -107,17 +107,16 @@ fn verifiers_from_network(
verifiers_from_checkpoint_list(network, CheckpointList::new(network))
}
static BLOCK_VERIFY_TRANSCRIPT_GENESIS: Lazy<
Vec<(Arc<Block>, Result<block::Hash, TransError>)>,
> = Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let hash = Ok(block.hash());
static BLOCK_VERIFY_TRANSCRIPT_GENESIS: Lazy<Vec<(Arc<Block>, Result<block::Hash, TransError>)>> =
Lazy::new(|| {
let block: Arc<_> =
Block::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_GENESIS_BYTES[..])
.unwrap()
.into();
let hash = Ok(block.hash());
vec![(block, hash)]
});
vec![(block, hash)]
});
static BLOCK_VERIFY_TRANSCRIPT_GENESIS_FAIL: Lazy<
Vec<(Arc<Block>, Result<block::Hash, TransError>)>,
@ -212,7 +211,7 @@ async fn verify_block() -> Result<(), Report> {
));
// Make a checkpoint list containing the genesis block
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> =
let checkpoint_list: BTreeMap<block::Height, block::Hash> =
checkpoint_data.iter().cloned().collect();
let checkpoint_list = CheckpointList::from_list(checkpoint_list).map_err(|e| eyre!(e))?;
@ -338,7 +337,7 @@ async fn verify_fail_add_block_checkpoint() -> Result<(), Report> {
async fn continuous_blockchain_test() -> Result<(), Report> {
continuous_blockchain(None).await?;
for height in 0..=10 {
continuous_blockchain(Some(BlockHeight(height))).await?;
continuous_blockchain(Some(block::Height(height))).await?;
}
Ok(())
}
@ -346,7 +345,7 @@ async fn continuous_blockchain_test() -> Result<(), Report> {
/// Test a continuous blockchain in the BlockVerifier and CheckpointVerifier,
/// restarting verification at `restart_height`.
#[spandoc::spandoc]
async fn continuous_blockchain(restart_height: Option<BlockHeight>) -> Result<(), Report> {
async fn continuous_blockchain(restart_height: Option<block::Height>) -> Result<(), Report> {
zebra_test::init();
// A continuous blockchain
@ -381,7 +380,7 @@ async fn continuous_blockchain(restart_height: Option<BlockHeight>) -> Result<()
}
// The checkpoint list will contain only blocks 0 and 4
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoints
let checkpoint_list: BTreeMap<block::Height, block::Hash> = checkpoints
.iter()
.map(|(_block, height, hash)| (*height, *hash))
.collect();
@ -407,7 +406,7 @@ async fn continuous_blockchain(restart_height: Option<BlockHeight>) -> Result<()
}
}
let initial_tip = restart_height
.map(|BlockHeight(height)| &blockchain[height as usize].0)
.map(|block::Height(height)| &blockchain[height as usize].0)
.cloned();
let block_verifier = crate::block::init(state_service.clone());

View File

@ -39,8 +39,7 @@ use tokio::sync::oneshot;
use tower::Service;
use zebra_chain::{
block::BlockHeight,
block::{Block, self},
block::{self, Block},
parameters::Network,
};
@ -109,10 +108,10 @@ pub struct CheckpointVerifier {
///
/// The first checkpoint does not have any ancestors, so it only verifies the
/// genesis block.
queued: BTreeMap<BlockHeight, QueuedBlockList>,
queued: BTreeMap<block::Height, QueuedBlockList>,
/// The current progress of this verifier.
verifier_progress: Progress<BlockHeight>,
verifier_progress: Progress<block::Height>,
}
/// The CheckpointVerifier implementation.
@ -152,7 +151,7 @@ impl CheckpointVerifier {
// This function is designed for use in tests.
#[allow(dead_code)]
pub(crate) fn from_list(
list: impl IntoIterator<Item = (BlockHeight, block::Hash)>,
list: impl IntoIterator<Item = (block::Height, block::Hash)>,
initial_tip: Option<Arc<Block>>,
) -> Result<Self, Error> {
Ok(Self::from_checkpoint_list(
@ -213,14 +212,14 @@ impl CheckpointVerifier {
/// `height` increases as checkpoints are verified.
///
/// If verification has finished, returns `FinalCheckpoint`.
fn previous_checkpoint_height(&self) -> Progress<BlockHeight> {
fn previous_checkpoint_height(&self) -> Progress<block::Height> {
self.verifier_progress
}
/// Return the start of the current checkpoint range.
///
/// Returns None if verification has finished.
fn current_start_bound(&self) -> Option<Bound<BlockHeight>> {
fn current_start_bound(&self) -> Option<Bound<block::Height>> {
match self.previous_checkpoint_height() {
BeforeGenesis => Some(Unbounded),
InitialTip(height) | PreviousCheckpoint(height) => Some(Excluded(height)),
@ -239,14 +238,14 @@ impl CheckpointVerifier {
/// `height` increases as checkpoints are verified.
///
/// If verification has finished, returns `FinishedVerifying`.
fn target_checkpoint_height(&self) -> Target<BlockHeight> {
fn target_checkpoint_height(&self) -> Target<block::Height> {
// Find the height we want to start searching at
let mut pending_height = match self.previous_checkpoint_height() {
// Check if we have the genesis block as a special case, to simplify the loop
BeforeGenesis if !self.queued.contains_key(&BlockHeight(0)) => {
BeforeGenesis if !self.queued.contains_key(&block::Height(0)) => {
return WaitingForBlocks;
}
BeforeGenesis => BlockHeight(0),
BeforeGenesis => block::Height(0),
InitialTip(height) | PreviousCheckpoint(height) => height,
FinalCheckpoint => return FinishedVerifying,
};
@ -265,7 +264,7 @@ impl CheckpointVerifier {
// it stops after the first gap.
for (&height, _) in self.queued.range((Excluded(pending_height), Unbounded)) {
// If the queued blocks are continuous.
if height == BlockHeight(pending_height.0 + 1) {
if height == block::Height(pending_height.0 + 1) {
pending_height = height;
} else {
break;
@ -320,7 +319,7 @@ impl CheckpointVerifier {
/// - the block's height is less than or equal to the previously verified
/// checkpoint
/// - verification has finished
fn check_height(&self, height: BlockHeight) -> Result<(), Error> {
fn check_height(&self, height: block::Height) -> Result<(), Error> {
if height > self.checkpoint_list.max_height() {
Err("block is higher than the maximum checkpoint")?;
}
@ -343,7 +342,7 @@ impl CheckpointVerifier {
}
/// Increase the current checkpoint height to `verified_height`,
fn update_progress(&mut self, verified_height: BlockHeight) {
fn update_progress(&mut self, verified_height: block::Height) {
// Ignore blocks that are below the previous checkpoint, or otherwise
// have invalid heights.
//
@ -369,7 +368,7 @@ impl CheckpointVerifier {
///
/// Returns an error if the block's height is invalid, see `check_height()`
/// for details.
fn check_block(&self, block: &Block) -> Result<BlockHeight, Error> {
fn check_block(&self, block: &Block) -> Result<block::Height, Error> {
let block_height = block
.coinbase_height()
.ok_or("the block does not have a coinbase height")?;
@ -385,10 +384,7 @@ impl CheckpointVerifier {
///
/// If the block does not have a coinbase height, sends an error on `tx`,
/// and does not queue the block.
fn queue_block(
&mut self,
block: Arc<Block>,
) -> oneshot::Receiver<Result<block::Hash, Error>> {
fn queue_block(&mut self, block: Arc<Block>) -> oneshot::Receiver<Result<block::Hash, Error>> {
// Set up a oneshot channel to send results
let (tx, rx) = oneshot::channel();
@ -459,7 +455,7 @@ impl CheckpointVerifier {
/// Returns the first valid block. If there is no valid block, returns None.
fn process_height(
&mut self,
height: BlockHeight,
height: block::Height,
expected_hash: block::Hash,
) -> Option<QueuedBlock> {
let mut qblocks = self
@ -567,7 +563,7 @@ impl CheckpointVerifier {
.expect("earlier code checks if verification has finished"),
Included(target_checkpoint_height),
);
let range_heights: Vec<BlockHeight> = self
let range_heights: Vec<block::Height> = self
.queued
.range_mut(current_range)
.rev()

View File

@ -18,7 +18,6 @@ use std::{
};
use zebra_chain::block;
use zebra_chain::block::BlockHeight;
use zebra_chain::parameters::Network;
const MAINNET_CHECKPOINTS: &str = include_str!("main-checkpoints.txt");
@ -38,19 +37,19 @@ type Error = Box<dyn error::Error + Send + Sync + 'static>;
/// This is actually a bijective map, but since it is read-only, we use a
/// BTreeMap, and do the value uniqueness check on initialisation.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub(crate) struct CheckpointList(BTreeMap<BlockHeight, block::Hash>);
pub(crate) struct CheckpointList(BTreeMap<block::Height, block::Hash>);
impl FromStr for CheckpointList {
type Err = Error;
/// Parse a string into a CheckpointList.
///
/// Each line has one checkpoint, consisting of a `BlockHeight` and
/// Each line has one checkpoint, consisting of a `block::Height` and
/// `block::Hash`, separated by a single space.
///
/// Assumes that the provided genesis checkpoint is correct.
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut checkpoint_list: Vec<(BlockHeight, block::Hash)> = Vec::new();
let mut checkpoint_list: Vec<(block::Height, block::Hash)> = Vec::new();
for checkpoint in s.lines() {
let fields = checkpoint.split(' ').collect::<Vec<_>>();
@ -78,7 +77,7 @@ impl CheckpointList {
.expect("Hard-coded Testnet checkpoint list parses and validates"),
};
match checkpoint_list.hash(BlockHeight(0)) {
match checkpoint_list.hash(block::Height(0)) {
Some(hash) if hash == parameters::genesis_hash(network) => checkpoint_list,
Some(_) => {
panic!("The hard-coded genesis checkpoint does not match the network genesis hash")
@ -92,25 +91,25 @@ impl CheckpointList {
/// Assumes that the provided genesis checkpoint is correct.
///
/// Checkpoint heights and checkpoint hashes must be unique.
/// There must be a checkpoint for a genesis block at BlockHeight 0.
/// There must be a checkpoint for a genesis block at block::Height 0.
/// (All other checkpoints are optional.)
pub(crate) fn from_list(
list: impl IntoIterator<Item = (BlockHeight, block::Hash)>,
list: impl IntoIterator<Item = (block::Height, block::Hash)>,
) -> Result<Self, Error> {
// BTreeMap silently ignores duplicates, so we count the checkpoints
// before adding them to the map
let original_checkpoints: Vec<(BlockHeight, block::Hash)> = list.into_iter().collect();
let original_checkpoints: Vec<(block::Height, block::Hash)> = list.into_iter().collect();
let original_len = original_checkpoints.len();
let checkpoints: BTreeMap<BlockHeight, block::Hash> =
let checkpoints: BTreeMap<block::Height, block::Hash> =
original_checkpoints.into_iter().collect();
// Check that the list starts with the correct genesis block
match checkpoints.iter().next() {
Some((BlockHeight(0), hash))
Some((block::Height(0), hash))
if (hash == &parameters::genesis_hash(Network::Mainnet)
|| hash == &parameters::genesis_hash(Network::Testnet)) => {}
Some((BlockHeight(0), _)) => {
Some((block::Height(0), _)) => {
Err("the genesis checkpoint does not match the Mainnet or Testnet genesis hash")?
}
Some(_) => Err("checkpoints must start at the genesis block height 0")?,
@ -135,7 +134,7 @@ impl CheckpointList {
}
let checkpoints = CheckpointList(checkpoints);
if checkpoints.max_height() > BlockHeight::MAX {
if checkpoints.max_height() > block::Height::MAX {
Err("checkpoint list contains invalid checkpoint: checkpoint height is greater than the maximum block height")?;
}
@ -145,7 +144,7 @@ impl CheckpointList {
/// Return true if there is a checkpoint at `height`.
///
/// See `BTreeMap::contains_key()` for details.
pub fn contains(&self, height: BlockHeight) -> bool {
pub fn contains(&self, height: block::Height) -> bool {
self.0.contains_key(&height)
}
@ -153,7 +152,7 @@ impl CheckpointList {
/// or None if there is no checkpoint at that height.
///
/// See `BTreeMap::get()` for details.
pub fn hash(&self, height: BlockHeight) -> Option<block::Hash> {
pub fn hash(&self, height: block::Height) -> Option<block::Hash> {
self.0.get(&height).cloned()
}
@ -161,15 +160,15 @@ impl CheckpointList {
///
/// If there is only a single checkpoint, then the maximum height will be
/// zero. (The genesis block.)
pub fn max_height(&self) -> BlockHeight {
pub fn max_height(&self) -> block::Height {
self.max_height_in_range(..)
.expect("checkpoint lists must have at least one checkpoint")
}
/// Return the block height of the highest checkpoint in a sub-range.
pub fn max_height_in_range<R>(&self, range: R) -> Option<BlockHeight>
pub fn max_height_in_range<R>(&self, range: R) -> Option<block::Height>
where
R: RangeBounds<BlockHeight>,
R: RangeBounds<block::Height>,
{
self.0.range(range).map(|(height, _)| *height).next_back()
}

View File

@ -26,7 +26,7 @@ fn checkpoint_list_genesis() -> Result<(), Error> {
));
// Make a checkpoint list containing the genesis block
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> =
let checkpoint_list: BTreeMap<block::Height, block::Hash> =
checkpoint_data.iter().cloned().collect();
let _ = CheckpointList::from_list(checkpoint_list)?;
@ -55,7 +55,8 @@ fn checkpoint_list_multiple() -> Result<(), Error> {
}
// Make a checkpoint list containing all the blocks
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoint_data.iter().cloned().collect();
let checkpoint_list: BTreeMap<block::Height, block::Hash> =
checkpoint_data.iter().cloned().collect();
let _ = CheckpointList::from_list(checkpoint_list)?;
Ok(())
@ -86,7 +87,8 @@ fn checkpoint_list_no_genesis_fail() -> Result<(), Error> {
));
// Make a checkpoint list containing the non-genesis block
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoint_data.iter().cloned().collect();
let checkpoint_list: BTreeMap<block::Height, block::Hash> =
checkpoint_data.iter().cloned().collect();
let _ = CheckpointList::from_list(checkpoint_list)
.expect_err("a checkpoint list with no genesis block should fail");
@ -98,10 +100,11 @@ fn checkpoint_list_no_genesis_fail() -> Result<(), Error> {
fn checkpoint_list_null_hash_fail() -> Result<(), Error> {
zebra_test::init();
let checkpoint_data = vec![(BlockHeight(0), block::Hash([0; 32]))];
let checkpoint_data = vec![(block::Height(0), block::Hash([0; 32]))];
// Make a checkpoint list containing the non-genesis block
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoint_data.iter().cloned().collect();
let checkpoint_list: BTreeMap<block::Height, block::Hash> =
checkpoint_data.iter().cloned().collect();
let _ = CheckpointList::from_list(checkpoint_list)
.expect_err("a checkpoint list with a null block hash should fail");
@ -113,18 +116,23 @@ fn checkpoint_list_null_hash_fail() -> Result<(), Error> {
fn checkpoint_list_bad_height_fail() -> Result<(), Error> {
zebra_test::init();
let checkpoint_data = vec![(BlockHeight(BlockHeight::MAX.0 + 1), block::Hash([1; 32]))];
let checkpoint_data = vec![(
block::Height(block::Height::MAX.0 + 1),
block::Hash([1; 32]),
)];
// Make a checkpoint list containing the non-genesis block
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoint_data.iter().cloned().collect();
let checkpoint_list: BTreeMap<block::Height, block::Hash> =
checkpoint_data.iter().cloned().collect();
let _ = CheckpointList::from_list(checkpoint_list).expect_err(
"a checkpoint list with an invalid block height (BlockHeight::MAX + 1) should fail",
"a checkpoint list with an invalid block height (block::Height::MAX + 1) should fail",
);
let checkpoint_data = vec![(BlockHeight(u32::MAX), block::Hash([1; 32]))];
let checkpoint_data = vec![(block::Height(u32::MAX), block::Hash([1; 32]))];
// Make a checkpoint list containing the non-genesis block
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoint_data.iter().cloned().collect();
let checkpoint_list: BTreeMap<block::Height, block::Hash> =
checkpoint_data.iter().cloned().collect();
let _ = CheckpointList::from_list(checkpoint_list)
.expect_err("a checkpoint list with an invalid block height (u32::MAX) should fail");
@ -176,8 +184,8 @@ fn checkpoint_list_duplicate_heights_fail() -> Result<(), Error> {
}
// Then add some fake entries with duplicate heights
checkpoint_data.push((BlockHeight(1), block::Hash([0xaa; 32])));
checkpoint_data.push((BlockHeight(1), block::Hash([0xbb; 32])));
checkpoint_data.push((block::Height(1), block::Hash([0xaa; 32])));
checkpoint_data.push((block::Height(1), block::Hash([0xbb; 32])));
// Make a checkpoint list containing some duplicate blocks
let _ = CheckpointList::from_list(checkpoint_data)
@ -204,8 +212,8 @@ fn checkpoint_list_duplicate_hashes_fail() -> Result<(), Error> {
}
// Then add some fake entries with duplicate hashes
checkpoint_data.push((BlockHeight(1), block::Hash([0xcc; 32])));
checkpoint_data.push((BlockHeight(2), block::Hash([0xcc; 32])));
checkpoint_data.push((block::Height(1), block::Hash([0xcc; 32])));
checkpoint_data.push((block::Height(2), block::Hash([0xcc; 32])));
// Make a checkpoint list containing some duplicate blocks
let _ = CheckpointList::from_list(checkpoint_data)

View File

@ -38,7 +38,7 @@ async fn single_item_checkpoint_list() -> Result<(), Report> {
let hash0 = block0.hash();
// Make a checkpoint list containing only the genesis block
let genesis_checkpoint_list: BTreeMap<BlockHeight, block::Hash> =
let genesis_checkpoint_list: BTreeMap<block::Height, block::Hash> =
[(block0.coinbase_height().unwrap(), hash0)]
.iter()
.cloned()
@ -57,7 +57,7 @@ async fn single_item_checkpoint_list() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
/// SPANDOC: Make sure the verifier service is ready
@ -90,7 +90,7 @@ async fn single_item_checkpoint_list() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
Ok(())
@ -119,7 +119,7 @@ async fn multi_item_checkpoint_list() -> Result<(), Report> {
}
// Make a checkpoint list containing all the blocks
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoint_data
let checkpoint_list: BTreeMap<block::Height, block::Hash> = checkpoint_data
.iter()
.map(|(_block, height, hash)| (*height, *hash))
.collect();
@ -137,7 +137,7 @@ async fn multi_item_checkpoint_list() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(1)
block::Height(1)
);
// Now verify each block
@ -184,7 +184,7 @@ async fn multi_item_checkpoint_list() -> Result<(), Report> {
}
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(1)
block::Height(1)
);
}
@ -198,7 +198,7 @@ async fn multi_item_checkpoint_list() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(1)
block::Height(1)
);
Ok(())
@ -208,14 +208,14 @@ async fn multi_item_checkpoint_list() -> Result<(), Report> {
async fn continuous_blockchain_test() -> Result<(), Report> {
continuous_blockchain(None).await?;
for height in 0..=10 {
continuous_blockchain(Some(BlockHeight(height))).await?;
continuous_blockchain(Some(block::Height(height))).await?;
}
Ok(())
}
/// Test a continuous blockchain, restarting verification at `restart_height`.
#[spandoc::spandoc]
async fn continuous_blockchain(restart_height: Option<BlockHeight>) -> Result<(), Report> {
async fn continuous_blockchain(restart_height: Option<block::Height>) -> Result<(), Report> {
zebra_test::init();
// A continuous blockchain
@ -251,7 +251,7 @@ async fn continuous_blockchain(restart_height: Option<BlockHeight>) -> Result<()
}
// The checkpoint list will contain only block 0, 5 and 9
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoints
let checkpoint_list: BTreeMap<block::Height, block::Hash> = checkpoints
.iter()
.map(|(_block, height, hash)| (*height, *hash))
.collect();
@ -259,7 +259,7 @@ async fn continuous_blockchain(restart_height: Option<BlockHeight>) -> Result<()
/// SPANDOC: Verify blocks, restarting at {?restart_height}
{
let initial_tip = restart_height
.map(|BlockHeight(height)| &blockchain[height as usize].0)
.map(|block::Height(height)| &blockchain[height as usize].0)
.cloned();
let mut checkpoint_verifier =
CheckpointVerifier::from_list(checkpoint_list, initial_tip).map_err(|e| eyre!(e))?;
@ -289,7 +289,7 @@ async fn continuous_blockchain(restart_height: Option<BlockHeight>) -> Result<()
}
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(9)
block::Height(9)
);
let mut handles = FuturesUnordered::new();
@ -354,7 +354,7 @@ async fn continuous_blockchain(restart_height: Option<BlockHeight>) -> Result<()
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(9)
block::Height(9)
);
}
@ -376,7 +376,7 @@ async fn block_higher_than_max_checkpoint_fail() -> Result<(), Report> {
Arc::<Block>::zcash_deserialize(&zebra_test::vectors::BLOCK_MAINNET_415000_BYTES[..])?;
// Make a checkpoint list containing only the genesis block
let genesis_checkpoint_list: BTreeMap<BlockHeight, block::Hash> =
let genesis_checkpoint_list: BTreeMap<block::Height, block::Hash> =
[(block0.coinbase_height().unwrap(), block0.as_ref().into())]
.iter()
.cloned()
@ -395,7 +395,7 @@ async fn block_higher_than_max_checkpoint_fail() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
/// SPANDOC: Make sure the verifier service is ready
@ -426,7 +426,7 @@ async fn block_higher_than_max_checkpoint_fail() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
Ok(())
@ -451,7 +451,7 @@ async fn wrong_checkpoint_hash_fail() -> Result<(), Report> {
let bad_block0: Arc<Block> = bad_block0.clone().into();
// Make a checkpoint list containing the genesis block checkpoint
let genesis_checkpoint_list: BTreeMap<BlockHeight, block::Hash> =
let genesis_checkpoint_list: BTreeMap<block::Height, block::Hash> =
[(good_block0.coinbase_height().unwrap(), good_block0_hash)]
.iter()
.cloned()
@ -470,7 +470,7 @@ async fn wrong_checkpoint_hash_fail() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
/// SPANDOC: Make sure the verifier service is ready (1/3)
@ -497,7 +497,7 @@ async fn wrong_checkpoint_hash_fail() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
/// SPANDOC: Make sure the verifier service is ready (2/3)
@ -524,7 +524,7 @@ async fn wrong_checkpoint_hash_fail() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
/// SPANDOC: Make sure the verifier service is ready (3/3)
@ -557,7 +557,7 @@ async fn wrong_checkpoint_hash_fail() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
// Now, await the bad futures, which should have completed
@ -580,7 +580,7 @@ async fn wrong_checkpoint_hash_fail() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
/// SPANDOC: Wait for the response for block 0, and expect failure again (2/3)
@ -601,7 +601,7 @@ async fn wrong_checkpoint_hash_fail() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(0)
block::Height(0)
);
Ok(())
@ -632,7 +632,7 @@ async fn checkpoint_drop_cancel() -> Result<(), Report> {
}
// Make a checkpoint list containing all the blocks
let checkpoint_list: BTreeMap<BlockHeight, block::Hash> = checkpoint_data
let checkpoint_list: BTreeMap<block::Height, block::Hash> = checkpoint_data
.iter()
.map(|(_block, height, hash)| (*height, *hash))
.collect();
@ -650,7 +650,7 @@ async fn checkpoint_drop_cancel() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(434873)
block::Height(434873)
);
let mut futures = Vec::new();
@ -673,7 +673,7 @@ async fn checkpoint_drop_cancel() -> Result<(), Report> {
// Only continuous checkpoints verify
assert_eq!(
checkpoint_verifier.previous_checkpoint_height(),
PreviousCheckpoint(BlockHeight(min(height.0, 1)))
PreviousCheckpoint(block::Height(min(height.0, 1)))
);
assert_eq!(
checkpoint_verifier.target_checkpoint_height(),
@ -681,7 +681,7 @@ async fn checkpoint_drop_cancel() -> Result<(), Report> {
);
assert_eq!(
checkpoint_verifier.checkpoint_list.max_height(),
BlockHeight(434873)
block::Height(434873)
);
}
@ -695,7 +695,7 @@ async fn checkpoint_drop_cancel() -> Result<(), Report> {
.await
.expect("timeout should not happen");
if height <= BlockHeight(1) {
if height <= block::Height(1) {
let verify_hash =
verify_response.expect("Continuous checkpoints should have succeeded before drop");
assert_eq!(verify_hash, hash);
@ -732,7 +732,7 @@ async fn hard_coded_mainnet() -> Result<(), Report> {
checkpoint_verifier.target_checkpoint_height(),
WaitingForBlocks
);
assert!(checkpoint_verifier.checkpoint_list.max_height() > BlockHeight(0));
assert!(checkpoint_verifier.checkpoint_list.max_height() > block::Height(0));
/// SPANDOC: Make sure the verifier service is ready
let ready_verifier_service = checkpoint_verifier
@ -756,14 +756,14 @@ async fn hard_coded_mainnet() -> Result<(), Report> {
assert_eq!(
checkpoint_verifier.previous_checkpoint_height(),
PreviousCheckpoint(BlockHeight(0))
PreviousCheckpoint(block::Height(0))
);
assert_eq!(
checkpoint_verifier.target_checkpoint_height(),
WaitingForBlocks
);
// The lists will get bigger over time, so we just pick a recent height
assert!(checkpoint_verifier.checkpoint_list.max_height() > BlockHeight(900_000));
assert!(checkpoint_verifier.checkpoint_list.max_height() > block::Height(900_000));
Ok(())
}

View File

@ -2,7 +2,7 @@
use std::cmp::Ordering;
use zebra_chain::block::BlockHeight;
use zebra_chain::block;
use Progress::*;
use Target::*;
@ -33,7 +33,7 @@ pub enum Progress<HeightOrHash> {
}
/// Block height progress, in chain order.
impl Ord for Progress<BlockHeight> {
impl Ord for Progress<block::Height> {
fn cmp(&self, other: &Self) -> Ordering {
if self == other {
return Ordering::Equal;
@ -56,7 +56,7 @@ impl Ord for Progress<BlockHeight> {
/// Partial order for block height progress.
///
/// The partial order must match the total order.
impl PartialOrd for Progress<BlockHeight> {
impl PartialOrd for Progress<block::Height> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
@ -79,7 +79,7 @@ pub enum Target<HeightOrHash> {
/// Block height target, in chain order.
///
/// `WaitingForBlocks` is incomparable with itself and `Checkpoint(_)`.
impl PartialOrd for Target<BlockHeight> {
impl PartialOrd for Target<block::Height> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self, other) {
// FinishedVerifying is the final state

View File

@ -1,10 +1,10 @@
//! The minimum difficulty block rule for Zcash.
use zebra_chain::{block::BlockHeight, parameters::Network};
use zebra_chain::{block, parameters::Network};
/// The testnet block height when minimum difficulty blocks start being
/// accepted.
pub(crate) const TESTNET_MINIMUM_DIFFICULTY_HEIGHT: BlockHeight = BlockHeight(299_188);
pub(crate) const TESTNET_MINIMUM_DIFFICULTY_HEIGHT: block::Height = block::Height(299_188);
/// The Zcash Testnet consensus rules were changed to allow
/// minimum-difficulty blocks, shortly after Testnet Sapling activation.
@ -26,7 +26,7 @@ pub enum MinimumDifficulty {
impl MinimumDifficulty {
/// Returns the current minimum difficulty rule for `network` and `height`.
pub fn current(network: Network, height: BlockHeight) -> MinimumDifficulty {
pub fn current(network: Network, height: block::Height) -> MinimumDifficulty {
use MinimumDifficulty::*;
use Network::*;

View File

@ -3,7 +3,7 @@
use super::*;
use zebra_chain::{
block::BlockHeight,
block,
parameters::Network::{self, *},
};
@ -19,6 +19,7 @@ fn minimum_difficulty_testnet() {
/// Test MinimumDifficulty
fn minimum_difficulty(network: Network) {
use block::Height;
use MinimumDifficulty::*;
let allowed_if_testnet = match network {
@ -26,24 +27,21 @@ fn minimum_difficulty(network: Network) {
Testnet => AllowedOnTestnet,
};
assert_eq!(MinimumDifficulty::current(network, Height(0)), Rejected);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight(0)),
MinimumDifficulty::current(network, Height(299_187)),
Rejected
);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight(299_187)),
Rejected
);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight(299_188)),
MinimumDifficulty::current(network, Height(299_188)),
allowed_if_testnet
);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight(299_189)),
MinimumDifficulty::current(network, Height(299_189)),
allowed_if_testnet
);
assert_eq!(
MinimumDifficulty::current(network, BlockHeight::MAX),
MinimumDifficulty::current(network, Height::MAX),
allowed_if_testnet
);
}

View File

@ -28,7 +28,7 @@ use tower::Service;
use tracing_futures::Instrument;
use zebra_chain::{
block::{Block, self},
block::{self, Block},
serialization::SerializationError,
};

View File

@ -18,7 +18,7 @@ use tower::Service;
use tracing::{span, Level};
use tracing_futures::Instrument;
use zebra_chain::block::BlockHeight;
use zebra_chain::block;
use crate::{
constants,
@ -137,7 +137,7 @@ where
// for a service that gets the current block height. Among other
// things we need it to reject peers who don't know about the
// current protocol epoch.
start_height: BlockHeight(0),
start_height: block::Height(0),
relay: false,
};

View File

@ -9,8 +9,7 @@ use chrono::{TimeZone, Utc};
use tokio_util::codec::{Decoder, Encoder};
use zebra_chain::{
block::BlockHeight,
block::{Block, self},
block::{self, Block},
parameters::Network,
serialization::{
sha256d, ReadZcashExt, SerializationError as Error, WriteZcashExt, ZcashDeserialize,
@ -429,7 +428,7 @@ impl Codec {
),
nonce: Nonce(reader.read_u64::<LittleEndian>()?),
user_agent: reader.read_string()?,
start_height: BlockHeight(reader.read_u32::<LittleEndian>()?),
start_height: block::Height(reader.read_u32::<LittleEndian>()?),
relay: match reader.read_u8()? {
0 => false,
1 => true,
@ -599,7 +598,7 @@ mod tests {
),
nonce: Nonce(0x9082_4908_8927_9238),
user_agent: "Zebra".to_owned(),
start_height: BlockHeight(540_000),
start_height: block::Height(540_000),
relay: true,
};

View File

@ -5,8 +5,8 @@ use std::{net, sync::Arc};
use chrono::{DateTime, Utc};
use zebra_chain::block::{Block, self};
use zebra_chain::{block::BlockHeight, block::BlockHeader, transaction::Transaction};
use zebra_chain::block::{self, Block};
use zebra_chain::{block::BlockHeader, transaction::Transaction};
use super::inv::InventoryHash;
use super::types::*;
@ -66,7 +66,7 @@ pub enum Message {
user_agent: String,
/// The last block received by the emitting node.
start_height: BlockHeight,
start_height: block::Height,
/// Whether the remote peer should announce relayed
/// transactions or not, see [BIP 0037](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki)

View File

@ -5,7 +5,7 @@ use crate::constants::magics;
use std::fmt;
use zebra_chain::{
block::BlockHeight,
block,
parameters::{
Network::{self, *},
NetworkUpgrade::{self, *},
@ -64,7 +64,7 @@ impl Version {
///
/// Returns None if the network has no branch id at this height.
#[allow(dead_code)]
pub fn current_min(network: Network, height: BlockHeight) -> Version {
pub fn current_min(network: Network, height: block::Height) -> Version {
let network_upgrade = NetworkUpgrade::current(network, height);
Version::min_for_upgrade(network, network_upgrade)
}
@ -153,14 +153,14 @@ mod test {
/// extreme values.
fn version_extremes(network: Network) {
assert_eq!(
Version::current_min(network, BlockHeight(0)),
Version::current_min(network, block::Height(0)),
Version::min_for_upgrade(network, BeforeOverwinter),
);
// We assume that the last version we know about continues forever
// (even if we suspect that won't be true)
assert_ne!(
Version::current_min(network, BlockHeight::MAX),
Version::current_min(network, block::Height::MAX),
Version::min_for_upgrade(network, BeforeOverwinter),
);
}
@ -178,7 +178,7 @@ mod test {
/// Check that the min_for_upgrade and current_min functions
/// are consistent for `network`.
fn version_consistent(network: Network) {
let highest_network_upgrade = NetworkUpgrade::current(network, BlockHeight::MAX);
let highest_network_upgrade = NetworkUpgrade::current(network, block::Height::MAX);
assert!(highest_network_upgrade == Canopy || highest_network_upgrade == Heartwood,
"expected coverage of all network upgrades: add the new network upgrade to the list in this test");

View File

@ -1,4 +1,4 @@
use zebra_chain::block::{Block, self};
use zebra_chain::block::{self, Block};
use crate::meta_addr::MetaAddr;
use std::sync::Arc;

View File

@ -3,14 +3,11 @@ use std::{
error::Error,
sync::Arc,
};
use zebra_chain::{
block::BlockHeight,
block::{Block, self},
};
use zebra_chain::block::{self, Block};
#[derive(Default)]
pub(super) struct BlockIndex {
by_hash: HashMap<block::Hash, Arc<Block>>,
height_map: BTreeMap<BlockHeight, block::Hash>,
height_map: BTreeMap<block::Height, block::Hash>,
}
impl BlockIndex {
@ -36,7 +33,7 @@ impl BlockIndex {
self.by_hash.get(&hash).cloned()
}
pub(super) fn get_main_chain_at(&self, height: BlockHeight) -> Option<block::Hash> {
pub(super) fn get_main_chain_at(&self, height: block::Height) -> Option<block::Hash> {
self.height_map.get(&height).cloned()
}

View File

@ -22,8 +22,7 @@ use std::{error, iter, sync::Arc};
use tower::{Service, ServiceExt};
use zebra_chain::{
block::BlockHeight,
block::{Block, self},
block::{self, Block},
parameters::Network,
};
@ -35,13 +34,13 @@ pub mod on_disk;
/// A transaction MUST NOT spend a transparent output of a coinbase transaction
/// from a block less than 100 blocks prior to the spend. Note that transparent
/// outputs of coinbase transactions include Founders' Reward outputs.
const MIN_TRASPARENT_COINBASE_MATURITY: BlockHeight = BlockHeight(100);
const MIN_TRASPARENT_COINBASE_MATURITY: block::Height = block::Height(100);
/// The maximum chain reorganisation height.
///
/// Allowing reorganisations past this height could allow double-spends of
/// coinbase transactions.
const MAX_BLOCK_REORG_HEIGHT: BlockHeight = BlockHeight(MIN_TRASPARENT_COINBASE_MATURITY.0 - 1);
const MAX_BLOCK_REORG_HEIGHT: block::Height = block::Height(MIN_TRASPARENT_COINBASE_MATURITY.0 - 1);
/// Configuration for the state service.
#[derive(Clone, Debug, Deserialize, Serialize)]
@ -162,7 +161,7 @@ pub enum Response {
}
/// Get the heights of the blocks for constructing a block_locator list
fn block_locator_heights(tip_height: BlockHeight) -> impl Iterator<Item = BlockHeight> {
fn block_locator_heights(tip_height: block::Height) -> impl Iterator<Item = block::Height> {
// Stop at the reorg limit, or the genesis block.
let min_locator_height = tip_height.0.saturating_sub(MAX_BLOCK_REORG_HEIGHT.0);
let locators = iter::successors(Some(1u32), |h| h.checked_mul(2))
@ -171,7 +170,7 @@ fn block_locator_heights(tip_height: BlockHeight) -> impl Iterator<Item = BlockH
.chain(locators)
.take_while(move |&height| height > min_locator_height)
.chain(iter::once(min_locator_height))
.map(BlockHeight);
.map(block::Height);
let locators: Vec<_> = locators.collect();
tracing::info!(
@ -279,7 +278,7 @@ mod tests {
#[test]
fn test_block_locator_heights() {
for (height, min_height) in BLOCK_LOCATOR_CASES.iter().cloned() {
let locator = block_locator_heights(BlockHeight(height)).collect::<Vec<_>>();
let locator = block_locator_heights(block::Height(height)).collect::<Vec<_>>();
assert!(!locator.is_empty(), "locators must not be empty");
if (height - min_height) > 1 {
@ -291,7 +290,7 @@ mod tests {
assert_eq!(
locator[0],
BlockHeight(height),
block::Height(height),
"locators must start with the tip height"
);
@ -305,7 +304,7 @@ mod tests {
let final_height = locator[locator.len() - 1];
assert_eq!(
final_height,
BlockHeight(min_height),
block::Height(min_height),
"locators must end with the specified final height"
);
assert!(height - final_height.0 <= MAX_BLOCK_REORG_HEIGHT.0,

View File

@ -13,8 +13,7 @@ use tower::{buffer::Buffer, util::BoxService, Service};
use tracing::instrument;
use zebra_chain::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
use zebra_chain::{
block::BlockHeight,
block::{Block, self},
block::{self, Block},
parameters::Network,
};
@ -75,7 +74,7 @@ impl SledState {
#[instrument(skip(self))]
pub(super) fn get_main_chain_at(
&self,
height: BlockHeight,
height: block::Height,
) -> Result<Option<block::Hash>, Error> {
let height_map = self.storage.open_tree(b"height_map")?;
let key = height.0.to_be_bytes();
@ -212,12 +211,12 @@ impl Service<Request> for SledState {
}
}
/// An alternate repr for `BlockHeight` that implements `AsRef<[u8]>` for usage
/// An alternate repr for `block::Height` that implements `AsRef<[u8]>` for usage
/// with sled
struct BytesHeight(u32, [u8; 4]);
impl From<BlockHeight> for BytesHeight {
fn from(height: BlockHeight) -> Self {
impl From<block::Height> for BytesHeight {
fn from(height: block::Height) -> Self {
let bytes = height.0.to_be_bytes();
Self(height.0, bytes)
}
@ -231,7 +230,7 @@ impl AsRef<[u8]> for BytesHeight {
pub(super) enum BlockQuery {
ByHash(block::Hash),
ByHeight(BlockHeight),
ByHeight(block::Height),
}
impl From<block::Hash> for BlockQuery {
@ -240,8 +239,8 @@ impl From<block::Hash> for BlockQuery {
}
}
impl From<BlockHeight> for BlockQuery {
fn from(height: BlockHeight) -> Self {
impl From<block::Height> for BlockQuery {
fn from(height: block::Height) -> Self {
Self::ByHeight(height)
}
}

View File

@ -18,7 +18,6 @@ use structopt::StructOpt;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use zebra_chain::block;
use zebra_chain::block::BlockHeight;
#[cfg(unix)]
use std::os::unix::process::ExitStatusExt;
@ -47,7 +46,7 @@ const MAX_CHECKPOINT_BYTE_COUNT: u64 = 256 * 1024 * 1024;
/// Checkpoints must be on the main chain, so we skip blocks that are within the
/// zcashd reorg limit.
const BLOCK_REORG_LIMIT: BlockHeight = BlockHeight(100);
const BLOCK_REORG_LIMIT: block::Height = block::Height(100);
/// Initialise tracing using its defaults.
fn init_tracing() {
@ -102,22 +101,22 @@ fn main() -> Result<()> {
let mut cmd = passthrough_cmd();
cmd.arg("getblockcount");
// calculate the maximum height
let height_limit: BlockHeight = cmd_output(&mut cmd)?.trim().parse()?;
assert!(height_limit <= BlockHeight::MAX);
let height_limit: block::Height = cmd_output(&mut cmd)?.trim().parse()?;
assert!(height_limit <= block::Height::MAX);
let height_limit = height_limit
.0
.checked_sub(BLOCK_REORG_LIMIT.0)
.map(BlockHeight)
.map(block::Height)
.expect("zcashd has some mature blocks: wait for zcashd to sync more blocks");
let starting_height = args::Args::from_args().last_checkpoint.map(BlockHeight);
let starting_height = args::Args::from_args().last_checkpoint.map(block::Height);
if starting_height.is_some() {
// Since we're about to add 1, height needs to be strictly less than the maximum
assert!(starting_height.unwrap() < BlockHeight::MAX);
assert!(starting_height.unwrap() < block::Height::MAX);
}
// Start at the next block after the last checkpoint.
// If there is no last checkpoint, start at genesis (height 0).
let starting_height = starting_height.map_or(0, |BlockHeight(h)| h + 1);
let starting_height = starting_height.map_or(0, |block::Height(h)| h + 1);
assert!(
starting_height < height_limit.0,
@ -126,7 +125,7 @@ fn main() -> Result<()> {
// set up counters
let mut cumulative_bytes: u64 = 0;
let mut height_gap: BlockHeight = BlockHeight(0);
let mut height_gap: block::Height = block::Height(0);
// loop through all blocks
for x in starting_height..height_limit.0 {
@ -141,17 +140,17 @@ fn main() -> Result<()> {
// get the values we are interested in
let hash: block::Hash = v["hash"].as_str().map(byte_reverse_hex).unwrap().parse()?;
let height = BlockHeight(v["height"].as_u64().unwrap() as u32);
assert!(height <= BlockHeight::MAX);
let height = block::Height(v["height"].as_u64().unwrap() as u32);
assert!(height <= block::Height::MAX);
assert_eq!(x, height.0);
let size = v["size"].as_u64().unwrap();
// compute
cumulative_bytes += size;
height_gap = BlockHeight(height_gap.0 + 1);
height_gap = block::Height(height_gap.0 + 1);
// check if checkpoint
if height == BlockHeight(0)
if height == block::Height(0)
|| cumulative_bytes >= MAX_CHECKPOINT_BYTE_COUNT
|| height_gap.0 >= zebra_consensus::checkpoint::MAX_CHECKPOINT_HEIGHT_GAP as u32
{
@ -160,7 +159,7 @@ fn main() -> Result<()> {
// reset counters
cumulative_bytes = 0;
height_gap = BlockHeight(0);
height_gap = block::Height(0);
}
}

View File

@ -8,7 +8,7 @@ use tower::{builder::ServiceBuilder, retry::Retry, timeout::Timeout, Service, Se
use tracing_futures::Instrument;
use zebra_chain::{
block::{Block, self},
block::{self, Block},
parameters::Network,
};
use zebra_consensus::checkpoint;