diff --git a/pallas-applying/src/alonzo.rs b/pallas-applying/src/alonzo.rs index aac55ff1..620278fd 100644 --- a/pallas-applying/src/alonzo.rs +++ b/pallas-applying/src/alonzo.rs @@ -4,7 +4,7 @@ use crate::utils::{ add_minted_value, add_values, aux_data_from_alonzo_minted_tx, compute_native_script_hash, compute_plutus_script_hash, empty_value, get_alonzo_comp_tx_size, get_lovelace_from_alonzo_val, get_network_id_value, get_payment_part, get_shelley_address, get_val_size_in_words, - mk_alonzo_vk_wits_check_list, values_are_equal, verify_signature, + mk_alonzo_vk_wits_check_list, value_from_multi_era_output, values_are_equal, verify_signature, AlonzoError::*, AlonzoProtParams, UTxOs, ValidationError::{self, *}, @@ -17,13 +17,10 @@ use pallas_codec::{ utils::{Bytes, KeepRaw}, }; use pallas_crypto::hash::Hash; -use pallas_primitives::{ - alonzo::{ - AddrKeyhash, Mint, MintedTx, MintedWitnessSet, Multiasset, NativeScript, PlutusData, - PlutusScript, PolicyId, Redeemer, RedeemerPointer, RedeemerTag, RequiredSigners, - TransactionBody, TransactionInput, TransactionOutput, VKeyWitness, Value, - }, - byron::TxOut, +use pallas_primitives::alonzo::{ + AddrKeyhash, Mint, MintedTx, MintedWitnessSet, Multiasset, NativeScript, PlutusData, + PlutusScript, PolicyId, Redeemer, RedeemerPointer, RedeemerTag, RequiredSigners, + TransactionBody, TransactionInput, TransactionOutput, VKeyWitness, Value, }; use pallas_traverse::{MultiEraInput, MultiEraOutput, OriginalHash}; use std::ops::Deref; @@ -55,7 +52,7 @@ pub fn validate_alonzo_tx( } // The set of transaction inputs is not empty. -fn check_ins_not_empty(tx_body: &TransactionBody) -> ValidationResult { +pub fn check_ins_not_empty(tx_body: &TransactionBody) -> ValidationResult { if tx_body.inputs.is_empty() { return Err(Alonzo(TxInsEmpty)); } @@ -64,7 +61,10 @@ fn check_ins_not_empty(tx_body: &TransactionBody) -> ValidationResult { // All transaction inputs and collateral inputs are in the set of (yet) unspent // transaction outputs. -fn check_ins_and_collateral_in_utxos(tx_body: &TransactionBody, utxos: &UTxOs) -> ValidationResult { +pub fn check_ins_and_collateral_in_utxos( + tx_body: &TransactionBody, + utxos: &UTxOs, +) -> ValidationResult { for input in tx_body.inputs.iter() { if !(utxos.contains_key(&MultiEraInput::from_alonzo_compatible(input))) { return Err(Alonzo(InputNotInUTxO)); @@ -85,7 +85,7 @@ fn check_ins_and_collateral_in_utxos(tx_body: &TransactionBody, utxos: &UTxOs) - // The block slot is contained in the transaction validity interval, and the // upper bound is translatable to UTC time. -fn check_tx_validity_interval( +pub fn check_tx_validity_interval( tx_body: &TransactionBody, mtx: &MintedTx, block_slot: &u64, @@ -129,7 +129,7 @@ fn check_upper_bound( } } -fn check_fee( +pub fn check_fee( tx_body: &TransactionBody, size: &u32, mtx: &MintedTx, @@ -175,7 +175,7 @@ fn check_collaterals( .ok_or(Alonzo(CollateralMissing))?; check_collaterals_number(collaterals, prot_pps)?; check_collaterals_address(collaterals, utxos)?; - check_collaterals_assets(tx_body, utxos, prot_pps) + check_collaterals_assets(tx_body, collaterals, utxos, prot_pps) } // The set of collateral inputs is not empty. @@ -184,10 +184,9 @@ fn check_collaterals_number( collaterals: &[TransactionInput], prot_pps: &AlonzoProtParams, ) -> ValidationResult { - let number_collateral: u32 = collaterals.len() as u32; - if number_collateral == 0 { + if collaterals.is_empty() { Err(Alonzo(CollateralMissing)) - } else if number_collateral > prot_pps.max_collateral_inputs { + } else if collaterals.len() > prot_pps.max_collateral_inputs as usize { Err(Alonzo(TooManyCollaterals)) } else { Ok(()) @@ -202,7 +201,7 @@ fn check_collaterals_address(collaterals: &[TransactionInput], utxos: &UTxOs) -> if let Some(alonzo_comp_output) = MultiEraOutput::as_alonzo(multi_era_output) { if let ShelleyPaymentPart::Script(_) = get_payment_part(&alonzo_comp_output.address) - .ok_or(Alonzo(InputDecoding))? + .ok_or(Alonzo(UnknownAddressFormat))? { return Err(Alonzo(CollateralNotVKeyLocked)); } @@ -218,47 +217,43 @@ fn check_collaterals_address(collaterals: &[TransactionInput], utxos: &UTxOs) -> // minimum allowed. fn check_collaterals_assets( tx_body: &TransactionBody, + collaterals: &[TransactionInput], utxos: &UTxOs, prot_pps: &AlonzoProtParams, ) -> ValidationResult { let fee_percentage: u64 = tx_body.fee * prot_pps.collateral_percentage as u64; - match &tx_body.collateral { - Some(collaterals) => { - for collateral in collaterals { - match utxos.get(&MultiEraInput::from_alonzo_compatible(collateral)) { - Some(multi_era_output) => match MultiEraOutput::as_alonzo(multi_era_output) { - Some(TransactionOutput { - amount: Value::Coin(n), - .. - }) => { - if *n * 100 < fee_percentage { - return Err(Alonzo(CollateralMinLovelace)); - } - } - Some(TransactionOutput { - amount: Value::Multiasset(n, multi_assets), - .. - }) => { - if *n * 100 < fee_percentage { - return Err(Alonzo(CollateralMinLovelace)); - } - if !multi_assets.is_empty() { - return Err(Alonzo(NonLovelaceCollateral)); - } - } - None => (), - }, - None => return Err(Alonzo(CollateralNotInUTxO)), + for collateral in collaterals { + match utxos.get(&MultiEraInput::from_alonzo_compatible(collateral)) { + Some(multi_era_output) => match MultiEraOutput::as_alonzo(multi_era_output) { + Some(TransactionOutput { + amount: Value::Coin(n), + .. + }) => { + if *n * 100 < fee_percentage { + return Err(Alonzo(CollateralMinLovelace)); + } } - } + Some(TransactionOutput { + amount: Value::Multiasset(n, multi_assets), + .. + }) => { + if *n * 100 < fee_percentage { + return Err(Alonzo(CollateralMinLovelace)); + } + if !multi_assets.is_empty() { + return Err(Alonzo(NonLovelaceCollateral)); + } + } + None => (), + }, + None => return Err(Alonzo(CollateralNotInUTxO)), } - None => return Err(Alonzo(CollateralMissing)), } Ok(()) } // The preservation of value property holds. -fn check_preservation_of_value(tx_body: &TransactionBody, utxos: &UTxOs) -> ValidationResult { +pub fn check_preservation_of_value(tx_body: &TransactionBody, utxos: &UTxOs) -> ValidationResult { let mut input: Value = get_consumed(tx_body, utxos)?; let produced: Value = get_produced(tx_body)?; let output: Value = add_values(&produced, &Value::Coin(tx_body.fee), &Alonzo(NegativeValue))?; @@ -274,20 +269,11 @@ fn check_preservation_of_value(tx_body: &TransactionBody, utxos: &UTxOs) -> Vali fn get_consumed(tx_body: &TransactionBody, utxos: &UTxOs) -> Result { let mut res: Value = empty_value(); for input in tx_body.inputs.iter() { - let utxo_value: &MultiEraOutput = utxos + let multi_era_output: &MultiEraOutput = utxos .get(&MultiEraInput::from_alonzo_compatible(input)) .ok_or(Alonzo(InputNotInUTxO))?; - match MultiEraOutput::as_alonzo(utxo_value) { - Some(TransactionOutput { amount, .. }) => { - res = add_values(&res, amount, &Alonzo(NegativeValue))? - } - None => match MultiEraOutput::as_byron(utxo_value) { - Some(TxOut { amount, .. }) => { - res = add_values(&res, &Value::Coin(*amount), &Alonzo(NegativeValue))? - } - _ => return Err(Alonzo(InputNotInUTxO)), - }, - } + let val: Value = value_from_multi_era_output(multi_era_output); + res = add_values(&res, &val, &Alonzo(NegativeValue))?; } Ok(res) } @@ -301,7 +287,10 @@ fn get_produced(tx_body: &TransactionBody) -> Result { } // All transaction outputs should contain at least the minimum lovelace. -fn check_min_lovelace(tx_body: &TransactionBody, prot_pps: &AlonzoProtParams) -> ValidationResult { +pub fn check_min_lovelace( + tx_body: &TransactionBody, + prot_pps: &AlonzoProtParams, +) -> ValidationResult { for output in tx_body.outputs.iter() { if get_lovelace_from_alonzo_val(&output.amount) < compute_min_lovelace(output, prot_pps) { return Err(Alonzo(MinLovelaceUnreached)); @@ -321,7 +310,7 @@ fn compute_min_lovelace(output: &TransactionOutput, prot_pps: &AlonzoProtParams) // The size of the value in each of the outputs should not be greater than the // maximum allowed. -fn check_output_val_size( +pub fn check_output_val_size( tx_body: &TransactionBody, prot_pps: &AlonzoProtParams, ) -> ValidationResult { @@ -334,7 +323,7 @@ fn check_output_val_size( } // The network ID of the transaction and its output addresses is correct. -fn check_network_id(tx_body: &TransactionBody, network_id: &u8) -> ValidationResult { +pub fn check_network_id(tx_body: &TransactionBody, network_id: &u8) -> ValidationResult { check_tx_outs_network_id(tx_body, network_id)?; check_tx_network_id(tx_body, network_id) } @@ -363,7 +352,7 @@ fn check_tx_network_id(tx_body: &TransactionBody, network_id: &u8) -> Validation } // The transaction size does not exceed the protocol limit. -fn check_tx_size(size: &u32, prot_pps: &AlonzoProtParams) -> ValidationResult { +pub fn check_tx_size(size: &u32, prot_pps: &AlonzoProtParams) -> ValidationResult { if *size > prot_pps.max_transaction_size { return Err(Alonzo(MaxTxSizeExceeded)); } @@ -372,7 +361,7 @@ fn check_tx_size(size: &u32, prot_pps: &AlonzoProtParams) -> ValidationResult { // The number of execution units of the transaction should not exceed the // maximum allowed. -fn check_tx_ex_units(mtx: &MintedTx, prot_pps: &AlonzoProtParams) -> ValidationResult { +pub fn check_tx_ex_units(mtx: &MintedTx, prot_pps: &AlonzoProtParams) -> ValidationResult { let tx_wits: &MintedWitnessSet = &mtx.transaction_witness_set; if presence_of_plutus_scripts(mtx) { match &tx_wits.redeemer { @@ -393,7 +382,7 @@ fn check_tx_ex_units(mtx: &MintedTx, prot_pps: &AlonzoProtParams) -> ValidationR Ok(()) } -fn check_witness_set(mtx: &MintedTx, utxos: &UTxOs) -> ValidationResult { +pub fn check_witness_set(mtx: &MintedTx, utxos: &UTxOs) -> ValidationResult { let tx_hash: &Vec = &Vec::from(mtx.transaction_body.original_hash().as_ref()); let tx_body: &TransactionBody = &mtx.transaction_body; let tx_wits: &MintedWitnessSet = &mtx.transaction_witness_set; @@ -733,7 +722,7 @@ fn check_vkey_input_wits( Some(multi_era_output) => { if let Some(alonzo_comp_output) = MultiEraOutput::as_alonzo(multi_era_output) { match get_payment_part(&alonzo_comp_output.address) - .ok_or(Alonzo(InputDecoding))? + .ok_or(Alonzo(UnknownAddressFormat))? { ShelleyPaymentPart::Key(payment_key_hash) => { check_vk_wit(&payment_key_hash, vk_wits, tx_hash)? @@ -821,12 +810,12 @@ fn find_and_check_req_signer( } // The required script languages are included in the protocol parameters. -fn check_languages(_mtx: &MintedTx, _prot_pps: &AlonzoProtParams) -> ValidationResult { +pub fn check_languages(_mtx: &MintedTx, _prot_pps: &AlonzoProtParams) -> ValidationResult { Ok(()) } // The metadata of the transaction is valid. -fn check_auxiliary_data(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { +pub fn check_auxiliary_data(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { match ( &tx_body.auxiliary_data_hash, aux_data_from_alonzo_minted_tx(mtx), @@ -837,17 +826,19 @@ fn check_auxiliary_data(tx_body: &TransactionBody, mtx: &MintedTx) -> Validation { Ok(()) } else { - Err(Alonzo(MetadataHash)) + Err(Alonzo(WrongMetadataHash)) // Computed metadata hash is + // wrong. } } + (Some(_), None) => Err(Alonzo(UnneededAuxDataHash)), + (None, Some(_)) => Err(Alonzo(AuxDataHashMissing)), (None, None) => Ok(()), - _ => Err(Alonzo(MetadataHash)), } } // The script data integrity hash matches the hash of the redeemers, languages // and datums of the transaction witness set. -fn check_script_data_hash(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { +pub fn check_script_data_hash(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { match tx_body.script_data_hash { Some(script_data_hash) => match ( &mtx.transaction_witness_set.plutus_data, @@ -864,7 +855,9 @@ fn check_script_data_hash(tx_body: &TransactionBody, mtx: &MintedTx) -> Validati Err(Alonzo(ScriptIntegrityHash)) } } - (_, _) => Err(Alonzo(ScriptIntegrityHash)), + (Some(_), None) => Err(Alonzo(RedeemerMissing)), + (None, Some(_)) => Err(Alonzo(DatumMissing)), + (None, None) => Err(Alonzo(RedeemerAndDatumMissing)), }, None => { if option_vec_is_empty(&mtx.transaction_witness_set.plutus_data) @@ -912,7 +905,7 @@ fn option_vec_is_empty(option_vec: &Option>) -> bool { // Each minted / burned asset is paired with an appropriate native script or // Plutus script. -fn check_minting(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { +pub fn check_minting(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { match &tx_body.mint { Some(minted_value) => { let native_script_wits: Vec = diff --git a/pallas-applying/src/babbage.rs b/pallas-applying/src/babbage.rs index 2dfa17f9..f07ef28b 100644 --- a/pallas-applying/src/babbage.rs +++ b/pallas-applying/src/babbage.rs @@ -5,7 +5,7 @@ use crate::utils::{ compute_plutus_script_hash, compute_plutus_v2_script_hash, empty_value, get_babbage_tx_size, get_lovelace_from_alonzo_val, get_network_id_value, get_payment_part, get_shelley_address, get_val_size_in_words, is_byron_address, lovelace_diff_or_fail, mk_alonzo_vk_wits_check_list, - values_are_equal, verify_signature, + value_from_multi_era_output, values_are_equal, verify_signature, BabbageError::*, BabbageProtParams, UTxOs, ValidationError::{self, *}, @@ -58,7 +58,7 @@ pub fn validate_babbage_tx( } // The set of transaction inputs is not empty. -fn check_ins_not_empty(tx_body: &MintedTransactionBody) -> ValidationResult { +pub fn check_ins_not_empty(tx_body: &MintedTransactionBody) -> ValidationResult { if tx_body.inputs.is_empty() { return Err(Babbage(TxInsEmpty)); } @@ -67,7 +67,7 @@ fn check_ins_not_empty(tx_body: &MintedTransactionBody) -> ValidationResult { // All transaction inputs, collateral inputs and reference inputs are in the // UTxO set. -fn check_all_ins_in_utxos(tx_body: &MintedTransactionBody, utxos: &UTxOs) -> ValidationResult { +pub fn check_all_ins_in_utxos(tx_body: &MintedTransactionBody, utxos: &UTxOs) -> ValidationResult { for input in tx_body.inputs.iter() { if !(utxos.contains_key(&MultiEraInput::from_alonzo_compatible(input))) { return Err(Babbage(InputNotInUTxO)); @@ -98,7 +98,7 @@ fn check_all_ins_in_utxos(tx_body: &MintedTransactionBody, utxos: &UTxOs) -> Val // The block slot is contained in the transaction validity interval, and the // upper bound is translatable to UTC time. -fn check_tx_validity_interval( +pub fn check_tx_validity_interval( tx_body: &MintedTransactionBody, block_slot: &u64, ) -> ValidationResult { @@ -137,7 +137,7 @@ fn check_upper_bound(tx_body: &MintedTransactionBody, block_slot: u64) -> Valida } } -fn check_fee( +pub fn check_fee( tx_body: &MintedTransactionBody, size: &u32, mtx: &MintedTx, @@ -188,7 +188,7 @@ fn check_collaterals( .ok_or(Babbage(CollateralMissing))?; check_collaterals_number(collaterals, prot_pps)?; check_collaterals_address(collaterals, utxos)?; - check_collaterals_assets(tx_body, utxos, prot_pps) + check_collaterals_assets(tx_body, collaterals, utxos, prot_pps) } // The set of collateral inputs is not empty. @@ -217,7 +217,7 @@ fn check_collaterals_address(collaterals: &[TransactionInput], utxos: &UTxOs) -> PseudoTransactionOutput::PostAlonzo(inner) => &inner.address, }; if let ShelleyPaymentPart::Script(_) = - get_payment_part(address).ok_or(Babbage(InputDecoding))? + get_payment_part(address).ok_or(Babbage(UnknownAddressFormat))? { return Err(Babbage(CollateralNotVKeyLocked)); } @@ -236,66 +236,71 @@ fn check_collaterals_address(collaterals: &[TransactionInput], utxos: &UTxOs) -> // The balance matches exactly the collateral annotated in the transaction body. fn check_collaterals_assets( tx_body: &MintedTransactionBody, + collaterals: &[TransactionInput], utxos: &UTxOs, prot_pps: &BabbageProtParams, ) -> ValidationResult { - match &tx_body.collateral { - Some(collaterals) => { - let mut coll_input: Value = empty_value(); - for collateral in collaterals { - match utxos.get(&MultiEraInput::from_alonzo_compatible(collateral)) { - Some(multi_era_output) => { - coll_input = add_values( - &coll_input, - &val_from_multi_era_output(multi_era_output), - &Babbage(NegativeValue), - )? - } - None => { - return Err(Babbage(CollateralNotInUTxO)); - } - } - } - let coll_return: Value = match &tx_body.collateral_return { - Some(PseudoTransactionOutput::Legacy(output)) => output.amount.clone(), - Some(PseudoTransactionOutput::PostAlonzo(output)) => output.value.clone(), - None => Value::Coin(0), - }; - // The balance between collateral inputs and output contains only lovelace. - let paid_collateral: u64 = - lovelace_diff_or_fail(&coll_input, &coll_return, &Babbage(NonLovelaceCollateral))?; - let fee_percentage: u64 = tx_body.fee * prot_pps.collateral_percentage as u64; - // The balance is not lower than the minimum allowed. - if paid_collateral * 100 < fee_percentage { - return Err(Babbage(CollateralMinLovelace)); + let mut coll_input: Value = empty_value(); + for collateral in collaterals { + match utxos.get(&MultiEraInput::from_alonzo_compatible(collateral)) { + Some(multi_era_output) => { + coll_input = add_values( + &coll_input, + &value_from_multi_era_output(multi_era_output), + &Babbage(NegativeValue), + )? } - // The balance matches exactly the collateral annotated in the transaction body. - if let Some(annotated_collateral) = &tx_body.total_collateral { - if paid_collateral != *annotated_collateral { - return Err(Babbage(CollateralAnnotation)); - } + None => { + return Err(Babbage(CollateralNotInUTxO)); } } - None => return Err(Babbage(CollateralMissing)), - } - Ok(()) -} - -fn val_from_multi_era_output(multi_era_output: &MultiEraOutput) -> Value { - match multi_era_output { - MultiEraOutput::Byron(output) => Value::Coin(output.amount), - MultiEraOutput::AlonzoCompatible(output) => output.amount.clone(), - babbage_output => match babbage_output.as_babbage() { + let coll_return: Value = match &tx_body.collateral_return { Some(PseudoTransactionOutput::Legacy(output)) => output.amount.clone(), Some(PseudoTransactionOutput::PostAlonzo(output)) => output.value.clone(), - None => unimplemented!(), /* If this is the case, then it must be that non-exhaustive - * type MultiEraOutput was extended with another variant */ - }, + None => Value::Coin(0), + }; + // The balance between collateral inputs and output contains only lovelace. + let paid_collateral: u64 = + lovelace_diff_or_fail(&coll_input, &coll_return, &Babbage(NonLovelaceCollateral))?; + let fee_percentage: u64 = tx_body.fee * prot_pps.collateral_percentage as u64; + // The balance is not lower than the minimum allowed. + if paid_collateral * 100 < fee_percentage { + return Err(Babbage(CollateralMinLovelace)); + } + // The balance matches exactly the collateral annotated in the transaction body. + if let Some(annotated_collateral) = &tx_body.total_collateral { + if paid_collateral != *annotated_collateral { + return Err(Babbage(CollateralAnnotation)); + } + } + } + let coll_return: Value = match &tx_body.collateral_return { + Some(PseudoTransactionOutput::Legacy(output)) => output.amount.clone(), + Some(PseudoTransactionOutput::PostAlonzo(output)) => output.value.clone(), + None => Value::Coin(0), + }; + // The balance between collateral inputs and output contains only lovelace. + let paid_collateral: u64 = + lovelace_diff_or_fail(&coll_input, &coll_return, &Babbage(NonLovelaceCollateral))?; + let fee_percentage: u64 = tx_body.fee * prot_pps.collateral_percentage as u64; + // The balance is not lower than the minimum allowed. + if paid_collateral * 100 < fee_percentage { + return Err(Babbage(CollateralMinLovelace)); + } + // The balance matches exactly the collateral annotated in the transaction body. + if let Some(annotated_collateral) = &tx_body.total_collateral { + if paid_collateral != *annotated_collateral { + return Err(Babbage(CollateralAnnotation)); + } } + Ok(()) } // The preservation of value property holds. -fn check_preservation_of_value(tx_body: &MintedTransactionBody, utxos: &UTxOs) -> ValidationResult { +pub fn check_preservation_of_value( + tx_body: &MintedTransactionBody, + utxos: &UTxOs, +) -> ValidationResult { let mut input: Value = get_consumed(tx_body, utxos)?; let produced: Value = get_produced(tx_body)?; let output: Value = add_values( @@ -318,7 +323,7 @@ fn get_consumed(tx_body: &MintedTransactionBody, utxos: &UTxOs) -> Result Result ValidationResult { @@ -361,7 +366,7 @@ fn compute_min_lovelace(val: &Value, prot_pps: &BabbageProtParams) -> u64 { // The size of the value in each of the outputs should not be greater than the // maximum allowed. -fn check_output_val_size( +pub fn check_output_val_size( tx_body: &MintedTransactionBody, prot_pps: &BabbageProtParams, ) -> ValidationResult { @@ -377,7 +382,7 @@ fn check_output_val_size( Ok(()) } -fn check_network_id(tx_body: &MintedTransactionBody, network_id: &u8) -> ValidationResult { +pub fn check_network_id(tx_body: &MintedTransactionBody, network_id: &u8) -> ValidationResult { check_tx_outs_network_id(tx_body, network_id)?; check_tx_network_id(tx_body, network_id) } @@ -389,7 +394,7 @@ fn check_tx_outs_network_id(tx_body: &MintedTransactionBody, network_id: &u8) -> PseudoTransactionOutput::PostAlonzo(output) => &output.address, }; let addr: ShelleyAddress = - get_shelley_address(Bytes::deref(addr_bytes)).ok_or(Babbage(AddressDecoding))?; + get_shelley_address(Bytes::deref(addr_bytes)).ok_or(Babbage(UnknownAddressFormat))?; if addr.network().value() != *network_id { return Err(Babbage(OutputWrongNetworkID)); } @@ -408,14 +413,14 @@ fn check_tx_network_id(tx_body: &MintedTransactionBody, network_id: &u8) -> Vali Ok(()) } -fn check_tx_size(size: &u32, prot_pps: &BabbageProtParams) -> ValidationResult { +pub fn check_tx_size(size: &u32, prot_pps: &BabbageProtParams) -> ValidationResult { if *size > prot_pps.max_transaction_size { return Err(Babbage(MaxTxSizeExceeded)); } Ok(()) } -fn check_tx_ex_units(mtx: &MintedTx, prot_pps: &BabbageProtParams) -> ValidationResult { +pub fn check_tx_ex_units(mtx: &MintedTx, prot_pps: &BabbageProtParams) -> ValidationResult { let tx_wits: &MintedWitnessSet = &mtx.transaction_witness_set; if presence_of_plutus_scripts(mtx) { match &tx_wits.redeemer { @@ -438,7 +443,7 @@ fn check_tx_ex_units(mtx: &MintedTx, prot_pps: &BabbageProtParams) -> Validation // Each minted / burned asset is paired with an appropriate native script or // Plutus script. -fn check_minting(tx_body: &MintedTransactionBody, mtx: &MintedTx) -> ValidationResult { +pub fn check_minting(tx_body: &MintedTransactionBody, mtx: &MintedTx) -> ValidationResult { match &tx_body.mint { Some(minted_value) => { let native_script_wits: Vec = @@ -479,11 +484,14 @@ fn check_minting(tx_body: &MintedTransactionBody, mtx: &MintedTx) -> ValidationR } } -fn check_well_formedness(_tx_body: &MintedTransactionBody, _mtx: &MintedTx) -> ValidationResult { +pub fn check_well_formedness( + _tx_body: &MintedTransactionBody, + _mtx: &MintedTx, +) -> ValidationResult { Ok(()) } -fn check_witness_set(mtx: &MintedTx, utxos: &UTxOs) -> ValidationResult { +pub fn check_witness_set(mtx: &MintedTx, utxos: &UTxOs) -> ValidationResult { let tx_hash: &Vec = &Vec::from(mtx.transaction_body.original_hash().as_ref()); let tx_body: &MintedTransactionBody = &mtx.transaction_body; let tx_wits: &MintedWitnessSet = &mtx.transaction_witness_set; @@ -1097,7 +1105,7 @@ fn check_vkey_input_wits( PseudoTransactionOutput::Legacy(output) => &output.address, PseudoTransactionOutput::PostAlonzo(output) => &output.address, }; - match get_payment_part(address).ok_or(Babbage(InputDecoding))? { + match get_payment_part(address).ok_or(Babbage(UnknownAddressFormat))? { ShelleyPaymentPart::Key(payment_key_hash) => { check_vk_wit(&payment_key_hash, vk_wits, tx_hash)? } @@ -1145,7 +1153,7 @@ fn check_remaining_vk_wits( Ok(()) } -fn check_languages( +pub fn check_languages( mtx: &MintedTx, utxos: &UTxOs, network_magic: &u32, @@ -1330,7 +1338,7 @@ fn tx_languages(mtx: &MintedTx, utxos: &UTxOs) -> Vec { } // The metadata of the transaction is valid. -fn check_auxiliary_data(tx_body: &MintedTransactionBody, mtx: &MintedTx) -> ValidationResult { +pub fn check_auxiliary_data(tx_body: &MintedTransactionBody, mtx: &MintedTx) -> ValidationResult { match ( &tx_body.auxiliary_data_hash, aux_data_from_babbage_minted_tx(mtx), @@ -1341,15 +1349,16 @@ fn check_auxiliary_data(tx_body: &MintedTransactionBody, mtx: &MintedTx) -> Vali { Ok(()) } else { - Err(Babbage(MetadataHash)) + Err(Babbage(WrongMetadataHash)) } } + (None, Some(_)) => Err(Babbage(AuxDataHashMissing)), + (Some(_), None) => Err(Babbage(UnneededAuxDataHash)), (None, None) => Ok(()), - _ => Err(Babbage(MetadataHash)), } } -fn check_script_data_hash( +pub fn check_script_data_hash( tx_body: &MintedTransactionBody, mtx: &MintedTx, utxos: &UTxOs, @@ -1384,15 +1393,17 @@ fn check_script_data_hash( Err(Babbage(ScriptIntegrityHash)) } } - (_, _) => Err(Babbage(ScriptIntegrityHash)), + (Some(_), None) => Err(Babbage(RedeemerMissing)), + (None, Some(_)) => Err(Babbage(DatumMissing)), + (None, None) => Err(Babbage(RedeemerAndDatumMissing)), }, None => { - if option_vec_is_empty(&mtx.transaction_witness_set.plutus_data) - && option_vec_is_empty(&mtx.transaction_witness_set.redeemer) - { - Ok(()) + if !option_vec_is_empty(&mtx.transaction_witness_set.plutus_data) { + Err(Babbage(UnneededDatum)) + } else if !option_vec_is_empty(&mtx.transaction_witness_set.redeemer) { + Err(Babbage(UnneededRedeemer)) } else { - Err(Babbage(ScriptIntegrityHash)) + Ok(()) } } } diff --git a/pallas-applying/src/byron.rs b/pallas-applying/src/byron.rs index c95c1651..bec6b4bb 100644 --- a/pallas-applying/src/byron.rs +++ b/pallas-applying/src/byron.rs @@ -42,21 +42,21 @@ pub fn validate_byron_tx( check_witnesses(mtxp, utxos, prot_magic) } -fn check_ins_not_empty(tx: &Tx) -> ValidationResult { +pub fn check_ins_not_empty(tx: &Tx) -> ValidationResult { if tx.inputs.clone().to_vec().is_empty() { return Err(Byron(TxInsEmpty)); } Ok(()) } -fn check_outs_not_empty(tx: &Tx) -> ValidationResult { +pub fn check_outs_not_empty(tx: &Tx) -> ValidationResult { if tx.outputs.clone().to_vec().is_empty() { return Err(Byron(TxOutsEmpty)); } Ok(()) } -fn check_ins_in_utxos(tx: &Tx, utxos: &UTxOs) -> ValidationResult { +pub fn check_ins_in_utxos(tx: &Tx, utxos: &UTxOs) -> ValidationResult { for input in tx.inputs.iter() { if !(utxos.contains_key(&MultiEraInput::from_byron(input))) { return Err(Byron(InputNotInUTxO)); @@ -65,7 +65,7 @@ fn check_ins_in_utxos(tx: &Tx, utxos: &UTxOs) -> ValidationResult { Ok(()) } -fn check_outs_have_lovelace(tx: &Tx) -> ValidationResult { +pub fn check_outs_have_lovelace(tx: &Tx) -> ValidationResult { for output in tx.outputs.iter() { if output.amount == 0 { return Err(Byron(OutputWithoutLovelace)); @@ -74,7 +74,12 @@ fn check_outs_have_lovelace(tx: &Tx) -> ValidationResult { Ok(()) } -fn check_fees(tx: &Tx, size: &u64, utxos: &UTxOs, prot_pps: &ByronProtParams) -> ValidationResult { +pub fn check_fees( + tx: &Tx, + size: &u64, + utxos: &UTxOs, + prot_pps: &ByronProtParams, +) -> ValidationResult { let mut inputs_balance: u64 = 0; let mut only_redeem_utxos: bool = true; for input in tx.inputs.iter() { @@ -119,7 +124,7 @@ fn is_redeem_utxo(input: &TxIn, utxos: &UTxOs) -> bool { } } -fn check_size(size: &u64, prot_pps: &ByronProtParams) -> ValidationResult { +pub fn check_size(size: &u64, prot_pps: &ByronProtParams) -> ValidationResult { if *size > prot_pps.max_tx_size { return Err(Byron(MaxTxSizeExceeded)); } @@ -139,7 +144,11 @@ pub enum TaggedSignature<'a> { RedeemWitness(&'a ByronSignature), } -fn check_witnesses(mtxp: &MintedTxPayload, utxos: &UTxOs, prot_magic: &u32) -> ValidationResult { +pub fn check_witnesses( + mtxp: &MintedTxPayload, + utxos: &UTxOs, + prot_magic: &u32, +) -> ValidationResult { let tx: &Tx = &mtxp.transaction; let tx_hash: Hash<32> = mtxp.transaction.original_hash(); let witnesses: Vec<(&PubKey, TaggedSignature)> = tag_witnesses(&mtxp.witness)?; @@ -167,7 +176,7 @@ fn tag_witnesses(wits: &[Twit]) -> Result, Valid Twit::RedeemWitness(CborWrap((pk, sig))) => { res.push((pk, TaggedSignature::RedeemWitness(sig))); } - _ => return Err(Byron(UnableToProcessWitness)), + _ => return Err(Byron(UnknownWitnessFormat)), // Unsupported witness format } } Ok(res) @@ -179,7 +188,8 @@ fn find_tx_out<'a>(input: &'a TxIn, utxos: &'a UTxOs) -> Result<&'a TxOut, Valid .get(&key) .ok_or(Byron(InputNotInUTxO))? .as_byron() - .ok_or(Byron(InputNotInUTxO)) + .ok_or(Byron(UnknownTxOutFormat)) // Unable to parse the MultiEraOutput + // as a Byron TxOut } fn find_raw_witness<'a>( @@ -187,9 +197,7 @@ fn find_raw_witness<'a>( witnesses: &'a Vec<(&'a PubKey, TaggedSignature<'a>)>, ) -> Result<(&'a PubKey, &'a TaggedSignature<'a>), ValidationError> { let address: ByronAddress = mk_byron_address(&tx_out.address); - let addr_payload: AddressPayload = address - .decode() - .map_err(|_| Byron(UnableToProcessWitness))?; + let addr_payload: AddressPayload = address.decode().map_err(|_| Byron(UnknownAddressFormat))?; // Unable to decode address let root: AddressId = addr_payload.root; let attr: AddrAttrs = addr_payload.attributes; let addr_type: AddrType = addr_payload.addrtype; @@ -197,7 +205,7 @@ fn find_raw_witness<'a>( if redeems(pub_key, sign, &root, &attr, &addr_type) { match addr_type { AddrType::PubKey | AddrType::Redeem => return Ok((pub_key, sign)), - _ => return Err(Byron(UnableToProcessWitness)), + _ => return Err(Byron(UnknownAddressFormat)), // Unknown address type } } } @@ -252,17 +260,19 @@ fn get_data_to_verify( match sign { TaggedSignature::PkWitness(_) => { enc.encode(1u64) - .map_err(|_| Byron(UnableToProcessWitness))?; + .map_err(|_| Byron(EncodingErrorWitsCheck))?; + // Encoding error while checking wits } TaggedSignature::RedeemWitness(_) => { enc.encode(2u64) - .map_err(|_| Byron(UnableToProcessWitness))?; + .map_err(|_| Byron(EncodingErrorWitsCheck))?; + // Encoding error while checking wits } } enc.encode(prot_magic) - .map_err(|_| Byron(UnableToProcessWitness))?; + .map_err(|_| Byron(EncodingErrorWitsCheck))?; // Encoding error while checking wits enc.encode(tx_hash) - .map_err(|_| Byron(UnableToProcessWitness))?; + .map_err(|_| Byron(EncodingErrorWitsCheck))?; // Encoding error while checking wits Ok(enc.into_writer().clone()) } diff --git a/pallas-applying/src/shelley_ma.rs b/pallas-applying/src/shelley_ma.rs index 5c280642..c969ed97 100644 --- a/pallas-applying/src/shelley_ma.rs +++ b/pallas-applying/src/shelley_ma.rs @@ -36,7 +36,7 @@ pub fn validate_shelley_ma_tx( check_ins_in_utxos(tx_body, utxos)?; check_ttl(tx_body, block_slot)?; check_tx_size(size, prot_pps)?; - check_min_lovelace(tx_body, prot_pps, era)?; + check_min_lovelace(tx_body, prot_pps)?; check_preservation_of_value(tx_body, utxos, era)?; check_fees(tx_body, size, prot_pps)?; check_network_id(tx_body, network_id)?; @@ -45,14 +45,14 @@ pub fn validate_shelley_ma_tx( check_minting(tx_body, mtx) } -fn check_ins_not_empty(tx_body: &TransactionBody) -> ValidationResult { +pub fn check_ins_not_empty(tx_body: &TransactionBody) -> ValidationResult { if tx_body.inputs.is_empty() { return Err(ShelleyMA(TxInsEmpty)); } Ok(()) } -fn check_ins_in_utxos(tx_body: &TransactionBody, utxos: &UTxOs) -> ValidationResult { +pub fn check_ins_in_utxos(tx_body: &TransactionBody, utxos: &UTxOs) -> ValidationResult { for input in tx_body.inputs.iter() { if !(utxos.contains_key(&MultiEraInput::from_alonzo_compatible(input))) { return Err(ShelleyMA(InputNotInUTxO)); @@ -61,7 +61,7 @@ fn check_ins_in_utxos(tx_body: &TransactionBody, utxos: &UTxOs) -> ValidationRes Ok(()) } -fn check_ttl(tx_body: &TransactionBody, block_slot: &u64) -> ValidationResult { +pub fn check_ttl(tx_body: &TransactionBody, block_slot: &u64) -> ValidationResult { match tx_body.ttl { Some(ttl) => { if ttl < *block_slot { @@ -74,28 +74,20 @@ fn check_ttl(tx_body: &TransactionBody, block_slot: &u64) -> ValidationResult { } } -fn check_tx_size(size: &u32, prot_pps: &ShelleyProtParams) -> ValidationResult { +pub fn check_tx_size(size: &u32, prot_pps: &ShelleyProtParams) -> ValidationResult { if *size > prot_pps.max_transaction_size { return Err(ShelleyMA(MaxTxSizeExceeded)); } Ok(()) } -fn check_min_lovelace( +pub fn check_min_lovelace( tx_body: &TransactionBody, prot_pps: &ShelleyProtParams, - era: &Era, ) -> ValidationResult { for output in &tx_body.outputs { - match era { - Era::Shelley | Era::Allegra | Era::Mary => { - if get_lovelace_from_alonzo_val(&output.amount) - < compute_min_lovelace(output, prot_pps) - { - return Err(ShelleyMA(MinLovelaceUnreached)); - } - } - _ => return Err(ShelleyMA(ValueNotShelley)), + if get_lovelace_from_alonzo_val(&output.amount) < compute_min_lovelace(output, prot_pps) { + return Err(ShelleyMA(MinLovelaceUnreached)); } } Ok(()) @@ -112,7 +104,7 @@ fn compute_min_lovelace(output: &TransactionOutput, prot_pps: &ShelleyProtParams } } -fn check_preservation_of_value( +pub fn check_preservation_of_value( tx_body: &TransactionBody, utxos: &UTxOs, era: &Era, @@ -125,7 +117,7 @@ fn check_preservation_of_value( add_minted_value(&output, m, &neg_val_err)?; } if !values_are_equal(&input, &output) { - return Err(ShelleyMA(PreservationOfValue)); + return Err(ShelleyMA(PreservationOfValueProp)); } Ok(()) } @@ -144,14 +136,17 @@ fn get_consumed( match MultiEraOutput::as_alonzo(utxo_value) { Some(TransactionOutput { amount, .. }) => match (amount, era) { (Value::Coin(..), _) => res = add_values(&res, amount, &neg_val_err)?, - (Value::Multiasset(..), Era::Shelley) => return Err(ShelleyMA(ValueNotShelley)), + (Value::Multiasset(..), Era::Shelley) => return Err(ShelleyMA(UnknownValueFormat)), + // Shelley does not come with multisaset + // values, unlike Mary or Allegra _ => res = add_values(&res, amount, &neg_val_err)?, }, None => match MultiEraOutput::as_byron(utxo_value) { Some(TxOut { amount, .. }) => { res = add_values(&res, &Value::Coin(*amount), &neg_val_err)? } - _ => return Err(ShelleyMA(InputNotInUTxO)), + _ => return Err(ShelleyMA(UnknownInputFormat)), + // Unable to parse as ShelleyMA TransactionOutput or as Byron TxOut }, } } @@ -171,7 +166,7 @@ fn get_produced(tx_body: &TransactionBody, era: &Era) -> Result ValidationResult { +pub fn check_network_id(tx_body: &TransactionBody, network_id: &u8) -> ValidationResult { for output in tx_body.outputs.iter() { let addr: ShelleyAddress = - get_shelley_address(&output.address).ok_or(ShelleyMA(AddressDecoding))?; + get_shelley_address(&output.address).ok_or(ShelleyMA(UnknownAddressFormat))?; if addr.network().value() != *network_id { return Err(ShelleyMA(WrongNetworkID)); } @@ -193,7 +188,7 @@ fn check_network_id(tx_body: &TransactionBody, network_id: &u8) -> ValidationRes Ok(()) } -fn check_metadata(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { +pub fn check_metadata(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { match ( &tx_body.auxiliary_data_hash, aux_data_from_alonzo_minted_tx(mtx), @@ -204,15 +199,17 @@ fn check_metadata(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { Ok(()) } else { - Err(ShelleyMA(MetadataHash)) + Err(ShelleyMA(WrongMetadataHash)) // Computed metadata hash is + // wrong. } } + (Some(_), None) => Err(ShelleyMA(UnneededAuxDataHash)), // metadata hash without metadata + (None, Some(_)) => Err(ShelleyMA(MissingAuxDataHash)), // metadata without metadata hash (None, None) => Ok(()), - _ => Err(ShelleyMA(MetadataHash)), } } -fn check_witnesses( +pub fn check_witnesses( tx_body: &TransactionBody, tx_wits: &MintedWitnessSet, utxos: &UTxOs, @@ -225,7 +222,7 @@ fn check_witnesses( Some(multi_era_output) => { if let Some(alonzo_comp_output) = MultiEraOutput::as_alonzo(multi_era_output) { match get_payment_part(&alonzo_comp_output.address) - .ok_or(ShelleyMA(AddressDecoding))? + .ok_or(ShelleyMA(UnknownAddressFormat))? { ShelleyPaymentPart::Key(payment_key_hash) => { check_vk_wit(&payment_key_hash, tx_hash, vk_wits)? @@ -257,11 +254,15 @@ fn check_vk_wit( *found = true; return Ok(()); } else { - return Err(ShelleyMA(WrongSignature)); + return Err(ShelleyMA(WrongSignature)); // Provided and computed + // hashes match but + // signature was not + // verified } } } - Err(ShelleyMA(MissingVKWitness)) + Err(ShelleyMA(MissingVKWitness)) // A matching witness for payment_key_hash + // was not found. } fn check_native_script_witness( @@ -277,9 +278,10 @@ fn check_native_script_witness( return Ok(()); } } - Err(ShelleyMA(MissingScriptWitness)) + Err(ShelleyMA(MissingScriptWitness)) // script_hash does not have a + // matching witness } - None => Err(ShelleyMA(MissingScriptWitness)), + None => Err(ShelleyMA(MissingScriptWitness)), // No script witnesses were provided } } @@ -299,7 +301,7 @@ fn check_remaining_vk_wits( Ok(()) } -fn check_minting(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { +pub fn check_minting(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult { match &tx_body.mint { Some(minted_value) => { let native_script_wits: Vec = diff --git a/pallas-applying/src/utils.rs b/pallas-applying/src/utils.rs index 5c375af6..126276c7 100644 --- a/pallas-applying/src/utils.rs +++ b/pallas-applying/src/utils.rs @@ -15,7 +15,9 @@ use pallas_primitives::{ AssetName, AuxiliaryData, Coin, MintedTx as AlonzoMintedTx, Multiasset, NativeScript, NetworkId, PlutusScript, PolicyId, TransactionBody, VKeyWitness, Value, }, - babbage::{MintedTransactionBody, MintedTx as BabbageMintedTx, PlutusV2Script}, + babbage::{ + MintedTransactionBody, MintedTx as BabbageMintedTx, PlutusV2Script, PseudoTransactionOutput, + }, }; use pallas_traverse::{MultiEraInput, MultiEraOutput}; use std::collections::HashMap; @@ -248,6 +250,19 @@ fn find_assets(assets: &KeyValuePairs, asset_name: &AssetName) None } +pub fn value_from_multi_era_output(multi_era_output: &MultiEraOutput) -> Value { + match multi_era_output { + MultiEraOutput::Byron(output) => Value::Coin(output.amount), + MultiEraOutput::AlonzoCompatible(output) => output.amount.clone(), + babbage_output => match babbage_output.as_babbage() { + Some(PseudoTransactionOutput::Legacy(output)) => output.amount.clone(), + Some(PseudoTransactionOutput::PostAlonzo(output)) => output.value.clone(), + None => unimplemented!(), /* If this is the case, then it must be that non-exhaustive + * type MultiEraOutput was extended with another variant */ + }, + } +} + pub fn get_lovelace_from_alonzo_val(val: &Value) -> Coin { match val { Value::Coin(res) => *res, @@ -268,7 +283,7 @@ pub fn mk_alonzo_vk_wits_check_list( ) -> Result, ValidationError> { Ok(wits .clone() - .ok_or(err)? + .ok_or(err)? // An error indicating wits is a None value .iter() .map(|x| (false, x.clone())) .collect::>()) diff --git a/pallas-applying/src/utils/validation.rs b/pallas-applying/src/utils/validation.rs index 5b560b40..3e0b9440 100644 --- a/pallas-applying/src/utils/validation.rs +++ b/pallas-applying/src/utils/validation.rs @@ -22,9 +22,12 @@ pub enum ByronError { UnableToComputeFees, FeesBelowMin, MaxTxSizeExceeded, - UnableToProcessWitness, MissingWitness, WrongSignature, + UnknownTxOutFormat, + UnknownAddressFormat, + UnknownWitnessFormat, + EncodingErrorWitsCheck, } #[derive(Debug, Clone)] @@ -36,19 +39,23 @@ pub enum ShelleyMAError { AlonzoCompNotShelley, UnknownTxSize, MaxTxSizeExceeded, - ValueNotShelley, MinLovelaceUnreached, - PreservationOfValue, + PreservationOfValueProp, NegativeValue, FeesBelowMin, WrongEraOutput, AddressDecoding, WrongNetworkID, - MetadataHash, + WrongMetadataHash, MissingVKWitness, MissingScriptWitness, WrongSignature, MintingLacksPolicy, + UnknownAddressFormat, + UnknownInputFormat, + UnknownValueFormat, + MissingAuxDataHash, + UnneededAuxDataHash, } #[derive(Debug, Clone)] @@ -58,8 +65,8 @@ pub enum AlonzoError { TxInsEmpty, InputNotInUTxO, CollateralNotInUTxO, - BlockExceedsValInt, BlockPrecedesValInt, + BlockExceedsValInt, ValIntUpperBoundMissing, FeeBelowMin, CollateralMissing, @@ -74,7 +81,6 @@ pub enum AlonzoError { MaxValSizeExceeded, OutputWrongNetworkID, TxWrongNetworkID, - RedeemerMissing, TxExUnitsExceeded, MaxTxSizeExceeded, VKWitnessMissing, @@ -83,14 +89,18 @@ pub enum AlonzoError { ReqSignerWrongSig, ScriptWitnessMissing, MintingLacksPolicy, - InputDecoding, UnneededNativeScript, UnneededPlutusScript, + RedeemerMissing, UnneededRedeemer, DatumMissing, UnneededDatum, - MetadataHash, + RedeemerAndDatumMissing, + WrongMetadataHash, + AuxDataHashMissing, + UnneededAuxDataHash, ScriptIntegrityHash, + UnknownAddressFormat, } #[derive(Debug, Clone)] @@ -101,33 +111,32 @@ pub enum BabbageError { InputNotInUTxO, CollateralNotInUTxO, ReferenceInputNotInUTxO, - RefInputNotInUTxO, BlockPrecedesValInt, BlockExceedsValInt, FeeBelowMin, CollateralMissing, TooManyCollaterals, - InputDecoding, CollateralNotVKeyLocked, CollateralMinLovelace, NonLovelaceCollateral, - CollateralWrongAssets, NegativeValue, CollateralAnnotation, PreservationOfValue, MinLovelaceUnreached, MaxValSizeExceeded, - AddressDecoding, OutputWrongNetworkID, TxWrongNetworkID, TxExUnitsExceeded, RedeemerMissing, UnneededRedeemer, - MaxTxSizeExceeded, - MintingLacksPolicy, - MetadataHash, DatumMissing, UnneededDatum, + RedeemerAndDatumMissing, + MaxTxSizeExceeded, + MintingLacksPolicy, + WrongMetadataHash, + AuxDataHashMissing, + UnneededAuxDataHash, ScriptWitnessMissing, UnneededNativeScript, UnneededPlutusV1Script, @@ -138,6 +147,7 @@ pub enum BabbageError { VKWrongSignature, UnsupportedPlutusLanguage, ScriptIntegrityHash, + UnknownAddressFormat, } pub type ValidationResult = Result<(), ValidationError>; diff --git a/pallas-applying/tests/alonzo.rs b/pallas-applying/tests/alonzo.rs index 3cb8c97e..495c8427 100644 --- a/pallas-applying/tests/alonzo.rs +++ b/pallas-applying/tests/alonzo.rs @@ -2129,7 +2129,7 @@ mod alonzo_tests { match validate(&metx, &utxos, &env) { Ok(()) => panic!("Transaction auxiliary data removed"), Err(err) => match err { - Alonzo(AlonzoError::MetadataHash) => (), + Alonzo(AlonzoError::UnneededAuxDataHash) => (), _ => panic!("Unexpected error ({:?})", err), }, } diff --git a/pallas-applying/tests/babbage.rs b/pallas-applying/tests/babbage.rs index 6acc31a5..c2dee267 100644 --- a/pallas-applying/tests/babbage.rs +++ b/pallas-applying/tests/babbage.rs @@ -1719,7 +1719,7 @@ mod babbage_tests { match validate(&metx, &utxos, &env) { Ok(()) => assert!(false, "Transaction auxiliary data removed"), Err(err) => match err { - Babbage(BabbageError::MetadataHash) => (), + Babbage(BabbageError::UnneededAuxDataHash) => (), _ => assert!(false, "Unexpected error ({:?})", err), }, } diff --git a/pallas-applying/tests/shelley_ma.rs b/pallas-applying/tests/shelley_ma.rs index a4ea1b9c..d5c5ca95 100644 --- a/pallas-applying/tests/shelley_ma.rs +++ b/pallas-applying/tests/shelley_ma.rs @@ -739,7 +739,7 @@ mod shelley_ma_tests { match validate(&metx, &utxos, &env) { Ok(()) => panic!("Preservation of value property doesn't hold"), Err(err) => match err { - ShelleyMA(ShelleyMAError::PreservationOfValue) => (), + ShelleyMA(ShelleyMAError::PreservationOfValueProp) => (), _ => panic!("Unexpected error ({:?})", err), }, } @@ -965,7 +965,7 @@ mod shelley_ma_tests { match validate(&metx, &utxos, &env) { Ok(()) => panic!("Output with wrong network ID should be rejected"), Err(err) => match err { - ShelleyMA(ShelleyMAError::MetadataHash) => (), + ShelleyMA(ShelleyMAError::UnneededAuxDataHash) => (), _ => panic!("Unexpected error ({:?})", err), }, }