From e8bbf767bacc0acc1e8ad4a571a0d185f91173d8 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Fri, 17 Nov 2023 13:10:23 +0200 Subject: [PATCH] test(merkle tree): Fix flaky `MerkleTree` consistency test (#475) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 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`. --- core/lib/merkle_tree/src/consistency.rs | 34 ++++++++++++------- .../src/metadata_calculator/tests.rs | 2 +- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/core/lib/merkle_tree/src/consistency.rs b/core/lib/merkle_tree/src/consistency.rs index afe0111f9a3d..85896bad1ae1 100644 --- a/core/lib/merkle_tree/src/consistency.rs +++ b/core/lib/merkle_tree/src/consistency.rs @@ -256,6 +256,7 @@ impl AtomicBitSet { #[cfg(test)] mod tests { use assert_matches::assert_matches; + use rayon::ThreadPoolBuilder; use std::num::NonZeroU64; @@ -290,7 +291,16 @@ 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] @@ -298,7 +308,7 @@ mod tests { 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)); } @@ -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)); } @@ -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 @@ -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 { @@ -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 { @@ -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 } @@ -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 { @@ -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, .. }); } @@ -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); } @@ -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 @@ -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 { diff --git a/core/lib/zksync_core/src/metadata_calculator/tests.rs b/core/lib/zksync_core/src/metadata_calculator/tests.rs index dd72410f950d..5e86db6087be 100644 --- a/core/lib/zksync_core/src/metadata_calculator/tests.rs +++ b/core/lib/zksync_core/src/metadata_calculator/tests.rs @@ -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(timeout: Duration, action: F) -> T where