cardano_sdk/protocol/
basic.rs1use crate::chain::{Block, BlockCompat, HeaderHash};
2use cbored::CborRepr;
3use cbored::{Decode, DecodeError, DecodeErrorKind, Encode, Reader, Writer};
4use std::fmt;
5
6#[derive(Clone, Debug)]
7pub struct Time(pub u32);
8
9impl Time {
10 pub fn now() -> Self {
11 Time(std::time::Instant::now().elapsed().as_micros() as u32)
12 }
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
16#[repr(u64)]
17pub enum Version {
18 V6 = 0x6,
19 V7 = 0x7,
20 V8 = 0x8,
21}
22
23impl Version {
24 pub const KNOWN: [Self; 3] = [Version::V6, Version::V7, Version::V8];
25
26 pub fn from_integer(v: u64) -> Option<Version> {
27 for k in Self::KNOWN {
28 if k as u64 == v {
29 return Some(k);
30 }
31 }
32 None
33 }
34}
35
36impl Decode for Version {
37 fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
38 let ver = reader.decode()?;
39 Version::from_integer(ver).ok_or(
40 cbored::DecodeErrorKind::Custom(format!("unknown version : {}", ver)).context::<Self>(),
41 )
42 }
43}
44
45impl Encode for Version {
46 fn encode(&self, writer: &mut Writer) {
47 writer.encode(&(*self as u64))
48 }
49}
50
51crate::vec_structure!(Versions, Version);
52
53#[derive(Clone, Copy, Debug, PartialEq, Eq)]
54pub enum DiffusionMode {
55 InitiatorOnly,
56 InitiatorAndResponder,
57}
58
59impl Encode for DiffusionMode {
60 fn encode(&self, writer: &mut Writer) {
61 match self {
62 DiffusionMode::InitiatorOnly => writer.bool(false),
63 DiffusionMode::InitiatorAndResponder => writer.bool(true),
64 }
65 }
66}
67
68impl Decode for DiffusionMode {
69 fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
70 match reader
71 .bool()
72 .map_err(DecodeErrorKind::ReaderError)
73 .map_err(|e| e.context::<Self>())?
74 {
75 true => Ok(DiffusionMode::InitiatorAndResponder),
76 false => Ok(DiffusionMode::InitiatorOnly),
77 }
78 }
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Eq, CborRepr)]
83#[cborrepr(structure = "flat")]
84pub struct Magic(pub u64);
85
86impl Magic {
87 pub const PREPROD: Self = Magic(1);
88 pub const PREVIEW: Self = Magic(2);
89 pub const TESTNET: Self = Magic(1097911063);
90 pub const MAINNET: Self = Magic(764824073);
91
92 pub const fn raw(value: u64) -> Self {
93 Magic(value)
94 }
95}
96
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub enum Point {
99 Origin,
100 BlockHeader { slot_nb: u64, hash: HeaderHash },
101}
102
103impl fmt::Display for Point {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 match self {
106 Point::Origin => write!(f, "origin"),
107 Point::BlockHeader { slot_nb, hash } => {
108 write!(f, "{}@{}", slot_nb, hash)
109 }
110 }
111 }
112}
113
114impl Point {
115 pub const ORIGIN: Self = Point::Origin;
116
117 pub fn from_raw(slot_nb: u64, s: &str) -> Option<Self> {
118 let hash = HeaderHash::from_hex(s)?;
119 Some(Point::BlockHeader { slot_nb, hash })
120 }
121
122 pub fn hash(&self) -> HeaderHash {
123 match self {
124 Point::Origin => HeaderHash([0; 32]),
125 Point::BlockHeader { slot_nb: _, hash } => hash.clone(),
126 }
127 }
128
129 pub fn slot_nb(&self) -> u64 {
130 match self {
131 Point::Origin => 0,
132 Point::BlockHeader { slot_nb, hash: _ } => *slot_nb,
133 }
134 }
135}
136
137impl Decode for Point {
138 fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
139 let array = reader
140 .array()
141 .map_err(DecodeErrorKind::ReaderError)
142 .map_err(|e| e.context::<Self>())?;
143 if array.len() == 0 {
144 Ok(Point::Origin)
145 } else if array.len() == 2 {
146 let slot_nb = array[0]
147 .decode()
148 .map_err(|e| e.push_str("slot_nb").push::<Self>())?;
149 let hash = array[1]
150 .decode()
151 .map_err(|e| e.push_str("hash").push::<Self>())?;
152 Ok(Point::BlockHeader { slot_nb, hash })
153 } else {
154 Err(DecodeErrorKind::Custom(format!(
155 "wrong expected length of 0 or 2, got {}",
156 array.len()
157 ))
158 .context::<Self>())
159 }
160 }
161}
162
163impl Encode for Point {
164 fn encode(&self, writer: &mut Writer) {
165 match self {
166 Point::Origin => {
167 let len = cbored::StructureLength::from(0);
168 writer.array_build(len, |_| {});
169 }
170 Point::BlockHeader { slot_nb, hash } => {
171 let len = cbored::StructureLength::from(2);
172 writer.array_build(len, |writer| {
173 writer.encode(slot_nb);
174 writer.encode(hash);
175 });
176 }
177 }
178 }
179}
180
181#[derive(Debug, Clone)]
182pub struct SerializedHeader(Vec<u8>);
183
184impl Decode for SerializedHeader {
185 fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
186 let cbor = reader
187 .decode::<cbored::tagged::EncodedCBOR>()
188 .map_err(|e| e.push::<Self>())?;
189 Ok(Self(cbor.to_bytes()))
190 }
191}
192
193impl Encode for SerializedHeader {
194 fn encode(&self, writer: &mut Writer) {
195 writer.encode(&cbored::tagged::EncodedCBOR::from_bytes(&self.0))
196 }
197}
198
199impl AsRef<[u8]> for SerializedHeader {
200 fn as_ref(&self) -> &[u8] {
201 &self.0
202 }
203}
204
205#[derive(Debug, Clone)]
206pub struct SerializedBlock(Vec<u8>);
207
208impl SerializedBlock {
209 pub fn unserialize(&self) -> Result<Block, DecodeError> {
210 let mut reader = Reader::new(&self.0);
211 let block = reader.decode_one()?;
212 Ok(block)
213 }
214
215 pub fn unserialize_compat(&self) -> Result<BlockCompat, DecodeError> {
216 let mut reader = Reader::new(&self.0);
217 let block = reader.decode_one()?;
218 Ok(block)
219 }
220}
221
222impl Decode for SerializedBlock {
223 fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
224 let cbor = reader
225 .decode::<cbored::tagged::EncodedCBOR>()
226 .map_err(|e| e.push::<Self>())?;
227 Ok(Self(cbor.to_bytes()))
228 }
229}
230
231impl Encode for SerializedBlock {
232 fn encode(&self, writer: &mut Writer) {
233 writer.encode(&cbored::tagged::EncodedCBOR::from_bytes(&self.0))
234 }
235}
236
237impl AsRef<[u8]> for SerializedBlock {
238 fn as_ref(&self) -> &[u8] {
239 &self.0
240 }
241}