Skip to content

Commit

Permalink
Only track the dirt for the leaves' parents on the heap
Browse files Browse the repository at this point in the history
This makes the code a little cleaner, and it performs the same or slightly better.

Before:
```
Running benchmark with always merkleize feature on
avg hash time   226.487µs, avg step time        226ns, step size         1, num_iters 200, total time  45.356958ms
avg hash time   285.669µs, avg step time      3.454µs, step size      1024, num_iters 200, total time  57.836958ms
avg hash time   673.086µs, avg step time    141.763µs, step size     32768, num_iters 200, total time    162.983ms
avg hash time   800.159µs, avg step time   3.333175ms, step size   1048576, num_iters 200, total time 826.676667ms
avg hash time  2.394079ms, avg step time  54.744735ms, step size  16777216, num_iters 134, total time 7.711356917s
avg hash time  6.981576ms, avg step time 221.284475ms, step size  67108864, num_iters  33, total time    7.754069s
avg hash time 23.845249ms, avg step time 826.907254ms, step size 268435456, num_iters   8, total time 7.632934667s
```

After:
```
Running benchmark with always merkleize feature on
avg hash time   223.077µs, avg step time        196ns, step size         1, num_iters 200, total time  44.670042ms
avg hash time   283.239µs, avg step time      4.477µs, step size      1024, num_iters 200, total time  57.556875ms
avg hash time   631.034µs, avg step time    139.475µs, step size     32768, num_iters 200, total time 154.115083ms
avg hash time   813.914µs, avg step time   3.357342ms, step size   1048576, num_iters 200, total time    834.265ms
avg hash time   2.39359ms, avg step time  55.253016ms, step size  16777216, num_iters 134, total time 7.779911875s
avg hash time  6.768607ms, avg step time 222.297451ms, step size  67108864, num_iters  33, total time 7.781483917s
avg hash time 25.057057ms, avg step time 840.610754ms, step size 268435456, num_iters   8, total time 7.765957833s
```
  • Loading branch information
eljobe committed Jul 18, 2024
1 parent 195a009 commit 0a890a9
Showing 1 changed file with 11 additions and 11 deletions.
22 changes: 11 additions & 11 deletions arbitrator/prover/src/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl MerkleType {
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
struct Layers {
data: Vec<Vec<Bytes32>>,
dirt: Vec<HashSet<usize>>,
dirty_leaf_parents: HashSet<usize>,
}

/// A Merkle tree with a fixed number of layers
Expand Down Expand Up @@ -208,19 +208,18 @@ impl Merkle {
min_depth
};
let mut layers: Vec<Vec<Bytes32>> = Vec::with_capacity(depth);
let dirty_leaf_parents = HashSet::with_capacity(hashes.len() / 2);
layers.push(hashes);
let mut dirty_indices: Vec<HashSet<usize>> = Vec::with_capacity(depth);
while layers.last().unwrap().len() > 1 || layers.len() < min_depth {
let layer = layers.last().unwrap();
let empty_hash = empty_hash_at(ty, layers.len() - 1);

let new_layer = new_layer(ty, layer, empty_hash);
dirty_indices.push(HashSet::with_capacity(new_layer.len()));
layers.push(new_layer);
}
let layers = Mutex::new(Layers {
data: layers,
dirt: dirty_indices,
dirty_leaf_parents,
});
Merkle {
ty,
Expand All @@ -231,14 +230,14 @@ impl Merkle {

fn rehash(&self, layers: &mut Layers) {
// If nothing is dirty, then there's no need to rehash.
if layers.dirt.is_empty() || layers.dirt[0].is_empty() {
if layers.dirty_leaf_parents.is_empty() {
return;
}
// Consume the leaf parents dirty indices.
let mut dirt = std::mem::take(&mut layers.dirty_leaf_parents);
// Process dirty indices starting from layer 1 (layer 0 is the leaves).
for layer_i in 1..layers.data.len() {
let dirty_i = layer_i - 1;
// Consume this layer's dirty indices.
let dirt = std::mem::take(&mut layers.dirt[dirty_i]);
let mut new_dirt = HashSet::with_capacity(dirt.len() / 2);
// It is important to process the dirty indices in order because
// when the leaves grown since the last rehash, the new parent is
// simply pused to the end of the layer's data.
Expand All @@ -261,9 +260,10 @@ impl Merkle {
}
// Mark the node's parent as dirty unless it's the root.
if layer_i < layers.data.len() - 1 {
layers.dirt[dirty_i + 1].insert(idx >> 1);
new_dirt.insert(idx >> 1);
}
}
dirt = new_dirt;
}
}

Expand Down Expand Up @@ -359,7 +359,7 @@ impl Merkle {
return;
}
layers.data[0][idx] = hash;
layers.dirt[0].insert(idx >> 1);
layers.dirty_leaf_parents.insert(idx >> 1);
}

/// Resizes the number of leaves the tree can hold.
Expand All @@ -381,7 +381,7 @@ impl Merkle {
}
let start = layers.data[0].len();
for i in start..new_len {
layers.dirt[0].insert(i);
layers.dirty_leaf_parents.insert(i);
}
Ok(layers.data[0].len())
}
Expand Down

0 comments on commit 0a890a9

Please sign in to comment.