mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-06-29 18:39:30 +00:00
feat(indexer): add Stalled status and chain breaker snapshot
test `RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p indexer_core --lib status`
This commit is contained in:
parent
fc3692813a
commit
4cc0d17d95
@ -62,9 +62,11 @@ impl IndexerCore {
|
||||
pub fn status(&self) -> IndexerStatus {
|
||||
let sync = IndexerSyncStatus::clone(&self.status.load());
|
||||
let indexed_block_id = self.store.get_last_block_id().ok().flatten();
|
||||
let chain_breaker = self.store.get_chain_breaker().ok().flatten();
|
||||
IndexerStatus {
|
||||
sync,
|
||||
indexed_block_id,
|
||||
chain_breaker,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::chain_breaker::ChainBreaker;
|
||||
|
||||
/// Coarse lifecycle state of the indexer's ingestion loop, so a client can tell
|
||||
/// "still catching up" apart from "something went wrong".
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
|
||||
@ -13,6 +15,9 @@ pub enum IndexerSyncState {
|
||||
CaughtUp,
|
||||
/// The last cycle failed (e.g. the L1 node is unreachable). See `last_error`.
|
||||
Error,
|
||||
/// Parked on a chain breaker: the validated tip is frozen awaiting a valid
|
||||
/// continuation. See `last_error` and the snapshot's `chain_breaker`.
|
||||
Stalled,
|
||||
}
|
||||
|
||||
/// Live ingestion status owned by the ingest loop: the coarse `state` plus the
|
||||
@ -56,6 +61,15 @@ impl IndexerSyncStatus {
|
||||
last_error: Some(reason),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parked on a chain breaker; `reason` mirrors the breaker's error message.
|
||||
/// The full breaker is attached to the [`IndexerStatus`] snapshot.
|
||||
pub(crate) const fn stalled(reason: String) -> Self {
|
||||
Self {
|
||||
state: IndexerSyncState::Stalled,
|
||||
last_error: Some(reason),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Full status snapshot returned to callers (FFI/RPC): the live [`IndexerSyncStatus`]
|
||||
@ -69,6 +83,7 @@ pub struct IndexerStatus {
|
||||
#[serde(flatten)]
|
||||
pub sync: IndexerSyncStatus,
|
||||
pub indexed_block_id: Option<u64>,
|
||||
pub chain_breaker: Option<ChainBreaker>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -80,6 +95,7 @@ mod tests {
|
||||
let status = IndexerStatus {
|
||||
sync: IndexerSyncStatus::error("boom".to_owned()),
|
||||
indexed_block_id: Some(7),
|
||||
chain_breaker: None,
|
||||
};
|
||||
let value = serde_json::to_value(&status).expect("serialize");
|
||||
assert_eq!(
|
||||
@ -88,6 +104,7 @@ mod tests {
|
||||
"state": "error",
|
||||
"lastError": "boom",
|
||||
"indexedBlockId": 7,
|
||||
"chainBreaker": null,
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -100,4 +117,28 @@ mod tests {
|
||||
serde_json::json!({ "state": "caught_up", "lastError": null })
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stalled_status_serializes_with_breaker() {
|
||||
use crate::{chain_breaker::ChainBreaker, ingest_error::BlockIngestError};
|
||||
|
||||
let status = IndexerStatus {
|
||||
sync: IndexerSyncStatus::stalled("broken chain link".to_owned()),
|
||||
indexed_block_id: Some(41),
|
||||
chain_breaker: Some(ChainBreaker {
|
||||
block_id: Some(42),
|
||||
block_hash: None,
|
||||
prev_block_hash: None,
|
||||
l1_slot: serde_json::Value::Null,
|
||||
error: BlockIngestError::StateTransition("boom".to_owned()),
|
||||
first_seen: None,
|
||||
orphans_since: 2,
|
||||
}),
|
||||
};
|
||||
let value = serde_json::to_value(&status).expect("serialize");
|
||||
assert_eq!(value["state"], serde_json::json!("stalled"));
|
||||
assert_eq!(value["lastError"], serde_json::json!("broken chain link"));
|
||||
assert_eq!(value["indexedBlockId"], serde_json::json!(41));
|
||||
assert_eq!(value["chainBreaker"]["orphansSince"], serde_json::json!(2));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user