use {
crate::{SharedError, node::Kind},
cid::Cid,
std::vec::Vec,
};
// type (
// Epoch struct {
// Kind int
// Epoch int
// Subsets List__Link
// }
// )
/// Representation of a `Kind::Epoch` node pointing to subset indexes.
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Epoch {
/// Kind discriminator copied from the CBOR payload.
pub kind: u64,
/// Epoch number encoded in the payload.
pub epoch: u64,
/// Subset CIDs that compose the epoch.
pub subsets: Vec<Cid>,
}
impl Epoch {
/// Decodes an [`Epoch`] from raw CBOR bytes.
pub fn from_bytes(data: Vec<u8>) -> Result<Epoch, SharedError> {
let decoded_data: serde_cbor::Value = serde_cbor::from_slice(&data).unwrap();
let epoch = Epoch::from_cbor(decoded_data)?;
Ok(epoch)
}
/// Decodes an [`Epoch`] from a CBOR [`serde_cbor::Value`].
pub fn from_cbor(val: serde_cbor::Value) -> Result<Epoch, SharedError> {
let mut epoch = Epoch {
kind: 0,
epoch: 0,
subsets: vec![],
};
if let serde_cbor::Value::Array(array) = val {
// println!("Kind: {:?}", array[0]);
if let Some(serde_cbor::Value::Integer(kind)) = array.first() {
// println!("Kind: {:?}", Kind::from_u64(kind as u64).unwrap().to_string());
epoch.kind = *kind as u64;
if *kind as u64 != Kind::Epoch as u64 {
return Err(Box::new(std::io::Error::other(std::format!(
"Wrong kind for Epoch. Expected {:?}, got {:?}",
Kind::Epoch,
kind
))) as SharedError);
}
}
if let Some(serde_cbor::Value::Integer(num)) = array.get(1) {
epoch.epoch = *num as u64;
}
if let Some(serde_cbor::Value::Array(subsets)) = &array.get(2) {
for subset in subsets {
if let serde_cbor::Value::Bytes(subset) = subset {
epoch
.subsets
.push(Cid::try_from(subset[1..].to_vec()).unwrap());
}
}
}
}
Ok(epoch)
}
/// Renders the epoch as a JSON object for debugging.
pub fn to_json(&self) -> serde_json::Value {
let mut subsets = vec![];
for subset in &self.subsets {
subsets.push(serde_json::json!({
"/": subset.to_string()
}));
}
let mut map = serde_json::Map::new();
map.insert("kind".to_string(), serde_json::Value::from(self.kind));
map.insert("epoch".to_string(), serde_json::Value::from(self.epoch));
map.insert("subsets".to_string(), serde_json::Value::from(subsets));
serde_json::Value::from(map)
}
}
#[cfg(test)]
mod epoch_tests {
use super::*;
#[test]
fn test_epoch() {
let epoch = Epoch {
kind: 4,
epoch: 1,
subsets: vec![
Cid::try_from(
vec![
1, 113, 18, 32, 56, 148, 167, 251, 237, 117, 200, 226, 181, 134, 79, 115,
131, 220, 232, 143, 20, 67, 224, 179, 48, 130, 197, 123, 226, 85, 85, 56,
38, 84, 106, 225,
]
.as_slice(),
)
.unwrap(),
],
};
let json = epoch.to_json();
let wanted_json = serde_json::json!({
"kind": 4,
"epoch": 1,
"subsets": [
{
"/":"bafyreibysst7x3lvzdrllbspoob5z2epcrb6bmzqqlcxxysvku4cmvdk4e"
}
]
});
assert_eq!(json, wanted_json);
}
#[test]
fn test_decoding() {
{
let raw = vec![
131, 4, 24, 39, 146, 216, 42, 88, 37, 0, 1, 113, 18, 32, 18, 250, 194, 194, 248,
17, 163, 227, 226, 73, 89, 102, 172, 193, 238, 225, 98, 252, 63, 160, 136, 37, 67,
188, 140, 158, 246, 249, 42, 240, 176, 158, 216, 42, 88, 37, 0, 1, 113, 18, 32,
141, 232, 135, 32, 121, 0, 141, 52, 185, 135, 124, 244, 29, 48, 8, 213, 206, 34,
160, 226, 133, 199, 250, 216, 46, 63, 127, 191, 1, 252, 193, 122, 216, 42, 88, 37,
0, 1, 113, 18, 32, 28, 215, 1, 242, 11, 99, 190, 187, 29, 134, 111, 71, 180, 38,
21, 233, 62, 146, 194, 176, 177, 47, 189, 174, 236, 78, 241, 30, 91, 101, 180, 22,
216, 42, 88, 37, 0, 1, 113, 18, 32, 40, 118, 5, 84, 62, 143, 201, 110, 0, 235, 217,
129, 120, 11, 135, 230, 60, 125, 28, 234, 31, 191, 19, 194, 9, 122, 240, 60, 68,
178, 205, 177, 216, 42, 88, 37, 0, 1, 113, 18, 32, 189, 201, 201, 183, 204, 13,
123, 108, 88, 63, 194, 26, 9, 177, 227, 158, 134, 213, 8, 206, 47, 165, 31, 23,
191, 49, 108, 157, 153, 213, 131, 88, 216, 42, 88, 37, 0, 1, 113, 18, 32, 254, 223,
153, 91, 142, 34, 11, 130, 186, 51, 189, 26, 251, 67, 219, 147, 144, 19, 162, 83,
8, 82, 172, 15, 113, 200, 248, 28, 88, 91, 74, 164, 216, 42, 88, 37, 0, 1, 113, 18,
32, 65, 102, 183, 74, 222, 146, 79, 191, 25, 96, 29, 218, 124, 17, 110, 46, 172,
116, 33, 47, 27, 125, 80, 180, 164, 203, 127, 11, 28, 62, 206, 75, 216, 42, 88, 37,
0, 1, 113, 18, 32, 167, 154, 154, 198, 222, 45, 240, 95, 86, 154, 251, 158, 68, 46,
157, 230, 102, 187, 159, 103, 168, 114, 55, 109, 250, 44, 28, 71, 108, 82, 231,
115, 216, 42, 88, 37, 0, 1, 113, 18, 32, 82, 71, 66, 71, 199, 27, 224, 128, 234,
120, 160, 107, 143, 167, 64, 126, 207, 46, 72, 141, 134, 96, 90, 10, 157, 102, 84,
129, 8, 99, 9, 56, 216, 42, 88, 37, 0, 1, 113, 18, 32, 10, 233, 51, 122, 206, 88,
77, 159, 103, 28, 129, 195, 12, 115, 12, 107, 81, 146, 23, 193, 86, 41, 224, 121,
37, 98, 65, 196, 222, 131, 123, 116, 216, 42, 88, 37, 0, 1, 113, 18, 32, 194, 151,
126, 15, 113, 49, 181, 9, 67, 107, 40, 107, 192, 41, 213, 115, 233, 113, 14, 53,
99, 130, 142, 127, 200, 225, 122, 46, 53, 48, 37, 56, 216, 42, 88, 37, 0, 1, 113,
18, 32, 193, 11, 88, 188, 64, 8, 137, 103, 83, 62, 200, 254, 126, 250, 47, 140,
116, 207, 16, 125, 221, 216, 119, 137, 156, 177, 209, 164, 48, 77, 166, 136, 216,
42, 88, 37, 0, 1, 113, 18, 32, 161, 148, 55, 178, 229, 153, 194, 49, 141, 184, 223,
219, 89, 53, 127, 213, 20, 255, 225, 254, 34, 26, 181, 198, 228, 166, 77, 8, 24,
77, 68, 26, 216, 42, 88, 37, 0, 1, 113, 18, 32, 3, 144, 157, 93, 68, 243, 255, 185,
75, 68, 156, 251, 18, 5, 206, 210, 83, 228, 52, 171, 254, 9, 69, 149, 9, 63, 91,
217, 132, 15, 133, 42, 216, 42, 88, 37, 0, 1, 113, 18, 32, 124, 110, 193, 69, 202,
85, 215, 41, 194, 150, 198, 245, 153, 132, 19, 9, 117, 110, 113, 30, 137, 231, 117,
38, 211, 51, 154, 3, 125, 84, 52, 229, 216, 42, 88, 37, 0, 1, 113, 18, 32, 55, 34,
35, 188, 88, 75, 147, 138, 231, 108, 17, 242, 53, 157, 170, 23, 90, 104, 245, 108,
103, 181, 52, 108, 160, 67, 19, 245, 244, 196, 150, 170, 216, 42, 88, 37, 0, 1,
113, 18, 32, 254, 72, 218, 251, 250, 18, 126, 94, 125, 102, 99, 110, 13, 94, 112,
18, 52, 62, 65, 106, 155, 128, 69, 146, 21, 78, 103, 244, 129, 7, 176, 189, 216,
42, 88, 37, 0, 1, 113, 18, 32, 44, 229, 44, 221, 134, 69, 72, 61, 15, 149, 152, 62,
95, 52, 255, 190, 69, 44, 46, 188, 100, 36, 61, 165, 179, 54, 172, 131, 149, 143,
143, 203,
];
let as_json_raw = serde_json::json!({"kind":4,"epoch":39,"subsets":[{"/":"bafyreias7lbmf6arupr6eskzm2wmd3xbml6d7ieievb3zde6634sv4fqty"},{"/":"bafyreien5cdsa6iaru2ltb346qotacgvzyrkbyufy75nqlr7p67qd7gbpi"},{"/":"bafyreia424a7ec3dx25r3btpi62cmfpjh2jmfmfrf66253co6epfwznucy"},{"/":"bafyreibioycvipupzfxab26zqf4axb7ghr6rz2q7x4j4ecl26a6ejmwnwe"},{"/":"bafyreif5zhe3ptanpnwfqp6cdie3dy46q3kqrtrpuuprppzrnsoztvmdla"},{"/":"bafyreih636mvxdrcboblum55dl5uhw4tsaj2euyikkwa64oi7aofqw2kuq"},{"/":"bafyreicbm23uvxusj67rsya53j6bc3rovr2ccly3pviljjglp4frypwojm"},{"/":"bafyreifhtknmnxrn6bpvngx3tzcc5hpgm25z6z5ioi3w36rmdrdwyuxhom"},{"/":"bafyreicsi5bepry34caou6fanoh2oqd6z4xerdmgmbnavhlgksaqqyyjha"},{"/":"bafyreiak5ezxvtsyjwpwohebymghgddlkgjbpqkwfhqhsjlcihcn5a33oq"},{"/":"bafyreigcs57a64jrwueug2zinpactvlt5fyq4nldqkhh7shbpixdkmbfha"},{"/":"bafyreigbbnmlyqairftvgpwi7z7pul4mothra7o53b3ythfr2gsdatngra"},{"/":"bafyreifbsq33fzmzyiyy3og73nmtk76vct76d7rcdk24nzfgjuebqtkedi"},{"/":"bafyreiadscov2rht764uwre47mjaltwskpsdjk76bfczkcj7lpmyid4ffi"},{"/":"bafyreid4n3aulssv24u4ffwg6wmyieyjovxhchuj452snuzttibx2vbu4u"},{"/":"bafyreibxeir3ywclsofoo3ar6i2z3kqxljupk3dhwu2gzicdcp27jrewvi"},{"/":"bafyreih6jdnpx6qspzph2ztdnygv44asgq7ec2u3qbczefkom72icb5qxu"},{"/":"bafyreibm4uwn3bsfja6q7fmyhzptj756iuwc5pdeeq62lmzwvsbzld4pzm"}]});
let epoch = Epoch::from_bytes(raw).unwrap();
let json = epoch.to_json();
assert_eq!(json, as_json_raw);
}
{
let raw = vec![
131, 4, 24, 120, 130, 216, 42, 88, 37, 0, 1, 113, 18, 32, 89, 118, 15, 47, 211,
244, 148, 72, 97, 22, 125, 223, 7, 22, 154, 131, 239, 74, 68, 115, 25, 83, 181,
103, 188, 221, 74, 184, 171, 49, 248, 175, 216, 42, 88, 37, 0, 1, 113, 18, 32, 111,
243, 18, 145, 137, 92, 10, 252, 113, 31, 191, 162, 236, 105, 154, 211, 177, 143,
180, 173, 61, 180, 154, 155, 60, 244, 221, 131, 213, 154, 68, 70,
];
let as_json_raw = serde_json::json!({"kind":4,"epoch":120,"subsets":[{"/":"bafyreiczoyhs7u7usregcft534drngud55fei4yzko2wppg5jk4kwmpyv4"},{"/":"bafyreidp6mjjdck4bl6hch57ulwgtgwtwgh3jlj5wsnjwphu3wb5lgseiy"}]});
let epoch = Epoch::from_bytes(raw).unwrap();
let json = epoch.to_json();
assert_eq!(json, as_json_raw);
}
}
}