diff --git a/indexer/service/protocol/Cargo.toml b/indexer/service/protocol/Cargo.toml index 2ee61b74..6b7c41a5 100644 --- a/indexer/service/protocol/Cargo.toml +++ b/indexer/service/protocol/Cargo.toml @@ -8,6 +8,7 @@ license = { workspace = true } workspace = true [dependencies] +chrono = { workspace = true } nssa_core = { workspace = true, optional = true, features = ["host"] } nssa = { workspace = true, optional = true } common = { workspace = true, optional = true } diff --git a/indexer/service/protocol/src/lib.rs b/indexer/service/protocol/src/lib.rs index d554267e..503d6187 100644 --- a/indexer/service/protocol/src/lib.rs +++ b/indexer/service/protocol/src/lib.rs @@ -303,11 +303,12 @@ pub struct Nullifier( ); #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] -pub struct ValidityWindow(pub (Option, Option)); +#[serde(transparent)] +pub struct ValidityWindow(pub (Option, Option)); -impl Display for ValidityWindow { +impl Display for ValidityWindow { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.0 { + match &self.0 { (Some(start), Some(end)) => write!(f, "[{start}, {end})"), (Some(start), None) => write!(f, "[{start}, \u{221e})"), (None, Some(end)) => write!(f, "(-\u{221e}, {end})"), @@ -316,6 +317,26 @@ impl Display for ValidityWindow { } } +impl ValidityWindow { + /// Convert to a UTC datetime window given a block-to-timestamp mapping. + pub fn to_datetime_window( + &self, + block_to_timestamp_ms: F, + ) -> ValidityWindow> + where + F: Fn(BlockId) -> Option, + { + let convert = |id: &BlockId| { + block_to_timestamp_ms(*id) + .and_then(|ms| chrono::DateTime::from_timestamp_millis(ms as i64)) + }; + ValidityWindow(( + self.0.0.as_ref().and_then(&convert), + self.0.1.as_ref().and_then(&convert), + )) + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] pub struct CommitmentSetDigest( #[serde(with = "base64::arr")]