Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/zaino-state/src/chain_index/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Zaino-State ChainIndex unit tests.

mod best_chaintip;
pub(crate) mod finalised_state;
pub(crate) mod mempool;
mod mockchain_tests;
Expand Down
39 changes: 39 additions & 0 deletions packages/zaino-state/src/chain_index/tests/best_chaintip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! Regression tests for `best_chaintip`.
//!
//! Tracks <https://github.com/zingolabs/zaino/issues/1047>: when the snapshot
//! is `StillSyncingFinalizedState` and the source cannot currently produce
//! the block at `validator_finalized_height`, `best_chaintip` surfaces the
//! miss as `database_hole` — the corruption kind — instead of a retryable
//! "not ready" signal.

use super::load_test_vectors_and_sync_chain_index;
use crate::chain_index::ChainIndex;
use crate::{ChainIndexSnapshot, Height};

/// Reaches the `StillSyncingFinalizedState` arm with a
/// `validator_finalized_height` the source cannot serve, mirroring the
/// cold-boot race where zebrad transiently can't produce block `tip - 100`.
/// The error (if any) must not be a `database_hole`: that category means
/// zaino's own on-disk index claims a height whose bytes are unreachable,
/// which is not what happened here.
#[tokio::test(flavor = "multi_thread")]
async fn passthrough_miss_is_not_a_database_hole() {
let (_blocks, _indexer, index_reader, mockchain) =
load_test_vectors_and_sync_chain_index(false).await;

let above_tip = Height(mockchain.max_chain_height() + 1_000);
let fake_snapshot = ChainIndexSnapshot::StillSyncingFinalizedState {
validator_finalized_height: above_tip,
};

match index_reader.best_chaintip(&fake_snapshot).await {
Ok(_tip) => {}
Err(e) => {
let rendered = e.to_string();
assert!(
!rendered.contains("hole in validator database"),
"best_chaintip misclassified a passthrough miss as a database hole: {rendered}",
);
}
}
}
Loading