From f407c531f6faddc9378a4e788f36b3165494cbf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=BAc=C3=A1s=20Meier?= Date: Mon, 22 Jul 2024 15:26:06 -0700 Subject: [PATCH] (backport) feat: add timestamp to all event protos (#4722) (#4734) this makes a non-consensus-breaking change, adding a timestamp field to the EventBlockRoot proto. This will be used to keep track of the timestamp of the block for use in pindexer. I tested this by running a local devnet with the changes to core. Pd runs fine and the timestamps are correctly propagated to the raw events db. prerequisite for https://github.com/penumbra-zone/penumbra/issues/4675 - [x] If this code contains consensus-breaking changes, I have added the "consensus-breaking" label. Otherwise, I declare my belief that there are not consensus-breaking changes, for the following reason: - only adds a field - adds this field to an Event proto ## Describe your changes ## Issue ticket number and link ## Checklist before requesting a review - [ ] If this code contains consensus-breaking changes, I have added the "consensus-breaking" label. Otherwise, I declare my belief that there are not consensus-breaking changes, for the following reason: > REPLACE THIS TEXT WITH RATIONALE (CAN BE BRIEF) --------- Co-authored-by: Josef Co-authored-by: Conor Schaefer --- .../src/gen/proto_descriptor.bin.no_lfs | Bin 99489 -> 96180 bytes .../core/component/sct/src/component/tree.rs | 12 +++-- crates/core/component/sct/src/event.rs | 19 +++++-- .../src/gen/penumbra.core.component.sct.v1.rs | 6 +++ .../penumbra.core.component.sct.v1.serde.rs | 51 ++++++++++++++++++ .../proto/src/gen/proto_descriptor.bin.no_lfs | Bin 545124 -> 542164 bytes .../penumbra/core/component/sct/v1/sct.proto | 4 ++ 7 files changed, 86 insertions(+), 6 deletions(-) diff --git a/crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs b/crates/cnidarium/src/gen/proto_descriptor.bin.no_lfs index 6e23fc5c3fa90b2ae6af49ab1a84a133ac4ac9bb..dc5d8505a30f0a0920b78effb24b371446844fb7 100644 GIT binary patch delta 19801 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 IL?)Exc)#m};G%A> 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 Pj+;1X{o|h1=HdSZt^gQ= delta 23133 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 PW?Ie6rpLbO@QeQfKu^ur diff --git a/crates/core/component/sct/src/component/tree.rs b/crates/core/component/sct/src/component/tree.rs index 897226d619..b0d987a109 100644 --- a/crates/core/component/sct/src/component/tree.rs +++ b/crates/core/component/sct/src/component/tree.rs @@ -72,6 +72,11 @@ pub trait SctManager: StateWrite { epoch_root: Option, ) { let sct_anchor = sct.root(); + let block_timestamp = self + .get_current_block_timestamp() + .await + .map(|t| t.unix_timestamp()) + .unwrap_or(0); // Write the anchor as a key, so we can check claimed anchors... self.put_proto(state_key::tree::anchor_lookup(sct_anchor), height); @@ -79,8 +84,8 @@ pub trait SctManager: StateWrite { // TODO: can we move this out to NV storage? self.put(state_key::tree::anchor_by_height(height), sct_anchor); - self.record_proto(event::anchor(height, sct_anchor)); - self.record_proto(event::block_root(height, block_root)); + self.record_proto(event::anchor(height, sct_anchor, block_timestamp)); + self.record_proto(event::block_root(height, block_root, block_timestamp)); // Only record an epoch root event if we are ending the epoch. if let Some(epoch_root) = epoch_root { let index = self @@ -88,7 +93,7 @@ pub trait SctManager: StateWrite { .await .expect("epoch must be set") .index; - self.record_proto(event::epoch_root(index, epoch_root)); + self.record_proto(event::epoch_root(index, epoch_root, block_timestamp)); } self.write_sct_cache(sct); @@ -238,4 +243,5 @@ pub trait VerificationExt: StateRead { Ok(()) } } + impl VerificationExt for T {} diff --git a/crates/core/component/sct/src/event.rs b/crates/core/component/sct/src/event.rs index 3bde931a2d..65a462b0f8 100644 --- a/crates/core/component/sct/src/event.rs +++ b/crates/core/component/sct/src/event.rs @@ -1,3 +1,4 @@ +use pbjson_types::Timestamp; use penumbra_tct as tct; use tct::builder::{block, epoch}; @@ -5,24 +6,36 @@ use penumbra_proto::core::component::sct::v1 as pb; use crate::CommitmentSource; -pub fn anchor(height: u64, anchor: tct::Root) -> pb::EventAnchor { +pub fn anchor(height: u64, anchor: tct::Root, timestamp: i64) -> pb::EventAnchor { pb::EventAnchor { height, anchor: Some(anchor.into()), + timestamp: Some(Timestamp { + seconds: timestamp, + nanos: 0, + }), } } -pub fn block_root(height: u64, root: block::Root) -> pb::EventBlockRoot { +pub fn block_root(height: u64, root: block::Root, timestamp: i64) -> pb::EventBlockRoot { pb::EventBlockRoot { height, root: Some(root.into()), + timestamp: Some(Timestamp { + seconds: timestamp, + nanos: 0, + }), } } -pub fn epoch_root(index: u64, root: epoch::Root) -> pb::EventEpochRoot { +pub fn epoch_root(index: u64, root: epoch::Root, timestamp: i64) -> pb::EventEpochRoot { pb::EventEpochRoot { index, root: Some(root.into()), + timestamp: Some(Timestamp { + seconds: timestamp, + nanos: 0, + }), } } diff --git a/crates/proto/src/gen/penumbra.core.component.sct.v1.rs b/crates/proto/src/gen/penumbra.core.component.sct.v1.rs index 6f132c5141..24724a4047 100644 --- a/crates/proto/src/gen/penumbra.core.component.sct.v1.rs +++ b/crates/proto/src/gen/penumbra.core.component.sct.v1.rs @@ -229,6 +229,8 @@ pub struct EventAnchor { >, #[prost(uint64, tag = "2")] pub height: u64, + #[prost(message, optional, tag = "3")] + pub timestamp: ::core::option::Option<::pbjson_types::Timestamp>, } impl ::prost::Name for EventAnchor { const NAME: &'static str = "EventAnchor"; @@ -247,6 +249,8 @@ pub struct EventEpochRoot { >, #[prost(uint64, tag = "2")] pub index: u64, + #[prost(message, optional, tag = "3")] + pub timestamp: ::core::option::Option<::pbjson_types::Timestamp>, } impl ::prost::Name for EventEpochRoot { const NAME: &'static str = "EventEpochRoot"; @@ -265,6 +269,8 @@ pub struct EventBlockRoot { >, #[prost(uint64, tag = "2")] pub height: u64, + #[prost(message, optional, tag = "3")] + pub timestamp: ::core::option::Option<::pbjson_types::Timestamp>, } impl ::prost::Name for EventBlockRoot { const NAME: &'static str = "EventBlockRoot"; diff --git a/crates/proto/src/gen/penumbra.core.component.sct.v1.serde.rs b/crates/proto/src/gen/penumbra.core.component.sct.v1.serde.rs index 6618d12701..773dcedfea 100644 --- a/crates/proto/src/gen/penumbra.core.component.sct.v1.serde.rs +++ b/crates/proto/src/gen/penumbra.core.component.sct.v1.serde.rs @@ -1147,6 +1147,9 @@ impl serde::Serialize for EventAnchor { if self.height != 0 { len += 1; } + if self.timestamp.is_some() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("penumbra.core.component.sct.v1.EventAnchor", len)?; if let Some(v) = self.anchor.as_ref() { struct_ser.serialize_field("anchor", v)?; @@ -1155,6 +1158,9 @@ impl serde::Serialize for EventAnchor { #[allow(clippy::needless_borrow)] struct_ser.serialize_field("height", ToString::to_string(&self.height).as_str())?; } + if let Some(v) = self.timestamp.as_ref() { + struct_ser.serialize_field("timestamp", v)?; + } struct_ser.end() } } @@ -1167,12 +1173,14 @@ impl<'de> serde::Deserialize<'de> for EventAnchor { const FIELDS: &[&str] = &[ "anchor", "height", + "timestamp", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { Anchor, Height, + Timestamp, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -1197,6 +1205,7 @@ impl<'de> serde::Deserialize<'de> for EventAnchor { match value { "anchor" => Ok(GeneratedField::Anchor), "height" => Ok(GeneratedField::Height), + "timestamp" => Ok(GeneratedField::Timestamp), _ => Ok(GeneratedField::__SkipField__), } } @@ -1218,6 +1227,7 @@ impl<'de> serde::Deserialize<'de> for EventAnchor { { let mut anchor__ = None; let mut height__ = None; + let mut timestamp__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Anchor => { @@ -1234,6 +1244,12 @@ impl<'de> serde::Deserialize<'de> for EventAnchor { Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } + GeneratedField::Timestamp => { + if timestamp__.is_some() { + return Err(serde::de::Error::duplicate_field("timestamp")); + } + timestamp__ = map_.next_value()?; + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -1242,6 +1258,7 @@ impl<'de> serde::Deserialize<'de> for EventAnchor { Ok(EventAnchor { anchor: anchor__, height: height__.unwrap_or_default(), + timestamp: timestamp__, }) } } @@ -1262,6 +1279,9 @@ impl serde::Serialize for EventBlockRoot { if self.height != 0 { len += 1; } + if self.timestamp.is_some() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("penumbra.core.component.sct.v1.EventBlockRoot", len)?; if let Some(v) = self.root.as_ref() { struct_ser.serialize_field("root", v)?; @@ -1270,6 +1290,9 @@ impl serde::Serialize for EventBlockRoot { #[allow(clippy::needless_borrow)] struct_ser.serialize_field("height", ToString::to_string(&self.height).as_str())?; } + if let Some(v) = self.timestamp.as_ref() { + struct_ser.serialize_field("timestamp", v)?; + } struct_ser.end() } } @@ -1282,12 +1305,14 @@ impl<'de> serde::Deserialize<'de> for EventBlockRoot { const FIELDS: &[&str] = &[ "root", "height", + "timestamp", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { Root, Height, + Timestamp, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -1312,6 +1337,7 @@ impl<'de> serde::Deserialize<'de> for EventBlockRoot { match value { "root" => Ok(GeneratedField::Root), "height" => Ok(GeneratedField::Height), + "timestamp" => Ok(GeneratedField::Timestamp), _ => Ok(GeneratedField::__SkipField__), } } @@ -1333,6 +1359,7 @@ impl<'de> serde::Deserialize<'de> for EventBlockRoot { { let mut root__ = None; let mut height__ = None; + let mut timestamp__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Root => { @@ -1349,6 +1376,12 @@ impl<'de> serde::Deserialize<'de> for EventBlockRoot { Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } + GeneratedField::Timestamp => { + if timestamp__.is_some() { + return Err(serde::de::Error::duplicate_field("timestamp")); + } + timestamp__ = map_.next_value()?; + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -1357,6 +1390,7 @@ impl<'de> serde::Deserialize<'de> for EventBlockRoot { Ok(EventBlockRoot { root: root__, height: height__.unwrap_or_default(), + timestamp: timestamp__, }) } } @@ -1509,6 +1543,9 @@ impl serde::Serialize for EventEpochRoot { if self.index != 0 { len += 1; } + if self.timestamp.is_some() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("penumbra.core.component.sct.v1.EventEpochRoot", len)?; if let Some(v) = self.root.as_ref() { struct_ser.serialize_field("root", v)?; @@ -1517,6 +1554,9 @@ impl serde::Serialize for EventEpochRoot { #[allow(clippy::needless_borrow)] struct_ser.serialize_field("index", ToString::to_string(&self.index).as_str())?; } + if let Some(v) = self.timestamp.as_ref() { + struct_ser.serialize_field("timestamp", v)?; + } struct_ser.end() } } @@ -1529,12 +1569,14 @@ impl<'de> serde::Deserialize<'de> for EventEpochRoot { const FIELDS: &[&str] = &[ "root", "index", + "timestamp", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { Root, Index, + Timestamp, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -1559,6 +1601,7 @@ impl<'de> serde::Deserialize<'de> for EventEpochRoot { match value { "root" => Ok(GeneratedField::Root), "index" => Ok(GeneratedField::Index), + "timestamp" => Ok(GeneratedField::Timestamp), _ => Ok(GeneratedField::__SkipField__), } } @@ -1580,6 +1623,7 @@ impl<'de> serde::Deserialize<'de> for EventEpochRoot { { let mut root__ = None; let mut index__ = None; + let mut timestamp__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Root => { @@ -1596,6 +1640,12 @@ impl<'de> serde::Deserialize<'de> for EventEpochRoot { Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } + GeneratedField::Timestamp => { + if timestamp__.is_some() { + return Err(serde::de::Error::duplicate_field("timestamp")); + } + timestamp__ = map_.next_value()?; + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -1604,6 +1654,7 @@ impl<'de> serde::Deserialize<'de> for EventEpochRoot { Ok(EventEpochRoot { root: root__, index: index__.unwrap_or_default(), + timestamp: timestamp__, }) } } diff --git a/crates/proto/src/gen/proto_descriptor.bin.no_lfs b/crates/proto/src/gen/proto_descriptor.bin.no_lfs index dfc57885204e0690f057bfebea28811ac2890860..e0830c914d985e5a05d885ff66b5d38c2f7b2c68 100644 GIT binary patch delta 21268 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