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