penumbra_sdk_proto/
protobuf.rs1use crate::Name;
2use std::convert::{From, TryFrom};
3
4#[cfg(feature = "tendermint")]
5mod tendermint_compat;
6
7pub trait DomainType
9where
10 Self: Clone + Sized + TryFrom<Self::Proto>,
11 Self::Proto: prost::Name + prost::Message + Default + From<Self> + Send + Sync + 'static,
12 anyhow::Error: From<<Self as TryFrom<Self::Proto>>::Error>,
13{
14 type Proto;
15
16 fn encode_to_vec(&self) -> Vec<u8> {
18 use prost::Message;
19 self.to_proto().encode_to_vec()
20 }
21
22 fn to_proto(&self) -> Self::Proto {
27 Self::Proto::from(self.clone())
28 }
29
30 fn decode<B: bytes::Buf>(buf: B) -> anyhow::Result<Self> {
32 <Self::Proto as prost::Message>::decode(buf)?
33 .try_into()
34 .map_err(Into::into)
35 }
36}
37
38use crate::penumbra::core::component::ibc::v1::IbcRelay;
44use crate::penumbra::crypto::decaf377_rdsa::v1::{
45 BindingSignature, SpendAuthSignature, SpendVerificationKey,
46};
47
48use decaf377_rdsa::{Binding, Signature, SpendAuth, VerificationKey};
49
50impl DomainType for Signature<SpendAuth> {
51 type Proto = SpendAuthSignature;
52}
53impl DomainType for Signature<Binding> {
54 type Proto = BindingSignature;
55}
56impl DomainType for VerificationKey<SpendAuth> {
57 type Proto = SpendVerificationKey;
58}
59
60impl From<Signature<SpendAuth>> for SpendAuthSignature {
61 fn from(sig: Signature<SpendAuth>) -> Self {
62 Self {
63 inner: sig.to_bytes().to_vec(),
64 }
65 }
66}
67
68impl From<Signature<Binding>> for BindingSignature {
69 fn from(sig: Signature<Binding>) -> Self {
70 Self {
71 inner: sig.to_bytes().to_vec(),
72 }
73 }
74}
75
76impl From<VerificationKey<SpendAuth>> for SpendVerificationKey {
77 fn from(key: VerificationKey<SpendAuth>) -> Self {
78 Self {
79 inner: key.to_bytes().to_vec(),
80 }
81 }
82}
83
84impl TryFrom<SpendAuthSignature> for Signature<SpendAuth> {
85 type Error = anyhow::Error;
86 fn try_from(value: SpendAuthSignature) -> Result<Self, Self::Error> {
87 Ok(value.inner.as_slice().try_into()?)
88 }
89}
90
91impl TryFrom<BindingSignature> for Signature<Binding> {
92 type Error = anyhow::Error;
93 fn try_from(value: BindingSignature) -> Result<Self, Self::Error> {
94 Ok(value.inner.as_slice().try_into()?)
95 }
96}
97
98impl TryFrom<SpendVerificationKey> for VerificationKey<SpendAuth> {
99 type Error = anyhow::Error;
100 fn try_from(value: SpendVerificationKey) -> Result<Self, Self::Error> {
101 Ok(value.inner.as_slice().try_into()?)
102 }
103}
104
105use crate::penumbra::crypto::decaf377_fmd::v1::Clue as ProtoClue;
107use decaf377_fmd::Clue;
108
109impl DomainType for Clue {
110 type Proto = ProtoClue;
111}
112
113impl From<Clue> for ProtoClue {
114 fn from(msg: Clue) -> Self {
115 ProtoClue { inner: msg.into() }
116 }
117}
118
119impl TryFrom<ProtoClue> for Clue {
120 type Error = anyhow::Error;
121
122 fn try_from(proto: ProtoClue) -> Result<Self, Self::Error> {
123 proto.inner[..]
124 .try_into()
125 .map_err(|_| anyhow::anyhow!("expected 68-byte clue"))
126 }
127}
128
129use crate::penumbra::core::keys::v1::ConsensusKey;
135
136impl DomainType for tendermint::PublicKey {
137 type Proto = ConsensusKey;
138}
139
140impl From<tendermint::PublicKey> for crate::penumbra::core::keys::v1::ConsensusKey {
141 fn from(v: tendermint::PublicKey) -> Self {
142 Self {
143 inner: v.to_bytes(),
144 }
145 }
146}
147
148impl TryFrom<crate::core::keys::v1::ConsensusKey> for tendermint::PublicKey {
149 type Error = anyhow::Error;
150 fn try_from(value: crate::core::keys::v1::ConsensusKey) -> Result<Self, Self::Error> {
151 Self::from_raw_ed25519(value.inner.as_slice())
152 .ok_or_else(|| anyhow::anyhow!("invalid ed25519 key"))
153 }
154}
155
156extern crate ibc_types;
158
159use ibc_proto::ibc::core::channel::v1::Channel as RawChannel;
160use ibc_proto::ibc::core::client::v1::Height as RawHeight;
161use ibc_proto::ibc::core::connection::v1::ClientPaths as RawClientPaths;
162use ibc_proto::ibc::core::connection::v1::ConnectionEnd as RawConnectionEnd;
163
164use ibc_types::core::channel::ChannelEnd;
165use ibc_types::core::client::Height;
166use ibc_types::core::connection::{ClientPaths, ConnectionEnd};
167use ibc_types::lightclients::tendermint::client_state::ClientState;
168use ibc_types::lightclients::tendermint::consensus_state::ConsensusState;
169
170impl DomainType for ClientPaths {
171 type Proto = RawClientPaths;
172}
173
174impl DomainType for ConnectionEnd {
175 type Proto = RawConnectionEnd;
176}
177
178impl DomainType for ChannelEnd {
179 type Proto = RawChannel;
180}
181impl DomainType for Height {
182 type Proto = RawHeight;
183}
184
185impl DomainType for ClientState {
186 type Proto = ibc_proto::google::protobuf::Any;
187}
188impl DomainType for ConsensusState {
189 type Proto = ibc_proto::google::protobuf::Any;
190}
191
192impl<T> From<T> for IbcRelay
193where
194 T: ibc_types::DomainType + Send + Sync + 'static,
195 <T as TryFrom<<T as ibc_types::DomainType>::Proto>>::Error: Send + Sync + std::error::Error,
196{
197 fn from(v: T) -> Self {
198 let value_bytes = v.encode_to_vec();
199 let any = pbjson_types::Any {
200 type_url: <T as ibc_types::DomainType>::Proto::type_url(),
201 value: value_bytes.into(),
202 };
203
204 Self {
205 raw_action: Some(any),
206 }
207 }
208}