ergotree_ir/serialization/
data.rs1use sigma_util::AsVecU8;
2
3use crate::chain::ergo_box::ErgoBox;
4use crate::mir::avl_tree_data::AvlTreeData;
5use crate::mir::constant::Literal;
6use crate::mir::constant::TryExtractFromError;
7use crate::mir::constant::TryExtractInto;
8use crate::mir::value::CollKind;
9use crate::mir::value::NativeColl;
10use crate::serialization::SigmaSerializationError;
11use crate::serialization::SigmaSerializeResult;
12use crate::serialization::{
13 sigma_byte_reader::SigmaByteRead, SigmaParsingError, SigmaSerializable,
14};
15use crate::sigma_protocol::{sigma_boolean::SigmaBoolean, sigma_boolean::SigmaProp};
16use crate::types::stuple;
17use crate::types::stype::SType;
18use ergo_chain_types::EcPoint;
19
20use super::sigma_byte_writer::SigmaByteWrite;
21use std::convert::TryInto;
22use std::sync::Arc;
23
24pub struct DataSerializer {}
26
27impl DataSerializer {
28 pub fn sigma_serialize<W: SigmaByteWrite>(c: &Literal, w: &mut W) -> SigmaSerializeResult {
29 Ok(match c {
31 Literal::Unit => (),
32 Literal::Boolean(v) => w.put_u8(u8::from(*v))?,
33 Literal::Byte(v) => w.put_i8(*v)?,
34 Literal::Short(v) => w.put_i16(*v)?,
35 Literal::Int(v) => w.put_i32(*v)?,
36 Literal::Long(v) => w.put_i64(*v)?,
37 Literal::BigInt(v) => {
38 let bytes = v.to_signed_bytes_be();
39 w.put_u16(bytes.len() as u16)?;
40 w.write_all(&bytes)?
41 }
42 Literal::GroupElement(ecp) => ecp.sigma_serialize(w)?,
43 Literal::SigmaProp(s) => s.value().sigma_serialize(w)?,
44 Literal::AvlTree(a) => a.sigma_serialize(w)?,
45 Literal::CBox(b) => b.sigma_serialize(w)?,
46 Literal::Coll(ct) => match ct {
47 CollKind::NativeColl(NativeColl::CollByte(b)) => {
48 w.put_usize_as_u16_unwrapped(b.len())?;
49 w.write_all(b.clone().as_vec_u8().as_slice())?
50 }
51 CollKind::WrappedColl {
52 elem_tpe: SType::SBoolean,
53 items: v,
54 } => {
55 w.put_usize_as_u16_unwrapped(v.len())?;
56 let maybe_bools: Result<Vec<bool>, TryExtractFromError> = v
57 .clone()
58 .iter()
59 .cloned()
60 .map(|i| i.try_extract_into::<bool>())
61 .collect();
62 w.put_bits(maybe_bools?.as_slice())?
63 }
64 CollKind::WrappedColl {
65 elem_tpe: _,
66 items: v,
67 } => {
68 w.put_usize_as_u16_unwrapped(v.len())?;
69 v.iter()
70 .try_for_each(|e| DataSerializer::sigma_serialize(e, w))?
71 }
72 },
73 Literal::Tup(items) => items
74 .iter()
75 .try_for_each(|i| DataSerializer::sigma_serialize(i, w))?,
76 Literal::Opt(_) => {
79 return Err(SigmaSerializationError::NotSupported(
80 "Option serialization is not supported".to_string(),
81 ));
82 }
83 })
84 }
85
86 pub fn sigma_parse<R: SigmaByteRead>(
87 tpe: &SType,
88 r: &mut R,
89 ) -> Result<Literal, SigmaParsingError> {
90 use SType::*;
92 Ok(match tpe {
93 SBoolean => Literal::Boolean(r.get_u8()? != 0),
94 SByte => Literal::Byte(r.get_i8()?),
95 SShort => Literal::Short(r.get_i16()?),
96 SInt => Literal::Int(r.get_i32()?),
97 SLong => Literal::Long(r.get_i64()?),
98 SBigInt => {
99 let size = r.get_u16()?;
100 if size > 32 {
101 return Err(SigmaParsingError::ValueOutOfBounds(format!(
102 "serialized BigInt size {0} bytes exceeds 32",
103 size
104 )));
105 }
106 let mut buf = vec![0u8; size as usize];
107 r.read_exact(&mut buf)?;
108 match buf.as_slice().try_into() {
109 Ok(x) => Literal::BigInt(x),
110 Err(e) => return Err(SigmaParsingError::ValueOutOfBounds(e)),
111 }
112 }
113 SUnit => Literal::Unit,
114 SGroupElement => Literal::GroupElement(Arc::new(EcPoint::sigma_parse(r)?)),
115 SSigmaProp => {
116 Literal::SigmaProp(Box::new(SigmaProp::new(SigmaBoolean::sigma_parse(r)?)))
117 }
118 SColl(elem_type) if **elem_type == SByte => {
119 let len = r.get_u16()? as usize;
120 let mut buf = vec![0u8; len];
121 r.read_exact(&mut buf)?;
122 Literal::Coll(CollKind::NativeColl(NativeColl::CollByte(
123 buf.into_iter().map(|v| v as i8).collect(),
124 )))
125 }
126 SColl(elem_type) if **elem_type == SBoolean => {
127 let len = r.get_u16()? as usize;
128 let bools = r.get_bits(len)?;
129 Literal::Coll(CollKind::WrappedColl {
130 elem_tpe: (**elem_type).clone(),
131 items: bools.into_iter().map(|b| b.into()).collect(),
132 })
133 }
134 SColl(elem_type) => {
135 let len = r.get_u16()? as usize;
136 let elems = (0..len)
137 .map(|_| DataSerializer::sigma_parse(elem_type, r))
138 .collect::<Result<Arc<[_]>, SigmaParsingError>>()?;
139 Literal::Coll(CollKind::WrappedColl {
140 elem_tpe: (**elem_type).clone(),
141 items: elems,
142 })
143 }
144 STuple(stuple::STuple { items: types }) => {
145 let mut items = Vec::new();
146 types.iter().try_for_each(|tpe| {
147 DataSerializer::sigma_parse(tpe, r).map(|v| items.push(v))
148 })?;
149 Literal::Tup(items.try_into()?)
153 }
154 SBox => Literal::CBox(Arc::new(ErgoBox::sigma_parse(r)?).into()),
155 SAvlTree => Literal::AvlTree(Box::new(AvlTreeData::sigma_parse(r)?)),
156 STypeVar(_) => return Err(SigmaParsingError::NotSupported("TypeVar data")),
157 SAny => return Err(SigmaParsingError::NotSupported("SAny data")),
158 SOption(_) => return Err(SigmaParsingError::NotSupported("SOption data")),
159 SFunc(_) => return Err(SigmaParsingError::NotSupported("SFunc data")),
160 SContext => return Err(SigmaParsingError::NotSupported("SContext data")),
161 SHeader => return Err(SigmaParsingError::NotSupported("SHeader data")),
162 SPreHeader => return Err(SigmaParsingError::NotSupported("SPreHeader data")),
163 SGlobal => return Err(SigmaParsingError::NotSupported("SGlobal data")),
164 })
165 }
166}