|
| 1 | +//! Cardano Improvement Proposal 509 (CIP-509) metadata module. |
| 2 | +//! Doc Reference: <https://github.com/input-output-hk/catalyst-CIPs/tree/x509-envelope-metadata/CIP-XXXX> |
| 3 | +//! CDDL Reference: <https://github.com/input-output-hk/catalyst-CIPs/blob/x509-envelope-metadata/CIP-XXXX/x509-envelope.cddl> |
| 4 | +
|
| 5 | +use std::sync::Arc; |
| 6 | + |
| 7 | +use minicbor::{Decode, Decoder}; |
| 8 | +use pallas::ledger::traverse::MultiEraTx; |
| 9 | +use rbac_registration::cardano::cip509::{Cip509 as RbacRegCip509, Cip509Validation, LABEL}; |
| 10 | + |
| 11 | +use super::{ |
| 12 | + DecodedMetadata, DecodedMetadataItem, DecodedMetadataValues, RawAuxData, ValidationReport, |
| 13 | +}; |
| 14 | + |
| 15 | +/// CIP509 metadatum. |
| 16 | +#[derive(Debug, PartialEq, Clone, Default)] |
| 17 | +pub struct Cip509 { |
| 18 | + /// CIP509 data. |
| 19 | + pub cip509: RbacRegCip509, |
| 20 | + /// Validation value, not a part of CIP509, justs storing validity of the data. |
| 21 | + pub validation: Cip509Validation, |
| 22 | +} |
| 23 | + |
| 24 | +impl Cip509 { |
| 25 | + /// Decode and validate CIP509 Metadata |
| 26 | + /// |
| 27 | + /// # Returns |
| 28 | + /// |
| 29 | + /// Nothing. IF CIP509 Metadata is found it will be updated in `decoded_metadata`. |
| 30 | + pub(crate) fn decode_and_validate( |
| 31 | + decoded_metadata: &DecodedMetadata, txn: &MultiEraTx, raw_aux_data: &RawAuxData, |
| 32 | + ) { |
| 33 | + // Get the CIP509 metadata if possible |
| 34 | + let Some(k509) = raw_aux_data.get_metadata(LABEL) else { |
| 35 | + return; |
| 36 | + }; |
| 37 | + |
| 38 | + let mut validation_report = ValidationReport::new(); |
| 39 | + let mut decoder = Decoder::new(k509.as_slice()); |
| 40 | + |
| 41 | + let cip509 = match RbacRegCip509::decode(&mut decoder, &mut ()) { |
| 42 | + Ok(metadata) => metadata, |
| 43 | + Err(e) => { |
| 44 | + Cip509::default().validation_failure( |
| 45 | + &format!("Failed to decode CIP509 metadata: {e}"), |
| 46 | + &mut validation_report, |
| 47 | + decoded_metadata, |
| 48 | + ); |
| 49 | + return; |
| 50 | + }, |
| 51 | + }; |
| 52 | + |
| 53 | + // Validate the decoded metadata |
| 54 | + let validation = cip509.validate(txn, &mut validation_report); |
| 55 | + |
| 56 | + // Create a Cip509 struct and insert it into decoded_metadata |
| 57 | + decoded_metadata.0.insert( |
| 58 | + LABEL, |
| 59 | + Arc::new(DecodedMetadataItem { |
| 60 | + value: DecodedMetadataValues::Cip509(Arc::new(Cip509 { cip509, validation })), |
| 61 | + report: validation_report.clone(), |
| 62 | + }), |
| 63 | + ); |
| 64 | + } |
| 65 | + |
| 66 | + /// Handle validation failure. |
| 67 | + fn validation_failure( |
| 68 | + &self, reason: &str, validation_report: &mut ValidationReport, |
| 69 | + decoded_metadata: &DecodedMetadata, |
| 70 | + ) { |
| 71 | + validation_report.push(reason.into()); |
| 72 | + decoded_metadata.0.insert( |
| 73 | + LABEL, |
| 74 | + Arc::new(DecodedMetadataItem { |
| 75 | + value: DecodedMetadataValues::Cip509(Arc::new(self.clone()).clone()), |
| 76 | + report: validation_report.clone(), |
| 77 | + }), |
| 78 | + ); |
| 79 | + } |
| 80 | +} |
0 commit comments