Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: tx builder metadata support #373

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion pallas-primitives/src/babbage/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//! Handcrafted, idiomatic rust artifacts based on based on the [Babbage CDDL](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/babbage/test-suite/cddl-files/babbage.cddl) file in IOHK repo.

use pallas_codec::minicbor::data::Tag;
use serde::{Deserialize, Serialize};

use pallas_codec::minicbor::{Decode, Encode};
Expand Down Expand Up @@ -644,7 +645,56 @@ pub use crate::alonzo::MetadatumLabel;

pub use crate::alonzo::Metadata;

pub use crate::alonzo::AuxiliaryData;
use crate::alonzo::ShelleyMaAuxiliaryData;

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum AuxiliaryData {
Shelley(Metadata),
ShelleyMa(ShelleyMaAuxiliaryData),
PostAlonzo(PostAlonzoAuxiliaryData),
}

impl<'b, C> minicbor::Decode<'b, C> for AuxiliaryData {
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
match d.datatype()? {
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
Ok(AuxiliaryData::Shelley(d.decode_with(ctx)?))
}
minicbor::data::Type::Array => Ok(AuxiliaryData::ShelleyMa(d.decode_with(ctx)?)),
minicbor::data::Type::Tag => {
d.tag()?;
Ok(AuxiliaryData::PostAlonzo(d.decode_with(ctx)?))
}
_ => Err(minicbor::decode::Error::message(
"Can't infer variant from data type for AuxiliaryData",
)),
}
}
}

impl<C> minicbor::Encode<C> for AuxiliaryData {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
match self {
AuxiliaryData::Shelley(m) => {
e.encode_with(m, ctx)?;
}
AuxiliaryData::ShelleyMa(m) => {
e.encode_with(m, ctx)?;
}
AuxiliaryData::PostAlonzo(v) => {
// TODO: check if this is the correct tag
e.tag(Tag::Unassigned(259))?;
e.encode_with(v, ctx)?;
}
};

Ok(())
}
}

pub use crate::alonzo::TransactionIndex;

Expand Down
52 changes: 51 additions & 1 deletion pallas-primitives/src/conway/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//! Handcrafted, idiomatic rust artifacts based on based on the [Conway CDDL](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl) file in IOHK repo.

use pallas_codec::minicbor::data::Tag;
use serde::{Deserialize, Serialize};

use pallas_codec::minicbor::{Decode, Encode};
Expand Down Expand Up @@ -1400,7 +1401,56 @@ pub use crate::alonzo::MetadatumLabel;

pub use crate::alonzo::Metadata;

pub use crate::alonzo::AuxiliaryData;
use crate::alonzo::ShelleyMaAuxiliaryData;

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum AuxiliaryData {
Shelley(Metadata),
ShelleyMa(ShelleyMaAuxiliaryData),
PostAlonzo(PostAlonzoAuxiliaryData),
}

impl<'b, C> minicbor::Decode<'b, C> for AuxiliaryData {
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
match d.datatype()? {
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
Ok(AuxiliaryData::Shelley(d.decode_with(ctx)?))
}
minicbor::data::Type::Array => Ok(AuxiliaryData::ShelleyMa(d.decode_with(ctx)?)),
minicbor::data::Type::Tag => {
d.tag()?;
Ok(AuxiliaryData::PostAlonzo(d.decode_with(ctx)?))
}
_ => Err(minicbor::decode::Error::message(
"Can't infer variant from data type for AuxiliaryData",
)),
}
}
}

impl<C> minicbor::Encode<C> for AuxiliaryData {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
match self {
AuxiliaryData::Shelley(m) => {
e.encode_with(m, ctx)?;
}
AuxiliaryData::ShelleyMa(m) => {
e.encode_with(m, ctx)?;
}
AuxiliaryData::PostAlonzo(v) => {
// TODO: check if this is the correct tag
e.tag(Tag::Unassigned(259))?;
e.encode_with(v, ctx)?;
}
};

Ok(())
}
}

pub use crate::alonzo::TransactionIndex;

Expand Down
134 changes: 116 additions & 18 deletions pallas-traverse/src/auxiliary.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,137 @@
use std::ops::Deref;

use pallas_primitives::alonzo;
use pallas_codec::utils::Nullable;
use pallas_primitives::{alonzo, babbage, conway};

use crate::MultiEraTx;

impl<'b> MultiEraTx<'b> {
pub fn aux_plutus_v1_scripts(&self) -> &[alonzo::PlutusScript] {
if let Some(aux_data) = self.aux_data() {
if let alonzo::AuxiliaryData::PostAlonzo(x) = aux_data.deref() {
if let Some(plutus) = &x.plutus_scripts {
return plutus.as_ref();
match self {
MultiEraTx::Byron(_) => &[],
MultiEraTx::AlonzoCompatible(x, _) => {
if let Nullable::Some(ad) = &x.auxiliary_data {
match ad.deref() {
alonzo::AuxiliaryData::PostAlonzo(y) => {
if let Some(scripts) = y.plutus_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
_ => &[],
}
} else {
&[]
}
}
MultiEraTx::Babbage(x) => {
if let Nullable::Some(ad) = &x.auxiliary_data {
match ad.deref() {
babbage::AuxiliaryData::PostAlonzo(y) => {
if let Some(scripts) = y.plutus_v1_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
_ => &[],
}
} else {
&[]
}
}
MultiEraTx::Conway(x) => {
if let Nullable::Some(ad) = &x.auxiliary_data {
match ad.deref() {
conway::AuxiliaryData::PostAlonzo(y) => {
if let Some(scripts) = y.plutus_v1_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
_ => &[],
}
} else {
&[]
}
}
}

&[]
}

pub fn aux_native_scripts(&self) -> &[alonzo::NativeScript] {
if let Some(aux_data) = self.aux_data() {
match aux_data.deref() {
alonzo::AuxiliaryData::PostAlonzo(x) => {
if let Some(scripts) = &x.native_scripts {
return scripts.as_ref();
match self {
MultiEraTx::Byron(_) => &[],
MultiEraTx::AlonzoCompatible(x, _) => {
if let Nullable::Some(ad) = &x.auxiliary_data {
match ad.deref() {
alonzo::AuxiliaryData::ShelleyMa(y) => {
if let Some(scripts) = y.auxiliary_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
alonzo::AuxiliaryData::PostAlonzo(y) => {
if let Some(scripts) = y.native_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
_ => &[],
}
} else {
&[]
}
}
MultiEraTx::Babbage(x) => {
if let Nullable::Some(ad) = &x.auxiliary_data {
match ad.deref() {
babbage::AuxiliaryData::ShelleyMa(y) => {
if let Some(scripts) = y.auxiliary_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
babbage::AuxiliaryData::PostAlonzo(y) => {
if let Some(scripts) = y.native_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
_ => &[],
}
} else {
&[]
}
alonzo::AuxiliaryData::ShelleyMa(x) => {
if let Some(scripts) = &x.auxiliary_scripts {
return scripts.as_ref();
}
MultiEraTx::Conway(x) => {
if let Nullable::Some(ad) = &x.auxiliary_data {
match ad.deref() {
conway::AuxiliaryData::ShelleyMa(y) => {
if let Some(scripts) = y.auxiliary_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
conway::AuxiliaryData::PostAlonzo(y) => {
if let Some(scripts) = y.native_scripts.as_ref() {
scripts.as_ref()
} else {
&[]
}
}
_ => &[],
}
} else {
&[]
}
_ => (),
}
}

&[]
}
}
12 changes: 12 additions & 0 deletions pallas-traverse/src/hashes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ impl ComputeHash<32> for babbage::DatumOption {
}
}

impl ComputeHash<32> for babbage::AuxiliaryData {
fn compute_hash(&self) -> pallas_crypto::hash::Hash<32> {
Hasher::<256>::hash_cbor(self)
}
}

// conway

impl ComputeHash<28> for conway::PlutusV3Script {
Expand All @@ -177,6 +183,12 @@ impl OriginalHash<32> for KeepRaw<'_, conway::MintedTransactionBody<'_>> {
}
}

impl ComputeHash<32> for conway::AuxiliaryData {
fn compute_hash(&self) -> pallas_crypto::hash::Hash<32> {
Hasher::<256>::hash_cbor(self)
}
}

impl ComputeHash<28> for PublicKey {
fn compute_hash(&self) -> Hash<28> {
Hasher::<224>::hash(&Into::<[u8; PublicKey::SIZE]>::into(*self))
Expand Down
Loading