1use std::convert::TryFrom;
2
3use bytes::Bytes;
4use prost::Message;
5
6use crate::{
7 codec::{
8 primitive::{Address, Hash},
9 CodecError, ProtocolCodecSync,
10 },
11 field, impl_default_bytes_codec_for,
12 types::primitive as protocol_primitive,
13 types::Bloom,
14 ProtocolError, ProtocolResult,
15};
16
17#[derive(Clone, Message)]
22pub struct Epoch {
23 #[prost(message, tag = "1")]
24 pub header: Option<EpochHeader>,
25
26 #[prost(message, repeated, tag = "2")]
27 pub ordered_tx_hashes: Vec<Hash>,
28}
29
30#[derive(Clone, Message)]
31pub struct EpochHeader {
32 #[prost(message, tag = "1")]
33 pub chain_id: Option<Hash>,
34
35 #[prost(uint64, tag = "2")]
36 pub epoch_id: u64,
37
38 #[prost(message, tag = "3")]
39 pub pre_hash: Option<Hash>,
40
41 #[prost(uint64, tag = "4")]
42 pub timestamp: u64,
43
44 #[prost(message, repeated, tag = "5")]
45 pub logs_bloom: Vec<Vec<u8>>,
46
47 #[prost(message, tag = "6")]
48 pub order_root: Option<Hash>,
49
50 #[prost(message, repeated, tag = "7")]
51 pub confirm_root: Vec<Hash>,
52
53 #[prost(message, tag = "8")]
54 pub state_root: Option<Hash>,
55
56 #[prost(message, repeated, tag = "9")]
57 pub receipt_root: Vec<Hash>,
58
59 #[prost(message, repeated, tag = "10")]
60 pub cycles_used: Vec<u64>,
61
62 #[prost(message, tag = "11")]
63 pub proposer: Option<Address>,
64
65 #[prost(message, tag = "12")]
66 pub proof: Option<Proof>,
67
68 #[prost(uint64, tag = "13")]
69 pub validator_version: u64,
70
71 #[prost(message, repeated, tag = "14")]
72 pub validators: Vec<Validator>,
73
74 #[prost(uint64, tag = "15")]
75 pub exec_epoch_id: u64,
76}
77
78#[derive(Clone, Message)]
79pub struct Proof {
80 #[prost(uint64, tag = "1")]
81 pub epoch_id: u64,
82
83 #[prost(uint64, tag = "2")]
84 pub round: u64,
85
86 #[prost(message, tag = "3")]
87 pub epoch_hash: Option<Hash>,
88
89 #[prost(bytes, tag = "4")]
90 pub signature: Vec<u8>,
91
92 #[prost(bytes, tag = "5")]
93 pub bitmap: Vec<u8>,
94}
95
96#[derive(Clone, Message)]
97pub struct Validator {
98 #[prost(message, tag = "1")]
99 pub address: Option<Address>,
100
101 #[prost(uint32, tag = "2")]
102 pub propose_weight: u32,
103
104 #[prost(uint32, tag = "3")]
105 pub vote_weight: u32,
106}
107
108#[derive(Clone, Message)]
109pub struct Pill {
110 #[prost(message, tag = "1")]
111 pub epoch: Option<Epoch>,
112
113 #[prost(message, repeated, tag = "2")]
114 pub propose_hashes: Vec<Hash>,
115}
116
117impl From<epoch::Epoch> for Epoch {
124 fn from(epoch: epoch::Epoch) -> Epoch {
125 let header = Some(EpochHeader::from(epoch.header));
126 let ordered_tx_hashes = epoch
127 .ordered_tx_hashes
128 .into_iter()
129 .map(Hash::from)
130 .collect::<Vec<_>>();
131
132 Epoch {
133 header,
134 ordered_tx_hashes,
135 }
136 }
137}
138
139impl TryFrom<Epoch> for epoch::Epoch {
140 type Error = ProtocolError;
141
142 fn try_from(epoch: Epoch) -> Result<epoch::Epoch, Self::Error> {
143 let header = field!(epoch.header, "Epoch", "header")?;
144
145 let mut ordered_tx_hashes = Vec::new();
146 for hash in epoch.ordered_tx_hashes {
147 ordered_tx_hashes.push(protocol_primitive::Hash::try_from(hash)?);
148 }
149
150 let epoch = epoch::Epoch {
151 header: epoch::EpochHeader::try_from(header)?,
152 ordered_tx_hashes,
153 };
154
155 Ok(epoch)
156 }
157}
158
159impl From<epoch::EpochHeader> for EpochHeader {
162 fn from(epoch_header: epoch::EpochHeader) -> EpochHeader {
163 let chain_id = Some(Hash::from(epoch_header.chain_id));
164 let pre_hash = Some(Hash::from(epoch_header.pre_hash));
165 let order_root = Some(Hash::from(epoch_header.order_root));
166 let state_root = Some(Hash::from(epoch_header.state_root));
167 let proposer = Some(Address::from(epoch_header.proposer));
168 let proof = Some(Proof::from(epoch_header.proof));
169
170 let logs_bloom = epoch_header
171 .logs_bloom
172 .into_iter()
173 .map(|bloom| bloom.as_bytes().to_vec())
174 .collect::<Vec<_>>();
175 let confirm_root = epoch_header
176 .confirm_root
177 .into_iter()
178 .map(Hash::from)
179 .collect::<Vec<_>>();
180 let receipt_root = epoch_header
181 .receipt_root
182 .into_iter()
183 .map(Hash::from)
184 .collect::<Vec<_>>();
185 let validators = epoch_header
186 .validators
187 .into_iter()
188 .map(Validator::from)
189 .collect::<Vec<_>>();
190
191 EpochHeader {
192 chain_id,
193 epoch_id: epoch_header.epoch_id,
194 exec_epoch_id: epoch_header.exec_epoch_id,
195 pre_hash,
196 timestamp: epoch_header.timestamp,
197 logs_bloom,
198 order_root,
199 confirm_root,
200 state_root,
201 receipt_root,
202 cycles_used: epoch_header.cycles_used,
203 proposer,
204 proof,
205 validator_version: epoch_header.validator_version,
206 validators,
207 }
208 }
209}
210
211impl TryFrom<EpochHeader> for epoch::EpochHeader {
212 type Error = ProtocolError;
213
214 fn try_from(epoch_header: EpochHeader) -> Result<epoch::EpochHeader, Self::Error> {
215 let chain_id = field!(epoch_header.chain_id, "EpochHeader", "chain_id")?;
216 let pre_hash = field!(epoch_header.pre_hash, "EpochHeader", "pre_hash")?;
217 let order_root = field!(epoch_header.order_root, "EpochHeader", "order_root")?;
218 let state_root = field!(epoch_header.state_root, "EpochHeader", "state_root")?;
219 let proposer = field!(epoch_header.proposer, "EpochHeader", "proposer")?;
220 let proof = field!(epoch_header.proof, "EpochHeader", "proof")?;
221
222 let mut logs_bloom = Vec::new();
223 for bloom in epoch_header.logs_bloom {
224 logs_bloom.push(Bloom::from_slice(&bloom));
225 }
226
227 let mut confirm_root = Vec::new();
228 for root in epoch_header.confirm_root {
229 confirm_root.push(protocol_primitive::Hash::try_from(root)?);
230 }
231
232 let mut receipt_root = Vec::new();
233 for root in epoch_header.receipt_root {
234 receipt_root.push(protocol_primitive::Hash::try_from(root)?);
235 }
236
237 let mut validators = Vec::new();
238 for validator in epoch_header.validators {
239 validators.push(epoch::Validator::try_from(validator)?);
240 }
241
242 let proof = epoch::EpochHeader {
243 chain_id: protocol_primitive::Hash::try_from(chain_id)?,
244 epoch_id: epoch_header.epoch_id,
245 exec_epoch_id: epoch_header.exec_epoch_id,
246 pre_hash: protocol_primitive::Hash::try_from(pre_hash)?,
247 timestamp: epoch_header.timestamp,
248 logs_bloom,
249 order_root: protocol_primitive::Hash::try_from(order_root)?,
250 confirm_root,
251 state_root: protocol_primitive::Hash::try_from(state_root)?,
252 receipt_root,
253 cycles_used: epoch_header.cycles_used,
254 proposer: protocol_primitive::Address::try_from(proposer)?,
255 proof: epoch::Proof::try_from(proof)?,
256 validator_version: epoch_header.validator_version,
257 validators,
258 };
259
260 Ok(proof)
261 }
262}
263
264impl From<epoch::Proof> for Proof {
267 fn from(proof: epoch::Proof) -> Proof {
268 let epoch_hash = Some(Hash::from(proof.epoch_hash));
269
270 Proof {
271 epoch_id: proof.epoch_id,
272 round: proof.round,
273 epoch_hash,
274 signature: proof.signature.to_vec(),
275 bitmap: proof.bitmap.to_vec(),
276 }
277 }
278}
279
280impl TryFrom<Proof> for epoch::Proof {
281 type Error = ProtocolError;
282
283 fn try_from(proof: Proof) -> Result<epoch::Proof, Self::Error> {
284 let epoch_hash = field!(proof.epoch_hash, "Proof", "epoch_hash")?;
285
286 let proof = epoch::Proof {
287 epoch_id: proof.epoch_id,
288 round: proof.round,
289 epoch_hash: protocol_primitive::Hash::try_from(epoch_hash)?,
290 signature: Bytes::from(proof.signature),
291 bitmap: Bytes::from(proof.bitmap),
292 };
293
294 Ok(proof)
295 }
296}
297
298impl From<epoch::Validator> for Validator {
301 fn from(validator: epoch::Validator) -> Validator {
302 let address = Some(Address::from(validator.address));
303
304 Validator {
305 address,
306 propose_weight: u32::from(validator.propose_weight),
307 vote_weight: u32::from(validator.vote_weight),
308 }
309 }
310}
311
312impl TryFrom<Validator> for epoch::Validator {
313 type Error = ProtocolError;
314
315 fn try_from(validator: Validator) -> Result<epoch::Validator, Self::Error> {
316 let address = field!(validator.address, "Validator", "address")?;
317
318 let validator = epoch::Validator {
319 address: protocol_primitive::Address::try_from(address)?,
320 propose_weight: validator.propose_weight as u8,
321 vote_weight: validator.vote_weight as u8,
322 };
323
324 Ok(validator)
325 }
326}
327
328impl From<epoch::Pill> for Pill {
331 fn from(pill: epoch::Pill) -> Pill {
332 let epoch = Some(Epoch::from(pill.epoch));
333 let propose_hashes = pill
334 .propose_hashes
335 .into_iter()
336 .map(Hash::from)
337 .collect::<Vec<_>>();
338
339 Pill {
340 epoch,
341 propose_hashes,
342 }
343 }
344}
345
346impl TryFrom<Pill> for epoch::Pill {
347 type Error = ProtocolError;
348
349 fn try_from(pill: Pill) -> Result<epoch::Pill, Self::Error> {
350 let epoch = field!(pill.epoch, "Pill", "epoch")?;
351
352 let mut propose_hashes = Vec::new();
353 for hash in pill.propose_hashes {
354 propose_hashes.push(protocol_primitive::Hash::try_from(hash)?);
355 }
356
357 let pill = epoch::Pill {
358 epoch: epoch::Epoch::try_from(epoch)?,
359 propose_hashes,
360 };
361
362 Ok(pill)
363 }
364}
365
366impl_default_bytes_codec_for!(epoch, [Epoch, EpochHeader, Proof, Validator, Pill]);
371
372#[cfg(test)]
373mod test {
374 #[test]
375 fn test_u8_convert_u32() {
376 for i in u8::min_value()..u8::max_value() {
377 let j = u32::from(i);
378 assert_eq!(i, (j as u8));
379 }
380 }
381}