Skip to content

Commit

Permalink
test(merkle tree): Fix flaky MerkleTree consistency test (#475)
Browse files Browse the repository at this point in the history
## What ❔

Fix duplicate_leaf_index_error test, which [sometimes fails in
CI](https://github.com/matter-labs/zksync-era/actions/runs/6848926146/job/18620092974?pr=432).

## Why ❔

Failing CI costs time and money.

## Checklist

- [x] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [x] Tests for the changes have been added / updated.
- [x] Code has been formatted via `zk fmt` and `zk lint`.
  • Loading branch information
slowli authored Nov 17, 2023
1 parent 851e800 commit e8bbf76
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
34 changes: 22 additions & 12 deletions core/lib/merkle_tree/src/consistency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ impl AtomicBitSet {
#[cfg(test)]
mod tests {
use assert_matches::assert_matches;
use rayon::ThreadPoolBuilder;

use std::num::NonZeroU64;

Expand Down Expand Up @@ -290,15 +291,24 @@ mod tests {
#[test]
fn basic_consistency_checks() {
let db = prepare_database();
MerkleTree::new(db).verify_consistency(0).unwrap();
deterministic_verify_consistency(db).unwrap();
}

/// Limits the number of `rayon` threads to 1 in order to get deterministic test execution.
fn deterministic_verify_consistency(db: PatchSet) -> Result<(), ConsistencyError> {
let thread_pool = ThreadPoolBuilder::new()
.num_threads(1)
.build()
.expect("failed initializing `rayon` thread pool");
thread_pool.install(|| MerkleTree::new(db).verify_consistency(0))
}

#[test]
fn missing_version_error() {
let mut db = prepare_database();
db.manifest_mut().version_count = 0;

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(err, ConsistencyError::MissingVersion(0));
}

Expand All @@ -307,7 +317,7 @@ mod tests {
let mut db = prepare_database();
db.remove_root(0);

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(err, ConsistencyError::MissingRoot(0));
}

Expand All @@ -321,7 +331,7 @@ mod tests {
let leaf_key = leaf_key.unwrap();
db.remove_node(&leaf_key);

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(
err,
ConsistencyError::MissingNode { key, is_leaf: true } if key == leaf_key
Expand All @@ -338,7 +348,7 @@ mod tests {
};
*leaf_count = NonZeroU64::new(42).unwrap();

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(
err,
ConsistencyError::LeafCountMismatch {
Expand All @@ -363,7 +373,7 @@ mod tests {
let child_ref = node.child_ref_mut(0xd).unwrap();
child_ref.hash = ValueHash::zero();

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(
err,
ConsistencyError::HashMismatch {
Expand All @@ -388,7 +398,7 @@ mod tests {
});
let leaf_key = leaf_key.unwrap();

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(
err,
ConsistencyError::FullKeyMismatch { key, full_key }
Expand All @@ -409,7 +419,7 @@ mod tests {
});
leaf_key.unwrap();

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(
err,
ConsistencyError::LeafIndexOverflow {
Expand All @@ -430,7 +440,7 @@ mod tests {
}
}

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(err, ConsistencyError::DuplicateLeafIndex { index: 1, .. });
}

Expand All @@ -446,7 +456,7 @@ mod tests {
});
let node_key = node_key.unwrap();

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(err, ConsistencyError::EmptyInternalNode { key } if key == node_key);
}

Expand All @@ -463,7 +473,7 @@ mod tests {
});
let node_key = node_key.unwrap();

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(
err,
ConsistencyError::KeyVersionMismatch { key, expected_version: 1 } if key == node_key
Expand All @@ -483,7 +493,7 @@ mod tests {
let (nibble, _) = node.children().next().unwrap();
node.child_ref_mut(nibble).unwrap().version = 42;

let err = MerkleTree::new(db).verify_consistency(0).unwrap_err();
let err = deterministic_verify_consistency(db).unwrap_err();
assert_matches!(
err,
ConsistencyError::RootVersionMismatch {
Expand Down
2 changes: 1 addition & 1 deletion core/lib/zksync_core/src/metadata_calculator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use super::{
};
use crate::genesis::{ensure_genesis_state, GenesisParams};

const RUN_TIMEOUT: Duration = Duration::from_secs(15);
const RUN_TIMEOUT: Duration = Duration::from_secs(30);

async fn run_with_timeout<T, F>(timeout: Duration, action: F) -> T
where
Expand Down

0 comments on commit e8bbf76

Please sign in to comment.