Skip to content

Commit 217bbec

Browse files
committed
f - in-place merkle root computation
1 parent 40ebd69 commit 217bbec

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

lightning/src/offers/merkle.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,29 @@ pub(super) fn tagged_root_hash(tag: sha256::Hash, data: &[u8]) -> sha256::Hash {
2626
let leaf_tag = sha256::Hash::hash("LnLeaf".as_bytes());
2727
let branch_tag = sha256::Hash::hash("LnBranch".as_bytes());
2828

29-
let mut merkle_leaves = Vec::new();
29+
let mut leaves = Vec::new();
3030
for record in TlvStream::new(&data[..]) {
3131
if !SIGNATURE_TYPES.contains(&record.r#type.0) {
32-
merkle_leaves.push(tagged_hash(leaf_tag, &record));
33-
merkle_leaves.push(tagged_hash(nonce_tag, &record));
32+
leaves.push(tagged_hash(leaf_tag, &record));
33+
leaves.push(tagged_hash(nonce_tag, &record));
3434
}
3535
}
3636

37-
while merkle_leaves.len() != 1 {
38-
let mut parents = Vec::with_capacity(merkle_leaves.len() / 2 + merkle_leaves.len() % 2);
39-
let mut iter = merkle_leaves.chunks_exact(2);
40-
for leaves in iter.by_ref() {
41-
parents.push(tagged_branch_hash(branch_tag, leaves[0], leaves[1]));
37+
let num_leaves = leaves.len();
38+
for level in 0.. {
39+
let step = 2 << level;
40+
let offset = step / 2;
41+
if offset >= num_leaves {
42+
break;
4243
}
43-
for leaf in iter.remainder() {
44-
parents.push(*leaf);
44+
45+
for (i, j) in (0..num_leaves).step_by(step).zip((offset..num_leaves).step_by(step)) {
46+
leaves[i] = tagged_branch_hash(branch_tag, leaves[i], leaves[j]);
4547
}
46-
core::mem::swap(&mut parents, &mut merkle_leaves);
4748
}
4849

49-
tagged_hash(tag, merkle_leaves.first().unwrap())
50+
// TODO: Can we ever have zero leaves?
51+
tagged_hash(tag, leaves.first().unwrap())
5052
}
5153

5254
fn tagged_branch_hash(tag: sha256::Hash, leaf1: sha256::Hash, leaf2: sha256::Hash) -> sha256::Hash {

0 commit comments

Comments
 (0)