sos_core/encoding/v1/
commit.rs1use crate::{
2 commit::{CommitHash, CommitProof, CommitState, Comparison},
3 encoding::encoding_error,
4};
5use async_trait::async_trait;
6use binary_stream::futures::{
7 BinaryReader, BinaryWriter, Decodable, Encodable,
8};
9use rs_merkle::{algorithms::Sha256, MerkleProof};
10use std::io::{Error, ErrorKind, Result};
11use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
12
13#[async_trait]
14impl Encodable for CommitHash {
15 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
16 &self,
17 writer: &mut BinaryWriter<W>,
18 ) -> Result<()> {
19 writer.write_bytes(self.as_ref()).await?;
20 Ok(())
21 }
22}
23
24#[async_trait]
25impl Decodable for CommitHash {
26 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
27 &mut self,
28 reader: &mut BinaryReader<R>,
29 ) -> Result<()> {
30 let commit: [u8; 32] = reader
31 .read_bytes(32)
32 .await?
33 .as_slice()
34 .try_into()
35 .map_err(encoding_error)?;
36 *self = CommitHash(commit);
37 Ok(())
38 }
39}
40
41#[async_trait]
42impl Encodable for CommitState {
43 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
44 &self,
45 writer: &mut BinaryWriter<W>,
46 ) -> Result<()> {
47 self.0.encode(&mut *writer).await?;
48 self.1.encode(&mut *writer).await?;
49 Ok(())
50 }
51}
52
53#[async_trait]
54impl Decodable for CommitState {
55 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
56 &mut self,
57 reader: &mut BinaryReader<R>,
58 ) -> Result<()> {
59 self.0.decode(&mut *reader).await?;
60 self.1.decode(&mut *reader).await?;
61 Ok(())
62 }
63}
64
65#[async_trait]
66impl Encodable for CommitProof {
67 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
68 &self,
69 writer: &mut BinaryWriter<W>,
70 ) -> Result<()> {
71 writer.write_bytes(self.root.as_ref()).await?;
72 let proof_bytes = self.proof.to_bytes();
73 writer.write_u32(proof_bytes.len() as u32).await?;
74 writer.write_bytes(&proof_bytes).await?;
75
76 self.length.encode(&mut *writer).await?;
77 self.indices.encode(&mut *writer).await?;
78
79 Ok(())
80 }
81}
82
83#[async_trait]
84impl Decodable for CommitProof {
85 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
86 &mut self,
87 reader: &mut BinaryReader<R>,
88 ) -> Result<()> {
89 let root_hash: [u8; 32] = reader
90 .read_bytes(32)
91 .await?
92 .as_slice()
93 .try_into()
94 .map_err(encoding_error)?;
95 self.root = CommitHash(root_hash);
96
97 let length = reader.read_u32().await?;
98 let proof_bytes = reader.read_bytes(length as usize).await?;
99 let proof = MerkleProof::<Sha256>::from_bytes(&proof_bytes)
100 .map_err(encoding_error)?;
101 self.proof = proof;
102
103 self.length.decode(&mut *reader).await?;
104 self.indices.decode(&mut *reader).await?;
105 Ok(())
106 }
107}
108
109#[async_trait]
110impl Encodable for Comparison {
111 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
112 &self,
113 writer: &mut BinaryWriter<W>,
114 ) -> Result<()> {
115 match self {
116 Self::Equal => {
117 writer.write_u8(1).await?;
118 }
119 Self::Contains(indices) => {
120 writer.write_u8(2).await?;
121 writer.write_u32(indices.len() as u32).await?;
122 for i in indices {
123 writer.write_u64(*i as u64).await?;
124 }
125 }
126 Self::Unknown => {
127 writer.write_u8(3).await?;
128 }
129 }
130 Ok(())
131 }
132}
133
134#[async_trait]
135impl Decodable for Comparison {
136 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
137 &mut self,
138 reader: &mut BinaryReader<R>,
139 ) -> Result<()> {
140 let kind = reader.read_u8().await?;
141 match kind {
142 1 => {
143 *self = Self::Equal;
144 }
145 2 => {
146 let indices_len = reader.read_u32().await? as usize;
147 let mut indices = Vec::with_capacity(indices_len);
148 for _ in 0..indices_len {
149 indices.push(reader.read_u64().await? as usize);
150 }
151
152 *self = Self::Contains(indices);
153 }
154 3 => {
155 *self = Self::Unknown;
156 }
157 _ => {
158 return Err(Error::new(
159 ErrorKind::Other,
160 format!("unknown comparison variant kind {}", kind),
161 ));
162 }
163 }
164 Ok(())
165 }
166}