pallas_primitives/alonzo/
json.rs1use std::ops::Deref;
2
3use serde_json::json;
4
5use crate::ToCanonicalJson;
6
7impl<A> super::Constr<A> {
8 pub fn constructor_value(&self) -> Option<u64> {
9 match self.tag {
10 121..=127 => Some(self.tag - 121),
11 1280..=1400 => Some(self.tag - 1280 + 7),
12 102 => self.any_constructor,
13 _ => None,
14 }
15 }
16}
17
18impl ToCanonicalJson for super::PlutusData {
20 fn to_json(&self) -> serde_json::Value {
21 match self {
22 super::PlutusData::Constr(x) => {
23 let fields: Vec<_> = x.fields.iter().map(|i| i.to_json()).collect();
24 json!({ "constructor": x.constructor_value(), "fields": fields })
25 }
26 super::PlutusData::Map(x) => {
27 let map: Vec<_> = x
28 .iter()
29 .map(|(k, v)| json!({ "k": k.to_json(), "v": v.to_json() }))
30 .collect();
31 json!({ "map": map })
32 }
33 super::PlutusData::BigInt(int) => match int {
34 super::BigInt::Int(n) => match i64::try_from(*n.deref()) {
35 Ok(x) => json!({ "int": x }),
36 Err(_) => {
37 json!({ "bignint": hex::encode(i128::from(*n.deref()).to_be_bytes()) })
38 }
39 },
40 super::BigInt::BigUInt(x) => json!({ "biguint": hex::encode(x.as_slice())}),
46 super::BigInt::BigNInt(x) => json!({ "bignint": hex::encode(x.as_slice())}),
47 },
48 super::PlutusData::BoundedBytes(x) => json!({ "bytes": hex::encode(x.as_slice())}),
49 super::PlutusData::Array(x) => {
50 let list: Vec<_> = x.iter().map(|i| i.to_json()).collect();
51 json!({ "list": list })
52 }
53 }
54 }
55}
56
57impl ToCanonicalJson for super::NativeScript {
58 fn to_json(&self) -> serde_json::Value {
59 match self {
60 super::NativeScript::ScriptPubkey(x) => {
61 json!({ "keyHash": x.to_string(), "type": "sig"})
62 }
63 super::NativeScript::ScriptAll(x) => {
64 let scripts: Vec<_> = x.iter().map(|i| i.to_json()).collect();
65 json!({ "type": "all", "scripts": scripts})
66 }
67 super::NativeScript::ScriptAny(x) => {
68 let scripts: Vec<_> = x.iter().map(|i| i.to_json()).collect();
69 json!({ "type": "any", "scripts": scripts})
70 }
71 super::NativeScript::ScriptNOfK(n, k) => {
72 let scripts: Vec<_> = k.iter().map(|i| i.to_json()).collect();
73 json!({ "type": "atLeast", "required": n, "scripts" : scripts })
74 }
75 super::NativeScript::InvalidBefore(slot) => json!({ "type": "after", "slot": slot }),
76 super::NativeScript::InvalidHereafter(slot) => json!({"type": "before", "slot": slot }),
77 }
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use pallas_codec::minicbor;
84
85 use crate::{alonzo::Block, ToCanonicalJson};
86
87 type BlockWrapper = (u16, Block);
88
89 #[test]
90 fn test_datums_serialize_as_expected() {
91 let test_blocks = [(
92 include_str!("../../../test_data/alonzo9.block"),
93 include_str!("../../../test_data/alonzo9.datums"),
94 )];
95
96 for (idx, (block_str, jsonl_str)) in test_blocks.iter().enumerate() {
97 println!("decoding json block {}", idx + 1);
98
99 let bytes = hex::decode(block_str).unwrap_or_else(|_| panic!("bad block file {idx}"));
100
101 let (_, block): BlockWrapper = minicbor::decode(&bytes[..])
102 .unwrap_or_else(|_| panic!("error decoding cbor for file {idx}"));
103
104 let mut datums = jsonl_str.lines();
105
106 for ws in block.transaction_witness_sets.iter() {
107 if let Some(pds) = &ws.plutus_data {
108 for pd in pds.iter() {
109 let expected: serde_json::Value =
110 serde_json::from_str(datums.next().unwrap()).unwrap();
111 let current = pd.to_json();
112 assert_eq!(current, expected);
113 }
114 }
115 }
116 }
117 }
118
119 #[test]
120 fn test_native_scripts_serialize_as_expected() {
121 let test_blocks = [(
122 include_str!("../../../test_data/alonzo9.block"),
123 include_str!("../../../test_data/alonzo9.native"),
124 )];
125
126 for (idx, (block_str, jsonl_str)) in test_blocks.iter().enumerate() {
127 println!("decoding json block {}", idx + 1);
128
129 let bytes = hex::decode(block_str).unwrap_or_else(|_| panic!("bad block file {idx}"));
130
131 let (_, block): BlockWrapper = minicbor::decode(&bytes[..])
132 .unwrap_or_else(|_| panic!("error decoding cbor for file {idx}"));
133
134 let mut scripts = jsonl_str.lines();
135
136 for ws in block.transaction_witness_sets.iter() {
137 if let Some(nss) = &ws.native_script {
138 for ns in nss.iter() {
139 let expected: serde_json::Value =
140 serde_json::from_str(scripts.next().unwrap()).unwrap();
141 let current = ns.to_json();
142 assert_eq!(current, expected);
143 }
144 }
145 }
146 }
147 }
148}