feat: Introduce 'traverse' library (#117)

This commit is contained in:
Santiago Carmuega 2022-06-12 19:09:33 -03:00 committed by GitHub
parent c9489c3ddf
commit 6913efef78
20 changed files with 377 additions and 106 deletions

View file

@ -74,7 +74,7 @@ pub struct Header {
pub body_signature: ByteVec,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct TransactionInput {
#[n(0)]
pub transaction_id: Hash<32>,
@ -85,7 +85,7 @@ pub struct TransactionInput {
// $nonce /= [ 0 // 1, bytes .size 32 ]
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[cbor(index_only)]
pub enum NonceVariant {
#[n(0)]
@ -95,7 +95,7 @@ pub enum NonceVariant {
Nonce,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct Nonce {
#[n(0)]
pub variant: NonceVariant,
@ -162,7 +162,7 @@ impl<C> minicbor::encode::Encode<C> for Value {
}
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct TransactionOutput {
#[n(0)]
pub address: ByteVec,
@ -187,7 +187,7 @@ pub type VrfKeyhash = Hash<32>;
; otherwise the funds are given to the other accounting pot.
*/
#[derive(Debug, PartialEq, PartialOrd)]
#[derive(Debug, PartialEq, PartialOrd, Clone)]
pub enum InstantaneousRewardSource {
Reserves,
Treasury,
@ -225,7 +225,7 @@ impl<C> minicbor::encode::Encode<C> for InstantaneousRewardSource {
}
}
#[derive(Debug, PartialEq, PartialOrd)]
#[derive(Debug, PartialEq, PartialOrd, Clone)]
pub enum InstantaneousRewardTarget {
StakeCredentials(KeyValuePairs<StakeCredential, i64>),
OtherAccountingPot(Coin),
@ -267,7 +267,7 @@ impl<C> minicbor::encode::Encode<C> for InstantaneousRewardTarget {
}
}
#[derive(Encode, Decode, Debug, PartialEq, PartialOrd)]
#[derive(Encode, Decode, Debug, PartialEq, PartialOrd, Clone)]
#[cbor]
pub struct MoveInstantaneousReward {
#[n(0)]
@ -284,7 +284,7 @@ pub type IPv4 = ByteVec;
pub type IPv6 = ByteVec;
pub type DnsName = String;
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum Relay {
SingleHostAddr(Option<Port>, Option<IPv4>, Option<IPv6>),
SingleHostName(Option<Port>, DnsName),
@ -351,7 +351,7 @@ impl<C> minicbor::encode::Encode<C> for Relay {
pub type PoolMetadataHash = Hash<32>;
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct PoolMetadata {
#[n(0)]
pub url: String,
@ -363,7 +363,7 @@ pub struct PoolMetadata {
pub type AddrKeyhash = Hash<28>;
pub type Scripthash = Hash<28>;
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub struct RationalNumber {
pub numerator: i64,
pub denominator: u64,
@ -401,7 +401,7 @@ pub type UnitInterval = RationalNumber;
pub type PositiveInterval = RationalNumber;
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord)]
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]
pub enum StakeCredential {
AddrKeyhash(AddrKeyhash),
Scripthash(Scripthash),
@ -447,7 +447,7 @@ impl<C> minicbor::encode::Encode<C> for StakeCredential {
}
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum Certificate {
StakeRegistration(StakeCredential),
StakeDeregistration(StakeCredential),
@ -615,7 +615,7 @@ impl<C> minicbor::encode::Encode<C> for Certificate {
}
}
#[derive(Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
#[cbor(index_only)]
pub enum NetworkId {
#[n(0)]
@ -624,7 +624,7 @@ pub enum NetworkId {
Two,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[cbor(index_only)]
pub enum Language {
#[n(0)]
@ -637,7 +637,7 @@ pub type CostMdls = KeyValuePairs<Language, CostModel>;
pub type ProtocolVersion = (u32, u32);
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[cbor(map)]
pub struct ProtocolParamUpdate {
#[n(0)]
@ -690,7 +690,7 @@ pub struct ProtocolParamUpdate {
pub max_collateral_inputs: Option<u32>,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct Update {
#[n(0)]
pub proposed_protocol_parameter_updates: KeyValuePairs<Genesishash, ProtocolParamUpdate>,
@ -699,7 +699,7 @@ pub struct Update {
pub epoch: Epoch,
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum TransactionBodyComponent {
Inputs(MaybeIndefArray<TransactionInput>),
Outputs(MaybeIndefArray<TransactionOutput>),
@ -814,7 +814,7 @@ impl<C> minicbor::encode::Encode<C> for TransactionBodyComponent {
// Can't derive encode for TransactionBody because it seems to require a very
// particular order for each key in the map
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub struct TransactionBody(Vec<TransactionBodyComponent>);
impl Deref for TransactionBody {
@ -850,7 +850,7 @@ impl<C> minicbor::encode::Encode<C> for TransactionBody {
}
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct VKeyWitness {
#[n(0)]
pub vkey: ByteVec,
@ -859,7 +859,7 @@ pub struct VKeyWitness {
pub signature: ByteVec,
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum NativeScript {
ScriptPubkey(AddrKeyhash),
ScriptAll(MaybeIndefArray<NativeScript>),
@ -931,7 +931,7 @@ impl<C> minicbor::encode::Encode<C> for NativeScript {
}
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[cbor(transparent)]
pub struct PlutusScript(#[n(0)] pub ByteVec);
@ -947,7 +947,7 @@ big_uint = #6.2(bounded_bytes) ; New
big_nint = #6.3(bounded_bytes) ; New
*/
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum BigInt {
Int(Int),
BigUInt(ByteVec),
@ -1009,7 +1009,7 @@ impl<C> minicbor::encode::Encode<C> for BigInt {
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum PlutusData {
Constr(Constr<PlutusData>),
Map(KeyValuePairs<PlutusData, PlutusData>),
@ -1090,7 +1090,7 @@ impl<C> minicbor::encode::Encode<C> for PlutusData {
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct Constr<A> {
pub tag: u64,
pub any_constructor: Option<u64>,
@ -1159,7 +1159,7 @@ where
}
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct ExUnits {
#[n(0)]
pub mem: u32,
@ -1167,7 +1167,7 @@ pub struct ExUnits {
pub steps: u64,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct ExUnitPrices {
#[n(0)]
mem_price: PositiveInterval,
@ -1176,7 +1176,7 @@ pub struct ExUnitPrices {
step_price: PositiveInterval,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[cbor(index_only)]
pub enum RedeemerTag {
#[n(0)]
@ -1189,7 +1189,7 @@ pub enum RedeemerTag {
Reward,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct Redeemer {
#[n(0)]
pub tag: RedeemerTag,
@ -1211,7 +1211,7 @@ pub struct Redeemer {
, attributes : bytes
] */
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct BootstrapWitness {
#[n(0)]
pub public_key: ByteVec,
@ -1226,7 +1226,7 @@ pub struct BootstrapWitness {
pub attributes: ByteVec,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[cbor(map)]
pub struct TransactionWitnessSet {
#[n(0)]
@ -1248,7 +1248,7 @@ pub struct TransactionWitnessSet {
pub redeemer: Option<MaybeIndefArray<Redeemer>>,
}
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
#[cbor(map)]
pub struct AlonzoAuxiliaryData {
#[n(0)]
@ -1259,7 +1259,7 @@ pub struct AlonzoAuxiliaryData {
pub plutus_scripts: Option<MaybeIndefArray<PlutusScript>>,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum Metadatum {
Int(Int),
Bytes(ByteVec),
@ -1350,7 +1350,7 @@ pub type MetadatumLabel = AnyUInt;
pub type Metadata = KeyValuePairs<MetadatumLabel, Metadatum>;
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum AuxiliaryData {
Shelley(Metadata),
ShelleyMa {
@ -1417,7 +1417,7 @@ impl<C> minicbor::Encode<C> for AuxiliaryData {
pub type TransactionIndex = u32;
#[derive(Encode, Decode, Debug, PartialEq)]
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
pub struct Block {
#[n(0)]
pub header: Header,
@ -1459,18 +1459,33 @@ pub struct MintedBlock<'b> {
}
#[derive(Encode, Decode, Debug)]
pub struct Transaction {
pub struct Tx {
#[n(0)]
transaction_body: TransactionBody,
pub transaction_body: TransactionBody,
#[n(1)]
transaction_witness_set: TransactionWitnessSet,
pub transaction_witness_set: TransactionWitnessSet,
#[n(2)]
success: bool,
pub success: bool,
#[n(3)]
auxiliary_data: Option<AuxiliaryData>,
pub auxiliary_data: Option<AuxiliaryData>,
}
#[derive(Encode, Decode, Debug)]
pub struct MintedTx<'b> {
#[b(0)]
pub transaction_body: KeepRaw<'b, TransactionBody>,
#[n(1)]
pub transaction_witness_set: TransactionWitnessSet,
#[n(2)]
pub success: bool,
#[n(3)]
pub auxiliary_data: Option<KeepRaw<'b, AuxiliaryData>>,
}
#[cfg(test)]

View file

@ -13,9 +13,9 @@ impl Address {
#[cfg(test)]
mod tests {
use crate::byron::MintedMainBlock;
use crate::byron::MintedBlock;
type BlockWrapper<'b> = (u16, MintedMainBlock<'b>);
type BlockWrapper<'b> = (u16, MintedBlock<'b>);
const KNOWN_ADDRESSES: &[&str] = &[
"DdzFFzCqrht8QHTQXbWy2qoyPaqTN8BjyfKygGmpy9dtot1tvkBfCaVTnR22XCaaDVn3M1U6aiMShoCLzw6VWSwzQKhhJrM3YjYp3wyy",

View file

@ -48,9 +48,9 @@ impl ToHash<32> for KeepRaw<'_, Tx> {
mod tests {
use pallas_codec::minicbor;
use crate::{byron::MintedMainBlock, ToHash};
use crate::{byron::MintedBlock, ToHash};
type BlockWrapper<'b> = (u16, MintedMainBlock<'b>);
type BlockWrapper<'b> = (u16, MintedBlock<'b>);
const KNOWN_HASH: &'static str =
"5c196e7394ace0449ba5a51c919369699b13896e97432894b4f0354dce8670b6";

View file

@ -48,9 +48,9 @@ impl TxPayload {
mod tests {
use pallas_codec::minicbor;
use crate::{byron::MainBlock, ToHash};
use crate::{byron::Block, ToHash};
type BlockWrapper = (u16, MainBlock);
type BlockWrapper = (u16, Block);
#[test]
fn known_fee_matches() {

View file

@ -51,7 +51,7 @@ pub type Attributes = EmptyMap;
// Addresses
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum AddrDistr {
Variant0(StakeholderId),
Variant1,
@ -96,7 +96,7 @@ impl minicbor::Encode<()> for AddrDistr {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum AddrType {
PubKey,
Script,
@ -137,7 +137,7 @@ impl<C> minicbor::Encode<C> for AddrType {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum AddrAttrProperty {
AddrDistr(AddrDistr),
Bytes(ByteVec),
@ -187,7 +187,7 @@ impl<C> minicbor::Encode<C> for AddrAttrProperty {
pub type AddrAttr = OrderPreservingProperties<AddrAttrProperty>;
#[derive(Debug, Encode, Decode)]
#[derive(Debug, Encode, Decode, Clone)]
pub struct AddressPayload {
#[n(0)]
pub root: AddressId,
@ -200,7 +200,7 @@ pub struct AddressPayload {
}
// address = [ #6.24(bytes .cbor ([addressid, addrattr, addrtype])), u64 ]
#[derive(Debug, Encode, Decode)]
#[derive(Debug, Encode, Decode, Clone)]
pub struct Address {
#[n(0)]
pub payload: CborWrap<AddressPayload>,
@ -212,7 +212,7 @@ pub struct Address {
// Transactions
// txout = [address, u64]
#[derive(Debug, Encode, Decode)]
#[derive(Debug, Encode, Decode, Clone)]
pub struct TxOut {
#[n(0)]
pub address: Address,
@ -221,7 +221,7 @@ pub struct TxOut {
pub amount: u64,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum TxIn {
// [0, #6.24(bytes .cbor ([txid, u32]))]
Variant0(CborWrap<(TxId, u32)>),
@ -269,7 +269,7 @@ impl<C> minicbor::Encode<C> for TxIn {
}
// tx = [[+ txin], [+ txout], attributes]
#[derive(Debug, Encode, Decode)]
#[derive(Debug, Encode, Decode, Clone)]
pub struct Tx {
#[n(0)]
pub inputs: MaybeIndefArray<TxIn>,
@ -287,7 +287,7 @@ pub type TxProof = (u32, ByronHash, ByronHash);
pub type ValidatorScript = (u16, ByteVec);
pub type RedeemerScript = (u16, ByteVec);
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Twit {
// [0, #6.24(bytes .cbor ([pubkey, signature]))]
PkWitness(CborWrap<(PubKey, Signature)>),
@ -841,7 +841,6 @@ pub struct BlockHead {
pub extra_data: BlockHeadEx,
}
// [tx, [* twit]]
#[derive(Debug, Encode, Decode)]
pub struct TxPayload {
#[n(0)]
@ -851,6 +850,15 @@ pub struct TxPayload {
pub witness: MaybeIndefArray<Twit>,
}
#[derive(Debug, Encode, Decode, Clone)]
pub struct MintedTxPayload<'b> {
#[b(0)]
pub transaction: KeepRaw<'b, Tx>,
#[n(1)]
pub witness: MaybeIndefArray<Twit>,
}
#[derive(Encode, Decode, Debug)]
pub struct BlockBody {
#[n(0)]
@ -866,6 +874,21 @@ pub struct BlockBody {
pub upd_payload: Up,
}
#[derive(Encode, Decode, Debug)]
pub struct MintedBlockBody<'b> {
#[b(0)]
pub tx_payload: MaybeIndefArray<MintedTxPayload<'b>>,
#[b(1)]
pub ssc_payload: Ssc,
#[b(2)]
pub dlg_payload: MaybeIndefArray<Dlg>,
#[b(3)]
pub upd_payload: Up,
}
// Epoch Boundary Blocks
#[derive(Encode, Decode, Debug)]
@ -896,7 +919,7 @@ pub struct EbbHead {
}
#[derive(Encode, Decode, Debug)]
pub struct MainBlock {
pub struct Block {
#[n(0)]
pub header: BlockHead,
@ -908,12 +931,12 @@ pub struct MainBlock {
}
#[derive(Encode, Decode, Debug)]
pub struct MintedMainBlock<'b> {
pub struct MintedBlock<'b> {
#[b(0)]
pub header: KeepRaw<'b, BlockHead>,
#[n(1)]
pub body: BlockBody,
#[b(1)]
pub body: MintedBlockBody<'b>,
#[n(2)]
pub extra: MaybeIndefArray<Attributes>,
@ -933,7 +956,7 @@ pub struct EbBlock {
#[cfg(test)]
mod tests {
use super::{BlockHead, EbBlock, MintedMainBlock};
use super::{BlockHead, EbBlock, MintedBlock};
use pallas_codec::minicbor::{self, to_vec};
#[test]
@ -958,7 +981,7 @@ mod tests {
#[test]
fn main_block_isomorphic_decoding_encoding() {
type BlockWrapper<'b> = (u16, MintedMainBlock<'b>);
type BlockWrapper<'b> = (u16, MintedBlock<'b>);
let test_blocks = vec![
//include_str!("../../../test_data/genesis.block"),

View file

@ -24,9 +24,9 @@ impl EbbHead {
mod tests {
use pallas_codec::minicbor;
use crate::byron::MainBlock;
use crate::byron::Block;
type BlockWrapper = (u16, MainBlock);
type BlockWrapper = (u16, Block);
#[test]
fn knwon_slot_matches() {

View file

@ -23,15 +23,6 @@ where
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Era {
Byron,
Shelley,
Allegra, // time-locks
Mary, // multi-assets
Alonzo, // smart-contracts
}
#[cfg(feature = "json")]
pub trait ToCanonicalJson {
fn to_json(&self) -> serde_json::Value;

View file

@ -4,6 +4,5 @@ mod framework;
pub mod alonzo;
pub mod byron;
pub mod probing;
pub use framework::*;

View file

@ -1,101 +0,0 @@
//! Heuristics for detecting cbor content without 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
// payload and infers with a certain degree of confidence the type of Cardano
// structure within.
pub fn probe_block_cbor_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),
_ => 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 = probe_block_cbor_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 = probe_block_cbor_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 = probe_block_cbor_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 = probe_block_cbor_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 = probe_block_cbor_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 = probe_block_cbor_era(bytes.as_slice());
assert!(matches!(inference, Outcome::Matched(Era::Alonzo)));
}
}