diff --git a/pallas-primitives/src/alonzo/model.rs b/pallas-primitives/src/alonzo/model.rs index d3103f1..0e30ba6 100644 --- a/pallas-primitives/src/alonzo/model.rs +++ b/pallas-primitives/src/alonzo/model.rs @@ -623,7 +623,9 @@ impl minicbor::encode::Encode for Certificate { } } -#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +#[derive( + Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, +)] #[cbor(index_only)] pub enum NetworkId { #[n(0)] diff --git a/pallas-traverse/src/assets.rs b/pallas-traverse/src/assets.rs index 28a29c1..006b106 100644 --- a/pallas-traverse/src/assets.rs +++ b/pallas-traverse/src/assets.rs @@ -26,13 +26,20 @@ impl<'b> MultiEraAsset<'b> { .collect::>() } - pub fn policy_id(&self) -> Option<&Hash<28>> { + pub fn policy(&self) -> Option<&Hash<28>> { match self { Self::AlonzoCompatible(x, ..) => Some(*x), Self::Lovelace(_) => None, } } + pub fn name(&self) -> Option<&[u8]> { + match self { + Self::AlonzoCompatible(_, n, _) => Some(n.as_ref()), + Self::Lovelace(_) => None, + } + } + pub fn coin(&self) -> i64 { match self { Self::AlonzoCompatible(_, _, x) => *x, diff --git a/pallas-traverse/src/header.rs b/pallas-traverse/src/header.rs index 9c3857d..ac27994 100644 --- a/pallas-traverse/src/header.rs +++ b/pallas-traverse/src/header.rs @@ -77,6 +77,33 @@ impl<'b> MultiEraHeader<'b> { } } + pub fn previous_hash(&self) -> Option> { + match self { + MultiEraHeader::AlonzoCompatible(x) => x.header_body.prev_hash, + MultiEraHeader::Babbage(x) => x.header_body.prev_hash, + MultiEraHeader::EpochBoundary(x) => Some(x.prev_block), + MultiEraHeader::Byron(x) => Some(x.prev_block), + } + } + + pub fn vrf_vkey(&self) -> Option<&[u8]> { + match self { + MultiEraHeader::AlonzoCompatible(x) => Some(x.header_body.vrf_vkey.as_ref()), + MultiEraHeader::Babbage(x) => Some(x.header_body.vrf_vkey.as_ref()), + MultiEraHeader::EpochBoundary(_) => None, + MultiEraHeader::Byron(_) => None, + } + } + + pub fn issuer_vkey(&self) -> Option<&[u8]> { + match self { + MultiEraHeader::AlonzoCompatible(x) => Some(x.header_body.issuer_vkey.as_ref()), + MultiEraHeader::Babbage(x) => Some(x.header_body.issuer_vkey.as_ref()), + MultiEraHeader::EpochBoundary(_) => None, + MultiEraHeader::Byron(_) => None, + } + } + pub fn leader_vrf_output(&self) -> Result, Error> { match self { MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(Era::Byron)), diff --git a/pallas-traverse/src/lib.rs b/pallas-traverse/src/lib.rs index 31d6594..5744144 100644 --- a/pallas-traverse/src/lib.rs +++ b/pallas-traverse/src/lib.rs @@ -24,6 +24,7 @@ pub mod meta; pub mod output; pub mod probe; pub mod signers; +pub mod size; pub mod time; pub mod tx; pub mod withdrawals; diff --git a/pallas-traverse/src/size.rs b/pallas-traverse/src/size.rs new file mode 100644 index 0000000..5f54236 --- /dev/null +++ b/pallas-traverse/src/size.rs @@ -0,0 +1,52 @@ +use pallas_codec::utils::Nullable; + +use crate::{MultiEraBlock, MultiEraTx}; + +impl<'b> MultiEraTx<'b> { + fn aux_data_size(&self) -> usize { + match self { + MultiEraTx::AlonzoCompatible(x, _) => match &x.auxiliary_data { + Nullable::Some(x) => x.raw_cbor().len(), + _ => 2, + }, + MultiEraTx::Babbage(x) => match &x.auxiliary_data { + Nullable::Some(x) => x.raw_cbor().len(), + _ => 2, + }, + MultiEraTx::Byron(_) => 0, + } + } + + fn body_size(&self) -> usize { + match self { + MultiEraTx::AlonzoCompatible(x, _) => x.transaction_body.raw_cbor().len(), + MultiEraTx::Babbage(x) => x.transaction_body.raw_cbor().len(), + MultiEraTx::Byron(x) => x.transaction.raw_cbor().len(), + } + } + + fn witness_set_size(&self) -> usize { + match self { + MultiEraTx::AlonzoCompatible(x, _) => x.transaction_witness_set.raw_cbor().len(), + MultiEraTx::Babbage(x) => x.transaction_witness_set.raw_cbor().len(), + MultiEraTx::Byron(x) => x.witness.raw_cbor().len(), + } + } + + pub fn size(&self) -> usize { + self.body_size() + self.witness_set_size() + self.aux_data_size() + } +} + +impl<'b> MultiEraBlock<'b> { + pub fn body_size(&self) -> Option { + match self { + MultiEraBlock::AlonzoCompatible(x, _) => { + Some(x.header.header_body.block_body_size as usize) + } + MultiEraBlock::Babbage(x) => Some(x.header.header_body.block_body_size as usize), + MultiEraBlock::EpochBoundary(_) => None, + MultiEraBlock::Byron(_) => None, + } + } +} diff --git a/pallas-traverse/src/tx.rs b/pallas-traverse/src/tx.rs index f2915ca..3965c25 100644 --- a/pallas-traverse/src/tx.rs +++ b/pallas-traverse/src/tx.rs @@ -2,7 +2,11 @@ use std::{borrow::Cow, ops::Deref}; use pallas_codec::{minicbor, utils::KeepRaw}; use pallas_crypto::hash::Hash; -use pallas_primitives::{alonzo, babbage, byron}; +use pallas_primitives::{ + alonzo, + babbage::{self, NetworkId}, + byron, +}; use crate::{ Era, MultiEraAsset, MultiEraCert, MultiEraInput, MultiEraMeta, MultiEraOutput, MultiEraSigners, @@ -305,6 +309,14 @@ impl<'b> MultiEraTx<'b> { } } + pub fn ttl(&self) -> Option { + match self { + MultiEraTx::AlonzoCompatible(x, _) => x.transaction_body.ttl, + MultiEraTx::Babbage(x) => x.transaction_body.ttl, + MultiEraTx::Byron(_) => None, + } + } + /// Returns the fee or attempts to compute it /// /// If the fee is available as part of the tx data (post-byron), this @@ -370,6 +382,22 @@ impl<'b> MultiEraTx<'b> { } } + pub fn validity_start(&self) -> Option { + match self { + MultiEraTx::AlonzoCompatible(x, _) => x.transaction_body.validity_interval_start, + MultiEraTx::Babbage(x) => x.transaction_body.validity_interval_start, + MultiEraTx::Byron(_) => None, + } + } + + pub fn network_id(&self) -> Option { + match self { + MultiEraTx::AlonzoCompatible(x, _) => x.transaction_body.network_id, + MultiEraTx::Babbage(x) => x.transaction_body.network_id, + MultiEraTx::Byron(_) => None, + } + } + pub fn is_valid(&self) -> bool { match self { MultiEraTx::AlonzoCompatible(x, _) => x.success, diff --git a/pallas-traverse/src/witnesses.rs b/pallas-traverse/src/witnesses.rs index 6f1dd1c..43ce2ac 100644 --- a/pallas-traverse/src/witnesses.rs +++ b/pallas-traverse/src/witnesses.rs @@ -7,114 +7,123 @@ use pallas_primitives::{ use crate::MultiEraTx; impl<'b> MultiEraTx<'b> { - pub fn vkey_witnesses(&self) -> Option<&[VKeyWitness]> { + pub fn vkey_witnesses(&self) -> &[VKeyWitness] { match self { Self::AlonzoCompatible(x, _) => x .transaction_witness_set .vkeywitness .as_ref() - .map(|x| x.as_ref()), + .map(|x| x.as_ref()) + .unwrap_or(&[]), Self::Babbage(x) => x .transaction_witness_set .vkeywitness .as_ref() - .map(|x| x.as_ref()), - _ => None, + .map(|x| x.as_ref()) + .unwrap_or(&[]), + _ => &[], } } - pub fn native_scripts(&self) -> Option<&[NativeScript]> { + pub fn native_scripts(&self) -> &[NativeScript] { match self { Self::AlonzoCompatible(x, _) => x .transaction_witness_set .native_script .as_ref() - .map(|x| x.as_ref()), + .map(|x| x.as_ref()) + .unwrap_or(&[]), Self::Babbage(x) => x .transaction_witness_set .native_script .as_ref() - .map(|x| x.as_ref()), - _ => None, + .map(|x| x.as_ref()) + .unwrap_or(&[]), + _ => &[], } } - pub fn bootstrap_witnesses(&self) -> Option<&[BootstrapWitness]> { + pub fn bootstrap_witnesses(&self) -> &[BootstrapWitness] { match self { Self::AlonzoCompatible(x, _) => x .transaction_witness_set .bootstrap_witness .as_ref() - .map(|x| x.as_ref()), + .map(|x| x.as_ref()) + .unwrap_or(&[]), Self::Babbage(x) => x .transaction_witness_set .bootstrap_witness .as_ref() - .map(|x| x.as_ref()), - _ => None, + .map(|x| x.as_ref()) + .unwrap_or(&[]), + _ => &[], } } - pub fn plutus_v1_scripts(&self) -> Vec<&alonzo::PlutusScript> { + pub fn plutus_v1_scripts(&self) -> &[alonzo::PlutusScript] { match self { Self::AlonzoCompatible(x, _) => x .transaction_witness_set .plutus_script - .iter() - .flatten() - .collect(), + .as_ref() + .map(|x| x.as_ref()) + .unwrap_or(&[]), Self::Babbage(x) => x .transaction_witness_set .plutus_v1_script - .iter() - .flatten() - .collect(), - _ => vec![], + .as_ref() + .map(|x| x.as_ref()) + .unwrap_or(&[]), + _ => &[], } } - pub fn plutus_data(&self) -> Vec<&KeepRaw<'b, PlutusData>> { + pub fn plutus_data(&self) -> &[KeepRaw<'b, PlutusData>] { match self { Self::AlonzoCompatible(x, _) => x .transaction_witness_set .plutus_data - .iter() - .flatten() - .collect(), + .as_ref() + .map(|x| x.as_ref()) + .unwrap_or(&[]), Self::Babbage(x) => x .transaction_witness_set .plutus_data - .iter() - .flatten() - .collect(), - _ => std::iter::empty().collect(), + .as_ref() + .map(|x| x.as_ref()) + .unwrap_or(&[]), + _ => &[], } } - pub fn redeemers(&self) -> Option<&[Redeemer]> { + pub fn redeemers(&self) -> &[Redeemer] { match self { Self::AlonzoCompatible(x, _) => x .transaction_witness_set .redeemer .as_ref() - .map(|x| x.as_ref()), + .map(|x| x.as_ref()) + .unwrap_or(&[]), Self::Babbage(x) => x .transaction_witness_set .redeemer .as_ref() - .map(|x| x.as_ref()), - _ => None, + .map(|x| x.as_ref()) + .unwrap_or(&[]), + _ => &[], } } - pub fn plutus_v2_scripts(&self) -> Option<&[PlutusV2Script]> { + pub fn plutus_v2_scripts(&self) -> &[PlutusV2Script] { match self { Self::Babbage(x) => x .transaction_witness_set .plutus_v2_script .as_ref() - .map(|x| x.as_ref()), - _ => None, + .map(|x| x.as_ref()) + .unwrap_or(&[]), + _ => &[], } } }