radix_transactions/model/v2/
notarized_transaction_v2.rs1use super::*;
2use crate::internal_prelude::*;
3
4#[derive(Debug, Clone, Eq, PartialEq, ManifestSbor, ScryptoDescribe, ScryptoSborAssertion)]
10#[sbor_assert(
11 fixed("FILE:notarized_transaction_v2_schema.bin"),
12 settings(allow_name_changes)
13)]
14pub struct NotarizedTransactionV2 {
24 pub signed_transaction_intent: SignedTransactionIntentV2,
25 pub notary_signature: NotarySignatureV2,
26}
27
28impl NotarizedTransactionV2 {
29 pub fn prepare_and_validate(
30 &self,
31 validator: &TransactionValidator,
32 ) -> Result<ValidatedNotarizedTransactionV2, TransactionValidationError> {
33 self.prepare(validator.preparation_settings())?
34 .validate(validator)
35 }
36
37 pub fn extract_manifest(&self) -> TransactionManifestV2 {
38 TransactionManifestV2::from_intent_core(
39 &self
40 .signed_transaction_intent
41 .transaction_intent
42 .root_intent_core,
43 )
44 }
45
46 pub fn extract_manifests_with_names(
47 &self,
48 names: TransactionObjectNames,
49 ) -> (UserTransactionManifest, Vec<UserSubintentManifest>) {
50 let mut transaction_manifest = TransactionManifestV2::from_intent_core(
51 &self
52 .signed_transaction_intent
53 .transaction_intent
54 .root_intent_core,
55 );
56 transaction_manifest.set_names_if_known(names.root_intent);
57 let subintents = &self
58 .signed_transaction_intent
59 .transaction_intent
60 .non_root_subintents
61 .0;
62 if subintents.len() != names.subintents.len() {
63 panic!(
64 "The transaction object names have names for {} subintents but the transaction has {} subintents",
65 names.subintents.len(),
66 subintents.len(),
67 )
68 }
69 let subintent_manifests = self
70 .signed_transaction_intent
71 .transaction_intent
72 .non_root_subintents
73 .0
74 .iter()
75 .zip(names.subintents)
76 .map(|(subintent, names)| {
77 let mut manifest = SubintentManifestV2::from_intent_core(&subintent.intent_core);
78 manifest.set_names_if_known(names);
79 manifest.into()
80 })
81 .collect();
82 (transaction_manifest.into(), subintent_manifests)
83 }
84}
85
86define_transaction_payload!(
87 NotarizedTransactionV2,
88 RawNotarizedTransaction,
89 PreparedNotarizedTransactionV2 {
90 signed_intent: PreparedSignedTransactionIntentV2,
91 notary_signature: PreparedNotarySignatureV2,
92 },
93 TransactionDiscriminator::V2Notarized,
94);
95
96#[derive(Debug, Clone, Eq, PartialEq, ManifestSbor, ScryptoDescribe)]
97#[sbor(transparent)]
98pub struct NotarySignatureV2(pub SignatureV1);
99
100impl TransactionPartialPrepare for NotarySignatureV2 {
101 type Prepared = PreparedNotarySignatureV2;
102}
103
104#[allow(deprecated)]
105pub type PreparedNotarySignatureV2 = SummarizedRawValueBody<NotarySignatureV2>;
106
107impl PreparedNotarizedTransactionV2 {
108 pub fn end_epoch_exclusive(&self) -> Epoch {
109 let transaction_intent = &self.signed_intent.transaction_intent;
110
111 let root_intent_expiry_epoch = transaction_intent
112 .root_intent_core
113 .header
114 .inner
115 .end_epoch_exclusive;
116 let non_root_intent_expiry_epochs = transaction_intent
117 .non_root_subintents
118 .subintents
119 .iter()
120 .map(|subintent| subintent.intent_core.header.inner.end_epoch_exclusive);
121
122 std::iter::once(root_intent_expiry_epoch)
124 .chain(non_root_intent_expiry_epochs)
125 .min()
126 .unwrap()
127 }
128
129 pub fn hashes(&self) -> UserTransactionHashes {
130 UserTransactionHashes {
131 transaction_intent_hash: self.transaction_intent_hash(),
132 signed_transaction_intent_hash: self.signed_transaction_intent_hash(),
133 notarized_transaction_hash: self.notarized_transaction_hash(),
134 non_root_subintent_hashes: self.non_root_subintent_hashes(),
136 }
137 }
138
139 pub fn validate(
140 self,
141 validator: &TransactionValidator,
142 ) -> Result<ValidatedNotarizedTransactionV2, TransactionValidationError> {
143 validator.validate_notarized_v2(self)
144 }
145}
146
147impl ResolveAsRawNotarizedTransaction for NotarizedTransactionV2 {
148 type Intermediate = RawNotarizedTransaction;
149
150 fn resolve_raw_notarized_transaction(self) -> Self::Intermediate {
151 self.to_raw().expect("Transaction should be encodable")
152 }
153}
154
155impl ResolveAsRawNotarizedTransaction for &NotarizedTransactionV2 {
156 type Intermediate = RawNotarizedTransaction;
157
158 fn resolve_raw_notarized_transaction(self) -> Self::Intermediate {
159 self.to_raw().expect("Transaction should be encodable")
160 }
161}
162
163impl IntoExecutable for NotarizedTransactionV2 {
164 type Error = TransactionValidationError;
165
166 fn into_executable(
167 self,
168 validator: &TransactionValidator,
169 ) -> Result<ExecutableTransaction, Self::Error> {
170 let executable = self.prepare_and_validate(validator)?.create_executable();
171 Ok(executable)
172 }
173}
174
175impl HasTransactionIntentHash for PreparedNotarizedTransactionV2 {
176 fn transaction_intent_hash(&self) -> TransactionIntentHash {
177 self.signed_intent.transaction_intent_hash()
178 }
179}
180
181impl HasSignedTransactionIntentHash for PreparedNotarizedTransactionV2 {
182 fn signed_transaction_intent_hash(&self) -> SignedTransactionIntentHash {
183 self.signed_intent.signed_transaction_intent_hash()
184 }
185}
186
187impl HasNotarizedTransactionHash for PreparedNotarizedTransactionV2 {
188 fn notarized_transaction_hash(&self) -> NotarizedTransactionHash {
189 NotarizedTransactionHash::from_hash(self.summary.hash)
190 }
191}
192
193impl HasNonRootSubintentHashes for PreparedNotarizedTransactionV2 {
194 fn non_root_subintent_hashes(&self) -> Vec<SubintentHash> {
195 self.signed_intent.non_root_subintent_hashes()
196 }
197}