partner_chains_plutus_data/
permissioned_candidates.rs1use cardano_serialization_lib::{BigNum, PlutusData, PlutusList};
3use sidechain_domain::*;
4
5use crate::{
6 DataDecodingError, DecodingResult, VersionedDatum, VersionedDatumWithLegacy,
7 VersionedGenericDatum,
8};
9
10#[derive(Clone, Debug, PartialEq)]
11pub enum PermissionedCandidateDatums {
13 V0(Vec<PermissionedCandidateDatumV0>),
15}
16
17#[derive(Clone, Debug, PartialEq)]
18pub struct PermissionedCandidateDatumV0 {
20 pub sidechain_public_key: SidechainPublicKey,
22 pub aura_public_key: AuraPublicKey,
24 pub grandpa_public_key: GrandpaPublicKey,
26}
27
28impl TryFrom<PlutusData> for PermissionedCandidateDatums {
29 type Error = DataDecodingError;
30 fn try_from(datum: PlutusData) -> DecodingResult<Self> {
31 Self::decode(&datum)
32 }
33}
34
35impl From<PermissionedCandidateDatumV0> for PermissionedCandidateData {
36 fn from(value: PermissionedCandidateDatumV0) -> Self {
37 Self {
38 sidechain_public_key: value.sidechain_public_key,
39 aura_public_key: value.aura_public_key,
40 grandpa_public_key: value.grandpa_public_key,
41 }
42 }
43}
44
45impl From<PermissionedCandidateDatums> for Vec<PermissionedCandidateData> {
46 fn from(value: PermissionedCandidateDatums) -> Self {
47 match value {
48 PermissionedCandidateDatums::V0(v) => v.into_iter().map(|d| d.into()).collect(),
49 }
50 }
51}
52
53pub fn permissioned_candidates_to_plutus_data(
73 candidates: &[PermissionedCandidateData],
74) -> PlutusData {
75 let mut list = PlutusList::new();
76 for candidate in candidates {
77 let mut candidate_datum = PlutusList::new();
78 candidate_datum.add(&PlutusData::new_bytes(candidate.sidechain_public_key.0.clone()));
79 candidate_datum.add(&PlutusData::new_bytes(candidate.aura_public_key.0.clone()));
80 candidate_datum.add(&PlutusData::new_bytes(candidate.grandpa_public_key.0.clone()));
81 list.add(&PlutusData::new_list(&candidate_datum));
82 }
83 let appendix = PlutusData::new_list(&list);
84 VersionedGenericDatum {
85 datum: PlutusData::new_empty_constr_plutus_data(&BigNum::zero()),
86 appendix,
87 version: 0,
88 }
89 .into()
90}
91
92impl VersionedDatumWithLegacy for PermissionedCandidateDatums {
93 const NAME: &str = "PermissionedCandidateDatums";
94
95 fn decode_legacy(data: &PlutusData) -> Result<Self, String> {
97 let permissioned_candidates = data
98 .as_list()
99 .and_then(|list_datums| {
100 list_datums
101 .into_iter()
102 .map(decode_legacy_candidate_datum)
103 .collect::<Option<Vec<PermissionedCandidateDatumV0>>>()
104 })
105 .ok_or("Expected [[ByteString, ByteString, ByteString]]")?;
106
107 Ok(Self::V0(permissioned_candidates))
108 }
109
110 fn decode_versioned(
111 version: u64,
112 _datum: &PlutusData,
113 appendix: &PlutusData,
114 ) -> Result<Self, String> {
115 match version {
116 0 => PermissionedCandidateDatums::decode_legacy(appendix)
117 .map_err(|msg| format!("Cannot parse appendix: {msg}")),
118 _ => Err(format!("Unknown version: {version}")),
119 }
120 }
121}
122
123fn decode_legacy_candidate_datum(datum: &PlutusData) -> Option<PermissionedCandidateDatumV0> {
124 let datums = datum.as_list().filter(|datums| datums.len() == 3)?;
125
126 let sc = datums.get(0).as_bytes()?;
127 let aura = datums.get(1).as_bytes()?;
128 let grandpa = datums.get(2).as_bytes()?;
129
130 Some(PermissionedCandidateDatumV0 {
131 sidechain_public_key: SidechainPublicKey(sc),
132 aura_public_key: AuraPublicKey(aura),
133 grandpa_public_key: GrandpaPublicKey(grandpa),
134 })
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use crate::test_helpers::*;
141 use hex_literal::hex;
142 use pretty_assertions::assert_eq;
143
144 #[test]
145 fn valid_legacy_permissioned_candidates() {
146 let plutus_data = test_plutus_data!({"list": [
147 {"list": [
148 {"bytes": "cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854"},
149 {"bytes": "bf20afa1c1a72af3341fa7a447e3f9eada9f3d054a7408fb9e49ad4d6e6559ec"},
150 {"bytes": "9042a40b0b1baa9adcead024432a923eac706be5e1a89d7f2f2d58bfa8f3c26d"}
151 ]},
152 {"list": [
153 {"bytes": "79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf"},
154 {"bytes": "56d1da82e56e4cb35b13de25f69a3e9db917f3e13d6f786321f4b0a9dc153b19"},
155 {"bytes": "7392f3ea668aa2be7997d82c07bcfbec3ee4a9a4e01e3216d92b8f0d0a086c32"}
156 ]}
157 ]});
158
159 let expected_datum = PermissionedCandidateDatums::V0(vec![
160 PermissionedCandidateDatumV0 {
161 sidechain_public_key: SidechainPublicKey(
162 hex!("cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854").into(),
163 ),
164 aura_public_key: AuraPublicKey(
165 hex!("bf20afa1c1a72af3341fa7a447e3f9eada9f3d054a7408fb9e49ad4d6e6559ec").into(),
166 ),
167 grandpa_public_key: GrandpaPublicKey(
168 hex!("9042a40b0b1baa9adcead024432a923eac706be5e1a89d7f2f2d58bfa8f3c26d").into(),
169 ),
170 },
171 PermissionedCandidateDatumV0 {
172 sidechain_public_key: SidechainPublicKey(
173 hex!("79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf").into(),
174 ),
175 aura_public_key: AuraPublicKey(
176 hex!("56d1da82e56e4cb35b13de25f69a3e9db917f3e13d6f786321f4b0a9dc153b19").into(),
177 ),
178 grandpa_public_key: GrandpaPublicKey(
179 hex!("7392f3ea668aa2be7997d82c07bcfbec3ee4a9a4e01e3216d92b8f0d0a086c32").into(),
180 ),
181 },
182 ]);
183
184 assert_eq!(PermissionedCandidateDatums::try_from(plutus_data).unwrap(), expected_datum)
185 }
186
187 fn v0_datum_json() -> serde_json::Value {
188 serde_json::json!({
189 "list": [
190 { "constructor": 0, "fields": [] },
191 { "list": [
192 {"list": [
193 {"bytes": "cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854"},
194 {"bytes": "bf20afa1c1a72af3341fa7a447e3f9eada9f3d054a7408fb9e49ad4d6e6559ec"},
195 {"bytes": "9042a40b0b1baa9adcead024432a923eac706be5e1a89d7f2f2d58bfa8f3c26d"}
196 ]},
197 {"list": [
198 {"bytes": "79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf"},
199 {"bytes": "56d1da82e56e4cb35b13de25f69a3e9db917f3e13d6f786321f4b0a9dc153b19"},
200 {"bytes": "7392f3ea668aa2be7997d82c07bcfbec3ee4a9a4e01e3216d92b8f0d0a086c32"}
201 ]}
202 ]},
203 { "int": 0 }
204 ]
205 })
206 }
207
208 #[test]
209 fn test_permissioned_candidates_to_plutus_data() {
210 let expected_plutus_data = json_to_plutus_data(v0_datum_json());
211
212 let domain_data = vec![
213 PermissionedCandidateData {
214 sidechain_public_key: SidechainPublicKey(
215 hex!("cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854")
216 .to_vec(),
217 ),
218 aura_public_key: AuraPublicKey(
219 hex!("bf20afa1c1a72af3341fa7a447e3f9eada9f3d054a7408fb9e49ad4d6e6559ec")
220 .to_vec(),
221 ),
222 grandpa_public_key: GrandpaPublicKey(
223 hex!("9042a40b0b1baa9adcead024432a923eac706be5e1a89d7f2f2d58bfa8f3c26d")
224 .to_vec(),
225 ),
226 },
227 PermissionedCandidateData {
228 sidechain_public_key: SidechainPublicKey(
229 hex!("79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf")
230 .to_vec(),
231 ),
232 aura_public_key: AuraPublicKey(
233 hex!("56d1da82e56e4cb35b13de25f69a3e9db917f3e13d6f786321f4b0a9dc153b19")
234 .to_vec(),
235 ),
236 grandpa_public_key: GrandpaPublicKey(
237 hex!("7392f3ea668aa2be7997d82c07bcfbec3ee4a9a4e01e3216d92b8f0d0a086c32")
238 .to_vec(),
239 ),
240 },
241 ];
242 assert_eq!(permissioned_candidates_to_plutus_data(&domain_data), expected_plutus_data)
243 }
244
245 #[test]
246 fn valid_v0_permissioned_candidates() {
247 let plutus_data = json_to_plutus_data(v0_datum_json());
248
249 let expected_datum = PermissionedCandidateDatums::V0(vec![
250 PermissionedCandidateDatumV0 {
251 sidechain_public_key: SidechainPublicKey(
252 hex!("cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854").into(),
253 ),
254 aura_public_key: AuraPublicKey(
255 hex!("bf20afa1c1a72af3341fa7a447e3f9eada9f3d054a7408fb9e49ad4d6e6559ec").into(),
256 ),
257 grandpa_public_key: GrandpaPublicKey(
258 hex!("9042a40b0b1baa9adcead024432a923eac706be5e1a89d7f2f2d58bfa8f3c26d").into(),
259 ),
260 },
261 PermissionedCandidateDatumV0 {
262 sidechain_public_key: SidechainPublicKey(
263 hex!("79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf").into(),
264 ),
265 aura_public_key: AuraPublicKey(
266 hex!("56d1da82e56e4cb35b13de25f69a3e9db917f3e13d6f786321f4b0a9dc153b19").into(),
267 ),
268 grandpa_public_key: GrandpaPublicKey(
269 hex!("7392f3ea668aa2be7997d82c07bcfbec3ee4a9a4e01e3216d92b8f0d0a086c32").into(),
270 ),
271 },
272 ]);
273
274 assert_eq!(PermissionedCandidateDatums::try_from(plutus_data).unwrap(), expected_datum)
275 }
276}