partner_chains_plutus_data/
version_oracle.rs

1//! Plutus types for the script versioning/script caching system.
2use crate::{DataDecodingError, DecodingResult, PlutusDataExtensions, decoding_error_and_log};
3use cardano_serialization_lib::{BigInt, PlutusData, PlutusList};
4
5/// Datum attached to 'VersionOraclePolicy' tokens stored on the 'VersionOracleValidator' script.
6/// This datum is not versioned intentionally, as it is not subject to observation.
7///
8/// Original definition in the smart contracts:
9/// ```haskell
10/// data VersionOracleDatum = VersionOracleDatum
11/// { versionOracle :: VersionOracle
12/// -- ^ VersionOracle which identifies the script.
13/// , currencySymbol :: CurrencySymbol
14/// -- ^ Currency Symbol of the VersioningOraclePolicy tokens.
15/// }
16///
17/// See https://preview.cexplorer.io/tx/70923772056f153d646488c56ac04d1bc2f1326f074773e4f262c63e03b72a3d/contract#data
18/// for an example of transaction outputting this datum.
19/// ```
20#[derive(Clone, Debug, PartialEq)]
21pub struct VersionOracleDatum {
22	/// Id of the script in the script cache/versioning system. See [raw_scripts::ScriptId].
23	pub version_oracle: u32,
24	/// Script hash of the oracle policy where cached/versioned scripts are stored.
25	pub currency_symbol: [u8; 28],
26}
27
28impl TryFrom<PlutusData> for VersionOracleDatum {
29	type Error = DataDecodingError;
30	fn try_from(datum: PlutusData) -> DecodingResult<Self> {
31		datum
32			.as_list()
33			.filter(|datum| datum.len() == 2)
34			.and_then(|items| {
35				Some(VersionOracleDatum {
36					version_oracle: items.get(0).as_u32()?,
37					currency_symbol: items.get(1).as_bytes()?.try_into().ok()?,
38				})
39			})
40			.ok_or_else(|| {
41				decoding_error_and_log(&datum, "VersionOracleDatum", "Expected [u32, [u8;32]]")
42			})
43	}
44}
45
46impl From<VersionOracleDatum> for PlutusData {
47	fn from(datum: VersionOracleDatum) -> Self {
48		PlutusData::new_list(&{
49			let mut list = PlutusList::new();
50			list.add(&PlutusData::new_integer(&BigInt::from(datum.version_oracle)));
51			list.add(&PlutusData::new_bytes(datum.currency_symbol.to_vec()));
52			list
53		})
54	}
55}
56
57#[cfg(test)]
58mod tests {
59	use super::*;
60	use crate::test_helpers::*;
61	use hex_literal::hex;
62	use pretty_assertions::assert_eq;
63
64	#[test]
65	fn decoding() {
66		let plutus_data = test_plutus_data!({"list": [
67			{"int": 32},
68			{"bytes": "e50a076eed80e645499abc26a5b33b61bef32f8cb1ab29b1ffcc1b88"}
69		]});
70
71		let expected_datum = VersionOracleDatum {
72			version_oracle: 32,
73			currency_symbol: hex!("e50a076eed80e645499abc26a5b33b61bef32f8cb1ab29b1ffcc1b88"),
74		};
75
76		assert_eq!(VersionOracleDatum::try_from(plutus_data).unwrap(), expected_datum)
77	}
78
79	#[test]
80	fn encoding() {
81		let datum = VersionOracleDatum {
82			version_oracle: 32,
83			currency_symbol: hex!("e50a076eed80e645499abc26a5b33b61bef32f8cb1ab29b1ffcc1b88"),
84		};
85
86		let expected_plutus_data = test_plutus_data!({"list": [
87			{"int": 32},
88			{"bytes": "e50a076eed80e645499abc26a5b33b61bef32f8cb1ab29b1ffcc1b88"}
89		]});
90
91		assert_eq!(PlutusData::from(datum), expected_plutus_data)
92	}
93}