feat: even more errors work
This commit is contained in:
		
							parent
							
								
									9bab3187b1
								
							
						
					
					
						commit
						6c34c9be19
					
				| 
						 | 
				
			
			@ -54,7 +54,7 @@ fn main() -> anyhow::Result<()> {
 | 
			
		|||
                        slot_length,
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    tx::eval(tx_babbage, &resolved_inputs, None, &slot_config)?;
 | 
			
		||||
                    tx::eval_phase_two(tx_babbage, &resolved_inputs, None, &slot_config, true)?;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,9 +7,13 @@ pub enum Error {
 | 
			
		|||
    #[error("Only shelley reward addresses can be a part of withdrawals")]
 | 
			
		||||
    BadWithdrawalAddress,
 | 
			
		||||
    #[error("{0}")]
 | 
			
		||||
    FlatDecode(#[from] flat_rs::de::Error),
 | 
			
		||||
    #[error("{0}")]
 | 
			
		||||
    FragmentDecode(#[from] pallas_primitives::Error),
 | 
			
		||||
    #[error("{0}")]
 | 
			
		||||
    Machine(#[from] machine::Error),
 | 
			
		||||
    #[error("Native script can't be executed in phase-two")]
 | 
			
		||||
    NativeScriptPhaseTwo,
 | 
			
		||||
    #[error("Can't eval without redeemers")]
 | 
			
		||||
    NoRedeemers,
 | 
			
		||||
    #[error("Mismatch in required redeemers: {} {}", .missing.join(" "), .extra.join(" "))]
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +25,10 @@ pub enum Error {
 | 
			
		|||
    ResolvedInputNotFound,
 | 
			
		||||
    #[error("A key hash cannot be the hash of a script")]
 | 
			
		||||
    ScriptKeyHash,
 | 
			
		||||
    #[error("PlutusV1 cost model not found.")]
 | 
			
		||||
    V1CostModelNotFound,
 | 
			
		||||
    #[error("PlutusV2 cost model not found.")]
 | 
			
		||||
    V2CostModelNotFound,
 | 
			
		||||
    #[error("Wrong era, Please use Babbage or Alonzo: {0}")]
 | 
			
		||||
    WrongEra(#[from] pallas_codec::minicbor::decode::Error),
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,9 +7,9 @@ use pallas_addresses::{Address, ScriptHash, StakePayload};
 | 
			
		|||
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
 | 
			
		||||
use pallas_crypto::hash::Hash;
 | 
			
		||||
use pallas_primitives::babbage::{
 | 
			
		||||
    Certificate, CostMdls, DatumHash, DatumOption, ExUnits, Language, Mint, MintedTx,
 | 
			
		||||
    Certificate, CostMdls, DatumHash, DatumOption, ExUnits, Language, Mint, MintedTx, NativeScript,
 | 
			
		||||
    PlutusV1Script, PlutusV2Script, PolicyId, Redeemer, RedeemerTag, RewardAccount, Script,
 | 
			
		||||
    StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals, NativeScript,
 | 
			
		||||
    StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals,
 | 
			
		||||
};
 | 
			
		||||
use pallas_traverse::{ComputeHash, OriginalHash};
 | 
			
		||||
use std::{collections::HashMap, convert::TryInto, ops::Deref, vec};
 | 
			
		||||
| 
						 | 
				
			
			@ -606,11 +606,11 @@ pub fn eval_redeemer(
 | 
			
		|||
                    .apply_data(redeemer.data.clone())
 | 
			
		||||
                    .apply_data(script_context.to_plutus_data());
 | 
			
		||||
 | 
			
		||||
                let result = if let Some(cost_mdls) = cost_mdls_opt {
 | 
			
		||||
                let (result, budget, _) = if let Some(cost_mdls) = cost_mdls_opt {
 | 
			
		||||
                    let costs = if let Some(costs) = &cost_mdls.plutus_v1 {
 | 
			
		||||
                        costs
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return Err(anyhow::Error::msg("PlutusV1 cost model not found."));
 | 
			
		||||
                        return Err(Error::V1CostModelNotFound);
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    program.eval_as(&Language::PlutusV1, costs)
 | 
			
		||||
| 
						 | 
				
			
			@ -618,18 +618,18 @@ pub fn eval_redeemer(
 | 
			
		|||
                    program.eval_v1()
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                match result.0 {
 | 
			
		||||
                    Ok(_) => {}
 | 
			
		||||
                    Err(_err) => unreachable!("Error in Plutus core."), // TODO: Add the actual error message
 | 
			
		||||
                }
 | 
			
		||||
                // TODO: do we want the logs in the error?
 | 
			
		||||
                result?;
 | 
			
		||||
 | 
			
		||||
                let initial_budget = ExBudget::default();
 | 
			
		||||
 | 
			
		||||
                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,
 | 
			
		||||
                        mem: (initial_budget.mem - budget.mem) as u32,
 | 
			
		||||
                        steps: (initial_budget.cpu - budget.cpu) as u64,
 | 
			
		||||
                    },
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -652,11 +652,11 @@ pub fn eval_redeemer(
 | 
			
		|||
                    .apply_data(redeemer.data.clone())
 | 
			
		||||
                    .apply_data(script_context.to_plutus_data());
 | 
			
		||||
 | 
			
		||||
                let result = if let Some(cost_mdls) = cost_mdls_opt {
 | 
			
		||||
                    let costs = if let Some(costs) = &cost_mdls.plutus_v1 {
 | 
			
		||||
                let (result, budget, _) = if let Some(cost_mdls) = cost_mdls_opt {
 | 
			
		||||
                    let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
 | 
			
		||||
                        costs
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return Err(anyhow::Error::msg("PlutusV1 cost model not found."));
 | 
			
		||||
                        return Err(Error::V2CostModelNotFound);
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    program.eval_as(&Language::PlutusV2, costs)
 | 
			
		||||
| 
						 | 
				
			
			@ -664,24 +664,24 @@ pub fn eval_redeemer(
 | 
			
		|||
                    program.eval()
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                match result.0 {
 | 
			
		||||
                    Ok(_) => {}
 | 
			
		||||
                    Err(_err) => unreachable!("Error in Plutus core."), // TODO: Add the actual error message
 | 
			
		||||
                }
 | 
			
		||||
                // TODO: do we want the logs in the error?
 | 
			
		||||
                result?;
 | 
			
		||||
 | 
			
		||||
                let initial_budget = ExBudget::default();
 | 
			
		||||
 | 
			
		||||
                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,
 | 
			
		||||
                        mem: (initial_budget.mem - budget.mem) as u32,
 | 
			
		||||
                        steps: (initial_budget.cpu - budget.cpu) as u64,
 | 
			
		||||
                    },
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                Ok(new_redeemer)
 | 
			
		||||
            }
 | 
			
		||||
            ScriptVersion::Native(_) => unreachable!("Native script can't be executed in phase-two.")
 | 
			
		||||
            ScriptVersion::Native(_) => Err(Error::NativeScriptPhaseTwo),
 | 
			
		||||
        },
 | 
			
		||||
        ExecutionPurpose::NoDatum(script_version) => match script_version {
 | 
			
		||||
            ScriptVersion::V1(script) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -700,11 +700,11 @@ pub fn eval_redeemer(
 | 
			
		|||
                    .apply_data(redeemer.data.clone())
 | 
			
		||||
                    .apply_data(script_context.to_plutus_data());
 | 
			
		||||
 | 
			
		||||
                let result = if let Some(cost_mdls) = cost_mdls_opt {
 | 
			
		||||
                let (result, budget, _) = if let Some(cost_mdls) = cost_mdls_opt {
 | 
			
		||||
                    let costs = if let Some(costs) = &cost_mdls.plutus_v1 {
 | 
			
		||||
                        costs
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return Err(anyhow::Error::msg("PlutusV1 cost model not found."));
 | 
			
		||||
                        return Err(Error::V1CostModelNotFound);
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    program.eval_as(&Language::PlutusV1, costs)
 | 
			
		||||
| 
						 | 
				
			
			@ -712,18 +712,18 @@ pub fn eval_redeemer(
 | 
			
		|||
                    program.eval_v1()
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                match result.0 {
 | 
			
		||||
                    Ok(_) => {}
 | 
			
		||||
                    Err(_err) => unreachable!("Error in Plutus core."), // TODO: Add the actual error message
 | 
			
		||||
                }
 | 
			
		||||
                // TODO: do we want the logs in the error?
 | 
			
		||||
                result?;
 | 
			
		||||
 | 
			
		||||
                let initial_budget = ExBudget::default();
 | 
			
		||||
 | 
			
		||||
                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,
 | 
			
		||||
                        mem: (initial_budget.mem - budget.mem) as u32,
 | 
			
		||||
                        steps: (initial_budget.cpu - budget.cpu) as u64,
 | 
			
		||||
                    },
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -745,11 +745,11 @@ pub fn eval_redeemer(
 | 
			
		|||
                    .apply_data(redeemer.data.clone())
 | 
			
		||||
                    .apply_data(script_context.to_plutus_data());
 | 
			
		||||
 | 
			
		||||
                let result = if let Some(cost_mdls) = cost_mdls_opt {
 | 
			
		||||
                    let costs = if let Some(costs) = &cost_mdls.plutus_v1 {
 | 
			
		||||
                let (result, budget, _) = if let Some(cost_mdls) = cost_mdls_opt {
 | 
			
		||||
                    let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
 | 
			
		||||
                        costs
 | 
			
		||||
                    } else {
 | 
			
		||||
                        return Err(anyhow::Error::msg("PlutusV1 cost model not found."));
 | 
			
		||||
                        return Err(Error::V2CostModelNotFound);
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    program.eval_as(&Language::PlutusV2, costs)
 | 
			
		||||
| 
						 | 
				
			
			@ -757,24 +757,24 @@ pub fn eval_redeemer(
 | 
			
		|||
                    program.eval()
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                match result.0 {
 | 
			
		||||
                    Ok(_) => {}
 | 
			
		||||
                    Err(_err) => unreachable!("Error in Plutus core."), // TODO: Add the actual error message
 | 
			
		||||
                }
 | 
			
		||||
                // TODO: do we want the logs in the error?
 | 
			
		||||
                result?;
 | 
			
		||||
 | 
			
		||||
                let initial_budget = ExBudget::default();
 | 
			
		||||
 | 
			
		||||
                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,
 | 
			
		||||
                        mem: (initial_budget.mem - budget.mem) as u32,
 | 
			
		||||
                        steps: (initial_budget.cpu - budget.cpu) as u64,
 | 
			
		||||
                    },
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                Ok(new_redeemer)
 | 
			
		||||
            }
 | 
			
		||||
            ScriptVersion::Native(_) => unreachable!("Native script can't be executed in phase-two.")
 | 
			
		||||
            ScriptVersion::Native(_) => Err(Error::NativeScriptPhaseTwo),
 | 
			
		||||
        },
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ pub fn validate_missing_scripts(
 | 
			
		|||
    needed: &AlonzoScriptsNeeded,
 | 
			
		||||
    txscripts: HashMap<ScriptHash, ScriptVersion>,
 | 
			
		||||
) -> Result<(), Error> {
 | 
			
		||||
    let received_hashes = txscripts.keys().map(|x| *x).collect::<Vec<ScriptHash>>();
 | 
			
		||||
    let received_hashes = txscripts.keys().copied().collect::<Vec<ScriptHash>>();
 | 
			
		||||
 | 
			
		||||
    let needed_hashes = needed.iter().map(|x| x.1).collect::<Vec<ScriptHash>>();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ pub fn validate_missing_scripts(
 | 
			
		|||
        .map(|x| format!("[Extraneous (sh: {:?})]", x))
 | 
			
		||||
        .collect();
 | 
			
		||||
 | 
			
		||||
    if missing.len() > 0 || extra.len() > 0 {
 | 
			
		||||
    if !missing.is_empty() || !extra.is_empty() {
 | 
			
		||||
        let missing_errors = missing.join(" ");
 | 
			
		||||
        let extra_errors = extra.join(" ");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -80,8 +80,8 @@ pub fn scripts_needed(
 | 
			
		|||
 | 
			
		||||
    let mut spend = Vec::new();
 | 
			
		||||
 | 
			
		||||
    for input in txb.inputs {
 | 
			
		||||
        let utxo = match utxos.iter().find(|utxo| utxo.input == input) {
 | 
			
		||||
    for input in txb.inputs.iter() {
 | 
			
		||||
        let utxo = match utxos.iter().find(|utxo| utxo.input == *input) {
 | 
			
		||||
            Some(u) => u,
 | 
			
		||||
            None => return Err(Error::ResolvedInputNotFound),
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +164,7 @@ pub fn has_exact_set_of_redeemers(
 | 
			
		|||
 | 
			
		||||
    for (script_purpose, script_hash) in needed {
 | 
			
		||||
        let redeemer_ptr = build_redeemer_ptr(tx, script_purpose)?;
 | 
			
		||||
        let script = tx_scripts.get(&script_hash);
 | 
			
		||||
        let script = tx_scripts.get(script_hash);
 | 
			
		||||
 | 
			
		||||
        if let (Some(ptr), Some(script)) = (redeemer_ptr, script) {
 | 
			
		||||
            match script {
 | 
			
		||||
| 
						 | 
				
			
			@ -200,9 +200,7 @@ pub fn has_exact_set_of_redeemers(
 | 
			
		|||
        .map(|x| {
 | 
			
		||||
            format!(
 | 
			
		||||
                "[Missing (redeemer_ptr: {:?}, script_purpose: {:?}, script_hash: {})]",
 | 
			
		||||
                x.0,
 | 
			
		||||
                x.1,
 | 
			
		||||
                x.2.to_string(),
 | 
			
		||||
                x.0, x.1, x.2,
 | 
			
		||||
            )
 | 
			
		||||
        })
 | 
			
		||||
        .collect();
 | 
			
		||||
| 
						 | 
				
			
			@ -213,10 +211,7 @@ pub fn has_exact_set_of_redeemers(
 | 
			
		|||
        .map(|x| format!("[Extraneous (redeemer_ptr: {:?})]", x))
 | 
			
		||||
        .collect();
 | 
			
		||||
 | 
			
		||||
    if missing.len() > 0 || extra.len() > 0 {
 | 
			
		||||
        let missing_errors = missing.join(" ");
 | 
			
		||||
        let extra_errors = extra.join(" ");
 | 
			
		||||
 | 
			
		||||
    if !missing.is_empty() || !extra.is_empty() {
 | 
			
		||||
        Err(Error::RequiredRedeemersMismatch { missing, extra })
 | 
			
		||||
    } else {
 | 
			
		||||
        Ok(())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue