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:
parent
d319262985
commit
aed785e896
|
@ -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]
|
||||||
|
|
76
src/lib.rs
76
src/lib.rs
|
@ -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))
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
|
|
@ -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)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue