Skip to content

Commit

Permalink
Use correct levels for cap nodes in put_shard_roots
Browse files Browse the repository at this point in the history
The Merkle hashes used for the note commitment trees are domain
separated by level, so when pretending that the subtree roots are leaves
of the cap tree, we need to adjust for their level not being zero.

Closes zcash#874.

Co-authored-by: Sean Bowe <[email protected]>
  • Loading branch information
str4d and ebfull committed Jul 18, 2023
1 parent b741eab commit 375c542
Showing 1 changed file with 34 additions and 2 deletions.
36 changes: 34 additions & 2 deletions zcash_client_sqlite/src/wallet/commitment_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,17 +775,49 @@ pub(crate) fn put_shard_roots<
// We treat the cap as a DEPTH-SHARD_HEIGHT tree so that we can make a batch insertion of
// root data using `Position::from(start_index)` as the starting position and treating the
// roots as level-0 leaves.
#[derive(Clone, Debug, PartialEq, Eq)]
struct LevelShifter<H, const SHARD_HEIGHT: u8>(H);
impl<H: Hashable, const SHARD_HEIGHT: u8> Hashable for LevelShifter<H, SHARD_HEIGHT> {
fn empty_leaf() -> Self {
Self(H::empty_root(SHARD_HEIGHT.into()))
}

fn combine(level: Level, a: &Self, b: &Self) -> Self {
Self(H::combine(level + SHARD_HEIGHT, &a.0, &b.0))
}

fn empty_root(level: Level) -> Self
where
Self: Sized,
{
Self(H::empty_root(level + SHARD_HEIGHT))
}
}
impl<H: HashSer, const SHARD_HEIGHT: u8> HashSer for LevelShifter<H, SHARD_HEIGHT> {
fn read<R: io::Read>(reader: R) -> io::Result<Self>
where
Self: Sized,
{
H::read(reader).map(Self)
}

fn write<W: io::Write>(&self, writer: W) -> io::Result<()> {
self.0.write(writer)
}
}

let cap = LocatedTree::from_parts(
Address::from_parts((DEPTH - SHARD_HEIGHT).into(), 0),
get_cap(conn, table_prefix).map_err(ShardTreeError::Storage)?,
get_cap::<LevelShifter<H, SHARD_HEIGHT>>(conn, table_prefix)
.map_err(ShardTreeError::Storage)?,
);

let cap_result = cap
.batch_insert(
Position::from(start_index),
roots.iter().map(|r| {
(
r.root_hash().clone(),
LevelShifter(r.root_hash().clone()),
Retention::Checkpoint {
id: (),
is_marked: false,
Expand Down

0 comments on commit 375c542

Please sign in to comment.