From 336c8277c5aa0bfe23effb8e314f726300f046b5 Mon Sep 17 00:00:00 2001 From: Arya Date: Fri, 19 Apr 2024 17:18:06 -0400 Subject: [PATCH] Checks that there is _some_ genesis block in the checkpoints list in `from_list()`, adds Regtest checkpoints (which only includes the genesis block) --- zebra-consensus/src/checkpoint/list.rs | 17 +++++++++++++++-- zebra-consensus/src/checkpoint/list/tests.rs | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/zebra-consensus/src/checkpoint/list.rs b/zebra-consensus/src/checkpoint/list.rs index d1d44a3d0..ffe60ffb8 100644 --- a/zebra-consensus/src/checkpoint/list.rs +++ b/zebra-consensus/src/checkpoint/list.rs @@ -66,7 +66,13 @@ impl ParameterCheckpoint for Network { fn checkpoint_list(&self) -> CheckpointList { let checkpoints_for_network = match self { Network::Mainnet => MAINNET_CHECKPOINTS, - Network::Testnet(_) => TESTNET_CHECKPOINTS, + Network::Testnet(params) if !params.is_regtest() => TESTNET_CHECKPOINTS, + // Returns only the genesis checkpoint for Regtest + Network::Testnet(_params) => { + // It's okay to skip checking the hard-coded genesis checkpoint is the genesis checkpoint + return CheckpointList::from_list([(block::Height(0), self.genesis_hash())]) + .expect("hard-coded checkpoint list parses and validates"); + } }; // Check that the list starts with the correct genesis block and parses checkpoint list. @@ -80,7 +86,7 @@ impl ParameterCheckpoint for Network { // parse calls CheckpointList::from_list Ok((block::Height(0), hash)) if hash == self.genesis_hash() => checkpoints_for_network .parse() - .expect("Hard-coded checkpoint list parses and validates"), + .expect("hard-coded checkpoint list parses and validates"), Ok((block::Height(0), _)) => { panic!("the genesis checkpoint does not match the Mainnet or Testnet genesis hash") } @@ -151,6 +157,13 @@ impl CheckpointList { let checkpoints: BTreeMap = original_checkpoints.into_iter().collect(); + // Check that the list starts with _some_ genesis block + match checkpoints.iter().next() { + Some((block::Height(0), _hash)) => {} + Some(_) => Err("checkpoints must start at the genesis block height 0")?, + None => Err("there must be at least one checkpoint, for the genesis block")?, + }; + // This check rejects duplicate heights, whether they have the same or // different hashes if checkpoints.len() != original_len { diff --git a/zebra-consensus/src/checkpoint/list/tests.rs b/zebra-consensus/src/checkpoint/list/tests.rs index 09288dfc0..1df05327d 100644 --- a/zebra-consensus/src/checkpoint/list/tests.rs +++ b/zebra-consensus/src/checkpoint/list/tests.rs @@ -237,6 +237,7 @@ fn checkpoint_list_load_hard_coded() -> Result<(), BoxError> { let _ = Mainnet.checkpoint_list(); let _ = Network::new_default_testnet().checkpoint_list(); + let _ = Network::new_regtest(Default::default()).checkpoint_list(); Ok(()) }