From cfe169ec31095376a58b5cb1384d3605962ef4dc Mon Sep 17 00:00:00 2001 From: Santiago Carmuega Date: Wed, 9 Feb 2022 08:07:09 -0300 Subject: [PATCH] feat: Implement block cbor probing --- pallas-primitives/Cargo.toml | 2 +- pallas-primitives/src/lib.rs | 1 + pallas-primitives/src/probing.rs | 57 ++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 pallas-primitives/src/probing.rs diff --git a/pallas-primitives/Cargo.toml b/pallas-primitives/Cargo.toml index ec133f92..15ae3489 100644 --- a/pallas-primitives/Cargo.toml +++ b/pallas-primitives/Cargo.toml @@ -14,7 +14,7 @@ authors = [ ] [dependencies] -minicbor = { version = "0.13", features = ["std"] } +minicbor = { version = "0.13", features = ["std", "half"] } minicbor-derive = "0.8.0" hex = "0.4.3" log = "0.4.14" diff --git a/pallas-primitives/src/lib.rs b/pallas-primitives/src/lib.rs index 0b85a7f8..fe32a294 100644 --- a/pallas-primitives/src/lib.rs +++ b/pallas-primitives/src/lib.rs @@ -4,6 +4,7 @@ mod framework; pub mod alonzo; pub mod byron; +pub mod probing; pub mod utils; pub use framework::*; diff --git a/pallas-primitives/src/probing.rs b/pallas-primitives/src/probing.rs new file mode 100644 index 00000000..8065588c --- /dev/null +++ b/pallas-primitives/src/probing.rs @@ -0,0 +1,57 @@ +//! Heuristics for detecting cbor content without decoding + +use minicbor::decode::{Token, Tokenizer}; + +pub enum BlockInference { + Byron, + Shelley, + Inconclusive, +} + +// Executes a very lightweight inspection of the initial tokens of the CBOR +// payload and infers with a certain degree of confidence the type of Cardano +// structure within. +pub fn probe_block_cbor(cbor: &[u8]) -> BlockInference { + let mut tokenizer = Tokenizer::new(cbor); + + if !matches!(tokenizer.next(), Some(Ok(Token::Array(2)))) { + return BlockInference::Inconclusive; + } + + if !matches!(tokenizer.next(), Some(Ok(Token::U8(_)))) { + return BlockInference::Inconclusive; + } + + //println!("{:?}", tokenizer.next()); + + match tokenizer.next() { + Some(Ok(Token::Array(3))) => BlockInference::Byron, + Some(Ok(Token::Array(5))) => BlockInference::Shelley, + _ => BlockInference::Inconclusive, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn byron_block_detected() { + let block_str = include_str!("byron/test_data/test1.block"); + let bytes = hex::decode(block_str).unwrap(); + + let inference = probe_block_cbor(bytes.as_slice()); + + assert!(matches!(inference, BlockInference::Byron)); + } + + #[test] + fn shelley_block_detected() { + let block_str = include_str!("alonzo/test_data/test1.block"); + let bytes = hex::decode(block_str).unwrap(); + + let inference = probe_block_cbor(bytes.as_slice()); + + assert!(matches!(inference, BlockInference::Shelley)); + } +}