feat(primitives): Introduce MintedBlock concept (#116)

This commit is contained in:
Santiago Carmuega 2022-06-12 10:44:16 -03:00 committed by GitHub
parent 4df94f94c6
commit fe80ff7800
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 214 additions and 188 deletions

View file

@ -1,10 +1,4 @@
use std::fmt::Debug;
use pallas::ledger::primitives::{alonzo, byron, probing, Era, Fragment};
fn pretty_print(block: impl Debug) {
println!("{:?}", block)
}
use pallas::ledger::primitives::{alonzo, byron, probing, Era};
fn main() {
let blocks = vec![
@ -16,16 +10,21 @@ fn main() {
];
for block_str in blocks.iter() {
let bytes = hex::decode(block_str).expect("valid hex");
let bytes = hex::decode(block_str).expect("invalid hex");
match probing::probe_block_cbor_era(&bytes) {
probing::Outcome::Matched(era) => match era {
Era::Byron => pretty_print(byron::Block::decode_fragment(&bytes)),
Era::Byron => {
let (_, block): (u16, byron::MainBlock) =
pallas::codec::minicbor::decode(&bytes).expect("invalid cbor");
println!("{:?}", block)
}
// we use alonzo for everything post-shelly since it's backward compatible
Era::Shelley => pretty_print(alonzo::BlockWrapper::decode_fragment(&bytes)),
Era::Allegra => pretty_print(alonzo::BlockWrapper::decode_fragment(&bytes)),
Era::Mary => pretty_print(alonzo::BlockWrapper::decode_fragment(&bytes)),
Era::Alonzo => pretty_print(alonzo::BlockWrapper::decode_fragment(&bytes)),
Era::Shelley | Era::Allegra | Era::Mary | Era::Alonzo => {
let (_, block): (u16, alonzo::Block) =
pallas::codec::minicbor::decode(&bytes).expect("invalid cbor");
println!("{:?}", block)
}
},
_ => println!("couldn't infer block era"),
};

View file

@ -15,8 +15,11 @@ impl TransactionOutput {
#[cfg(test)]
mod tests {
use crate::alonzo::{BlockWrapper, TransactionBodyComponent};
use crate::Fragment;
use pallas_codec::minicbor;
use crate::alonzo::{Block, TransactionBodyComponent};
type BlockWrapper = (u16, Block);
const KNOWN_ADDRESSES: &[&str] =&[
"addr_test1vzzql63nddp8qdgka578hx6pats290js9kmn4uay5we9fwsgza0z3",
@ -36,10 +39,10 @@ mod tests {
fn known_address_matches() {
// TODO: expand this test to include more test blocks
let block_idx = 1;
let block_str = include_str!("../test_data/alonzo2.block");
let block_str = include_str!("../../../test_data/alonzo2.block");
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
let BlockWrapper(_, block) = BlockWrapper::decode_fragment(&block_bytes[..])
let (_, block): BlockWrapper = minicbor::decode(&block_bytes[..])
.expect(&format!("error decoding cbor for file {}", block_idx));
// don't want to pass if we don't have tx in the block

View file

@ -50,21 +50,24 @@ impl ToHash<32> for KeepRaw<'_, TransactionBody> {
mod tests {
use std::str::FromStr;
use pallas_codec::minicbor;
use pallas_codec::minicbor::data::Int;
use pallas_codec::utils::MaybeIndefArray;
use pallas_crypto::hash::Hash;
use crate::alonzo::{BigInt, BlockWrapper, Constr, NativeScript, PlutusData};
use crate::{Fragment, ToHash};
use crate::alonzo::{BigInt, Constr, MintedBlock, NativeScript, PlutusData};
use crate::ToHash;
type BlockWrapper<'b> = (u16, MintedBlock<'b>);
#[test]
fn transaction_hash_works() {
// TODO: expand this test to include more test blocks
let block_idx = 1;
let block_str = include_str!("../test_data/alonzo1.block");
let block_str = include_str!("../../../test_data/alonzo1.block");
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
let block_model = BlockWrapper::decode_fragment(&block_bytes[..])
let (_, block_model): BlockWrapper = minicbor::decode(&block_bytes[..])
.expect(&format!("error decoding cbor for file {}", block_idx));
let valid_hashes = vec![
@ -75,7 +78,7 @@ mod tests {
"8838f5ab27894a6543255aeaec086f7b3405a6db6e7457a541409cdbbf0cd474",
];
for (tx_idx, tx) in block_model.1.transaction_bodies.iter().enumerate() {
for (tx_idx, tx) in block_model.transaction_bodies.iter().enumerate() {
let computed_hash = tx.to_hash();
let known_hash = valid_hashes[tx_idx];
assert_eq!(hex::encode(computed_hash), known_hash)

View file

@ -80,13 +80,17 @@ impl ToCanonicalJson for super::NativeScript {
#[cfg(test)]
mod tests {
use crate::{alonzo::BlockWrapper, Fragment, ToCanonicalJson};
use pallas_codec::minicbor;
use crate::{alonzo::Block, ToCanonicalJson};
type BlockWrapper = (u16, Block);
#[test]
fn test_datums_serialize_as_expected() {
let test_blocks = vec![(
include_str!("../test_data/alonzo9.block"),
include_str!("../test_data/alonzo9.datums"),
include_str!("../../../test_data/alonzo9.block"),
include_str!("../../../test_data/alonzo9.datums"),
)];
for (idx, (block_str, jsonl_str)) in test_blocks.iter().enumerate() {
@ -94,7 +98,7 @@ mod tests {
let bytes = hex::decode(block_str).expect(&format!("bad block file {}", idx));
let BlockWrapper(_, block) = BlockWrapper::decode_fragment(&bytes[..])
let (_, block): BlockWrapper = minicbor::decode(&bytes[..])
.expect(&format!("error decoding cbor for file {}", idx));
let mut datums = jsonl_str.lines();
@ -115,8 +119,8 @@ mod tests {
#[test]
fn test_native_scripts_serialize_as_expected() {
let test_blocks = vec![(
include_str!("../test_data/alonzo9.block"),
include_str!("../test_data/alonzo9.native"),
include_str!("../../../test_data/alonzo9.block"),
include_str!("../../../test_data/alonzo9.native"),
)];
for (idx, (block_str, jsonl_str)) in test_blocks.iter().enumerate() {
@ -124,7 +128,7 @@ mod tests {
let bytes = hex::decode(block_str).expect(&format!("bad block file {}", idx));
let BlockWrapper(_, block) = BlockWrapper::decode_fragment(&bytes[..])
let (_, block): BlockWrapper = minicbor::decode(&bytes[..])
.expect(&format!("error decoding cbor for file {}", idx));
let mut scripts = jsonl_str.lines();

View file

@ -1418,12 +1418,12 @@ impl<C> minicbor::Encode<C> for AuxiliaryData {
pub type TransactionIndex = u32;
#[derive(Encode, Decode, Debug, PartialEq)]
pub struct Block<'b> {
pub struct Block {
#[n(0)]
pub header: Header,
#[b(1)]
pub transaction_bodies: MaybeIndefArray<KeepRaw<'b, TransactionBody>>,
pub transaction_bodies: MaybeIndefArray<TransactionBody>,
#[n(2)]
pub transaction_witness_sets: MaybeIndefArray<TransactionWitnessSet>,
@ -1435,82 +1435,107 @@ pub struct Block<'b> {
pub invalid_transactions: Option<MaybeIndefArray<TransactionIndex>>,
}
#[derive(Encode, Decode, Debug)]
pub struct BlockWrapper<'b>(#[n(0)] pub u16, #[b(1)] pub Block<'b>);
/// A memory representation of an already minted block
///
/// This structure is analogous to [Block], but it allows to retrieve the
/// original CBOR bytes for each structure that might require hashing. In this
/// way, we make sure that the resulting hash matches what exists on-chain.
#[derive(Encode, Decode, Debug, PartialEq)]
pub struct MintedBlock<'b> {
#[n(0)]
pub header: KeepRaw<'b, Header>,
#[b(1)]
pub transaction_bodies: MaybeIndefArray<KeepRaw<'b, TransactionBody>>,
#[n(2)]
pub transaction_witness_sets: MaybeIndefArray<TransactionWitnessSet>,
#[n(3)]
pub auxiliary_data_set: KeyValuePairs<TransactionIndex, KeepRaw<'b, AuxiliaryData>>,
#[n(4)]
pub invalid_transactions: Option<MaybeIndefArray<TransactionIndex>>,
}
#[derive(Encode, Decode, Debug)]
pub struct Transaction {
#[n(0)]
transaction_body: TransactionBody,
#[n(1)]
transaction_witness_set: TransactionWitnessSet,
#[n(2)]
success: bool,
#[n(3)]
auxiliary_data: Option<AuxiliaryData>,
}
#[cfg(test)]
mod tests {
use super::BlockWrapper;
use crate::Fragment;
use pallas_codec::minicbor::to_vec;
use pallas_codec::minicbor::{self, to_vec};
use super::MintedBlock;
type BlockWrapper<'b> = (u16, MintedBlock<'b>);
#[test]
fn block_isomorphic_decoding_encoding() {
let test_blocks = vec![
include_str!("../test_data/alonzo1.block"),
include_str!("../test_data/alonzo2.block"),
include_str!("../test_data/alonzo3.block"),
include_str!("../test_data/alonzo4.block"),
include_str!("../test_data/alonzo5.block"),
include_str!("../test_data/alonzo6.block"),
include_str!("../test_data/alonzo7.block"),
include_str!("../test_data/alonzo8.block"),
include_str!("../test_data/alonzo9.block"),
include_str!("../../../test_data/alonzo1.block"),
include_str!("../../../test_data/alonzo2.block"),
include_str!("../../../test_data/alonzo3.block"),
include_str!("../../../test_data/alonzo4.block"),
include_str!("../../../test_data/alonzo5.block"),
include_str!("../../../test_data/alonzo6.block"),
include_str!("../../../test_data/alonzo7.block"),
include_str!("../../../test_data/alonzo8.block"),
include_str!("../../../test_data/alonzo9.block"),
// old block without invalid_transactions fields
include_str!("../test_data/alonzo10.block"),
include_str!("../../../test_data/alonzo10.block"),
// peculiar block with protocol update params
include_str!("../test_data/alonzo11.block"),
include_str!("../../../test_data/alonzo11.block"),
// peculiar block with decoding issue
// https://github.com/txpipe/oura/issues/37
include_str!("../test_data/alonzo12.block"),
include_str!("../../../test_data/alonzo12.block"),
// peculiar block with protocol update params, including nonce
include_str!("../test_data/alonzo13.block"),
include_str!("../../../test_data/alonzo13.block"),
// peculiar block with overflow crash
// https://github.com/txpipe/oura/issues/113
include_str!("../test_data/alonzo14.block"),
include_str!("../../../test_data/alonzo14.block"),
// peculiar block with many move-instantaneous-rewards certs
include_str!("../test_data/alonzo15.block"),
include_str!("../../../test_data/alonzo15.block"),
// peculiar block with protocol update values
include_str!("../test_data/alonzo16.block"),
include_str!("../../../test_data/alonzo16.block"),
// peculiar block with missing nonce hash
include_str!("../test_data/alonzo17.block"),
include_str!("../../../test_data/alonzo17.block"),
// peculiar block with strange AuxiliaryData variant
include_str!("../test_data/alonzo18.block"),
include_str!("../../../test_data/alonzo18.block"),
// peculiar block with strange AuxiliaryData variant
include_str!("../test_data/alonzo18.block"),
include_str!("../../../test_data/alonzo18.block"),
// peculiar block with nevative i64 overflow
include_str!("../test_data/alonzo19.block"),
include_str!("../../../test_data/alonzo19.block"),
// peculiar block with very BigInt in plutus code
include_str!("../test_data/alonzo20.block"),
include_str!("../../../test_data/alonzo20.block"),
// peculiar block with bad tx hash
include_str!("../test_data/alonzo21.block"),
include_str!("../../../test_data/alonzo21.block"),
// peculiar block with bad tx hash
include_str!("../test_data/alonzo22.block"),
include_str!("../../../test_data/alonzo22.block"),
];
for (idx, block_str) in test_blocks.iter().enumerate() {
println!("decoding test block {}", idx + 1);
let bytes = hex::decode(block_str).expect(&format!("bad block file {}", idx));
let block = BlockWrapper::decode_fragment(&bytes[..])
let block: BlockWrapper = minicbor::decode(&bytes[..])
.expect(&format!("error decoding cbor for file {}", idx));
let bytes2 =
to_vec(block).expect(&format!("error encoding block cbor for file {}", idx));
assert_eq!(bytes, bytes2);
assert!(bytes.eq(&bytes2), "re-encoded bytes didn't match original");
}
}
}

View file

@ -13,9 +13,9 @@ impl Address {
#[cfg(test)]
mod tests {
use crate::byron::Block;
use crate::Fragment;
use std::ops::Deref;
use crate::byron::MintedMainBlock;
type BlockWrapper<'b> = (u16, MintedMainBlock<'b>);
const KNOWN_ADDRESSES: &[&str] = &[
"DdzFFzCqrht8QHTQXbWy2qoyPaqTN8BjyfKygGmpy9dtot1tvkBfCaVTnR22XCaaDVn3M1U6aiMShoCLzw6VWSwzQKhhJrM3YjYp3wyy",
@ -32,22 +32,17 @@ mod tests {
fn known_address_matches() {
// TODO: expand this test to include more test blocks
let block_idx = 1;
let block_str = include_str!("test_data/test2.block");
let block_str = include_str!("../../../test_data/byron2.block");
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
let block = Block::decode_fragment(&block_bytes[..])
let (_, block): BlockWrapper = pallas_codec::minicbor::decode(&block_bytes[..])
.expect(&format!("error decoding cbor for file {}", block_idx));
let block = match block {
Block::MainBlock(x) => x,
Block::EbBlock(_) => panic!(),
};
// don't want to pass if we don't have tx in the block
assert!(block.body.tx_payload.len() > 0);
for tx in block.body.tx_payload.iter() {
for output in tx.deref().transaction.outputs.iter() {
for output in tx.transaction.outputs.iter() {
let addr_str = output.address.to_addr_string().unwrap();
assert!(

View file

@ -1,39 +1,56 @@
use super::{Block, BlockHead, EbbHead, Tx};
use crate::ToHash;
use super::{BlockHead, EbbHead, Tx};
use pallas_codec::utils::KeepRaw;
use pallas_crypto::hash::{Hash, Hasher};
impl EbbHead {
pub fn to_hash(&self) -> Hash<32> {
impl ToHash<32> for EbbHead {
fn to_hash(&self) -> Hash<32> {
// hash expects to have a prefix for the type of block
Hasher::<256>::hash_cbor(&(0, self))
}
}
impl BlockHead {
pub fn to_hash(&self) -> Hash<32> {
impl ToHash<32> for KeepRaw<'_, EbbHead> {
fn to_hash(&self) -> Hash<32> {
// hash expects to have a prefix for the type of block
Hasher::<256>::hash_cbor(&(0, self))
}
}
impl ToHash<32> for BlockHead {
fn to_hash(&self) -> Hash<32> {
// hash expects to have a prefix for the type of block
Hasher::<256>::hash_cbor(&(1, self))
}
}
impl Block {
pub fn to_hash(&self) -> Hash<32> {
match self {
Block::EbBlock(x) => x.header.to_hash(),
Block::MainBlock(x) => x.header.to_hash(),
}
impl ToHash<32> for KeepRaw<'_, BlockHead> {
fn to_hash(&self) -> Hash<32> {
// hash expects to have a prefix for the type of block
Hasher::<256>::hash_cbor(&(1, self))
}
}
impl Tx {
pub fn to_hash(&self) -> Hash<32> {
impl ToHash<32> for Tx {
fn to_hash(&self) -> Hash<32> {
Hasher::<256>::hash_cbor(self)
}
}
impl ToHash<32> for KeepRaw<'_, Tx> {
fn to_hash(&self) -> Hash<32> {
Hasher::<256>::hash(self.raw_cbor())
}
}
#[cfg(test)]
mod tests {
use crate::byron::Block;
use crate::Fragment;
use pallas_codec::minicbor;
use crate::{byron::MintedMainBlock, ToHash};
type BlockWrapper<'b> = (u16, MintedMainBlock<'b>);
const KNOWN_HASH: &'static str =
"5c196e7394ace0449ba5a51c919369699b13896e97432894b4f0354dce8670b6";
@ -42,13 +59,13 @@ mod tests {
fn transaction_hash_works() {
// TODO: expand this test to include more test blocks
let block_idx = 1;
let block_str = include_str!("test_data/test1.block");
let block_str = include_str!("../../../test_data/byron1.block");
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
let block_model = Block::decode_fragment(&block_bytes[..])
let (_, block_model): BlockWrapper = minicbor::decode(&block_bytes[..])
.expect(&format!("error decoding cbor for file {}", block_idx));
let computed_hash = block_model.to_hash();
let computed_hash = block_model.header.to_hash();
assert_eq!(hex::encode(computed_hash), KNOWN_HASH)
}

View file

@ -46,24 +46,22 @@ impl TxPayload {
#[cfg(test)]
mod tests {
use crate::byron::Block;
use crate::Fragment;
use pallas_codec::minicbor;
use crate::{byron::MainBlock, ToHash};
type BlockWrapper = (u16, MainBlock);
#[test]
fn known_fee_matches() {
// TODO: expand this test to include more test blocks
let block_idx = 1;
let block_str = include_str!("test_data/test4.block");
let block_str = include_str!("../../../test_data/byron4.block");
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
let block = Block::decode_fragment(&block_bytes[..])
let (_, block): BlockWrapper = minicbor::decode(&block_bytes[..])
.expect(&format!("error decoding cbor for file {}", block_idx));
let block = match block {
Block::MainBlock(x) => x,
Block::EbBlock(_) => panic!(),
};
// don't want to pass if we don't have tx in the block
assert!(block.body.tx_payload.len() > 0);

View file

@ -6,8 +6,8 @@ use pallas_codec::minicbor::{bytes::ByteVec, Decode, Encode};
use pallas_crypto::hash::Hash;
use pallas_codec::utils::{
CborWrap, EmptyMap, KeyValuePairs, MaybeIndefArray, OrderPreservingProperties, TagWrap,
ZeroOrOneArray,
CborWrap, EmptyMap, KeepRaw, KeyValuePairs, MaybeIndefArray, OrderPreservingProperties,
TagWrap, ZeroOrOneArray,
};
// required for derive attrs to work
@ -907,6 +907,18 @@ pub struct MainBlock {
pub extra: MaybeIndefArray<Attributes>,
}
#[derive(Encode, Decode, Debug)]
pub struct MintedMainBlock<'b> {
#[b(0)]
pub header: KeepRaw<'b, BlockHead>,
#[n(1)]
pub body: BlockBody,
#[n(2)]
pub extra: MaybeIndefArray<Attributes>,
}
#[derive(Encode, Decode, Debug)]
pub struct EbBlock {
#[n(0)]
@ -919,79 +931,51 @@ pub struct EbBlock {
pub extra: MaybeIndefArray<Attributes>,
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
pub enum Block {
MainBlock(MainBlock),
EbBlock(EbBlock),
}
impl<'b, C> minicbor::Decode<'b, C> for Block {
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
d.array()?;
let variant = d.u32()?;
match variant {
0 => Ok(Block::EbBlock(d.decode_with(ctx)?)),
1 => Ok(Block::MainBlock(d.decode_with(ctx)?)),
_ => Err(minicbor::decode::Error::message(
"unknown variant for block",
)),
}
}
}
impl minicbor::Encode<()> for Block {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
_ctx: &mut (),
) -> Result<(), minicbor::encode::Error<W::Error>> {
match self {
Block::EbBlock(x) => {
e.array(2)?;
e.encode(0)?;
e.encode(x)?;
Ok(())
}
Block::MainBlock(x) => {
e.array(2)?;
e.encode(1)?;
e.encode(x)?;
Ok(())
}
}
}
}
#[cfg(test)]
mod tests {
use crate::byron::{Block, BlockHead};
use crate::Fragment;
use pallas_codec::minicbor::to_vec;
use super::{BlockHead, EbBlock, MintedMainBlock};
use pallas_codec::minicbor::{self, to_vec};
#[test]
fn block_isomorphic_decoding_encoding() {
fn boundary_block_isomorphic_decoding_encoding() {
type BlockWrapper = (u16, EbBlock);
let test_blocks = vec![include_str!("../../../test_data/genesis.block")];
for (idx, block_str) in test_blocks.iter().enumerate() {
println!("decoding test block {}", idx + 1);
let bytes = hex::decode(block_str).expect(&format!("bad block file {}", idx));
let block: BlockWrapper = minicbor::decode(&bytes[..])
.expect(&format!("error decoding cbor for file {}", idx));
let bytes2 =
to_vec(block).expect(&format!("error encoding block cbor for file {}", idx));
assert_eq!(hex::encode(bytes), hex::encode(bytes2));
}
}
#[test]
fn main_block_isomorphic_decoding_encoding() {
type BlockWrapper<'b> = (u16, MintedMainBlock<'b>);
let test_blocks = vec![
include_str!("test_data/genesis.block"),
include_str!("test_data/test1.block"),
include_str!("test_data/test2.block"),
include_str!("test_data/test3.block"),
include_str!("test_data/test4.block"),
include_str!("test_data/test5.block"),
include_str!("test_data/test6.block"),
include_str!("test_data/test7.block"),
//include_str!("../../../test_data/genesis.block"),
include_str!("../../../test_data/byron1.block"),
include_str!("../../../test_data/byron2.block"),
include_str!("../../../test_data/byron3.block"),
include_str!("../../../test_data/byron4.block"),
include_str!("../../../test_data/byron5.block"),
include_str!("../../../test_data/byron6.block"),
include_str!("../../../test_data/byron7.block"),
];
for (idx, block_str) in test_blocks.iter().enumerate() {
println!("decoding test block {}", idx + 1);
let bytes = hex::decode(block_str).expect(&format!("bad block file {}", idx));
let block = Block::decode_fragment(&bytes[..])
let block: BlockWrapper = minicbor::decode(&bytes[..])
.expect(&format!("error decoding cbor for file {}", idx));
let bytes2 =
@ -1003,13 +987,13 @@ mod tests {
#[test]
fn header_isomorphic_decoding_encoding() {
let subjects = vec![include_str!("test_data/test1.header")];
let subjects = vec![include_str!("../../../test_data/byron1.header")];
for (idx, str) in subjects.iter().enumerate() {
println!("decoding test header {}", idx + 1);
let bytes = hex::decode(str).expect(&format!("bad header file {}", idx));
let block = BlockHead::decode_fragment(&bytes[..])
let block: BlockHead = minicbor::decode(&bytes[..])
.expect(&format!("error decoding cbor for file {}", idx));
let bytes2 =

View file

@ -22,24 +22,22 @@ impl EbbHead {
#[cfg(test)]
mod tests {
use crate::byron::Block;
use crate::Fragment;
use pallas_codec::minicbor;
use crate::byron::MainBlock;
type BlockWrapper = (u16, MainBlock);
#[test]
fn knwon_slot_matches() {
// TODO: expand this test to include more test blocks
let block_idx = 1;
let block_str = include_str!("test_data/test1.block");
let block_str = include_str!("../../../test_data/byron1.block");
let block_bytes = hex::decode(block_str).expect(&format!("bad block file {}", block_idx));
let block = Block::decode_fragment(&block_bytes[..])
let (_, block): BlockWrapper = minicbor::decode(&block_bytes[..])
.expect(&format!("error decoding cbor for file {}", block_idx));
let block = match block {
Block::MainBlock(x) => x,
Block::EbBlock(_) => panic!(),
};
let computed_slot = block.header.consensus_data.0.to_abs_slot();
assert_eq!(computed_slot, 4492794);

View file

@ -23,11 +23,6 @@ where
}
}
#[cfg(feature = "json")]
pub trait ToCanonicalJson {
fn to_json(&self) -> serde_json::Value;
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Era {
Byron,
@ -37,6 +32,11 @@ pub enum Era {
Alonzo, // smart-contracts
}
#[cfg(feature = "json")]
pub trait ToCanonicalJson {
fn to_json(&self) -> serde_json::Value;
}
pub trait ToHash<const BYTES: usize> {
fn to_hash(&self) -> pallas_crypto::hash::Hash<BYTES>;
}

View file

@ -7,7 +7,7 @@ use crate::Era;
#[derive(Debug)]
pub enum Outcome {
Matched(Era),
GenesisBlock,
EpochBoundary,
Inconclusive,
}
@ -23,7 +23,7 @@ pub fn probe_block_cbor_era(cbor: &[u8]) -> Outcome {
match tokenizer.next() {
Some(Ok(Token::U8(variant))) => match variant {
0 => Outcome::GenesisBlock,
0 => Outcome::EpochBoundary,
1 => Outcome::Matched(Era::Byron),
2 => Outcome::Matched(Era::Shelley),
3 => Outcome::Matched(Era::Allegra),
@ -41,17 +41,17 @@ mod tests {
#[test]
fn genesis_block_detected() {
let block_str = include_str!("byron/test_data/genesis.block");
let block_str = include_str!("../../test_data/genesis.block");
let bytes = hex::decode(block_str).unwrap();
let inference = probe_block_cbor_era(bytes.as_slice());
assert!(matches!(inference, Outcome::GenesisBlock));
assert!(matches!(inference, Outcome::EpochBoundary));
}
#[test]
fn byron_block_detected() {
let block_str = include_str!("byron/test_data/test1.block");
let block_str = include_str!("../../test_data/byron1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = probe_block_cbor_era(bytes.as_slice());
@ -61,7 +61,7 @@ mod tests {
#[test]
fn shelley_block_detected() {
let block_str = include_str!("test_data/shelley1.block");
let block_str = include_str!("../../test_data/shelley1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = probe_block_cbor_era(bytes.as_slice());
@ -71,7 +71,7 @@ mod tests {
#[test]
fn allegra_block_detected() {
let block_str = include_str!("test_data/allegra1.block");
let block_str = include_str!("../../test_data/allegra1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = probe_block_cbor_era(bytes.as_slice());
@ -81,7 +81,7 @@ mod tests {
#[test]
fn mary_block_detected() {
let block_str = include_str!("test_data/mary1.block");
let block_str = include_str!("../../test_data/mary1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = probe_block_cbor_era(bytes.as_slice());
@ -91,7 +91,7 @@ mod tests {
#[test]
fn alonzo_block_detected() {
let block_str = include_str!("test_data/alonzo1.block");
let block_str = include_str!("../../test_data/alonzo1.block");
let bytes = hex::decode(block_str).unwrap();
let inference = probe_block_cbor_era(bytes.as_slice());