Skip to content

Commit 7cf3d26

Browse files
committed
feat: define explicit associated types on Hashable
1 parent 7d9a19c commit 7cf3d26

File tree

5 files changed

+103
-26
lines changed

5 files changed

+103
-26
lines changed

firewood/src/proof.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,32 @@ impl std::fmt::Debug for ProofNode {
108108
}
109109

110110
impl Hashable for ProofNode {
111-
fn parent_prefix_path(&self) -> impl IntoSplitPath + '_ {
111+
type LeadingPath<'a>
112+
= &'a [PathComponent]
113+
where
114+
Self: 'a;
115+
116+
type PartialPath<'a>
117+
= &'a [PathComponent]
118+
where
119+
Self: 'a;
120+
121+
type FullPath<'a>
122+
= &'a [PathComponent]
123+
where
124+
Self: 'a;
125+
126+
fn parent_prefix_path(&self) -> Self::LeadingPath<'_> {
112127
let (prefix, _) = self.key.split_at(self.partial_len);
113128
prefix
114129
}
115130

116-
fn partial_path(&self) -> impl IntoSplitPath + '_ {
131+
fn partial_path(&self) -> Self::PartialPath<'_> {
117132
let (_, suffix) = self.key.split_at(self.partial_len);
118133
suffix
119134
}
120135

121-
fn full_path(&self) -> impl IntoSplitPath + '_ {
136+
fn full_path(&self) -> Self::FullPath<'_> {
122137
&self.key
123138
}
124139

storage/src/hashednode.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
use crate::{
55
Children, HashType, HashableShunt, IntoSplitPath, Node, Path, PathComponent, SplitPath,
6-
TriePath,
76
};
87
use smallvec::SmallVec;
98

@@ -153,22 +152,32 @@ impl<T: AsRef<[u8]>> AsRef<[u8]> for ValueDigest<T> {
153152

154153
/// A node in the trie that can be hashed.
155154
pub trait Hashable: std::fmt::Debug {
155+
/// The type of the leading path.
156+
type LeadingPath<'a>: IntoSplitPath + 'a
157+
where
158+
Self: 'a;
159+
160+
/// The type of the partial path.
161+
type PartialPath<'a>: IntoSplitPath + 'a
162+
where
163+
Self: 'a;
164+
165+
/// The type of the full path.
166+
type FullPath<'a>: IntoSplitPath + 'a
167+
where
168+
Self: 'a;
169+
156170
/// The full path of this node's parent where each byte is a nibble.
157-
fn parent_prefix_path(&self) -> impl IntoSplitPath + '_;
171+
fn parent_prefix_path(&self) -> Self::LeadingPath<'_>;
158172
/// The partial path of this node where each byte is a nibble.
159-
fn partial_path(&self) -> impl IntoSplitPath + '_;
173+
fn partial_path(&self) -> Self::PartialPath<'_>;
174+
/// The full path of this node including the parent's prefix where each byte is a nibble.
175+
fn full_path(&self) -> Self::FullPath<'_>;
160176
/// The node's value or hash.
161177
fn value_digest(&self) -> Option<ValueDigest<&[u8]>>;
162178
/// Each element is a child's index and hash.
163179
/// Yields 0 elements if the node is a leaf.
164180
fn children(&self) -> Children<Option<HashType>>;
165-
166-
/// The full path of this node including the parent's prefix where each byte is a nibble.
167-
fn full_path(&self) -> impl IntoSplitPath + '_ {
168-
self.parent_prefix_path()
169-
.into_split_path()
170-
.append(self.partial_path().into_split_path())
171-
}
172181
}
173182

174183
/// A preimage of a hash.

storage/src/hashedshunt.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (C) 2025, Ava Labs, Inc. All rights reserved.
22
// See the file LICENSE.md for licensing terms.
33

4-
use crate::{Children, HashType, Hashable, IntoSplitPath, SplitPath, ValueDigest};
4+
use crate::{Children, HashType, Hashable, JoinedPath, SplitPath, ValueDigest};
55

66
/// A shunt for a hasheable trie that we can use to compute the hash of a node
77
/// using component parts.
@@ -51,14 +51,33 @@ impl<P1: SplitPath, P2: SplitPath> std::fmt::Debug for HashableShunt<'_, P1, P2>
5151
}
5252

5353
impl<P1: SplitPath, P2: SplitPath> Hashable for HashableShunt<'_, P1, P2> {
54-
fn parent_prefix_path(&self) -> impl IntoSplitPath + '_ {
54+
type LeadingPath<'a>
55+
= P1
56+
where
57+
Self: 'a;
58+
59+
type PartialPath<'a>
60+
= P2
61+
where
62+
Self: 'a;
63+
64+
type FullPath<'a>
65+
= JoinedPath<P1, P2>
66+
where
67+
Self: 'a;
68+
69+
fn parent_prefix_path(&self) -> Self::LeadingPath<'_> {
5570
self.parent_prefix
5671
}
5772

58-
fn partial_path(&self) -> impl IntoSplitPath + '_ {
73+
fn partial_path(&self) -> Self::PartialPath<'_> {
5974
self.partial_path
6075
}
6176

77+
fn full_path(&self) -> Self::FullPath<'_> {
78+
self.parent_prefix_path().append(self.partial_path())
79+
}
80+
6281
fn value_digest(&self) -> Option<ValueDigest<&[u8]>> {
6382
self.value.clone()
6483
}

storage/src/tries/kvp.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#[cfg(not(feature = "branch_factor_256"))]
55
use crate::PackedPathRef;
66
use crate::{
7-
Children, HashType, Hashable, HashableShunt, HashedTrieNode, PathBuf, PathComponent, PathGuard,
8-
SplitPath, TrieNode, TriePath, TriePathFromPackedBytes, ValueDigest,
7+
Children, HashType, Hashable, HashableShunt, HashedTrieNode, JoinedPath, PathBuf,
8+
PathComponent, PathGuard, SplitPath, TrieNode, TriePath, TriePathFromPackedBytes, ValueDigest,
99
};
1010

1111
#[cfg(feature = "branch_factor_256")]
@@ -280,7 +280,12 @@ impl<'a, T: AsRef<[u8]> + ?Sized> HashedKeyValueTrieRoot<'a, T> {
280280
}
281281

282282
impl<T: AsRef<[u8]> + ?Sized> TrieNode<T> for KeyValueTrieRoot<'_, T> {
283-
fn partial_path(&self) -> impl SplitPath + '_ {
283+
type PartialPath<'a>
284+
= PackedPathRef<'a>
285+
where
286+
Self: 'a;
287+
288+
fn partial_path(&self) -> Self::PartialPath<'_> {
284289
self.partial_path
285290
}
286291

@@ -305,7 +310,12 @@ impl<T: AsRef<[u8]> + ?Sized> TrieNode<T> for KeyValueTrieRoot<'_, T> {
305310
}
306311

307312
impl<T: AsRef<[u8]> + ?Sized> TrieNode<T> for HashedKeyValueTrieRoot<'_, T> {
308-
fn partial_path(&self) -> impl SplitPath + '_ {
313+
type PartialPath<'a>
314+
= PackedPathRef<'a>
315+
where
316+
Self: 'a;
317+
318+
fn partial_path(&self) -> Self::PartialPath<'_> {
309319
self.partial_path
310320
}
311321

@@ -334,15 +344,34 @@ impl<T: AsRef<[u8]> + ?Sized> HashedTrieNode<T> for HashedKeyValueTrieRoot<'_, T
334344
}
335345
}
336346

337-
impl<T: AsRef<[u8]> + ?Sized> Hashable for HashedKeyValueTrieRoot<'_, T> {
338-
fn parent_prefix_path(&self) -> impl crate::IntoSplitPath + '_ {
339-
self.leading_path.as_slice()
347+
impl<'a, T: AsRef<[u8]> + ?Sized> Hashable for HashedKeyValueTrieRoot<'a, T> {
348+
type LeadingPath<'b>
349+
= &'b [PathComponent]
350+
where
351+
Self: 'b;
352+
353+
type PartialPath<'b>
354+
= PackedPathRef<'a>
355+
where
356+
Self: 'b;
357+
358+
type FullPath<'b>
359+
= JoinedPath<&'b [PathComponent], PackedPathRef<'a>>
360+
where
361+
Self: 'b;
362+
363+
fn parent_prefix_path(&self) -> Self::LeadingPath<'_> {
364+
&self.leading_path
340365
}
341366

342-
fn partial_path(&self) -> impl crate::IntoSplitPath + '_ {
367+
fn partial_path(&self) -> Self::PartialPath<'_> {
343368
self.partial_path
344369
}
345370

371+
fn full_path(&self) -> Self::FullPath<'_> {
372+
self.parent_prefix_path().append(self.partial_path)
373+
}
374+
346375
fn value_digest(&self) -> Option<ValueDigest<&[u8]>> {
347376
self.value.map(|v| ValueDigest::Value(v.as_ref()))
348377
}

storage/src/tries/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
mod iter;
55
mod kvp;
66

7-
use crate::{HashType, PathComponent, SplitPath};
7+
use crate::{HashType, IntoSplitPath, PathComponent};
88

99
pub use self::iter::{IterAscending, IterDescending, TrieEdgeIter, TrieValueIter};
1010
pub use self::kvp::{DuplicateKeyError, HashedKeyValueTrieRoot, KeyValueTrieRoot};
@@ -38,8 +38,13 @@ pub enum TrieEdgeState<'a, N: ?Sized> {
3838

3939
/// A node in a fixed-arity radix trie.
4040
pub trait TrieNode<V: AsRef<[u8]> + ?Sized> {
41+
/// The type of path from this node's parent to this node.
42+
type PartialPath<'a>: IntoSplitPath + 'a
43+
where
44+
Self: 'a;
45+
4146
/// The path from this node's parent to this node.
42-
fn partial_path(&self) -> impl SplitPath + '_;
47+
fn partial_path(&self) -> Self::PartialPath<'_>;
4348

4449
/// The value stored at this node, if any.
4550
fn value(&self) -> Option<&V>;

0 commit comments

Comments
 (0)