sos_core/encoding/v1/
commit.rs

1use 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}