added plutusV1

This commit is contained in:
alessandrokonrad 2022-09-13 11:41:42 +02:00 committed by rvcas
parent d9b34973c7
commit 6e4ff1e282
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
3 changed files with 339 additions and 111 deletions

View File

@ -30,7 +30,7 @@ pub enum TxCommand {
}
#[derive(Deserialize)]
pub struct ResolvedInput {
pub struct ResolvedInputOld {
pub input: Input,
pub output: Output,
}

View File

@ -16,7 +16,7 @@ mod utils;
use args::{Args, TxCommand, UplcCommand};
use crate::args::ResolvedInput;
use crate::args::ResolvedInputOld;
fn main() -> anyhow::Result<()> {
let args = Args::default();
@ -66,7 +66,8 @@ fn main() -> anyhow::Result<()> {
let file = File::open(&resolved_inputs)?;
let reader = BufReader::new(file);
let resolved_inputs: Vec<ResolvedInput> = serde_json::from_reader(reader)?;
let resolved_inputs: Vec<ResolvedInputOld> =
serde_json::from_reader(reader)?;
let tx_in_info = utils::get_tx_in_info_old(&resolved_inputs)?;
}

View File

@ -8,9 +8,9 @@ use pallas_codec::{
use pallas_crypto::hash::{Hash, Hasher};
use pallas_primitives::{
babbage::{
AddrKeyhash, AssetName, BigInt, Certificate, Constr, CostModel, DatumHash, DatumOption,
ExUnits, Language, Mint, MintedTx, PlutusV1Script, PlutusV2Script, PolicyId, Redeemer,
RedeemerTag, RewardAccount, Script, ScriptRef, StakeCredential, TransactionInput,
AddrKeyhash, AssetName, BigInt, Certificate, Coin, Constr, CostModel, DatumHash,
DatumOption, ExUnits, Language, Mint, MintedTx, PlutusV1Script, PlutusV2Script, PolicyId,
Redeemer, RedeemerTag, RewardAccount, Script, ScriptRef, StakeCredential, TransactionInput,
TransactionOutput, Tx, Value, Withdrawals,
},
Fragment, ToHash,
@ -19,6 +19,7 @@ use pallas_traverse::{Era, MultiEraTx};
use std::{
collections::HashMap,
convert::{TryFrom, TryInto},
ops::Deref,
str::FromStr,
vec,
};
@ -28,9 +29,9 @@ use uplc::{
PlutusData,
};
use crate::args::ResolvedInput;
use crate::args::ResolvedInputOld;
pub fn get_tx_in_info_old(resolved_inputs: &[ResolvedInput]) -> anyhow::Result<Vec<PlutusData>> {
pub fn get_tx_in_info_old(resolved_inputs: &[ResolvedInputOld]) -> anyhow::Result<Vec<PlutusData>> {
let mut tx_in_info = Vec::new();
for resolved_input in resolved_inputs {
@ -120,7 +121,7 @@ fn empty_constr(index: u64) -> PlutusData {
})
}
/// Translate constructor index to cbor tag
/// Translate constructor index to cbor tag.
fn constr_index(index: u64) -> u64 {
121 + index
}
@ -132,17 +133,6 @@ pub trait ToPlutusData {
impl ToPlutusData for Address {
fn to_plutus_data(&self) -> PlutusData {
match self {
Address::Byron(byron_address) => {
wrap_multiple_with_constr(
0,
vec![
//addressCredential
wrap_with_constr(0, byron_address.decode().unwrap().root.to_plutus_data()),
//addressStakeCredential
None::<StakeCredential>.to_plutus_data(),
],
)
}
Address::Shelley(shelley_address) => {
let payment_part = shelley_address.payment();
let stake_part = shelley_address.delegation();
@ -177,7 +167,7 @@ impl ToPlutusData for Address {
wrap_multiple_with_constr(0, vec![payment_part_plutus_data, stake_part_plutus_data])
}
Address::Stake(_) => unreachable!(),
_ => unreachable!(),
}
}
}
@ -206,6 +196,12 @@ impl ToPlutusData for ByteVec {
}
}
impl<K: ToPlutusData, V: ToPlutusData> ToPlutusData for (K, V) {
fn to_plutus_data(&self) -> PlutusData {
wrap_multiple_with_constr(0, vec![self.0.to_plutus_data(), self.1.to_plutus_data()])
}
}
impl<A: ToPlutusData> ToPlutusData for MaybeIndefArray<A> {
fn to_plutus_data(&self) -> PlutusData {
PlutusData::Array(MaybeIndefArray::Indef(
@ -329,31 +325,61 @@ impl ToPlutusData for ScriptRef {
}
}
impl ToPlutusData for TransactionOutput {
impl ToPlutusData for TxOut {
fn to_plutus_data(&self) -> PlutusData {
match self {
TransactionOutput::Legacy(legacy_output) => wrap_multiple_with_constr(
0,
vec![
Address::from_bytes(&legacy_output.address)
.unwrap()
.to_plutus_data(),
legacy_output.amount.to_plutus_data(),
None::<DatumOption>.to_plutus_data(),
None::<ScriptRef>.to_plutus_data(),
],
),
TransactionOutput::PostAlonzo(post_alonzo_output) => wrap_multiple_with_constr(
0,
vec![
Address::from_bytes(&post_alonzo_output.address)
.unwrap()
.to_plutus_data(),
post_alonzo_output.value.to_plutus_data(),
post_alonzo_output.datum_option.to_plutus_data(),
post_alonzo_output.script_ref.to_plutus_data(),
],
),
TxOut::V1(output) => match output {
TransactionOutput::Legacy(legacy_output) => wrap_multiple_with_constr(
0,
vec![
Address::from_bytes(&legacy_output.address)
.unwrap()
.to_plutus_data(),
legacy_output.amount.to_plutus_data(),
legacy_output.datum_hash.to_plutus_data(),
],
),
TransactionOutput::PostAlonzo(post_alonzo_output) => wrap_multiple_with_constr(
0,
vec![
Address::from_bytes(&post_alonzo_output.address)
.unwrap()
.to_plutus_data(),
post_alonzo_output.value.to_plutus_data(),
match post_alonzo_output.datum_option {
Some(DatumOption::Hash(hash)) => Some(hash).to_plutus_data(),
_ => None::<DatumOption>.to_plutus_data(),
},
],
),
},
TxOut::V2(output) => match output {
TransactionOutput::Legacy(legacy_output) => wrap_multiple_with_constr(
0,
vec![
Address::from_bytes(&legacy_output.address)
.unwrap()
.to_plutus_data(),
legacy_output.amount.to_plutus_data(),
match legacy_output.datum_hash {
Some(hash) => wrap_with_constr(1, hash.to_plutus_data()),
_ => empty_constr(0),
},
None::<ScriptRef>.to_plutus_data(),
],
),
TransactionOutput::PostAlonzo(post_alonzo_output) => wrap_multiple_with_constr(
0,
vec![
Address::from_bytes(&post_alonzo_output.address)
.unwrap()
.to_plutus_data(),
post_alonzo_output.value.to_plutus_data(),
post_alonzo_output.datum_option.to_plutus_data(),
post_alonzo_output.script_ref.to_plutus_data(),
],
),
},
}
}
}
@ -581,23 +607,40 @@ impl ToPlutusData for ScriptPurpose {
impl ToPlutusData for TxInfo {
fn to_plutus_data(&self) -> PlutusData {
wrap_multiple_with_constr(
0,
vec![
self.inputs.to_plutus_data(),
self.reference_inputs.to_plutus_data(),
self.outputs.to_plutus_data(),
self.fee.to_plutus_data(),
self.mint.to_plutus_data(),
self.dcert.to_plutus_data(),
self.wdrl.to_plutus_data(),
self.valid_range.to_plutus_data(),
self.signatories.to_plutus_data(),
self.redeemers.to_plutus_data(),
self.data.to_plutus_data(),
wrap_with_constr(0, self.id.to_plutus_data()),
],
)
match self {
TxInfo::V1(tx_info) => wrap_multiple_with_constr(
0,
vec![
tx_info.inputs.to_plutus_data(),
tx_info.outputs.to_plutus_data(),
tx_info.fee.to_plutus_data(),
tx_info.mint.to_plutus_data(),
tx_info.dcert.to_plutus_data(),
tx_info.wdrl.to_plutus_data(),
tx_info.valid_range.to_plutus_data(),
tx_info.signatories.to_plutus_data(),
tx_info.data.to_plutus_data(),
wrap_with_constr(0, tx_info.id.to_plutus_data()),
],
),
TxInfo::V2(tx_info) => wrap_multiple_with_constr(
0,
vec![
tx_info.inputs.to_plutus_data(),
tx_info.reference_inputs.to_plutus_data(),
tx_info.outputs.to_plutus_data(),
tx_info.fee.to_plutus_data(),
tx_info.mint.to_plutus_data(),
tx_info.dcert.to_plutus_data(),
tx_info.wdrl.to_plutus_data(),
tx_info.valid_range.to_plutus_data(),
tx_info.signatories.to_plutus_data(),
tx_info.redeemers.to_plutus_data(),
tx_info.data.to_plutus_data(),
wrap_with_constr(0, tx_info.id.to_plutus_data()),
],
),
}
}
}
@ -619,12 +662,21 @@ impl ToPlutusData for bool {
}
}
// Plutus V2 only for now
#[derive(Debug, PartialEq, Clone)]
pub struct ResolvedInput {
input: TransactionInput,
output: TransactionOutput,
}
#[derive(Debug, PartialEq, Clone)]
pub struct TxInInfo {
out_ref: TransactionInput,
resolved: TransactionOutput,
resolved: TxOut,
}
#[derive(Debug, PartialEq, Clone)]
pub enum TxOut {
V1(TransactionOutput),
V2(TransactionOutput),
}
#[derive(Debug, PartialEq, Clone)]
@ -636,10 +688,24 @@ pub enum ScriptPurpose {
}
#[derive(Debug, PartialEq, Clone)]
pub struct TxInfo {
pub struct TxInfoV1 {
inputs: MaybeIndefArray<TxInInfo>,
outputs: MaybeIndefArray<TxOut>,
fee: Value,
mint: Mint,
dcert: MaybeIndefArray<Certificate>,
wdrl: MaybeIndefArray<(RewardAccount, Coin)>,
valid_range: TimeRange,
signatories: MaybeIndefArray<AddrKeyhash>,
data: MaybeIndefArray<(DatumHash, PlutusData)>,
id: Hash<32>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct TxInfoV2 {
inputs: MaybeIndefArray<TxInInfo>,
reference_inputs: MaybeIndefArray<TxInInfo>,
outputs: MaybeIndefArray<TransactionOutput>,
outputs: MaybeIndefArray<TxOut>,
fee: Value,
mint: Mint,
dcert: MaybeIndefArray<Certificate>,
@ -651,6 +717,12 @@ pub struct TxInfo {
id: Hash<32>,
}
#[derive(Debug, PartialEq, Clone)]
pub enum TxInfo {
V1(TxInfoV1),
V2(TxInfoV2),
}
#[derive(Debug, PartialEq, Clone)]
pub struct ScriptContext {
tx_info: TxInfo,
@ -689,8 +761,8 @@ fn slot_range_to_posix_time_range(slot_range: TimeRange, sc: &SlotConfig) -> Tim
#[derive(Debug, PartialEq, Clone)]
enum ScriptVersion {
PlutusV1(PlutusV1Script),
PlutusV2(PlutusV2Script),
V1(PlutusV1Script),
V2(PlutusV2Script),
}
#[derive(Debug, PartialEq, Clone)]
@ -704,15 +776,34 @@ struct DataLookupTable {
scripts: HashMap<ScriptHash, ScriptVersion>,
}
fn get_tx_in_info(
fn get_tx_in_info_v1(
inputs: &MaybeIndefArray<TransactionInput>,
utxos: &MaybeIndefArray<TxInInfo>,
utxos: &MaybeIndefArray<ResolvedInput>,
) -> anyhow::Result<MaybeIndefArray<TxInInfo>> {
Ok(MaybeIndefArray::Indef(
utxos
.iter()
.filter(|utxo| inputs.contains(&utxo.out_ref))
.map(|utxo| utxo.clone())
.filter(|utxo| inputs.contains(&utxo.input))
.map(|utxo| TxInInfo {
out_ref: utxo.input.clone(),
resolved: TxOut::V1(utxo.output.clone()),
})
.collect::<Vec<TxInInfo>>(),
))
}
fn get_tx_in_info_v2(
inputs: &MaybeIndefArray<TransactionInput>,
utxos: &MaybeIndefArray<ResolvedInput>,
) -> anyhow::Result<MaybeIndefArray<TxInInfo>> {
Ok(MaybeIndefArray::Indef(
utxos
.iter()
.filter(|utxo| inputs.contains(&utxo.input))
.map(|utxo| TxInInfo {
out_ref: utxo.input.clone(),
resolved: TxOut::V2(utxo.output.clone()),
})
.collect::<Vec<TxInInfo>>(),
))
}
@ -770,14 +861,14 @@ fn get_script_purpose(
let addresss = Address::from_bytes(&reward_account)?;
let credential = match addresss {
Address::Stake(stake_address) => match stake_address.payload() {
StakePayload::Stake(stake_keyhash) => {
StakeCredential::AddrKeyhash(stake_keyhash.clone())
}
StakePayload::Script(script_hash) => {
StakeCredential::Scripthash(script_hash.clone())
}
StakePayload::Stake(_) => {
unreachable!();
}
},
_ => panic!(),
_ => unreachable!(),
};
Ok(ScriptPurpose::Rewarding(credential))
}
@ -789,22 +880,94 @@ fn get_script_purpose(
}
}
fn get_tx_info(
fn get_tx_info_v1(
tx: &MintedTx,
utxos: &MaybeIndefArray<TxInInfo>,
utxos: &MaybeIndefArray<ResolvedInput>,
slot_config: &SlotConfig,
) -> anyhow::Result<TxInfo> {
// Check if outputs do not contain ref scripts or inline datums or byron addresses in outputs
let body = tx.transaction_body.clone();
let inputs = get_tx_in_info(&body.inputs, &utxos)?;
let reference_inputs = get_tx_in_info(
let inputs = get_tx_in_info_v1(&body.inputs, &utxos)?;
let outputs = MaybeIndefArray::Indef(
body.outputs
.iter()
.map(|output| TxOut::V1(output.clone()))
.collect(),
);
let fee = Value::Coin(AnyUInt::U64(body.fee));
let mint = body.mint.clone().unwrap_or(KeyValuePairs::Indef(vec![]));
let dcert = body
.certificates
.clone()
.unwrap_or(MaybeIndefArray::Indef(vec![]));
let wdrl = MaybeIndefArray::Indef(
body.withdrawals
.clone()
.unwrap_or(KeyValuePairs::Indef(vec![]))
.deref()
.clone(),
);
let valid_range = slot_range_to_posix_time_range(
TimeRange {
lower_bound: body.validity_interval_start,
upper_bound: body.ttl,
},
&slot_config,
);
let signatories = body
.required_signers
.clone()
.unwrap_or(MaybeIndefArray::Indef(vec![]));
let data = MaybeIndefArray::Indef(
tx.transaction_witness_set
.plutus_data
.as_ref()
.unwrap_or(&MaybeIndefArray::Indef(vec![]))
.iter()
.map(|d| (d.to_hash(), d.clone()))
.collect(),
);
let id = tx.transaction_body.to_hash();
Ok(TxInfo::V1(TxInfoV1 {
inputs,
outputs,
fee,
mint,
dcert,
wdrl,
valid_range,
signatories,
data,
id,
}))
}
fn get_tx_info_v2(
tx: &MintedTx,
utxos: &MaybeIndefArray<ResolvedInput>,
slot_config: &SlotConfig,
) -> anyhow::Result<TxInfo> {
//TODO: Check if no byron addresses in outputs
let body = tx.transaction_body.clone();
let inputs = get_tx_in_info_v2(&body.inputs, &utxos)?;
let reference_inputs = get_tx_in_info_v2(
&body
.reference_inputs
.clone()
.unwrap_or(MaybeIndefArray::Indef(vec![])),
&utxos,
)?;
let outputs = body.outputs.clone();
let outputs = MaybeIndefArray::Indef(
body.outputs
.iter()
.map(|output| TxOut::V2(output.clone()))
.collect(),
);
let fee = Value::Coin(AnyUInt::U64(body.fee));
let mint = body.mint.clone().unwrap_or(KeyValuePairs::Indef(vec![]));
let dcert = body
@ -858,7 +1021,7 @@ fn get_tx_info(
);
let id = tx.transaction_body.to_hash();
Ok(TxInfo {
Ok(TxInfo::V2(TxInfoV2 {
inputs,
reference_inputs,
outputs,
@ -871,11 +1034,11 @@ fn get_tx_info(
redeemers,
data,
id,
})
}))
}
fn get_execution_purpose(
utxos: &MaybeIndefArray<TxInInfo>,
utxos: &MaybeIndefArray<ResolvedInput>,
script_purpose: &ScriptPurpose,
lookup_table: &DataLookupTable,
) -> ExecutionPurpose {
@ -888,8 +1051,8 @@ fn get_execution_purpose(
ExecutionPurpose::NoDatum(script.clone())
}
ScriptPurpose::Spending(out_ref) => {
let utxo = utxos.iter().find(|utxo| utxo.out_ref == *out_ref).unwrap();
match &utxo.resolved {
let utxo = utxos.iter().find(|utxo| utxo.input == *out_ref).unwrap();
match &utxo.output {
TransactionOutput::Legacy(output) => {
let address = Address::from_bytes(&output.address).unwrap();
match address {
@ -902,9 +1065,6 @@ fn get_execution_purpose(
let datum =
lookup_table.datum.get(&output.datum_hash.unwrap()).unwrap();
let a = hex::encode(datum.encode_fragment().unwrap());
println!("{:?}", a);
ExecutionPurpose::WithDatum(script.clone(), datum.clone())
}
_ => unreachable!(),
@ -967,7 +1127,7 @@ fn get_execution_purpose(
fn get_script_and_datum_lookup_table(
tx: &MintedTx,
utxos: &MaybeIndefArray<TxInInfo>,
utxos: &MaybeIndefArray<ResolvedInput>,
) -> DataLookupTable {
let mut datum = HashMap::new();
let mut scripts = HashMap::new();
@ -1003,7 +1163,7 @@ fn get_script_and_datum_lookup_table(
prefixed_script.extend(script.0.iter());
let hash = Hasher::<224>::hash(&prefixed_script);
scripts.insert(hash, ScriptVersion::PlutusV1(script.clone()));
scripts.insert(hash, ScriptVersion::V1(script.clone()));
}
for script in scripts_v2_witnesses.iter() {
@ -1013,13 +1173,13 @@ fn get_script_and_datum_lookup_table(
prefixed_script.extend(script.0.iter());
let hash = Hasher::<224>::hash(&prefixed_script);
scripts.insert(hash, ScriptVersion::PlutusV2(script.clone()));
scripts.insert(hash, ScriptVersion::V2(script.clone()));
}
// discovery in utxos (script ref)
for utxo in utxos.iter() {
match &utxo.resolved {
match &utxo.output {
TransactionOutput::Legacy(_) => {}
TransactionOutput::PostAlonzo(output) => match &output.script_ref {
Some(script) => match &script.0 {
@ -1029,7 +1189,7 @@ fn get_script_and_datum_lookup_table(
prefixed_script.extend(v1.0.iter());
let hash = Hasher::<224>::hash(&prefixed_script);
scripts.insert(hash, ScriptVersion::PlutusV1(v1.clone()));
scripts.insert(hash, ScriptVersion::V1(v1.clone()));
}
Script::PlutusV2Script(v2) => {
// scripts.insert(v2.to_hash(), ScriptVersion::PlutusV2(v2.clone())); // TODO: fix hashing bug in pallas
@ -1038,7 +1198,7 @@ fn get_script_and_datum_lookup_table(
prefixed_script.extend(v2.0.iter());
let hash = Hasher::<224>::hash(&prefixed_script);
scripts.insert(hash, ScriptVersion::PlutusV2(v2.clone()));
scripts.insert(hash, ScriptVersion::V2(v2.clone()));
}
_ => {}
},
@ -1052,7 +1212,7 @@ fn get_script_and_datum_lookup_table(
fn eval_redeemer(
tx: &MintedTx,
utxos: &MaybeIndefArray<TxInInfo>,
utxos: &MaybeIndefArray<ResolvedInput>,
slot_config: &SlotConfig,
redeemer: &Redeemer,
lookup_table: &DataLookupTable,
@ -1069,9 +1229,40 @@ fn eval_redeemer(
match execution_purpose {
ExecutionPurpose::WithDatum(script_version, datum) => match script_version {
ScriptVersion::PlutusV1(script) => todo!(),
ScriptVersion::PlutusV2(script) => {
let tx_info = get_tx_info(tx, utxos, slot_config)?;
ScriptVersion::V1(script) => {
let tx_info = get_tx_info_v1(tx, utxos, slot_config)?;
let script_context = ScriptContext { tx_info, purpose };
let program: Program<NamedDeBruijn> = {
let mut buffer = Vec::new();
let prog = Program::<FakeNamedDeBruijn>::from_cbor(&script.0, &mut buffer)?;
prog.into()
};
let result = program
.apply_data(datum.clone())
.apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data())
.eval();
result.0.unwrap();
let new_redeemer = Redeemer {
tag: redeemer.tag.clone(),
index: redeemer.index,
data: redeemer.data.clone(),
ex_units: ExUnits {
mem: (ExBudget::default().mem - result.1.mem) as u32,
steps: (ExBudget::default().cpu - result.1.cpu) as u64,
},
};
Ok(new_redeemer)
}
ScriptVersion::V2(script) => {
let tx_info = get_tx_info_v2(tx, utxos, slot_config)?;
let script_context = ScriptContext { tx_info, purpose };
let program: Program<NamedDeBruijn> = {
@ -1104,9 +1295,39 @@ fn eval_redeemer(
}
},
ExecutionPurpose::NoDatum(script_version) => match script_version {
ScriptVersion::PlutusV1(script) => todo!(),
ScriptVersion::PlutusV2(script) => {
let tx_info = get_tx_info(tx, utxos, slot_config)?;
ScriptVersion::V1(script) => {
let tx_info = get_tx_info_v1(tx, utxos, slot_config)?;
let script_context = ScriptContext { tx_info, purpose };
let program: Program<NamedDeBruijn> = {
let mut buffer = Vec::new();
let prog = Program::<FakeNamedDeBruijn>::from_cbor(&script.0, &mut buffer)?;
prog.into()
};
let result = program
.apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data())
.eval();
result.0.unwrap();
let new_redeemer = Redeemer {
tag: redeemer.tag.clone(),
index: redeemer.index,
data: redeemer.data.clone(),
ex_units: ExUnits {
mem: (ExBudget::default().mem - result.1.mem) as u32,
steps: (ExBudget::default().cpu - result.1.cpu) as u64,
},
};
Ok(new_redeemer)
}
ScriptVersion::V2(script) => {
let tx_info = get_tx_info_v2(tx, utxos, slot_config)?;
let script_context = ScriptContext { tx_info, purpose };
let program: Program<NamedDeBruijn> = {
@ -1154,7 +1375,7 @@ fn eval_redeemer(
fn eval_tx(
tx: &MintedTx,
utxos: &MaybeIndefArray<TxInInfo>,
utxos: &MaybeIndefArray<ResolvedInput>,
//TODO: costMdls
slot_config: &SlotConfig,
) -> anyhow::Result<MaybeIndefArray<Redeemer>> {
@ -1190,11 +1411,14 @@ mod tests {
use pallas_traverse::{Era, MultiEraTx};
use uplc::PlutusData;
use super::{eval_tx, SlotConfig, TxInInfo};
use super::{eval_tx, ResolvedInput, SlotConfig, TxInInfo};
#[test]
fn test_eval() {
/*
PlutusV2
{-# INLINEABLE mintTestValidator #-}
mintTestValidator :: () -> Api.ScriptContext -> Bool
mintTestValidator _ ctx = Api.txInfoFee txInfo == Api.txInfoFee txInfo && (case Api.txInfoSignatories txInfo of [] -> True)
@ -1211,13 +1435,13 @@ mod tests {
let inputs = MaybeIndefArray::<TransactionInput>::decode_fragment(&raw_inputs).unwrap();
let outputs = MaybeIndefArray::<TransactionOutput>::decode_fragment(&raw_outputs).unwrap();
let utxos: MaybeIndefArray<TxInInfo> = MaybeIndefArray::Indef(
let utxos: MaybeIndefArray<ResolvedInput> = MaybeIndefArray::Indef(
inputs
.iter()
.zip(outputs.iter())
.map(|(input, output)| TxInInfo {
out_ref: input.clone(),
resolved: output.clone(),
.map(|(input, output)| ResolvedInput {
input: input.clone(),
output: output.clone(),
})
.collect(),
);
@ -1243,6 +1467,9 @@ mod tests {
#[test]
fn test_eval_1() {
/*
PlutusV2
{-# INLINEABLE mintTestValidator #-}
mintTestValidator :: () -> Api.ScriptContext -> Bool
mintTestValidator _ ctx = Api.txInfoFee txInfo == Api.txInfoFee txInfo
@ -1259,13 +1486,13 @@ mod tests {
let inputs = MaybeIndefArray::<TransactionInput>::decode_fragment(&raw_inputs).unwrap();
let outputs = MaybeIndefArray::<TransactionOutput>::decode_fragment(&raw_outputs).unwrap();
let utxos: MaybeIndefArray<TxInInfo> = MaybeIndefArray::Indef(
let utxos: MaybeIndefArray<ResolvedInput> = MaybeIndefArray::Indef(
inputs
.iter()
.zip(outputs.iter())
.map(|(input, output)| TxInInfo {
out_ref: input.clone(),
resolved: output.clone(),
.map(|(input, output)| ResolvedInput {
input: input.clone(),
output: output.clone(),
})
.collect(),
);