penumbra_sdk_sct/
event.rs1use anyhow::{anyhow, Context as _};
2use pbjson_types::Timestamp;
3use penumbra_sdk_tct as tct;
4use tct::builder::{block, epoch};
5
6use penumbra_sdk_proto::{
7 core::component::sct::v1::{self as pb},
8 DomainType, Name as _,
9};
10
11use crate::CommitmentSource;
12
13pub fn anchor(height: u64, anchor: tct::Root, timestamp: i64) -> pb::EventAnchor {
14 pb::EventAnchor {
15 height,
16 anchor: Some(anchor.into()),
17 timestamp: Some(Timestamp {
18 seconds: timestamp,
19 nanos: 0,
20 }),
21 }
22}
23
24#[derive(Debug, Clone)]
25pub struct EventBlockRoot {
26 pub height: u64,
27 pub root: block::Root,
28 pub timestamp_seconds: i64,
29}
30
31impl TryFrom<pb::EventBlockRoot> for EventBlockRoot {
32 type Error = anyhow::Error;
33
34 fn try_from(value: pb::EventBlockRoot) -> Result<Self, Self::Error> {
35 fn inner(value: pb::EventBlockRoot) -> anyhow::Result<EventBlockRoot> {
36 Ok(EventBlockRoot {
37 height: value.height,
38 root: value.root.ok_or(anyhow!("missing `root`"))?.try_into()?,
39 timestamp_seconds: value
40 .timestamp
41 .ok_or(anyhow!("missing `timestamp`"))?
42 .seconds,
43 })
44 }
45 inner(value).context(format!("parsing {}", pb::EventBlockRoot::NAME))
46 }
47}
48
49impl From<EventBlockRoot> for pb::EventBlockRoot {
50 fn from(value: EventBlockRoot) -> Self {
51 Self {
52 height: value.height,
53 root: Some(value.root.into()),
54 timestamp: Some(Timestamp {
55 seconds: value.timestamp_seconds,
56 nanos: 0,
57 }),
58 }
59 }
60}
61
62impl DomainType for EventBlockRoot {
63 type Proto = pb::EventBlockRoot;
64}
65
66#[derive(Debug, Clone)]
67pub struct EventEpochRoot {
68 pub index: u64,
69 pub root: epoch::Root,
70 pub timestamp_seconds: i64,
71}
72
73impl From<EventEpochRoot> for pb::EventEpochRoot {
74 fn from(value: EventEpochRoot) -> Self {
75 pb::EventEpochRoot {
76 index: value.index,
77 root: Some(value.root.into()),
78 timestamp: Some(Timestamp {
79 seconds: value.timestamp_seconds,
80 nanos: 0,
81 }),
82 }
83 }
84}
85
86impl TryFrom<pb::EventEpochRoot> for EventEpochRoot {
87 type Error = anyhow::Error;
88
89 fn try_from(value: pb::EventEpochRoot) -> Result<Self, Self::Error> {
90 fn inner(value: pb::EventEpochRoot) -> anyhow::Result<EventEpochRoot> {
91 Ok(EventEpochRoot {
92 index: value.index,
93 root: value.root.ok_or(anyhow!("missing `root`"))?.try_into()?,
94 timestamp_seconds: value
95 .timestamp
96 .ok_or(anyhow!("missing `timestamp`"))?
97 .seconds,
98 })
99 }
100 inner(value).context(format!("parsing {}", pb::EventEpochRoot::NAME))
101 }
102}
103
104impl DomainType for EventEpochRoot {
105 type Proto = pb::EventEpochRoot;
106}
107
108pub fn commitment(
109 commitment: tct::StateCommitment,
110 position: tct::Position,
111 source: CommitmentSource,
112) -> pb::EventCommitment {
113 pb::EventCommitment {
114 commitment: Some(commitment.into()),
115 position: position.into(),
116 source: Some(source.into()),
117 }
118}