From 365fb3bb24cfa622e9abb3d46eda49a5f10469c9 Mon Sep 17 00:00:00 2001 From: Santiago Carmuega Date: Tue, 1 Oct 2024 09:34:10 -0300 Subject: [PATCH] feat(traverse): introduce MultiEraValue --- pallas-traverse/src/lib.rs | 9 +++++ pallas-traverse/src/output.rs | 59 ++++++++++++---------------- pallas-traverse/src/value.rs | 73 +++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 34 deletions(-) create mode 100644 pallas-traverse/src/value.rs diff --git a/pallas-traverse/src/lib.rs b/pallas-traverse/src/lib.rs index e18054ba..7a9c3ca2 100644 --- a/pallas-traverse/src/lib.rs +++ b/pallas-traverse/src/lib.rs @@ -31,6 +31,7 @@ pub mod size; pub mod time; pub mod tx; pub mod update; +pub mod value; pub mod withdrawals; pub mod witnesses; @@ -89,6 +90,14 @@ pub enum MultiEraTx<'b> { Conway(Box>>), } +#[derive(Debug, Clone)] +#[non_exhaustive] +pub enum MultiEraValue<'b> { + Byron(u64), + AlonzoCompatible(Cow<'b, alonzo::Value>), + Conway(Cow<'b, conway::Value>), +} + #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum MultiEraOutput<'b> { diff --git a/pallas-traverse/src/output.rs b/pallas-traverse/src/output.rs index 70d4ed57..92021882 100644 --- a/pallas-traverse/src/output.rs +++ b/pallas-traverse/src/output.rs @@ -4,7 +4,7 @@ use pallas_addresses::{Address, ByronAddress, Error as AddressError}; use pallas_codec::minicbor; use pallas_primitives::{alonzo, babbage, byron, conway}; -use crate::{Era, MultiEraOutput, MultiEraPolicyAssets}; +use crate::{Era, MultiEraOutput, MultiEraPolicyAssets, MultiEraValue}; impl<'b> MultiEraOutput<'b> { pub fn from_byron(output: &'b byron::TxOut) -> Self { @@ -23,7 +23,7 @@ impl<'b> MultiEraOutput<'b> { Self::Conway(Box::new(Cow::Borrowed(output))) } - pub fn datum(&self) -> Option { + pub fn datum(&self) -> Option { match self { MultiEraOutput::AlonzoCompatible(x, _) => { x.datum_hash.map(babbage::MintedDatumOption::Hash) @@ -160,46 +160,37 @@ impl<'b> MultiEraOutput<'b> { } } - /// The amount of ADA asset expressed in Lovelace unit - /// - /// The value returned provides the amount of the ADA in a particular - /// output. The value is expressed in 'lovelace' (1 ADA = 1,000,000 - /// lovelace). - pub fn lovelace_amount(&self) -> u64 { + pub fn value(&self) -> MultiEraValue<'_> { match self { - MultiEraOutput::AlonzoCompatible(x, _) => match x.amount { - alonzo::Value::Coin(c) => c, - alonzo::Value::Multiasset(c, _) => c, - }, + MultiEraOutput::Byron(x) => MultiEraValue::Byron(x.amount), + MultiEraOutput::AlonzoCompatible(x, _) => { + MultiEraValue::AlonzoCompatible(Cow::Borrowed(&x.amount)) + } MultiEraOutput::Babbage(x) => match x.deref().deref() { - babbage::MintedTransactionOutput::Legacy(x) => match x.amount { - babbage::Value::Coin(c) => c, - babbage::Value::Multiasset(c, _) => c, - }, - babbage::MintedTransactionOutput::PostAlonzo(x) => match x.value { - babbage::Value::Coin(c) => c, - babbage::Value::Multiasset(c, _) => c, - }, + babbage::MintedTransactionOutput::Legacy(x) => { + MultiEraValue::AlonzoCompatible(Cow::Borrowed(&x.amount)) + } + babbage::MintedTransactionOutput::PostAlonzo(x) => { + MultiEraValue::AlonzoCompatible(Cow::Borrowed(&x.value)) + } }, - MultiEraOutput::Byron(x) => x.amount, MultiEraOutput::Conway(x) => match x.deref().deref() { - conway::MintedTransactionOutput::Legacy(x) => match x.amount { - babbage::Value::Coin(c) => c, - babbage::Value::Multiasset(c, _) => c, - }, - conway::MintedTransactionOutput::PostAlonzo(x) => match x.value { - conway::Value::Coin(c) => c, - conway::Value::Multiasset(c, _) => c, - }, + conway::MintedTransactionOutput::Legacy(x) => { + MultiEraValue::AlonzoCompatible(Cow::Borrowed(&x.amount)) + } + conway::MintedTransactionOutput::PostAlonzo(x) => { + MultiEraValue::Conway(Cow::Borrowed(&x.value)) + } }, } } - /// List of native assets in the output - /// - /// Returns a list of Asset structs where each one represent a native asset - /// present in the output of the tx. ADA assets are not included in this - /// list. + #[deprecated(note = "Use `value().coin()` instead")] + pub fn lovelace_amount(&self) -> u64 { + self.value().coin() + } + + #[deprecated(note = "Use `value().assets()` instead")] pub fn non_ada_assets(&self) -> Vec { match self { MultiEraOutput::AlonzoCompatible(x, _) => match &x.amount { diff --git a/pallas-traverse/src/value.rs b/pallas-traverse/src/value.rs new file mode 100644 index 00000000..7c0342c4 --- /dev/null +++ b/pallas-traverse/src/value.rs @@ -0,0 +1,73 @@ +use std::ops::Deref; + +use pallas_primitives::{alonzo, conway}; + +use crate::{MultiEraPolicyAssets, MultiEraValue}; + +impl MultiEraValue<'_> { + pub fn into_alonzo(&self) -> alonzo::Value { + match self { + Self::Byron(x) => alonzo::Value::Coin(*x), + Self::AlonzoCompatible(x) => x.deref().clone(), + Self::Conway(x) => match x.deref() { + conway::Value::Coin(x) => alonzo::Value::Coin(*x), + conway::Value::Multiasset(x, assets) => { + let coin = *x; + let assets = assets + .iter() + .map(|(k, v)| { + let v = v.iter().map(|(k, v)| (k.clone(), v.into())).collect(); + (*k, v) + }) + .collect(); + + alonzo::Value::Multiasset(coin, assets) + } + }, + } + } + + /// The amount of ADA asset expressed in Lovelace unit + /// + /// The value returned provides the amount of the ADA in a particular + /// output. The value is expressed in 'lovelace' (1 ADA = 1,000,000 + /// lovelace). + pub fn coin(&self) -> u64 { + match self { + Self::Byron(x) => *x, + Self::AlonzoCompatible(x) => match x.deref() { + alonzo::Value::Coin(c) => *c, + alonzo::Value::Multiasset(c, _) => *c, + }, + Self::Conway(x) => match x.deref() { + conway::Value::Coin(c) => *c, + conway::Value::Multiasset(c, _) => *c, + }, + } + } + + /// List of native assets in the output + /// + /// Returns a list of Asset structs where each one represent a native asset + /// present in the output of the tx. ADA assets are not included in this + /// list. + pub fn assets(&self) -> Vec> { + match self { + Self::Byron(_) => vec![], + Self::AlonzoCompatible(x) => match x.deref() { + alonzo::Value::Coin(_) => vec![], + alonzo::Value::Multiasset(_, x) => x + .iter() + .map(|(k, v)| MultiEraPolicyAssets::AlonzoCompatibleOutput(k, v)) + .collect(), + }, + Self::Conway(x) => match x.deref() { + conway::Value::Coin(_) => vec![], + conway::Value::Multiasset(_, x) => x + .iter() + .map(|(k, v)| MultiEraPolicyAssets::ConwayOutput(k, v)) + .collect(), + }, + } + } +}