amaru_kernel/cardano/
raw_block.rs1use std::{fmt, ops::Deref, sync::Arc};
16
17use minicbor::decode;
18
19use crate::{Block, cardano::network_block::NetworkBlock};
20
21#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize)]
23pub struct RawBlock(Arc<[u8]>);
24
25impl fmt::Debug for RawBlock {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 let bytes = &self.0;
28 let total_len = bytes.len();
29 let preview_len = 32.min(total_len);
30 let preview = &bytes[0..preview_len];
31
32 let mut preview_hex = String::with_capacity(2 * preview_len + 3);
33 for &b in preview {
34 const HEX_CHARS: [u8; 16] = *b"0123456789abcdef";
35 preview_hex.push(HEX_CHARS[(b >> 4) as usize] as char);
36 preview_hex.push(HEX_CHARS[(b & 0x0f) as usize] as char);
37 }
38 if preview_len < total_len {
39 preview_hex.push_str("...");
40 }
41
42 write!(f, "RawBlock({total_len}, {preview_hex})")
43 }
44}
45
46impl Deref for RawBlock {
47 type Target = [u8];
48
49 fn deref(&self) -> &Self::Target {
50 &self.0
51 }
52}
53
54impl From<&[u8]> for RawBlock {
55 fn from(bytes: &[u8]) -> Self {
56 Self(Arc::from(bytes))
57 }
58}
59
60impl From<Box<[u8]>> for RawBlock {
61 fn from(bytes: Box<[u8]>) -> Self {
62 Self(Arc::from(bytes))
63 }
64}
65
66impl RawBlock {
67 pub fn decode(&self) -> Result<Block, decode::Error> {
70 let network_block: NetworkBlock = minicbor::decode(&self.0)?;
71 network_block.decode_block()
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use amaru_minicbor_extra::{from_cbor, to_cbor};
78
79 use crate::{
80 BlockHeader, TESTNET_ERA_HISTORY,
81 cardano::network_block::{NetworkBlock, make_block_with_header},
82 make_header,
83 };
84
85 #[test]
86 fn decode_returns_inner_block() {
87 let header = BlockHeader::from(make_header(1, 42, None));
88 let era_history = &*TESTNET_ERA_HISTORY;
89
90 let block = make_block_with_header(&header);
92
93 assert_eq!(block, from_cbor(to_cbor(&block).as_slice()).unwrap());
95
96 let network_block = NetworkBlock::new(era_history, &block).expect("make network block");
98 let decoded_block = network_block.decode_block().expect("network block should decode");
99 assert_eq!(decoded_block, block);
100
101 let raw_block = network_block.raw_block();
103 let decoded_block = raw_block.decode().expect("raw block should decode");
104 assert_eq!(decoded_block, block);
105 }
106}