feat(traverse): Introduce more new accessor methods (#153)

This commit is contained in:
Santiago Carmuega 2022-07-17 16:40:49 -03:00 committed by GitHub
parent 33c6152f19
commit c377a6aaec
11 changed files with 182 additions and 51 deletions

View file

@ -282,6 +282,8 @@ pub type RewardAccount = ByteVec;
pub type Withdrawals = KeyValuePairs<RewardAccount, Coin>; pub type Withdrawals = KeyValuePairs<RewardAccount, Coin>;
pub type RequiredSigners = MaybeIndefArray<AddrKeyhash>;
pub type Port = u32; pub type Port = u32;
pub type IPv4 = ByteVec; pub type IPv4 = ByteVec;
pub type IPv6 = ByteVec; pub type IPv6 = ByteVec;
@ -742,7 +744,7 @@ pub struct TransactionBody {
pub collateral: Option<MaybeIndefArray<TransactionInput>>, pub collateral: Option<MaybeIndefArray<TransactionInput>>,
#[n(14)] #[n(14)]
pub required_signers: Option<MaybeIndefArray<AddrKeyhash>>, pub required_signers: Option<RequiredSigners>,
#[n(15)] #[n(15)]
pub network_id: Option<NetworkId>, pub network_id: Option<NetworkId>,

View file

@ -113,6 +113,10 @@ pub use crate::alonzo::MoveInstantaneousReward;
pub use crate::alonzo::RewardAccount; pub use crate::alonzo::RewardAccount;
pub type Withdrawals = KeyValuePairs<RewardAccount, Coin>;
pub type RequiredSigners = MaybeIndefArray<AddrKeyhash>;
pub use crate::alonzo::Port; pub use crate::alonzo::Port;
pub use crate::alonzo::IPv4; pub use crate::alonzo::IPv4;

View file

@ -693,13 +693,15 @@ pub struct BlockHead {
pub extra_data: BlockHeadEx, pub extra_data: BlockHeadEx,
} }
pub type Witnesses = MaybeIndefArray<Twit>;
#[derive(Debug, Encode, Decode)] #[derive(Debug, Encode, Decode)]
pub struct TxPayload { pub struct TxPayload {
#[n(0)] #[n(0)]
pub transaction: Tx, pub transaction: Tx,
#[n(1)] #[n(1)]
pub witness: MaybeIndefArray<Twit>, pub witness: Witnesses,
} }
#[derive(Debug, Encode, Decode, Clone)] #[derive(Debug, Encode, Decode, Clone)]
@ -708,7 +710,7 @@ pub struct MintedTxPayload<'b> {
pub transaction: KeepRaw<'b, Tx>, pub transaction: KeepRaw<'b, Tx>,
#[n(1)] #[n(1)]
pub witness: MaybeIndefArray<Twit>, pub witness: KeepRaw<'b, Witnesses>,
} }
#[derive(Encode, Decode, Debug)] #[derive(Encode, Decode, Debug)]

View file

@ -13,61 +13,49 @@ impl<'b> MultiEraBlock<'b> {
let (_, block): BlockWrapper<byron::MintedEbBlock> = let (_, block): BlockWrapper<byron::MintedEbBlock> =
minicbor::decode(cbor).map_err(Error::invalid_cbor)?; minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
Ok(Self::EpochBoundary(Box::new(Cow::Owned(block)))) Ok(Self::EpochBoundary(Box::new(block)))
} }
pub fn decode_byron(cbor: &'b [u8]) -> Result<Self, Error> { pub fn decode_byron(cbor: &'b [u8]) -> Result<Self, Error> {
let (_, block): BlockWrapper<byron::MintedBlock> = let (_, block): BlockWrapper<byron::MintedBlock> =
minicbor::decode(cbor).map_err(Error::invalid_cbor)?; minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
Ok(Self::Byron(Box::new(Cow::Owned(block)))) Ok(Self::Byron(Box::new(block)))
} }
pub fn decode_shelley(cbor: &'b [u8]) -> Result<Self, Error> { pub fn decode_shelley(cbor: &'b [u8]) -> Result<Self, Error> {
let (_, block): BlockWrapper<alonzo::MintedBlock> = let (_, block): BlockWrapper<alonzo::MintedBlock> =
minicbor::decode(cbor).map_err(Error::invalid_cbor)?; minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
Ok(Self::AlonzoCompatible( Ok(Self::AlonzoCompatible(Box::new(block), Era::Shelley))
Box::new(Cow::Owned(block)),
Era::Shelley,
))
} }
pub fn decode_allegra(cbor: &'b [u8]) -> Result<Self, Error> { pub fn decode_allegra(cbor: &'b [u8]) -> Result<Self, Error> {
let (_, block): BlockWrapper<alonzo::MintedBlock> = let (_, block): BlockWrapper<alonzo::MintedBlock> =
minicbor::decode(cbor).map_err(Error::invalid_cbor)?; minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
Ok(Self::AlonzoCompatible( Ok(Self::AlonzoCompatible(Box::new(block), Era::Allegra))
Box::new(Cow::Owned(block)),
Era::Allegra,
))
} }
pub fn decode_mary(cbor: &'b [u8]) -> Result<Self, Error> { pub fn decode_mary(cbor: &'b [u8]) -> Result<Self, Error> {
let (_, block): BlockWrapper<alonzo::MintedBlock> = let (_, block): BlockWrapper<alonzo::MintedBlock> =
minicbor::decode(cbor).map_err(Error::invalid_cbor)?; minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
Ok(Self::AlonzoCompatible( Ok(Self::AlonzoCompatible(Box::new(block), Era::Mary))
Box::new(Cow::Owned(block)),
Era::Mary,
))
} }
pub fn decode_alonzo(cbor: &'b [u8]) -> Result<Self, Error> { pub fn decode_alonzo(cbor: &'b [u8]) -> Result<Self, Error> {
let (_, block): BlockWrapper<alonzo::MintedBlock> = let (_, block): BlockWrapper<alonzo::MintedBlock> =
minicbor::decode(cbor).map_err(Error::invalid_cbor)?; minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
Ok(Self::AlonzoCompatible( Ok(Self::AlonzoCompatible(Box::new(block), Era::Alonzo))
Box::new(Cow::Owned(block)),
Era::Alonzo,
))
} }
pub fn decode_babbage(cbor: &'b [u8]) -> Result<Self, Error> { pub fn decode_babbage(cbor: &'b [u8]) -> Result<Self, Error> {
let (_, block): BlockWrapper<babbage::MintedBlock> = let (_, block): BlockWrapper<babbage::MintedBlock> =
minicbor::decode(cbor).map_err(Error::invalid_cbor)?; minicbor::decode(cbor).map_err(Error::invalid_cbor)?;
Ok(Self::Babbage(Box::new(Cow::Owned(block)))) Ok(Self::Babbage(Box::new(block)))
} }
pub fn decode(cbor: &'b [u8]) -> Result<MultiEraBlock<'b>, Error> { pub fn decode(cbor: &'b [u8]) -> Result<MultiEraBlock<'b>, Error> {

View file

@ -1,8 +1,9 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::ops::Deref;
use pallas_codec::minicbor; use pallas_codec::minicbor;
use pallas_crypto::hash::{Hash, Hasher}; use pallas_crypto::hash::{Hash, Hasher};
use pallas_primitives::ToHash; use pallas_primitives::{alonzo, babbage, byron, ToHash};
use crate::Era::Byron; use crate::Era::Byron;
use crate::{Error, MultiEraHeader}; use crate::{Error, MultiEraHeader};
@ -97,4 +98,32 @@ impl<'b> MultiEraHeader<'b> {
MultiEraHeader::Byron(_) => Err(Error::InvalidEra(Byron)), MultiEraHeader::Byron(_) => Err(Error::InvalidEra(Byron)),
} }
} }
pub fn as_eb(&self) -> Option<&byron::EbbHead> {
match self {
MultiEraHeader::EpochBoundary(x) => Some(x.deref().deref()),
_ => None,
}
}
pub fn as_byron(&self) -> Option<&byron::BlockHead> {
match self {
MultiEraHeader::Byron(x) => Some(x.deref().deref()),
_ => None,
}
}
pub fn as_alonzo(&self) -> Option<&alonzo::Header> {
match self {
MultiEraHeader::AlonzoCompatible(x) => Some(x.deref().deref()),
_ => None,
}
}
pub fn as_babbage(&self) -> Option<&babbage::Header> {
match self {
MultiEraHeader::Babbage(x) => Some(x.deref().deref()),
_ => None,
}
}
} }

View file

@ -18,9 +18,11 @@ pub mod meta;
pub mod mint; pub mod mint;
pub mod output; pub mod output;
pub mod probe; pub mod probe;
pub mod signers;
mod support; mod support;
pub mod tx; pub mod tx;
pub mod withdrawals; pub mod withdrawals;
pub mod witnesses;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[non_exhaustive] #[non_exhaustive]
@ -56,10 +58,10 @@ pub enum MultiEraHeader<'b> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub enum MultiEraBlock<'b> { pub enum MultiEraBlock<'b> {
EpochBoundary(Box<Cow<'b, byron::MintedEbBlock<'b>>>), EpochBoundary(Box<byron::MintedEbBlock<'b>>),
AlonzoCompatible(Box<Cow<'b, alonzo::MintedBlock<'b>>>, Era), AlonzoCompatible(Box<alonzo::MintedBlock<'b>>, Era),
Babbage(Box<Cow<'b, babbage::MintedBlock<'b>>>), Babbage(Box<babbage::MintedBlock<'b>>),
Byron(Box<Cow<'b, byron::MintedBlock<'b>>>), Byron(Box<byron::MintedBlock<'b>>),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -97,7 +99,7 @@ pub enum MultiEraCert<'b> {
pub enum MultiEraMeta<'b> { pub enum MultiEraMeta<'b> {
NotApplicable, NotApplicable,
Empty, Empty,
AlonzoCompatible(Cow<'b, alonzo::Metadata>), AlonzoCompatible(&'b alonzo::Metadata),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -105,7 +107,7 @@ pub enum MultiEraMeta<'b> {
pub enum MultiEraMint<'b> { pub enum MultiEraMint<'b> {
NotApplicable, NotApplicable,
Empty, Empty,
AlonzoCompatible(Cow<'b, alonzo::Mint>), AlonzoCompatible(&'b alonzo::Mint),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -113,7 +115,23 @@ pub enum MultiEraMint<'b> {
pub enum MultiEraWithdrawals<'b> { pub enum MultiEraWithdrawals<'b> {
NotApplicable, NotApplicable,
Empty, Empty,
AlonzoCompatible(Cow<'b, alonzo::Withdrawals>), AlonzoCompatible(&'b alonzo::Withdrawals),
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum MultiEraSigners<'b> {
NotApplicable,
Empty,
AlonzoCompatible(&'b alonzo::RequiredSigners),
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum MultiEraWitnesses<'b> {
Byron(&'b KeepRaw<'b, byron::Witnesses>),
AlonzoCompatible(&'b KeepRaw<'b, alonzo::TransactionWitnessSet>),
Babbage(&'b KeepRaw<'b, babbage::TransactionWitnessSet>),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -34,12 +34,9 @@ impl<'b> MultiEraMeta<'b> {
T: FromIterator<(&'a alonzo::MetadatumLabel, &'a alonzo::Metadatum)>, T: FromIterator<(&'a alonzo::MetadatumLabel, &'a alonzo::Metadatum)>,
{ {
match self { match self {
MultiEraMeta::NotApplicable => T::from_iter(std::iter::empty()), MultiEraMeta::NotApplicable => std::iter::empty().collect(),
MultiEraMeta::Empty => T::from_iter(std::iter::empty()), MultiEraMeta::Empty => std::iter::empty().collect(),
MultiEraMeta::AlonzoCompatible(x) => { MultiEraMeta::AlonzoCompatible(x) => x.iter().map(|(k, v)| (k, v)).collect(),
let iter = x.iter().map(|(k, v)| (k, v));
T::from_iter(iter)
}
} }
} }
} }

View file

@ -0,0 +1,37 @@
use pallas_crypto::hash::Hash;
use pallas_primitives::alonzo;
use crate::MultiEraSigners;
impl Default for MultiEraSigners<'_> {
fn default() -> Self {
Self::Empty
}
}
impl<'b> MultiEraSigners<'b> {
pub fn as_alonzo(&self) -> Option<&alonzo::RequiredSigners> {
match self {
Self::AlonzoCompatible(x) => Some(x),
_ => None,
}
}
pub fn is_empty(&self) -> bool {
match self {
Self::AlonzoCompatible(x) => x.is_empty(),
_ => true,
}
}
pub fn collect<'a, T>(&'a self) -> T
where
T: FromIterator<&'a Hash<28>>,
{
match self {
Self::NotApplicable => std::iter::empty().collect(),
Self::Empty => std::iter::empty().collect(),
Self::AlonzoCompatible(x) => x.iter().collect(),
}
}
}

View file

@ -7,8 +7,8 @@ use pallas_primitives::{
use std::{borrow::Cow, ops::Deref}; use std::{borrow::Cow, ops::Deref};
use crate::{ use crate::{
Era, MultiEraCert, MultiEraInput, MultiEraMeta, MultiEraMint, MultiEraOutput, MultiEraTx, Era, MultiEraCert, MultiEraInput, MultiEraMeta, MultiEraMint, MultiEraOutput, MultiEraSigners,
MultiEraWithdrawals, MultiEraTx, MultiEraWithdrawals, MultiEraWitnesses,
}; };
impl<'b> MultiEraTx<'b> { impl<'b> MultiEraTx<'b> {
@ -160,13 +160,13 @@ impl<'b> MultiEraTx<'b> {
.transaction_body .transaction_body
.mint .mint
.as_ref() .as_ref()
.map(|c| MultiEraMint::AlonzoCompatible(Cow::Borrowed(c))) .map(MultiEraMint::AlonzoCompatible)
.unwrap_or_default(), .unwrap_or_default(),
MultiEraTx::Babbage(x) => x MultiEraTx::Babbage(x) => x
.transaction_body .transaction_body
.mint .mint
.as_ref() .as_ref()
.map(|c| MultiEraMint::AlonzoCompatible(Cow::Borrowed(c))) .map(MultiEraMint::AlonzoCompatible)
.unwrap_or_default(), .unwrap_or_default(),
MultiEraTx::Byron(_) => MultiEraMint::NotApplicable, MultiEraTx::Byron(_) => MultiEraMint::NotApplicable,
} }
@ -192,14 +192,14 @@ impl<'b> MultiEraTx<'b> {
} }
} }
pub fn withdrawals(&'b self) -> MultiEraWithdrawals<'b> { pub fn withdrawals(&self) -> MultiEraWithdrawals {
match self { match self {
MultiEraTx::AlonzoCompatible(x, _) => match &x.transaction_body.withdrawals { MultiEraTx::AlonzoCompatible(x, _) => match &x.transaction_body.withdrawals {
Some(x) => MultiEraWithdrawals::AlonzoCompatible(Cow::Borrowed(x)), Some(x) => MultiEraWithdrawals::AlonzoCompatible(x),
None => MultiEraWithdrawals::Empty, None => MultiEraWithdrawals::Empty,
}, },
MultiEraTx::Babbage(x) => match &x.transaction_body.withdrawals { MultiEraTx::Babbage(x) => match &x.transaction_body.withdrawals {
Some(x) => MultiEraWithdrawals::AlonzoCompatible(Cow::Borrowed(x)), Some(x) => MultiEraWithdrawals::AlonzoCompatible(x),
None => MultiEraWithdrawals::Empty, None => MultiEraWithdrawals::Empty,
}, },
MultiEraTx::Byron(_) => MultiEraWithdrawals::NotApplicable, MultiEraTx::Byron(_) => MultiEraWithdrawals::NotApplicable,
@ -214,23 +214,51 @@ impl<'b> MultiEraTx<'b> {
} }
} }
pub fn metadata(&'b self) -> MultiEraMeta<'b> { pub fn metadata(&self) -> MultiEraMeta {
match self.aux_data() { match self.aux_data() {
Some(x) => match x.deref() { Some(x) => match x.deref() {
AuxiliaryData::Shelley(x) => MultiEraMeta::AlonzoCompatible(Cow::Borrowed(x)), AuxiliaryData::Shelley(x) => MultiEraMeta::AlonzoCompatible(x),
AuxiliaryData::ShelleyMa(x) => { AuxiliaryData::ShelleyMa(x) => {
MultiEraMeta::AlonzoCompatible(Cow::Borrowed(&x.transaction_metadata)) MultiEraMeta::AlonzoCompatible(&x.transaction_metadata)
} }
AuxiliaryData::PostAlonzo(x) => x AuxiliaryData::PostAlonzo(x) => x
.metadata .metadata
.as_ref() .as_ref()
.map(|x| MultiEraMeta::AlonzoCompatible(Cow::Borrowed(x))) .map(MultiEraMeta::AlonzoCompatible)
.unwrap_or_default(), .unwrap_or_default(),
}, },
None => MultiEraMeta::Empty, None => MultiEraMeta::Empty,
} }
} }
pub fn required_signers(&self) -> MultiEraSigners {
match self {
MultiEraTx::AlonzoCompatible(x, _) => x
.transaction_body
.required_signers
.as_ref()
.map(MultiEraSigners::AlonzoCompatible)
.unwrap_or_default(),
MultiEraTx::Babbage(x) => x
.transaction_body
.required_signers
.as_ref()
.map(MultiEraSigners::AlonzoCompatible)
.unwrap_or_default(),
MultiEraTx::Byron(_) => MultiEraSigners::NotApplicable,
}
}
pub fn witnesses(&self) -> MultiEraWitnesses {
match self {
MultiEraTx::AlonzoCompatible(x, _) => {
MultiEraWitnesses::AlonzoCompatible(&x.transaction_witness_set)
}
MultiEraTx::Babbage(x) => MultiEraWitnesses::Babbage(&x.transaction_witness_set),
MultiEraTx::Byron(x) => MultiEraWitnesses::Byron(&x.witness),
}
}
pub fn is_valid(&self) -> bool { pub fn is_valid(&self) -> bool {
match self { match self {
MultiEraTx::AlonzoCompatible(x, _) => x.success, MultiEraTx::AlonzoCompatible(x, _) => x.success,

View file

@ -22,11 +22,10 @@ impl<'b> MultiEraWithdrawals<'b> {
T: FromIterator<(&'a [u8], u64)>, T: FromIterator<(&'a [u8], u64)>,
{ {
match self { match self {
MultiEraWithdrawals::NotApplicable => T::from_iter(std::iter::empty()), MultiEraWithdrawals::NotApplicable => std::iter::empty().collect(),
MultiEraWithdrawals::Empty => T::from_iter(std::iter::empty()), MultiEraWithdrawals::Empty => std::iter::empty().collect(),
MultiEraWithdrawals::AlonzoCompatible(x) => { MultiEraWithdrawals::AlonzoCompatible(x) => {
let iter = x.iter().map(|(k, v)| (k.as_slice(), v.into())); x.iter().map(|(k, v)| (k.as_slice(), v.into())).collect()
T::from_iter(iter)
} }
} }
} }

View file

@ -0,0 +1,27 @@
use pallas_primitives::{alonzo, babbage};
use crate::MultiEraWitnesses;
impl<'b> MultiEraWitnesses<'b> {
pub fn as_alonzo(&self) -> Option<&alonzo::TransactionWitnessSet> {
match self {
Self::AlonzoCompatible(x) => Some(x),
_ => None,
}
}
pub fn as_babbage(&self) -> Option<&babbage::TransactionWitnessSet> {
match self {
Self::Babbage(x) => Some(x),
_ => None,
}
}
pub fn cbor(&self) -> &[u8] {
match self {
MultiEraWitnesses::AlonzoCompatible(x) => x.raw_cbor(),
MultiEraWitnesses::Babbage(x) => x.raw_cbor(),
MultiEraWitnesses::Byron(x) => x.raw_cbor(),
}
}
}