pallas/pallas-traverse/src/probe.rs
2022-07-03 20:27:06 -03:00

102 lines
2.9 KiB
Rust

//! Lightweight inspection of block data without full CBOR decoding
use pallas_codec::minicbor::decode::{Token, Tokenizer};
use crate::Era;
#[derive(Debug)]
pub enum Outcome {
Matched(Era),
EpochBoundary,
Inconclusive,
}
// Executes a very lightweight inspection of the initial tokens of the CBOR
// block payload to extract the tag of the block wrapper which defines the era
// of the contained bytes.
pub fn block_era(cbor: &[u8]) -> Outcome {
let mut tokenizer = Tokenizer::new(cbor);
if !matches!(tokenizer.next(), Some(Ok(Token::Array(2)))) {
return Outcome::Inconclusive;
}
match tokenizer.next() {
Some(Ok(Token::U8(variant))) => match variant {
0 => Outcome::EpochBoundary,
1 => Outcome::Matched(Era::Byron),
2 => Outcome::Matched(Era::Shelley),
3 => Outcome::Matched(Era::Allegra),
4 => Outcome::Matched(Era::Mary),
5 => Outcome::Matched(Era::Alonzo),
6 => Outcome::Matched(Era::Babbage),
_ => Outcome::Inconclusive,
},
_ => Outcome::Inconclusive,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn genesis_block_detected() {
let block_str = include_str!("../../test_data/genesis.block");
let bytes = hex::decode(block_str).unwrap();
let inference = block_era(bytes.as_slice());
assert!(matches!(inference, Outcome::EpochBoundary));
}
#[test]
fn byron_block_detected() {
let block_str = include_str!("../../test_data/byron1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = block_era(bytes.as_slice());
assert!(matches!(inference, Outcome::Matched(Era::Byron)));
}
#[test]
fn shelley_block_detected() {
let block_str = include_str!("../../test_data/shelley1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = block_era(bytes.as_slice());
assert!(matches!(inference, Outcome::Matched(Era::Shelley)));
}
#[test]
fn allegra_block_detected() {
let block_str = include_str!("../../test_data/allegra1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = block_era(bytes.as_slice());
assert!(matches!(inference, Outcome::Matched(Era::Allegra)));
}
#[test]
fn mary_block_detected() {
let block_str = include_str!("../../test_data/mary1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = block_era(bytes.as_slice());
assert!(matches!(inference, Outcome::Matched(Era::Mary)));
}
#[test]
fn alonzo_block_detected() {
let block_str = include_str!("../../test_data/alonzo1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = block_era(bytes.as_slice());
assert!(matches!(inference, Outcome::Matched(Era::Alonzo)));
}
}