diff --git a/pallas-codec/src/utils.rs b/pallas-codec/src/utils.rs index 8b2387f..2f626c5 100644 --- a/pallas-codec/src/utils.rs +++ b/pallas-codec/src/utils.rs @@ -98,8 +98,8 @@ where impl<'b, C, K, V> minicbor::decode::Decode<'b, C> for KeyValuePairs where - K: Encode + Decode<'b, C> + Clone, - V: Encode + Decode<'b, C> + Clone, + K: Decode<'b, C> + Clone, + V: Decode<'b, C> + Clone, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { let datatype = d.datatype()?; @@ -153,7 +153,7 @@ where } /// A struct that maintains a reference to whether a cbor array was indef or not -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum MaybeIndefArray { Def(Vec), Indef(Vec), @@ -290,6 +290,12 @@ where #[serde(transparent)] pub struct CborWrap(pub T); +impl CborWrap { + pub fn unwrap(self) -> T { + self.0 + } +} + impl<'b, C, T> minicbor::Decode<'b, C> for CborWrap where T: minicbor::Decode<'b, C>, diff --git a/pallas-primitives/src/babbage/model.rs b/pallas-primitives/src/babbage/model.rs index 94edb45..7e0fa45 100644 --- a/pallas-primitives/src/babbage/model.rs +++ b/pallas-primitives/src/babbage/model.rs @@ -230,14 +230,14 @@ pub struct Update { pub epoch: Epoch, } -#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] +#[derive(Encode, Decode, Debug, PartialEq, Clone)] #[cbor(map)] -pub struct TransactionBody { +pub struct PseudoTransactionBody { #[n(0)] pub inputs: Vec, #[n(1)] - pub outputs: Vec, + pub outputs: Vec, #[n(2)] pub fee: u64, @@ -276,7 +276,7 @@ pub struct TransactionBody { pub network_id: Option, #[n(16)] - pub collateral_return: Option, + pub collateral_return: Option, #[n(17)] pub total_collateral: Option, @@ -285,23 +285,51 @@ pub struct TransactionBody { pub reference_inputs: Option>, } -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] -pub enum TransactionOutput { - Legacy(LegacyTransactionOutput), - PostAlonzo(PostAlonzoTransactionOutput), +pub type TransactionBody = PseudoTransactionBody; + +pub type MintedTransactionBody<'a> = PseudoTransactionBody>; + +impl<'a> From> for TransactionBody { + fn from(value: MintedTransactionBody<'a>) -> Self { + Self { + inputs: value.inputs, + outputs: value.outputs.into_iter().map(|x| x.into()).collect(), + fee: value.fee, + ttl: value.ttl, + certificates: value.certificates, + withdrawals: value.withdrawals, + update: value.update, + auxiliary_data_hash: value.auxiliary_data_hash, + validity_interval_start: value.validity_interval_start, + mint: value.mint, + script_data_hash: value.script_data_hash, + collateral: value.collateral, + required_signers: value.required_signers, + network_id: value.network_id, + collateral_return: value.collateral_return.map(|x| x.into()), + total_collateral: value.total_collateral, + reference_inputs: value.reference_inputs, + } + } } -impl<'b, C> minicbor::Decode<'b, C> for TransactionOutput { - fn decode( - d: &mut minicbor::Decoder<'b>, - _ctx: &mut C, - ) -> Result { +#[derive(Debug, PartialEq, Clone)] +pub enum PseudoTransactionOutput { + Legacy(LegacyTransactionOutput), + PostAlonzo(T), +} + +impl<'b, C, T> minicbor::Decode<'b, C> for PseudoTransactionOutput +where + T: minicbor::Decode<'b, C>, +{ + fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { match d.datatype()? { minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => { - Ok(TransactionOutput::Legacy(d.decode()?)) + Ok(PseudoTransactionOutput::Legacy(d.decode_with(ctx)?)) } minicbor::data::Type::Map | minicbor::data::Type::MapIndef => { - Ok(TransactionOutput::PostAlonzo(d.decode()?)) + Ok(PseudoTransactionOutput::PostAlonzo(d.decode_with(ctx)?)) } _ => Err(minicbor::decode::Error::message( "invalid type for transaction output struct", @@ -310,22 +338,39 @@ impl<'b, C> minicbor::Decode<'b, C> for TransactionOutput { } } -impl minicbor::Encode for TransactionOutput { +impl minicbor::Encode for PseudoTransactionOutput +where + T: minicbor::Encode, +{ fn encode( &self, e: &mut minicbor::Encoder, ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { match self { - TransactionOutput::Legacy(x) => x.encode(e, ctx), - TransactionOutput::PostAlonzo(x) => x.encode(e, ctx), + PseudoTransactionOutput::Legacy(x) => x.encode(e, ctx), + PseudoTransactionOutput::PostAlonzo(x) => x.encode(e, ctx), } } } -#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)] +pub type TransactionOutput = PseudoTransactionOutput; + +pub type MintedTransactionOutput<'b> = + PseudoTransactionOutput>; + +impl<'b> From> for TransactionOutput { + fn from(value: MintedTransactionOutput<'b>) -> Self { + match value { + PseudoTransactionOutput::Legacy(x) => Self::Legacy(x), + PseudoTransactionOutput::PostAlonzo(x) => Self::PostAlonzo(x.into()), + } + } +} + +#[derive(Encode, Decode, Debug, PartialEq, Clone)] #[cbor(map)] -pub struct PostAlonzoTransactionOutput { +pub struct PseudoPostAlonzoTransactionOutput { #[n(0)] pub address: Bytes, @@ -333,12 +378,28 @@ pub struct PostAlonzoTransactionOutput { pub value: Value, #[n(2)] - pub datum_option: Option, + pub datum_option: Option, #[n(3)] pub script_ref: Option, } +pub type PostAlonzoTransactionOutput = PseudoPostAlonzoTransactionOutput; + +pub type MintedPostAlonzoTransactionOutput<'b> = + PseudoPostAlonzoTransactionOutput>; + +impl<'b> From> for PostAlonzoTransactionOutput { + fn from(value: MintedPostAlonzoTransactionOutput<'b>) -> Self { + Self { + address: value.address, + value: value.value, + datum_option: value.datum_option.map(|x| x.into()), + script_ref: value.script_ref, + } + } +} + pub use crate::alonzo::VKeyWitness; pub use crate::alonzo::NativeScript; @@ -455,25 +516,25 @@ pub struct PostAlonzoAuxiliaryData { pub type DatumHash = Hash<32>; -pub type Data = CborWrap; +//pub type Data = CborWrap; // datum_option = [ 0, $hash32 // 1, data ] -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub enum DatumOption { +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum PseudoDatumOption { Hash(Hash<32>), - Data(Data), + Data(CborWrap), } -impl<'b, C> minicbor::Decode<'b, C> for DatumOption { - fn decode( - d: &mut minicbor::Decoder<'b>, - _ctx: &mut C, - ) -> Result { +impl<'b, C, T> minicbor::Decode<'b, C> for PseudoDatumOption +where + T: minicbor::Decode<'b, C>, +{ + fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { d.array()?; match d.u8()? { - 0 => Ok(Self::Hash(d.decode()?)), - 1 => Ok(Self::Data(d.decode()?)), + 0 => Ok(Self::Hash(d.decode_with(ctx)?)), + 1 => Ok(Self::Data(d.decode_with(ctx)?)), _ => Err(minicbor::decode::Error::message( "invalid variant for datum option enum", )), @@ -481,7 +542,10 @@ impl<'b, C> minicbor::Decode<'b, C> for DatumOption { } } -impl minicbor::Encode for DatumOption { +impl minicbor::Encode for PseudoDatumOption +where + T: minicbor::Encode, +{ fn encode( &self, e: &mut minicbor::Encoder, @@ -496,6 +560,19 @@ impl minicbor::Encode for DatumOption { } } +pub type DatumOption = PseudoDatumOption; + +pub type MintedDatumOption<'b> = PseudoDatumOption>; + +impl<'b> From> for DatumOption { + fn from(value: MintedDatumOption<'b>) -> Self { + match value { + PseudoDatumOption::Hash(x) => Self::Hash(x), + PseudoDatumOption::Data(x) => Self::Data(CborWrap(x.unwrap().unwrap())), + } + } +} + // script_ref = #6.24(bytes .cbor script) pub type ScriptRef = CborWrap