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