Skip to content

Commit adcc38c

Browse files
committed
Merge remote-tracking branch 'origin/main' into danlaine/contiguous-2
2 parents 447f6d8 + cc18999 commit adcc38c

3 files changed

Lines changed: 46 additions & 40 deletions

File tree

storage/src/journal/authenticated.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,8 @@ impl<F: Family, D: Digest, Item: Send + Sync> MerkleizedBatch<F, D, Item> {
203203

204204
/// Create a new speculative batch of operations with this batch as its parent.
205205
///
206-
/// All uncommitted ancestors in the chain must be kept alive until the child (or any
207-
/// descendant) is merkleized. Dropping an uncommitted ancestor causes data
208-
/// loss detected at `apply_batch` time.
206+
/// The batch becomes invalid if any ancestor is dropped before being applied, or a sibling
207+
/// fork has been applied.
209208
pub fn new_batch<H: Hasher<Digest = D>>(self: &Arc<Self>) -> UnmerkleizedBatch<F, H, Item>
210209
where
211210
Item: Encode,
@@ -2378,11 +2377,11 @@ mod tests {
23782377
let child_a = journal.merkle.with_mem(|mem| batch_a.merkleize(mem));
23792378
let batch_b = parent.new_batch::<Sha256>().add(create_operation::<F>(30));
23802379
let child_b = journal.merkle.with_mem(|mem| batch_b.merkleize(mem));
2381-
drop(parent);
23822380

23832381
// Apply child_a, then child_b should be stale.
23842382
journal.apply_batch(&child_a).await.unwrap();
23852383
let result = journal.apply_batch(&child_b).await;
2384+
drop(parent);
23862385
assert!(
23872386
matches!(
23882387
result,

storage/src/merkle/batch.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@
5656
//! For positions in the committed structure, callers fall through to [`Mem::get_node`]
5757
//! (or an adapter that layers a batch over a `Mem`).
5858
//!
59+
//! # Batch invalidation
60+
//!
61+
//! A batch becomes _invalid_ when an unapplied ancestor is dropped, or a sibling fork has been
62+
//! applied. Invalid batches must not be used: their methods may return incorrect data rather than
63+
//! erroring.
64+
//!
5965
//! # Example (MMR)
6066
//!
6167
//! ```ignore
@@ -590,9 +596,8 @@ impl<F: Family, D: Digest> MerkleizedBatch<F, D> {
590596

591597
/// Create a child batch on top of this merkleized batch.
592598
///
593-
/// All uncommitted ancestors in the chain must be kept alive until the child (or any
594-
/// descendant) is merkleized. Dropping an uncommitted ancestor causes data
595-
/// loss detected at `apply_batch` time.
599+
/// The batch becomes invalid if any ancestor is dropped before being applied, or a sibling
600+
/// fork has been applied.
596601
pub fn new_batch(self: &Arc<Self>) -> UnmerkleizedBatch<F, D> {
597602
let batch = UnmerkleizedBatch::new(Arc::clone(self));
598603
#[cfg(feature = "std")]

storage/src/merkle/benches/update.rs

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn bench_update_family<F: Family>(c: &mut Criterion, runner: &tokio::Runner, fam
4444
module_path!(),
4545
),
4646
|b| {
47-
b.to_async(runner).iter_custom(|_iters| async move {
47+
b.to_async(runner).iter_custom(|iters| async move {
4848
let pool = match strategy {
4949
Strategy::BatchedParallel => {
5050
let ctx = context::get::<commonware_runtime::tokio::Context>();
@@ -74,43 +74,45 @@ fn bench_update_family<F: Family>(c: &mut Criterion, runner: &tokio::Runner, fam
7474

7575
// Randomly update leaves -- this is what we are benchmarking.
7676
let start = Instant::now();
77+
for _ in 0..iters {
78+
// Simulate leaf-batching being the responsibility of the caller.
79+
let mut leaf_map = HashMap::new();
80+
for _ in 0..updates {
81+
let rand_leaf_num = sampler.gen_range(0..leaves);
82+
let rand_leaf_loc = leaf_locations[rand_leaf_num];
83+
let rand_leaf_swap = sampler.gen_range(0..elements.len());
84+
let new_element = &elements[rand_leaf_swap];
85+
leaf_map.insert(rand_leaf_loc, *new_element);
86+
}
7787

78-
// Simulate leaf-batching being the responsibility of the caller.
79-
let mut leaf_map = HashMap::new();
80-
for _ in 0..updates {
81-
let rand_leaf_num = sampler.gen_range(0..leaves);
82-
let rand_leaf_loc = leaf_locations[rand_leaf_num];
83-
let rand_leaf_swap = sampler.gen_range(0..elements.len());
84-
let new_element = &elements[rand_leaf_swap];
85-
leaf_map.insert(rand_leaf_loc, *new_element);
86-
}
87-
88-
match strategy {
89-
Strategy::NoBatching => {
90-
for (loc, element) in &leaf_map {
91-
let batch =
92-
mem.new_batch().update_leaf(&h, *loc, element).unwrap();
93-
let batch = batch.merkleize(&mem, &h);
88+
match strategy {
89+
Strategy::NoBatching => {
90+
for (loc, element) in &leaf_map {
91+
let batch = mem
92+
.new_batch()
93+
.update_leaf(&h, *loc, element)
94+
.unwrap();
95+
let batch = batch.merkleize(&mem, &h);
96+
mem.apply_batch(&batch).unwrap();
97+
}
98+
}
99+
_ => {
100+
let updates: Vec<(
101+
Location<F>,
102+
commonware_cryptography::sha256::Digest,
103+
)> = leaf_map.into_iter().collect();
104+
let batch = {
105+
let mut batch = mem.new_batch();
106+
if let Some(ref p) = pool {
107+
batch = batch.with_pool(Some(p.clone()));
108+
}
109+
batch = batch.update_leaf_batched(&updates).unwrap();
110+
batch.merkleize(&mem, &h)
111+
};
94112
mem.apply_batch(&batch).unwrap();
95113
}
96114
}
97-
_ => {
98-
let updates: Vec<(
99-
Location<F>,
100-
commonware_cryptography::sha256::Digest,
101-
)> = leaf_map.into_iter().collect();
102-
let batch = {
103-
let mut batch = mem.new_batch();
104-
if let Some(ref p) = pool {
105-
batch = batch.with_pool(Some(p.clone()));
106-
}
107-
batch = batch.update_leaf_batched(&updates).unwrap();
108-
batch.merkleize(&mem, &h)
109-
};
110-
mem.apply_batch(&batch).unwrap();
111-
}
112115
}
113-
114116
start.elapsed()
115117
});
116118
},

0 commit comments

Comments
 (0)