Rename "Level" -> "Altitude"

The FlyClient spec uses "Altitude" for this concept in
Merkle mountain ranges, so I'm renaming for consistency.
This commit is contained in:
Kris Nuttycombe 2021-06-19 11:24:33 -06:00
parent d319262985
commit aed785e896
3 changed files with 95 additions and 95 deletions

View File

@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::Hash; use std::hash::Hash;
use super::{Hashable, Level, Recording, Tree}; use super::{Altitude, Hashable, Recording, Tree};
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[repr(transparent)] #[repr(transparent)]
@ -19,18 +19,18 @@ impl Position {
self.0 += 1 self.0 += 1
} }
fn max_level(&self) -> Level { fn max_level(&self) -> Altitude {
Level(if self.0 == 0 { Altitude(if self.0 == 0 {
0 0
} else { } else {
63 - self.0.leading_zeros() 63 - self.0.leading_zeros()
}) })
} }
pub fn parent_levels(&self) -> impl Iterator<Item = Level> + '_ { pub fn parent_levels(&self) -> impl Iterator<Item = Altitude> + '_ {
(0..=self.max_level().0).into_iter().filter_map(move |i| { (0..=self.max_level().0).into_iter().filter_map(move |i| {
if i != 0 && self.0 & (1 << i) != 0 { if i != 0 && self.0 & (1 << i) != 0 {
Some(Level(i)) Some(Altitude(i))
} else { } else {
None None
} }
@ -41,29 +41,29 @@ impl Position {
self.levels_required().count() self.levels_required().count()
} }
pub fn levels_required(&self) -> impl Iterator<Item = Level> + '_ { pub fn levels_required(&self) -> impl Iterator<Item = Altitude> + '_ {
(0..=(self.max_level() + 1).0) (0..=(self.max_level() + 1).0)
.into_iter() .into_iter()
.filter_map(move |i| { .filter_map(move |i| {
if self.0 == 0 || self.0 & (1 << i) == 0 { if self.0 == 0 || self.0 & (1 << i) == 0 {
Some(Level(i)) Some(Altitude(i))
} else { } else {
None None
} }
}) })
} }
pub fn all_levels_required(&self) -> impl Iterator<Item = Level> + '_ { pub fn all_levels_required(&self) -> impl Iterator<Item = Altitude> + '_ {
(0..64).into_iter().filter_map(move |i| { (0..64).into_iter().filter_map(move |i| {
if self.0 == 0 || self.0 & (1 << i) == 0 { if self.0 == 0 || self.0 & (1 << i) == 0 {
Some(Level(i)) Some(Altitude(i))
} else { } else {
None None
} }
}) })
} }
pub fn is_complete(&self, to_level: Level) -> bool { pub fn is_complete(&self, to_level: Altitude) -> bool {
for i in 0..(to_level.0) { for i in 0..(to_level.0) {
if self.0 & (1 << i) == 0 { if self.0 & (1 << i) == 0 {
return false; return false;
@ -72,7 +72,7 @@ impl Position {
true true
} }
pub fn has_observed(&self, level: Level, since: Position) -> bool { pub fn has_observed(&self, level: Altitude, since: Position) -> bool {
let level_delta = 2usize.pow(level.0); let level_delta = 2usize.pow(level.0);
self.0 - since.0 > level_delta self.0 - since.0 > level_delta
} }
@ -120,9 +120,9 @@ impl<H: Hashable + Clone> NonEmptyFrontier<H> {
Leaf::Right(a, b) => { Leaf::Right(a, b) => {
carry = Some(( carry = Some((
Parent { Parent {
value: H::combine(Level::zero(), &a, &b), value: H::combine(Altitude::zero(), &a, &b),
}, },
Level::one(), Altitude::one(),
)); ));
self.leaf = Leaf::Left(value); self.leaf = Leaf::Left(value);
} }
@ -171,8 +171,8 @@ impl<H: Hashable + Clone> NonEmptyFrontier<H> {
/// If the tree is full to the specified level, return the data /// If the tree is full to the specified level, return the data
/// required to witness a sibling at that level. /// required to witness a sibling at that level.
pub fn witness(&self, sibling_level: Level) -> Option<H> { pub fn witness(&self, sibling_level: Altitude) -> Option<H> {
if sibling_level == Level::zero() { if sibling_level == Altitude::zero() {
match &self.leaf { match &self.leaf {
Leaf::Left(_) => None, Leaf::Left(_) => None,
Leaf::Right(_, a) => Some(a.clone()), Leaf::Right(_, a) => Some(a.clone()),
@ -193,13 +193,13 @@ impl<H: Hashable + Clone> NonEmptyFrontier<H> {
/// If the tree is not full, generate the root of the incomplete subtree /// If the tree is not full, generate the root of the incomplete subtree
/// by hashing with empty branches /// by hashing with empty branches
pub fn witness_incomplete(&self, level: Level) -> Option<H> { pub fn witness_incomplete(&self, level: Altitude) -> Option<H> {
if self.position.is_complete(level) { if self.position.is_complete(level) {
// if the tree is complete to this level, its hash should // if the tree is complete to this level, its hash should
// have already been included in an auth fragment. // have already been included in an auth fragment.
None None
} else { } else {
Some(if level == Level::zero() { Some(if level == Altitude::zero() {
H::empty_leaf() H::empty_leaf()
} else { } else {
Self::inner_root( Self::inner_root(
@ -217,14 +217,14 @@ impl<H: Hashable + Clone> NonEmptyFrontier<H> {
position: Position, position: Position,
leaf: &Leaf<H>, leaf: &Leaf<H>,
parents: &[Parent<H>], parents: &[Parent<H>],
result_lvl: Option<Level>, result_lvl: Option<Altitude>,
) -> H { ) -> H {
let mut digest = match leaf { let mut digest = match leaf {
Leaf::Left(a) => H::combine(Level::zero(), a, &H::empty_leaf()), Leaf::Left(a) => H::combine(Altitude::zero(), a, &H::empty_leaf()),
Leaf::Right(a, b) => H::combine(Level::zero(), a, b), Leaf::Right(a, b) => H::combine(Altitude::zero(), a, b),
}; };
let mut complete_lvl = Level::one(); let mut complete_lvl = Altitude::one();
for (parent, parent_lvl) in parents.iter().zip(position.parent_levels()) { for (parent, parent_lvl) in parents.iter().zip(position.parent_levels()) {
// stop once we've reached the max level // stop once we've reached the max level
if result_lvl if result_lvl
@ -264,8 +264,8 @@ impl<H: Hashable + Clone> NonEmptyFrontier<H> {
} }
} }
pub fn value_at(&self, lvl: Level) -> Option<H> { pub fn value_at(&self, lvl: Altitude) -> Option<H> {
if lvl == Level::zero() { if lvl == Altitude::zero() {
Some(self.leaf_value()) Some(self.leaf_value())
} else { } else {
self.parents self.parents
@ -276,7 +276,7 @@ impl<H: Hashable + Clone> NonEmptyFrontier<H> {
} }
} }
pub fn max_level(&self) -> Level { pub fn max_level(&self) -> Altitude {
self.position.max_level() self.position.max_level()
} }
@ -289,14 +289,14 @@ impl<H: Hashable + Clone> NonEmptyFrontier<H> {
/// full functionality of a Merkle bridge is not necessary. /// full functionality of a Merkle bridge is not necessary.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Frontier<H> { pub struct Frontier<H> {
max_level: Level, max_level: Altitude,
frontier: Option<NonEmptyFrontier<H>>, frontier: Option<NonEmptyFrontier<H>>,
} }
impl<H> Frontier<H> { impl<H> Frontier<H> {
pub fn new(max_depth: usize) -> Self { pub fn new(max_depth: usize) -> Self {
Frontier { Frontier {
max_level: Level(max_depth as u32 - 1), max_level: Altitude(max_depth as u32 - 1),
frontier: None, frontier: None,
} }
} }
@ -371,7 +371,7 @@ impl<A> AuthFragment<A> {
self.levels_observed >= self.position.levels_required_count() self.levels_observed >= self.position.levels_required_count()
} }
pub fn next_required_level(&self) -> Option<Level> { pub fn next_required_level(&self) -> Option<Altitude> {
self.position self.position
.all_levels_required() .all_levels_required()
.nth(self.levels_observed) .nth(self.levels_observed)
@ -449,7 +449,7 @@ impl<H: Hashable + Clone + PartialEq> MerkleBridge<H> {
} }
} }
pub fn max_level(&self) -> Level { pub fn max_level(&self) -> Altitude {
self.frontier.max_level() self.frontier.max_level()
} }
@ -518,7 +518,7 @@ pub struct BridgeTree<H: Hash + Eq> {
/// Version value for the serialized form /// Version value for the serialized form
ser_version: u8, ser_version: u8,
/// The depth of the Merkle tree /// The depth of the Merkle tree
max_level: Level, max_level: Altitude,
/// The ordered list of Merkle bridges representing the history /// The ordered list of Merkle bridges representing the history
/// of the tree. There will be one bridge for each saved leaf, plus /// of the tree. There will be one bridge for each saved leaf, plus
/// the current bridge to the tip of the tree. /// the current bridge to the tip of the tree.
@ -550,7 +550,7 @@ impl<H: Hashable + Hash + Eq + Clone> BridgeTree<H> {
pub fn new(max_depth: usize, max_checkpoints: usize) -> Self { pub fn new(max_depth: usize, max_checkpoints: usize) -> Self {
BridgeTree { BridgeTree {
ser_version: 0, ser_version: 0,
max_level: Level(max_depth as u32 - 1), max_level: Altitude(max_depth as u32 - 1),
bridges: vec![], bridges: vec![],
incomplete_from: 0, incomplete_from: 0,
saved: HashMap::new(), saved: HashMap::new(),
@ -688,7 +688,7 @@ impl<H: Hashable + Hash + Eq + Clone> Tree<H> for BridgeTree<H> {
result.push( result.push(
auth_values auth_values
.next() .next()
.unwrap_or_else(|| H::empty_root(Level(synth_lvl as u32))), .unwrap_or_else(|| H::empty_root(Altitude(synth_lvl as u32))),
) )
} }
result.push(parent.value.clone()); result.push(parent.value.clone());
@ -698,7 +698,7 @@ impl<H: Hashable + Hash + Eq + Clone> Tree<H> for BridgeTree<H> {
result.push( result.push(
auth_values auth_values
.next() .next()
.unwrap_or_else(|| H::empty_root(Level(synth_lvl as u32))), .unwrap_or_else(|| H::empty_root(Altitude(synth_lvl as u32))),
); );
} }
@ -815,7 +815,7 @@ impl<H: Hashable + Hash + Eq + Clone> Tree<H> for BridgeTree<H> {
#[derive(Clone)] #[derive(Clone)]
pub struct BridgeRecording<H> { pub struct BridgeRecording<H> {
max_level: Level, max_level: Altitude,
bridge: Option<MerkleBridge<H>>, bridge: Option<MerkleBridge<H>>,
} }
@ -858,13 +858,13 @@ mod tests {
#[test] #[test]
fn position_levels() { fn position_levels() {
assert_eq!(Position(0).max_level(), Level(0)); assert_eq!(Position(0).max_level(), Altitude(0));
assert_eq!(Position(1).max_level(), Level(0)); assert_eq!(Position(1).max_level(), Altitude(0));
assert_eq!(Position(2).max_level(), Level(1)); assert_eq!(Position(2).max_level(), Altitude(1));
assert_eq!(Position(3).max_level(), Level(1)); assert_eq!(Position(3).max_level(), Altitude(1));
assert_eq!(Position(4).max_level(), Level(2)); assert_eq!(Position(4).max_level(), Altitude(2));
assert_eq!(Position(7).max_level(), Level(2)); assert_eq!(Position(7).max_level(), Altitude(2));
assert_eq!(Position(8).max_level(), Level(3)); assert_eq!(Position(8).max_level(), Altitude(3));
} }
#[test] #[test]

View File

@ -33,44 +33,44 @@ use std::ops::Sub;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[repr(transparent)] #[repr(transparent)]
pub struct Level(u32); pub struct Altitude(u32);
impl Level { impl Altitude {
pub fn zero() -> Self { pub fn zero() -> Self {
Level(0) Altitude(0)
} }
pub fn one() -> Self { pub fn one() -> Self {
Level(1) Altitude(1)
} }
pub fn iter_to(self, other: Level) -> impl Iterator<Item = Level> { pub fn iter_to(self, other: Altitude) -> impl Iterator<Item = Altitude> {
(self.0..other.0).into_iter().map(Level) (self.0..other.0).into_iter().map(Altitude)
} }
} }
impl Add<u32> for Level { impl Add<u32> for Altitude {
type Output = Level; type Output = Altitude;
fn add(self, value: u32) -> Self { fn add(self, value: u32) -> Self {
Level(self.0 + value) Altitude(self.0 + value)
} }
} }
impl Sub<u32> for Level { impl Sub<u32> for Altitude {
type Output = Level; type Output = Altitude;
fn sub(self, value: u32) -> Self { fn sub(self, value: u32) -> Self {
Level(self.0 - value) Altitude(self.0 - value)
} }
} }
impl From<u32> for Level { impl From<u32> for Altitude {
fn from(value: u32) -> Self { fn from(value: u32) -> Self {
Level(value) Altitude(value)
} }
} }
impl From<Level> for usize { impl From<Altitude> for usize {
fn from(level: Level) -> usize { fn from(level: Altitude) -> usize {
level.0 as usize level.0 as usize
} }
} }
@ -80,10 +80,10 @@ impl From<Level> for usize {
pub trait Hashable: Sized { pub trait Hashable: Sized {
fn empty_leaf() -> Self; fn empty_leaf() -> Self;
fn combine(level: Level, a: &Self, b: &Self) -> Self; fn combine(level: Altitude, a: &Self, b: &Self) -> Self;
fn empty_root(level: Level) -> Self { fn empty_root(level: Altitude) -> Self {
Level::zero() Altitude::zero()
.iter_to(level) .iter_to(level)
.fold(Self::empty_leaf(), |v, lvl| Self::combine(lvl, &v, &v)) .fold(Self::empty_leaf(), |v, lvl| Self::combine(lvl, &v, &v))
} }
@ -163,7 +163,7 @@ pub(crate) mod tests {
use super::bridgetree::{BridgeRecording, BridgeTree}; use super::bridgetree::{BridgeRecording, BridgeTree};
use super::sample::{lazy_root, CompleteRecording, CompleteTree}; use super::sample::{lazy_root, CompleteRecording, CompleteTree};
use super::{Frontier, Hashable, Level, Recording, Tree}; use super::{Altitude, Frontier, Hashable, Recording, Tree};
#[derive(Clone)] #[derive(Clone)]
pub struct CombinedTree<H: Hashable + Hash + Eq> { pub struct CombinedTree<H: Hashable + Hash + Eq> {
@ -294,7 +294,7 @@ pub(crate) mod tests {
SipHashable(0) SipHashable(0)
} }
fn combine(_level: Level, a: &Self, b: &Self) -> Self { fn combine(_level: Altitude, a: &Self, b: &Self) -> Self {
let mut hasher = SipHasher::new(); let mut hasher = SipHasher::new();
hasher.write_u64(a.0); hasher.write_u64(a.0);
hasher.write_u64(b.0); hasher.write_u64(b.0);
@ -307,7 +307,7 @@ pub(crate) mod tests {
"_".to_string() "_".to_string()
} }
fn combine(_: Level, a: &Self, b: &Self) -> Self { fn combine(_: Altitude, a: &Self, b: &Self) -> Self {
a.to_string() + b a.to_string() + b
} }
} }
@ -369,7 +369,7 @@ pub(crate) mod tests {
path: &[H], path: &[H],
) -> H { ) -> H {
let mut cur = value; let mut cur = value;
let mut lvl = Level::zero(); let mut lvl = Altitude::zero();
for (i, v) in path for (i, v) in path
.iter() .iter()
.enumerate() .enumerate()
@ -388,16 +388,16 @@ pub(crate) mod tests {
#[test] #[test]
fn test_compute_root_from_auth_path() { fn test_compute_root_from_auth_path() {
let expected = SipHashable::combine( let expected = SipHashable::combine(
<Level>::from(2), <Altitude>::from(2),
&SipHashable::combine( &SipHashable::combine(
Level::one(), Altitude::one(),
&SipHashable::combine(Level::zero(), &SipHashable(0), &SipHashable(1)), &SipHashable::combine(Altitude::zero(), &SipHashable(0), &SipHashable(1)),
&SipHashable::combine(Level::zero(), &SipHashable(2), &SipHashable(3)), &SipHashable::combine(Altitude::zero(), &SipHashable(2), &SipHashable(3)),
), ),
&SipHashable::combine( &SipHashable::combine(
Level::one(), Altitude::one(),
&SipHashable::combine(Level::zero(), &SipHashable(4), &SipHashable(5)), &SipHashable::combine(Altitude::zero(), &SipHashable(4), &SipHashable(5)),
&SipHashable::combine(Level::zero(), &SipHashable(6), &SipHashable(7)), &SipHashable::combine(Altitude::zero(), &SipHashable(6), &SipHashable(7)),
), ),
); );
@ -407,11 +407,11 @@ pub(crate) mod tests {
0, 0,
&[ &[
SipHashable(1), SipHashable(1),
SipHashable::combine(Level::zero(), &SipHashable(2), &SipHashable(3)), SipHashable::combine(Altitude::zero(), &SipHashable(2), &SipHashable(3)),
SipHashable::combine( SipHashable::combine(
Level::one(), Altitude::one(),
&SipHashable::combine(Level::zero(), &SipHashable(4), &SipHashable(5)), &SipHashable::combine(Altitude::zero(), &SipHashable(4), &SipHashable(5)),
&SipHashable::combine(Level::zero(), &SipHashable(6), &SipHashable(7)) &SipHashable::combine(Altitude::zero(), &SipHashable(6), &SipHashable(7))
) )
] ]
), ),
@ -424,11 +424,11 @@ pub(crate) mod tests {
4, 4,
&[ &[
SipHashable(5), SipHashable(5),
SipHashable::combine(Level::zero(), &SipHashable(6), &SipHashable(7)), SipHashable::combine(Altitude::zero(), &SipHashable(6), &SipHashable(7)),
SipHashable::combine( SipHashable::combine(
Level::one(), Altitude::one(),
&SipHashable::combine(Level::zero(), &SipHashable(0), &SipHashable(1)), &SipHashable::combine(Altitude::zero(), &SipHashable(0), &SipHashable(1)),
&SipHashable::combine(Level::zero(), &SipHashable(2), &SipHashable(3)) &SipHashable::combine(Altitude::zero(), &SipHashable(2), &SipHashable(3))
) )
] ]
), ),

View File

@ -1,5 +1,5 @@
/// Sample implementation of the Tree interface. /// Sample implementation of the Tree interface.
use super::{Frontier, Hashable, Level, Recording, Tree}; use super::{Altitude, Frontier, Hashable, Recording, Tree};
#[derive(Clone)] #[derive(Clone)]
pub struct CompleteTree<H: Hashable> { pub struct CompleteTree<H: Hashable> {
@ -214,7 +214,7 @@ impl<H: Hashable + Clone> Recording<H> for CompleteRecording<H> {
pub(crate) fn lazy_root<H: Hashable + Clone>(mut leaves: Vec<H>) -> H { pub(crate) fn lazy_root<H: Hashable + Clone>(mut leaves: Vec<H>) -> H {
//leaves are always at level zero, so we start there. //leaves are always at level zero, so we start there.
let mut level = Level::zero(); let mut level = Altitude::zero();
while leaves.len() != 1 { while leaves.len() != 1 {
leaves = leaves leaves = leaves
.iter() .iter()
@ -239,7 +239,7 @@ pub(crate) fn lazy_root<H: Hashable + Clone>(mut leaves: Vec<H>) -> H {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::tests::{compute_root_from_auth_path, SipHashable}; use crate::tests::{compute_root_from_auth_path, SipHashable};
use crate::{Frontier, Hashable, Level, Tree}; use crate::{Altitude, Frontier, Hashable, Tree};
use super::CompleteTree; use super::CompleteTree;
@ -267,16 +267,16 @@ mod tests {
assert!(!tree.append(&SipHashable(0))); assert!(!tree.append(&SipHashable(0)));
let expected = SipHashable::combine( let expected = SipHashable::combine(
<Level>::from(2), <Altitude>::from(2),
&SipHashable::combine( &SipHashable::combine(
Level::one(), Altitude::one(),
&SipHashable::combine(Level::zero(), &SipHashable(0), &SipHashable(1)), &SipHashable::combine(Altitude::zero(), &SipHashable(0), &SipHashable(1)),
&SipHashable::combine(Level::zero(), &SipHashable(2), &SipHashable(3)), &SipHashable::combine(Altitude::zero(), &SipHashable(2), &SipHashable(3)),
), ),
&SipHashable::combine( &SipHashable::combine(
Level::one(), Altitude::one(),
&SipHashable::combine(Level::zero(), &SipHashable(4), &SipHashable(5)), &SipHashable::combine(Altitude::zero(), &SipHashable(4), &SipHashable(5)),
&SipHashable::combine(Level::zero(), &SipHashable(6), &SipHashable(7)), &SipHashable::combine(Altitude::zero(), &SipHashable(6), &SipHashable(7)),
), ),
); );
@ -296,16 +296,16 @@ mod tests {
assert!(!tree.append(&SipHashable(0))); assert!(!tree.append(&SipHashable(0)));
let expected = SipHashable::combine( let expected = SipHashable::combine(
<Level>::from(2), <Altitude>::from(2),
&SipHashable::combine( &SipHashable::combine(
Level::one(), Altitude::one(),
&SipHashable::combine(Level::zero(), &SipHashable(0), &SipHashable(1)), &SipHashable::combine(Altitude::zero(), &SipHashable(0), &SipHashable(1)),
&SipHashable::combine(Level::zero(), &SipHashable(2), &SipHashable(3)), &SipHashable::combine(Altitude::zero(), &SipHashable(2), &SipHashable(3)),
), ),
&SipHashable::combine( &SipHashable::combine(
Level::one(), Altitude::one(),
&SipHashable::combine(Level::zero(), &SipHashable(4), &SipHashable(5)), &SipHashable::combine(Altitude::zero(), &SipHashable(4), &SipHashable(5)),
&SipHashable::combine(Level::zero(), &SipHashable(6), &SipHashable(7)), &SipHashable::combine(Altitude::zero(), &SipHashable(6), &SipHashable(7)),
), ),
); );