Skip to content

Commit

Permalink
feat(traverse): allow searching for witness plutus data by hash
Browse files Browse the repository at this point in the history
  • Loading branch information
scarmuega committed Jan 16, 2025
1 parent 069f189 commit 96b341d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 37 deletions.
10 changes: 8 additions & 2 deletions pallas-traverse/src/witnesses.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use pallas_codec::utils::KeepRaw;
use pallas_primitives::{
alonzo::{self, BootstrapWitness, NativeScript, VKeyWitness},
conway, PlutusData, PlutusScript,
conway, Hash, PlutusData, PlutusScript,
};

use crate::{MultiEraRedeemer, MultiEraTx};
use crate::{MultiEraRedeemer, MultiEraTx, OriginalHash as _};

impl<'b> MultiEraTx<'b> {
pub fn vkey_witnesses(&self) -> &[VKeyWitness] {
Expand Down Expand Up @@ -127,6 +127,12 @@ impl<'b> MultiEraTx<'b> {
}
}

pub fn find_plutus_data(&self, hash: &Hash<32>) -> Option<&KeepRaw<'b, PlutusData>> {
self.plutus_data()
.iter()
.find(|x| x.original_hash() == *hash)
}

pub fn redeemers(&self) -> Vec<MultiEraRedeemer> {
match self {
Self::Byron(_) => vec![],
Expand Down
53 changes: 18 additions & 35 deletions pallas-utxorpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub type Cbor = Vec<u8>;
pub type EraCbor = (trv::Era, Cbor);
pub type UtxoMap = HashMap<TxoRef, EraCbor>;
pub type DatumMap = HashMap<Hash<32>, alonzo::PlutusData>;

pub trait LedgerContext: Clone {
fn get_utxos(&self, refs: &[TxoRef]) -> Option<UtxoMap>;
}
Expand Down Expand Up @@ -78,7 +79,7 @@ impl<C: LedgerContext> Mapper<C> {
&self,
resolved: &Option<UtxoMap>,
input: &trv::MultiEraInput,
datum_map: &Option<DatumMap>,
tx: &trv::MultiEraTx,
) -> Option<u5c::TxOutput> {
let as_txref = (*input.hash(), input.index() as u32);

Expand All @@ -87,7 +88,7 @@ impl<C: LedgerContext> Mapper<C> {
.and_then(|x| x.get(&as_txref))
.and_then(|(era, cbor)| {
let o = trv::MultiEraOutput::decode(*era, cbor.as_slice()).ok()?;
Some(self.map_tx_output(&o, datum_map))
Some(self.map_tx_output(&o, tx))
})
}

Expand All @@ -98,12 +99,11 @@ impl<C: LedgerContext> Mapper<C> {
// lexicographical order of the input we're mapping
order: u32,
resolved: &Option<UtxoMap>,
datum_map: &Option<DatumMap>,
) -> u5c::TxInput {
u5c::TxInput {
tx_hash: input.hash().to_vec().into(),
output_index: input.index() as u32,
as_output: self.decode_resolved_utxo(resolved, input, datum_map),
as_output: self.decode_resolved_utxo(resolved, input, tx),
redeemer: tx.find_spend_redeemer(order).map(|x| self.map_redeemer(&x)),
}
}
Expand All @@ -112,11 +112,12 @@ impl<C: LedgerContext> Mapper<C> {
&self,
input: &trv::MultiEraInput,
resolved: &Option<UtxoMap>,
tx: &trv::MultiEraTx,
) -> u5c::TxInput {
u5c::TxInput {
tx_hash: input.hash().to_vec().into(),
output_index: input.index() as u32,
as_output: self.decode_resolved_utxo(resolved, input, &None),
as_output: self.decode_resolved_utxo(resolved, input, tx),
redeemer: None,
}
}
Expand All @@ -125,20 +126,17 @@ impl<C: LedgerContext> Mapper<C> {
&self,
input: &trv::MultiEraInput,
resolved: &Option<UtxoMap>,
tx: &trv::MultiEraTx,
) -> u5c::TxInput {
u5c::TxInput {
tx_hash: input.hash().to_vec().into(),
output_index: input.index() as u32,
as_output: self.decode_resolved_utxo(resolved, input, &None),
as_output: self.decode_resolved_utxo(resolved, input, tx),
redeemer: None,
}
}

pub fn map_tx_datum(
&self,
x: &trv::MultiEraOutput,
datum_map: &Option<DatumMap>,
) -> u5c::Datum {
pub fn map_tx_datum(&self, x: &trv::MultiEraOutput, tx: &trv::MultiEraTx) -> u5c::Datum {
u5c::Datum {
hash: match x.datum() {
Some(babbage::PseudoDatumOption::Data(x)) => x.original_hash().to_vec().into(),
Expand All @@ -147,9 +145,8 @@ impl<C: LedgerContext> Mapper<C> {
},
payload: match x.datum() {
Some(babbage::PseudoDatumOption::Data(x)) => self.map_plutus_datum(&x.0).into(),
Some(babbage::PseudoDatumOption::Hash(x)) => datum_map
.as_ref()
.and_then(|m| m.get(&x))
Some(babbage::PseudoDatumOption::Hash(x)) => tx
.find_plutus_data(&x)
.map(|d| self.map_plutus_datum(d))
.into(),
_ => None,
Expand All @@ -161,11 +158,7 @@ impl<C: LedgerContext> Mapper<C> {
}
}

pub fn map_tx_output(
&self,
x: &trv::MultiEraOutput,
datum_map: &Option<DatumMap>,
) -> u5c::TxOutput {
pub fn map_tx_output(&self, x: &trv::MultiEraOutput, tx: &trv::MultiEraTx) -> u5c::TxOutput {
u5c::TxOutput {
address: x.address().map(|a| a.to_vec()).unwrap_or_default().into(),
coin: x.value().coin(),
Expand All @@ -178,7 +171,7 @@ impl<C: LedgerContext> Mapper<C> {
.iter()
.map(|x| self.map_policy_assets(x))
.collect(),
datum: self.map_tx_datum(x, datum_map).into(),
datum: self.map_tx_datum(x, tx).into(),
script: match x.script_ref() {
Some(conway::PseudoScript::NativeScript(x)) => u5c::Script {
script: u5c::script::Script::Native(Self::map_native_script(&x)).into(), /* */
Expand Down Expand Up @@ -489,26 +482,18 @@ impl<C: LedgerContext> Mapper<C> {
ctx.get_utxos(to_resolve.as_slice())
});

let mut datum_map: DatumMap = HashMap::new();
for datum in tx.plutus_data().iter() {
let hash = datum.original_hash();
datum_map.insert(hash, datum.clone().unwrap());
}

u5c::Tx {
hash: tx.hash().to_vec().into(),
inputs: tx
.inputs_sorted_set()
.iter()
.enumerate()
.map(|(order, i)| {
self.map_tx_input(i, tx, order as u32, &resolved, &Some(datum_map.clone()))
})
.map(|(order, i)| self.map_tx_input(i, tx, order as u32, &resolved))
.collect(),
outputs: tx
.outputs()
.iter()
.map(|x| self.map_tx_output(x, &Some(datum_map.clone())))
.map(|x| self.map_tx_output(x, tx))
.collect(),
certificates: tx
.certs()
Expand Down Expand Up @@ -539,7 +524,7 @@ impl<C: LedgerContext> Mapper<C> {
reference_inputs: tx
.reference_inputs()
.iter()
.map(|x| self.map_tx_reference_input(x, &resolved))
.map(|x| self.map_tx_reference_input(x, &resolved, tx))
.collect(),
witnesses: u5c::WitnessSet {
vkeywitness: tx
Expand All @@ -559,11 +544,9 @@ impl<C: LedgerContext> Mapper<C> {
collateral: tx
.collateral()
.iter()
.map(|x| self.map_tx_collateral(x, &resolved))
.map(|x| self.map_tx_collateral(x, &resolved, tx))
.collect(),
collateral_return: tx
.collateral_return()
.map(|x| self.map_tx_output(&x, &None)),
collateral_return: tx.collateral_return().map(|x| self.map_tx_output(&x, tx)),
total_collateral: tx.total_collateral().unwrap_or_default(),
}
.into(),
Expand Down

0 comments on commit 96b341d

Please sign in to comment.