1use crate::base_types::AuthorityName;
5use crate::committee::{Committee, EpochId};
6use crate::crypto::{
7 AuthorityKeyPair, AuthorityQuorumSignInfo, AuthoritySignInfo, AuthoritySignature,
8 AuthorityStrongQuorumSignInfo, EmptySignInfo, Signer,
9};
10use crate::error::SuiResult;
11use crate::executable_transaction::CertificateProof;
12use crate::messages_checkpoint::CheckpointSequenceNumber;
13use fastcrypto::traits::KeyPair;
14use once_cell::sync::OnceCell;
15use serde::{Deserialize, Serialize, de::DeserializeOwned};
16use serde_name::{DeserializeNameAdapter, SerializeNameAdapter};
17use shared_crypto::intent::{Intent, IntentScope};
18use std::fmt::{Debug, Display, Formatter};
19use std::ops::{Deref, DerefMut};
20
21pub trait Message {
22 type DigestType: Clone + Debug;
23 const SCOPE: IntentScope;
24
25 fn scope(&self) -> IntentScope {
26 Self::SCOPE
27 }
28
29 fn digest(&self) -> Self::DigestType;
30}
31
32#[derive(Clone, Debug, Eq, Serialize, Deserialize)]
33#[serde(remote = "Envelope")]
34pub struct Envelope<T: Message, S> {
35 #[serde(skip)]
36 digest: OnceCell<T::DigestType>,
37
38 data: T,
39 auth_signature: S,
40}
41
42impl<'de, T, S> Deserialize<'de> for Envelope<T, S>
43where
44 T: Message + Deserialize<'de>,
45 S: Deserialize<'de>,
46{
47 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
48 where
49 D: serde::de::Deserializer<'de>,
50 {
51 Envelope::deserialize(DeserializeNameAdapter::new(
52 deserializer,
53 std::any::type_name::<Self>(),
54 ))
55 }
56}
57
58impl<T, Sig> Serialize for Envelope<T, Sig>
59where
60 T: Message + Serialize,
61 Sig: Serialize,
62{
63 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64 where
65 S: serde::ser::Serializer,
66 {
67 Envelope::serialize(
68 self,
69 SerializeNameAdapter::new(serializer, std::any::type_name::<Self>()),
70 )
71 }
72}
73
74impl<T: Message, S> Envelope<T, S> {
75 pub fn new_from_data_and_sig(data: T, sig: S) -> Self {
76 Self {
77 digest: Default::default(),
78 data,
79 auth_signature: sig,
80 }
81 }
82
83 pub fn data(&self) -> &T {
84 &self.data
85 }
86
87 pub fn into_data(self) -> T {
88 self.data
89 }
90
91 pub fn into_sig(self) -> S {
92 self.auth_signature
93 }
94
95 pub fn into_data_and_sig(self) -> (T, S) {
96 let Self {
97 data,
98 auth_signature,
99 ..
100 } = self;
101 (data, auth_signature)
102 }
103
104 pub fn into_unsigned(self) -> Envelope<T, EmptySignInfo> {
106 Envelope::<T, EmptySignInfo>::new(self.into_data())
107 }
108
109 pub fn auth_sig(&self) -> &S {
110 &self.auth_signature
111 }
112
113 pub fn auth_sig_mut_for_testing(&mut self) -> &mut S {
114 &mut self.auth_signature
115 }
116
117 pub fn digest(&self) -> &T::DigestType {
118 self.digest.get_or_init(|| self.data.digest())
119 }
120
121 pub fn data_mut_for_testing(&mut self) -> &mut T {
122 &mut self.data
123 }
124}
125
126impl<T: Message + PartialEq, S: PartialEq> PartialEq for Envelope<T, S> {
127 fn eq(&self, other: &Self) -> bool {
128 self.data == other.data && self.auth_signature == other.auth_signature
129 }
130}
131
132impl<T: Message> Envelope<T, EmptySignInfo> {
133 pub fn new(data: T) -> Self {
134 Self {
135 digest: OnceCell::new(),
136 data,
137 auth_signature: EmptySignInfo {},
138 }
139 }
140}
141
142impl<T> Envelope<T, AuthoritySignInfo>
143where
144 T: Message + Serialize,
145{
146 pub fn new(
147 epoch: EpochId,
148 data: T,
149 secret: &dyn Signer<AuthoritySignature>,
150 authority: AuthorityName,
151 ) -> Self {
152 let auth_signature = Self::sign(epoch, &data, secret, authority);
153 Self {
154 digest: OnceCell::new(),
155 data,
156 auth_signature,
157 }
158 }
159
160 pub fn sign(
161 epoch: EpochId,
162 data: &T,
163 secret: &dyn Signer<AuthoritySignature>,
164 authority: AuthorityName,
165 ) -> AuthoritySignInfo {
166 AuthoritySignInfo::new(epoch, &data, Intent::sui_app(T::SCOPE), authority, secret)
167 }
168
169 pub fn epoch(&self) -> EpochId {
170 self.auth_signature.epoch
171 }
172}
173
174impl<T, const S: bool> Envelope<T, AuthorityQuorumSignInfo<S>>
175where
176 T: Message + Serialize,
177{
178 pub fn new(
179 data: T,
180 signatures: Vec<AuthoritySignInfo>,
181 committee: &Committee,
182 ) -> SuiResult<Self> {
183 let cert = Self {
184 digest: OnceCell::new(),
185 data,
186 auth_signature: AuthorityQuorumSignInfo::<S>::new_from_auth_sign_infos(
187 signatures, committee,
188 )?,
189 };
190
191 Ok(cert)
192 }
193
194 pub fn new_from_keypairs_for_testing(
195 data: T,
196 keypairs: &[AuthorityKeyPair],
197 committee: &Committee,
198 ) -> Self {
199 let signatures = keypairs
200 .iter()
201 .map(|keypair| {
202 AuthoritySignInfo::new(
203 committee.epoch(),
204 &data,
205 Intent::sui_app(T::SCOPE),
206 keypair.public().into(),
207 keypair,
208 )
209 })
210 .collect();
211 Self::new(data, signatures, committee).unwrap()
212 }
213
214 pub fn epoch(&self) -> EpochId {
215 self.auth_signature.epoch
216 }
217}
218
219#[derive(Clone, Serialize, Deserialize)]
233pub struct TrustedEnvelope<T: Message, S>(Envelope<T, S>);
234
235impl<T, S: Debug> Debug for TrustedEnvelope<T, S>
236where
237 T: Message + Debug,
238{
239 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
240 write!(f, "{:?}", self.0)
241 }
242}
243
244impl<T: Message, S> TrustedEnvelope<T, S> {
245 pub fn into_inner(self) -> Envelope<T, S> {
246 self.0
247 }
248
249 pub fn inner(&self) -> &Envelope<T, S> {
250 &self.0
251 }
252}
253
254#[derive(Clone)]
256struct NoSer;
257static_assertions::assert_not_impl_any!(NoSer: Serialize, DeserializeOwned);
259
260#[derive(Clone)]
261pub struct VerifiedEnvelope<T: Message, S>(TrustedEnvelope<T, S>, NoSer);
262
263impl<T, S: Debug> Debug for VerifiedEnvelope<T, S>
264where
265 T: Message + Debug,
266{
267 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
268 write!(f, "{:?}", self.0.0)
269 }
270}
271
272impl<T: Message, S> VerifiedEnvelope<T, S> {
273 pub fn new_from_verified(inner: Envelope<T, S>) -> Self {
275 Self(TrustedEnvelope(inner), NoSer)
276 }
277
278 pub fn new_unchecked(inner: Envelope<T, S>) -> Self {
282 Self(TrustedEnvelope(inner), NoSer)
283 }
284
285 pub fn into_inner(self) -> Envelope<T, S> {
286 self.0.0
287 }
288
289 pub fn inner(&self) -> &Envelope<T, S> {
290 &self.0.0
291 }
292
293 pub fn into_message(self) -> T {
294 self.into_inner().into_data()
295 }
296
297 pub fn serializable_ref(&self) -> &TrustedEnvelope<T, S> {
301 &self.0
302 }
303
304 pub fn serializable(self) -> TrustedEnvelope<T, S> {
308 self.0
309 }
310
311 pub fn into_unsigned(self) -> VerifiedEnvelope<T, EmptySignInfo> {
313 VerifiedEnvelope::<T, EmptySignInfo>::new_from_verified(self.into_inner().into_unsigned())
314 }
315}
316
317impl<T: Message, S> From<TrustedEnvelope<T, S>> for VerifiedEnvelope<T, S> {
320 fn from(e: TrustedEnvelope<T, S>) -> Self {
321 Self::new_unchecked(e.0)
322 }
323}
324
325impl<T: Message, S> Deref for VerifiedEnvelope<T, S> {
326 type Target = Envelope<T, S>;
327 fn deref(&self) -> &Self::Target {
328 &self.0.0
329 }
330}
331
332impl<T: Message, S> Deref for Envelope<T, S> {
333 type Target = T;
334 fn deref(&self) -> &Self::Target {
335 &self.data
336 }
337}
338
339impl<T: Message, S> DerefMut for Envelope<T, S> {
340 fn deref_mut(&mut self) -> &mut Self::Target {
341 &mut self.data
342 }
343}
344
345impl<T: Message, S> From<VerifiedEnvelope<T, S>> for Envelope<T, S> {
346 fn from(v: VerifiedEnvelope<T, S>) -> Self {
347 v.0.0
348 }
349}
350
351impl<T: Message, S> PartialEq for VerifiedEnvelope<T, S>
352where
353 Envelope<T, S>: PartialEq,
354{
355 fn eq(&self, other: &Self) -> bool {
356 self.0.0 == other.0.0
357 }
358}
359
360impl<T: Message, S> Eq for VerifiedEnvelope<T, S> where Envelope<T, S>: Eq {}
361
362impl<T, S> Display for VerifiedEnvelope<T, S>
363where
364 T: Message,
365 Envelope<T, S>: Display,
366{
367 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
368 write!(f, "{}", self.0.0)
369 }
370}
371
372impl<T: Message> VerifiedEnvelope<T, CertificateProof> {
379 pub fn new_from_certificate(
380 certificate: VerifiedEnvelope<T, AuthorityStrongQuorumSignInfo>,
381 ) -> Self {
382 let inner = certificate.into_inner();
383 let Envelope {
384 digest,
385 data,
386 auth_signature,
387 } = inner;
388 VerifiedEnvelope::new_unchecked(Envelope {
389 digest,
390 data,
391 auth_signature: CertificateProof::new_from_cert_sig(auth_signature),
392 })
393 }
394
395 pub fn new_from_checkpoint(
396 transaction: VerifiedEnvelope<T, EmptySignInfo>,
397 epoch: EpochId,
398 checkpoint: CheckpointSequenceNumber,
399 ) -> Self {
400 let inner = transaction.into_inner();
401 let Envelope {
402 digest,
403 data,
404 auth_signature: _,
405 } = inner;
406 VerifiedEnvelope::new_unchecked(Envelope {
407 digest,
408 data,
409 auth_signature: CertificateProof::new_from_checkpoint(epoch, checkpoint),
410 })
411 }
412
413 pub fn new_system(transaction: VerifiedEnvelope<T, EmptySignInfo>, epoch: EpochId) -> Self {
414 let inner = transaction.into_inner();
415 let Envelope {
416 digest,
417 data,
418 auth_signature: _,
419 } = inner;
420 VerifiedEnvelope::new_unchecked(Envelope {
421 digest,
422 data,
423 auth_signature: CertificateProof::new_system(epoch),
424 })
425 }
426
427 pub fn new_from_consensus(
428 transaction: VerifiedEnvelope<T, EmptySignInfo>,
429 epoch: EpochId,
430 ) -> Self {
431 let inner = transaction.into_inner();
432 let Envelope {
433 digest,
434 data,
435 auth_signature: _,
436 } = inner;
437 VerifiedEnvelope::new_unchecked(Envelope {
438 digest,
439 data,
440 auth_signature: CertificateProof::new_from_consensus(epoch),
441 })
442 }
443
444 pub fn epoch(&self) -> EpochId {
445 self.auth_signature.epoch()
446 }
447}