pub fn get_closest_checkpoint(chain_name: &str, height: u64) -> Option<(u64, &'static str, &'static str)> { match chain_name { "test" => get_test_checkpoint(height), "main" => get_main_checkpoint(height), _ => None } } fn get_test_checkpoint(height: u64) -> Option<(u64, &'static str, &'static str)> { let checkpoints: Vec<(u64, &str, &str)> = vec![ (130000, "000000001c4a5aa11e6c142931463fcf7a9f5b9fb41061d26c18ff1860431881", "" ), (152000, "00000000d7c0f7d63b7e628cfcb9fdd45c9d2a244326532c61dfff7fb0d4af45", "" ) ]; find_checkpoint(height, checkpoints) } fn get_main_checkpoint(height: u64) -> Option<(u64, &'static str, &'static str)> { let checkpoints: Vec<(u64, &str, &str)> = vec![ (170947, "0000000269bfc4db6f23aff43dba54afe20398018082cd8b5e90644257b5adc9", "0000000269bfc4db6f23aff43dba54afe20398018082cd8b5e90644257b5adc9" ) ]; find_checkpoint(height, checkpoints) } fn find_checkpoint(height: u64, chkpts: Vec<(u64, &'static str, &'static str)>) -> Option<(u64, &'static str, &'static str)> { // Find the closest checkpoint let mut heights = chkpts.iter().map(|(h, _, _)| *h as u64).collect::>(); heights.sort(); match get_first_lower_than(height, heights) { Some(closest_height) => { chkpts.iter().find(|(h, _, _)| *h == closest_height).map(|t| *t) }, None => None } } fn get_first_lower_than(height: u64, heights: Vec) -> Option { // If it's before the first checkpoint, return None. if heights.len() == 0 || height < heights[0] { return None; } for (i, h) in heights.iter().enumerate() { if height < *h { return Some(heights[i-1]); } } return Some(*heights.last().unwrap()); } #[cfg(test)] pub mod tests { use super::*; #[test] fn test_lower_than() { assert_eq!(get_first_lower_than( 9, vec![10, 30, 40]), None); assert_eq!(get_first_lower_than(10, vec![10, 30, 40]).unwrap(), 10); assert_eq!(get_first_lower_than(11, vec![10, 30, 40]).unwrap(), 10); assert_eq!(get_first_lower_than(29, vec![10, 30, 40]).unwrap(), 10); assert_eq!(get_first_lower_than(30, vec![10, 30, 40]).unwrap(), 30); assert_eq!(get_first_lower_than(40, vec![10, 30, 40]).unwrap(), 40); assert_eq!(get_first_lower_than(41, vec![10, 30, 40]).unwrap(), 40); assert_eq!(get_first_lower_than(99, vec![10, 30, 40]).unwrap(), 40); } #[test] fn test_checkpoints() { assert_eq!(get_test_checkpoint(100000), None); assert_eq!(get_test_checkpoint(120000).unwrap().0, 120000); assert_eq!(get_test_checkpoint(125000).unwrap().0, 120000); assert_eq!(get_test_checkpoint(157000).unwrap().0, 157000); assert_eq!(get_test_checkpoint(175000).unwrap().0, 157000); assert_eq!(get_main_checkpoint(100000), None); assert_eq!(get_main_checkpoint(170947).unwrap().0, 170947); assert_eq!(get_main_checkpoint(170949).unwrap().0, 170947); } }