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