diff --git a/zebra-consensus/src/checkpoint/list/tests.rs b/zebra-consensus/src/checkpoint/list/tests.rs index d566c5075..9ad1febeb 100644 --- a/zebra-consensus/src/checkpoint/list/tests.rs +++ b/zebra-consensus/src/checkpoint/list/tests.rs @@ -280,8 +280,8 @@ fn checkpoint_list_hard_coded_max_gap_testnet() -> Result<(), BoxError> { /// Check that the hard-coded checkpoints are within [`MAX_CHECKPOINT_HEIGHT_GAP`], /// and a calculated minimum number of blocks. This also checks the heights are in order. /// -/// We can't test [`MAX_CHECKPOINT_BYTE_COUNT`] directly, because we don't have access to the -/// entire blockchain in the tests. Instead, we check the number of maximum-size blocks in a +/// We can't test [`MAX_CHECKPOINT_BYTE_COUNT`] directly, because we don't have access to a large +/// enough blockchain in the tests. Instead, we check the number of maximum-size blocks in a /// checkpoint. (This is ok, because the byte count only impacts performance.) fn checkpoint_list_hard_coded_max_gap(network: Network) -> Result<(), BoxError> { let _init_guard = zebra_test::init(); diff --git a/zebra-utils/src/bin/zebra-checkpoints/main.rs b/zebra-utils/src/bin/zebra-checkpoints/main.rs index 6481df8b7..a8d2d4e3e 100644 --- a/zebra-utils/src/bin/zebra-checkpoints/main.rs +++ b/zebra-utils/src/bin/zebra-checkpoints/main.rs @@ -14,7 +14,7 @@ use std::{ffi::OsString, process::Stdio}; use std::os::unix::process::ExitStatusExt; use color_eyre::{ - eyre::{ensure, Result}, + eyre::{ensure, eyre, Result}, Help, }; use itertools::Itertools; @@ -166,8 +166,14 @@ async fn main() -> Result<()> { // Zcash reorg limit. let height_limit = height_limit - HeightDiff::try_from(MIN_TRANSPARENT_COINBASE_MATURITY).expect("constant fits in i32"); - let height_limit = - height_limit.expect("node has some mature blocks: wait for it to sync more blocks"); + let height_limit = height_limit + .ok_or_else(|| { + eyre!( + "checkpoint generation needs at least {:?} blocks", + MIN_TRANSPARENT_COINBASE_MATURITY + ) + }) + .with_suggestion(|| "Hint: wait for the node to sync more blocks")?; // Start at the next block after the last checkpoint. // If there is no last checkpoint, start at genesis (height 0). @@ -180,7 +186,8 @@ async fn main() -> Result<()> { assert!( starting_height < height_limit, - "No mature blocks after the last checkpoint: wait for node to sync more blocks" + "checkpoint generation needs more blocks than the starting height {starting_height:?}. \ + Hint: wait for the node to sync more blocks" ); // set up counters @@ -232,15 +239,19 @@ async fn main() -> Result<()> { let block_bytes: Vec = hex::decode(block_bytes)?; - // TODO: is it faster to call both `getblock height 0` and `getblock height 1`, - // rather than deserializing the block and calculating its hash? + // TODO: is it faster to call both `getblock height verbosity=0` + // and `getblock height verbosity=1`, rather than deserializing the block + // and calculating its hash? + // + // It seems to be fast enough for checkpoint updates for now, + // but generating the full list takes more than an hour. let block: Block = block_bytes.zcash_deserialize_into()?; ( block.hash(), block .coinbase_height() - .expect("block has always a coinbase height"), + .expect("valid blocks always have a coinbase height"), block_bytes.len().try_into()?, ) }