stacks_core/
codec.rs

1//! Module for serializing and deserializing Stacks data types
2use std::io;
3
4use bdk::bitcoin::{
5	secp256k1::ecdsa::{RecoverableSignature, RecoveryId},
6	Amount, Script,
7};
8use thiserror::Error;
9
10use crate::StacksResult;
11
12#[derive(Error, Debug)]
13/// Codec error
14pub enum CodecError {
15	#[error("Could not serialize or deserialize: {0}")]
16	/// Io error
17	IoError(#[from] io::Error),
18}
19
20/// Codec result
21pub type CodecResult<T> = Result<T, CodecError>;
22
23/// Serializing and deserializing Stacks data types
24pub trait Codec {
25	/// Serialize to a writer
26	fn codec_serialize<W: io::Write>(&self, dest: &mut W) -> io::Result<()>;
27	/// Deserialize from a reader
28	fn codec_deserialize<R: io::Read>(data: &mut R) -> io::Result<Self>
29	where
30		Self: Sized;
31
32	/// Serialize to a writer and return a StacksResult
33	fn serialize<W: io::Write>(&self, dest: &mut W) -> StacksResult<()> {
34		self.codec_serialize(dest)
35			.map_err(|err| CodecError::IoError(err).into())
36	}
37
38	/// Deserialize from a reader and return a StacksResult
39	fn deserialize<R: io::Read>(data: &mut R) -> StacksResult<Self>
40	where
41		Self: Sized,
42	{
43		Self::codec_deserialize(data)
44			.map_err(|err| CodecError::IoError(err).into())
45	}
46
47	/// Serialize to a vector
48	fn serialize_to_vec(&self) -> Vec<u8> {
49		let mut buffer = vec![];
50
51		self.serialize(&mut buffer).unwrap();
52
53		buffer
54	}
55}
56
57impl Codec for Amount {
58	fn codec_serialize<W: io::Write>(&self, dest: &mut W) -> io::Result<()> {
59		dest.write_all(&self.to_sat().to_be_bytes())
60	}
61
62	fn codec_deserialize<R: io::Read>(data: &mut R) -> io::Result<Self>
63	where
64		Self: Sized,
65	{
66		let mut buffer = [0; 8];
67		data.read_exact(&mut buffer)?;
68
69		Ok(Self::from_sat(u64::from_be_bytes(buffer)))
70	}
71}
72
73impl Codec for RecoverableSignature {
74	fn codec_serialize<W: io::Write>(&self, dest: &mut W) -> io::Result<()> {
75		let (id, signature) = self.serialize_compact();
76
77		let id: u8 = id.to_i32().try_into().unwrap();
78
79		dest.write_all(&[id])?;
80		dest.write_all(&signature)
81	}
82
83	fn codec_deserialize<R: io::Read>(data: &mut R) -> io::Result<Self>
84	where
85		Self: Sized,
86	{
87		let mut id_buffer = [0; 1];
88		data.read_exact(&mut id_buffer)?;
89
90		let id = RecoveryId::from_i32(id_buffer[0] as i32)
91			.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
92
93		let mut signature_buffer = [0; 64];
94		data.read_exact(&mut signature_buffer)?;
95
96		Self::from_compact(&signature_buffer, id)
97			.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))
98	}
99}
100
101impl Codec for u64 {
102	fn codec_serialize<W: io::Write>(&self, dest: &mut W) -> io::Result<()> {
103		dest.write_all(&self.to_be_bytes())
104	}
105
106	fn codec_deserialize<R: io::Read>(data: &mut R) -> io::Result<Self>
107	where
108		Self: Sized,
109	{
110		let mut bytes = [0; 8];
111		data.read_exact(&mut bytes)?;
112
113		Ok(Self::from_be_bytes(bytes))
114	}
115}
116
117impl Codec for Script {
118	fn codec_serialize<W: io::Write>(&self, dest: &mut W) -> io::Result<()> {
119		dest.write_all(self.as_bytes())
120	}
121
122	fn codec_deserialize<R: io::Read>(data: &mut R) -> io::Result<Self>
123	where
124		Self: Sized,
125	{
126		let mut buffer = vec![];
127		data.read_to_end(&mut buffer)?;
128
129		Ok(Self::from(buffer))
130	}
131}