cml_chain/auxdata/
utils.rs

1use crate::auxdata::metadata::Metadata;
2
3use crate::{
4    plutus::{PlutusV1Script, PlutusV2Script},
5    transaction::NativeScript,
6};
7
8use super::{AuxiliaryData, ConwayFormatAuxData, ShelleyMAFormatAuxData};
9
10impl AuxiliaryData {
11    pub fn new() -> Self {
12        Self::new_shelley(Metadata::new())
13    }
14
15    pub fn metadata(&self) -> Option<&Metadata> {
16        match self {
17            Self::Shelley(shelley) => Some(shelley),
18            Self::ShelleyMA(shelley_ma) => Some(&shelley_ma.transaction_metadata),
19            Self::Conway(conway) => conway.metadata.as_ref(),
20        }
21    }
22
23    /// Mut ref to the general tx metadata.
24    /// Will be created if it didn't exist (i.e. Conway format)
25    pub fn metadata_mut(&mut self) -> &mut Metadata {
26        match self {
27            Self::Shelley(shelley) => shelley,
28            Self::ShelleyMA(shelley_ma) => &mut shelley_ma.transaction_metadata,
29            Self::Conway(conway) => {
30                if conway.metadata.is_none() {
31                    conway.metadata = Some(Metadata::new());
32                }
33                conway.metadata.as_mut().unwrap()
34            }
35        }
36    }
37
38    pub fn native_scripts(&self) -> Option<&Vec<NativeScript>> {
39        match self {
40            Self::Shelley { .. } => None,
41            Self::ShelleyMA(shelley_ma) => Some(&shelley_ma.auxiliary_scripts),
42            Self::Conway(conway) => conway.native_scripts.as_ref(),
43        }
44        .filter(|scripts| !scripts.is_empty())
45    }
46
47    pub fn plutus_v1_scripts(&self) -> Option<&Vec<PlutusV1Script>> {
48        match self {
49            Self::Shelley { .. } => None,
50            Self::ShelleyMA(_shelley_ma) => None,
51            Self::Conway(conway) => conway.plutus_v1_scripts.as_ref(),
52        }
53        .filter(|scripts| !scripts.is_empty())
54    }
55
56    pub fn plutus_v2_scripts(&self) -> Option<&Vec<PlutusV2Script>> {
57        match self {
58            Self::Shelley { .. } => None,
59            Self::ShelleyMA(_shelley_ma) => None,
60            Self::Conway(conway) => conway.plutus_v2_scripts.as_ref(),
61        }
62        .filter(|scripts| !scripts.is_empty())
63    }
64
65    /// Warning: overwrites any conflicting metadatum labels present
66    pub fn add_metadata(&mut self, other: Metadata) {
67        let metadata = match self {
68            Self::Shelley(shelley) => shelley,
69            Self::ShelleyMA(shelley_ma) => &mut shelley_ma.transaction_metadata,
70            Self::Conway(conway) => {
71                if conway.metadata.is_none() {
72                    conway.metadata = Some(Metadata::new());
73                }
74                conway.metadata.as_mut().unwrap()
75            }
76        };
77        metadata.entries.extend(other.entries);
78    }
79
80    /// Warning: does not check for duplicates and may migrate eras
81    pub fn add_native_scripts(&mut self, scripts: Vec<NativeScript>) {
82        match self {
83            Self::Shelley(shelley) => {
84                *self = Self::ShelleyMA(ShelleyMAFormatAuxData::new(shelley.clone(), scripts));
85            }
86            Self::ShelleyMA(shelley_ma) => {
87                shelley_ma.auxiliary_scripts.extend(scripts);
88            }
89            Self::Conway(conway) => {
90                if let Some(old_scripts) = &mut conway.native_scripts {
91                    old_scripts.extend(scripts);
92                } else {
93                    conway.native_scripts = Some(scripts);
94                }
95            }
96        }
97    }
98
99    /// Warning: does not check for duplicates and may migrate eras
100    pub fn add_plutus_v1_scripts(&mut self, scripts: Vec<PlutusV1Script>) {
101        match self {
102            Self::Shelley(shelley) => {
103                let mut conway = ConwayFormatAuxData::new();
104                if !shelley.entries.is_empty() {
105                    conway.metadata = Some(shelley.clone());
106                }
107                conway.plutus_v1_scripts = Some(scripts);
108                *self = Self::Conway(conway);
109            }
110            Self::ShelleyMA(shelley_ma) => {
111                let mut conway = ConwayFormatAuxData::new();
112                if !shelley_ma.transaction_metadata.entries.is_empty() {
113                    conway.metadata = Some(shelley_ma.transaction_metadata.clone());
114                }
115                if !shelley_ma.auxiliary_scripts.is_empty() {
116                    conway.native_scripts = Some(shelley_ma.auxiliary_scripts.clone());
117                }
118                conway.plutus_v1_scripts = Some(scripts);
119                *self = Self::Conway(conway);
120            }
121            Self::Conway(conway) => {
122                if let Some(old_scripts) = &mut conway.plutus_v1_scripts {
123                    old_scripts.extend(scripts);
124                } else {
125                    conway.plutus_v1_scripts = Some(scripts);
126                }
127            }
128        }
129    }
130
131    /// Warning: does not check for duplicates and may migrate eras
132    pub fn add_plutus_v2_scripts(&mut self, scripts: Vec<PlutusV2Script>) {
133        match self {
134            Self::Shelley(shelley) => {
135                let mut conway = ConwayFormatAuxData::new();
136                if !shelley.entries.is_empty() {
137                    conway.metadata = Some(shelley.clone());
138                }
139                conway.plutus_v2_scripts = Some(scripts);
140                *self = Self::Conway(conway);
141            }
142            Self::ShelleyMA(shelley_ma) => {
143                let mut conway = ConwayFormatAuxData::new();
144                if !shelley_ma.transaction_metadata.entries.is_empty() {
145                    conway.metadata = Some(shelley_ma.transaction_metadata.clone());
146                }
147                if !shelley_ma.auxiliary_scripts.is_empty() {
148                    conway.native_scripts = Some(shelley_ma.auxiliary_scripts.clone());
149                }
150                conway.plutus_v2_scripts = Some(scripts);
151                *self = Self::Conway(conway);
152            }
153            Self::Conway(conway) => {
154                if let Some(old_scripts) = &mut conway.plutus_v2_scripts {
155                    old_scripts.extend(scripts);
156                } else {
157                    conway.plutus_v2_scripts = Some(scripts);
158                }
159            }
160        }
161    }
162
163    /// Adds everything present in other to self
164    /// May change the era the aux data is in if necessary
165    /// Warning: overwrites any metadatum labels present
166    /// also does not check for duplicates in scripts
167    pub fn add(&mut self, other: AuxiliaryData) {
168        // to avoid redundant migrating of formats, we set the content with
169        // plutus scripts first, then native scripts, then metadata in
170        // reverse chronological (era format wise) order.
171        match other {
172            Self::Shelley(shelley) => {
173                self.add_metadata(shelley);
174            }
175            Self::ShelleyMA(shelley_ma) => {
176                self.add_native_scripts(shelley_ma.auxiliary_scripts);
177                self.add_metadata(shelley_ma.transaction_metadata);
178            }
179            Self::Conway(conway) => {
180                if let Some(scripts) = conway.plutus_v2_scripts {
181                    self.add_plutus_v2_scripts(scripts);
182                }
183                if let Some(scripts) = conway.plutus_v1_scripts {
184                    self.add_plutus_v1_scripts(scripts);
185                }
186                if let Some(scripts) = conway.native_scripts {
187                    self.add_native_scripts(scripts);
188                }
189                if let Some(metadata) = conway.metadata {
190                    self.add_metadata(metadata);
191                }
192            }
193        }
194    }
195}
196
197impl Default for AuxiliaryData {
198    fn default() -> Self {
199        Self::new()
200    }
201}