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.into_iter())
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
100#[allow(deprecated)]
101pub type PreparedNotarySignatureV2 = SummarizedRawValueBody<NotarySignatureV2>;
102
103impl PreparedNotarizedTransactionV2 {
104 pub fn end_epoch_exclusive(&self) -> Epoch {
105 let transaction_intent = &self.signed_intent.transaction_intent;
106
107 let root_intent_expiry_epoch = transaction_intent
108 .root_intent_core
109 .header
110 .inner
111 .end_epoch_exclusive;
112 let non_root_intent_expiry_epochs = transaction_intent
113 .non_root_subintents
114 .subintents
115 .iter()
116 .map(|subintent| subintent.intent_core.header.inner.end_epoch_exclusive);
117
118 std::iter::once(root_intent_expiry_epoch)
120 .chain(non_root_intent_expiry_epochs)
121 .min()
122 .unwrap()
123 }
124
125 pub fn hashes(&self) -> UserTransactionHashes {
126 UserTransactionHashes {
127 transaction_intent_hash: self.transaction_intent_hash(),
128 signed_transaction_intent_hash: self.signed_transaction_intent_hash(),
129 notarized_transaction_hash: self.notarized_transaction_hash(),
130 non_root_subintent_hashes: self.non_root_subintent_hashes(),
132 }
133 }
134
135 pub fn validate(
136 self,
137 validator: &TransactionValidator,
138 ) -> Result<ValidatedNotarizedTransactionV2, TransactionValidationError> {
139 validator.validate_notarized_v2(self)
140 }
141}
142
143impl ResolveAsRawNotarizedTransaction for NotarizedTransactionV2 {
144 type Intermediate = RawNotarizedTransaction;
145
146 fn resolve_raw_notarized_transaction(self) -> Self::Intermediate {
147 self.to_raw().expect("Transaction should be encodable")
148 }
149}
150
151impl<'a> ResolveAsRawNotarizedTransaction for &'a NotarizedTransactionV2 {
152 type Intermediate = RawNotarizedTransaction;
153
154 fn resolve_raw_notarized_transaction(self) -> Self::Intermediate {
155 self.to_raw().expect("Transaction should be encodable")
156 }
157}
158
159impl IntoExecutable for NotarizedTransactionV2 {
160 type Error = TransactionValidationError;
161
162 fn into_executable(
163 self,
164 validator: &TransactionValidator,
165 ) -> Result<ExecutableTransaction, Self::Error> {
166 let executable = self.prepare_and_validate(validator)?.create_executable();
167 Ok(executable)
168 }
169}
170
171impl HasTransactionIntentHash for PreparedNotarizedTransactionV2 {
172 fn transaction_intent_hash(&self) -> TransactionIntentHash {
173 self.signed_intent.transaction_intent_hash()
174 }
175}
176
177impl HasSignedTransactionIntentHash for PreparedNotarizedTransactionV2 {
178 fn signed_transaction_intent_hash(&self) -> SignedTransactionIntentHash {
179 self.signed_intent.signed_transaction_intent_hash()
180 }
181}
182
183impl HasNotarizedTransactionHash for PreparedNotarizedTransactionV2 {
184 fn notarized_transaction_hash(&self) -> NotarizedTransactionHash {
185 NotarizedTransactionHash::from_hash(self.summary.hash)
186 }
187}
188
189impl HasNonRootSubintentHashes for PreparedNotarizedTransactionV2 {
190 fn non_root_subintent_hashes(&self) -> Vec<SubintentHash> {
191 self.signed_intent.non_root_subintent_hashes()
192 }
193}