feat: even more errors work

This commit is contained in:
rvcas 2022-09-19 01:05:33 -04:00
parent 9bab3187b1
commit 6c34c9be19
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
4 changed files with 54 additions and 51 deletions

View File

@ -54,7 +54,7 @@ fn main() -> anyhow::Result<()> {
slot_length, slot_length,
}; };
tx::eval(tx_babbage, &resolved_inputs, None, &slot_config)?; tx::eval_phase_two(tx_babbage, &resolved_inputs, None, &slot_config, true)?;
} }
} }
}, },

View File

@ -7,9 +7,13 @@ pub enum Error {
#[error("Only shelley reward addresses can be a part of withdrawals")] #[error("Only shelley reward addresses can be a part of withdrawals")]
BadWithdrawalAddress, BadWithdrawalAddress,
#[error("{0}")] #[error("{0}")]
FlatDecode(#[from] flat_rs::de::Error),
#[error("{0}")]
FragmentDecode(#[from] pallas_primitives::Error), FragmentDecode(#[from] pallas_primitives::Error),
#[error("{0}")] #[error("{0}")]
Machine(#[from] machine::Error), Machine(#[from] machine::Error),
#[error("Native script can't be executed in phase-two")]
NativeScriptPhaseTwo,
#[error("Can't eval without redeemers")] #[error("Can't eval without redeemers")]
NoRedeemers, NoRedeemers,
#[error("Mismatch in required redeemers: {} {}", .missing.join(" "), .extra.join(" "))] #[error("Mismatch in required redeemers: {} {}", .missing.join(" "), .extra.join(" "))]
@ -21,6 +25,10 @@ pub enum Error {
ResolvedInputNotFound, ResolvedInputNotFound,
#[error("A key hash cannot be the hash of a script")] #[error("A key hash cannot be the hash of a script")]
ScriptKeyHash, ScriptKeyHash,
#[error("PlutusV1 cost model not found.")]
V1CostModelNotFound,
#[error("PlutusV2 cost model not found.")]
V2CostModelNotFound,
#[error("Wrong era, Please use Babbage or Alonzo: {0}")] #[error("Wrong era, Please use Babbage or Alonzo: {0}")]
WrongEra(#[from] pallas_codec::minicbor::decode::Error), WrongEra(#[from] pallas_codec::minicbor::decode::Error),
} }

View File

@ -7,9 +7,9 @@ use pallas_addresses::{Address, ScriptHash, StakePayload};
use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray}; use pallas_codec::utils::{KeyValuePairs, MaybeIndefArray};
use pallas_crypto::hash::Hash; use pallas_crypto::hash::Hash;
use pallas_primitives::babbage::{ 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, PlutusV1Script, PlutusV2Script, PolicyId, Redeemer, RedeemerTag, RewardAccount, Script,
StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals, NativeScript, StakeCredential, TransactionInput, TransactionOutput, Value, Withdrawals,
}; };
use pallas_traverse::{ComputeHash, OriginalHash}; use pallas_traverse::{ComputeHash, OriginalHash};
use std::{collections::HashMap, convert::TryInto, ops::Deref, vec}; use std::{collections::HashMap, convert::TryInto, ops::Deref, vec};
@ -606,11 +606,11 @@ pub fn eval_redeemer(
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()); .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 { let costs = if let Some(costs) = &cost_mdls.plutus_v1 {
costs costs
} else { } else {
return Err(anyhow::Error::msg("PlutusV1 cost model not found.")); return Err(Error::V1CostModelNotFound);
}; };
program.eval_as(&Language::PlutusV1, costs) program.eval_as(&Language::PlutusV1, costs)
@ -618,18 +618,18 @@ pub fn eval_redeemer(
program.eval_v1() program.eval_v1()
}; };
match result.0 { // TODO: do we want the logs in the error?
Ok(_) => {} result?;
Err(_err) => unreachable!("Error in Plutus core."), // TODO: Add the actual error message
} let initial_budget = ExBudget::default();
let new_redeemer = Redeemer { let new_redeemer = Redeemer {
tag: redeemer.tag.clone(), tag: redeemer.tag.clone(),
index: redeemer.index, index: redeemer.index,
data: redeemer.data.clone(), data: redeemer.data.clone(),
ex_units: ExUnits { ex_units: ExUnits {
mem: (ExBudget::default().mem - result.1.mem) as u32, mem: (initial_budget.mem - budget.mem) as u32,
steps: (ExBudget::default().cpu - result.1.cpu) as u64, steps: (initial_budget.cpu - budget.cpu) as u64,
}, },
}; };
@ -652,11 +652,11 @@ pub fn eval_redeemer(
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()); .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 { let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
costs costs
} else { } else {
return Err(anyhow::Error::msg("PlutusV1 cost model not found.")); return Err(Error::V2CostModelNotFound);
}; };
program.eval_as(&Language::PlutusV2, costs) program.eval_as(&Language::PlutusV2, costs)
@ -664,24 +664,24 @@ pub fn eval_redeemer(
program.eval() program.eval()
}; };
match result.0 { // TODO: do we want the logs in the error?
Ok(_) => {} result?;
Err(_err) => unreachable!("Error in Plutus core."), // TODO: Add the actual error message
} let initial_budget = ExBudget::default();
let new_redeemer = Redeemer { let new_redeemer = Redeemer {
tag: redeemer.tag.clone(), tag: redeemer.tag.clone(),
index: redeemer.index, index: redeemer.index,
data: redeemer.data.clone(), data: redeemer.data.clone(),
ex_units: ExUnits { ex_units: ExUnits {
mem: (ExBudget::default().mem - result.1.mem) as u32, mem: (initial_budget.mem - budget.mem) as u32,
steps: (ExBudget::default().cpu - result.1.cpu) as u64, steps: (initial_budget.cpu - budget.cpu) as u64,
}, },
}; };
Ok(new_redeemer) 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 { ExecutionPurpose::NoDatum(script_version) => match script_version {
ScriptVersion::V1(script) => { ScriptVersion::V1(script) => {
@ -700,11 +700,11 @@ pub fn eval_redeemer(
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()); .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 { let costs = if let Some(costs) = &cost_mdls.plutus_v1 {
costs costs
} else { } else {
return Err(anyhow::Error::msg("PlutusV1 cost model not found.")); return Err(Error::V1CostModelNotFound);
}; };
program.eval_as(&Language::PlutusV1, costs) program.eval_as(&Language::PlutusV1, costs)
@ -712,18 +712,18 @@ pub fn eval_redeemer(
program.eval_v1() program.eval_v1()
}; };
match result.0 { // TODO: do we want the logs in the error?
Ok(_) => {} result?;
Err(_err) => unreachable!("Error in Plutus core."), // TODO: Add the actual error message
} let initial_budget = ExBudget::default();
let new_redeemer = Redeemer { let new_redeemer = Redeemer {
tag: redeemer.tag.clone(), tag: redeemer.tag.clone(),
index: redeemer.index, index: redeemer.index,
data: redeemer.data.clone(), data: redeemer.data.clone(),
ex_units: ExUnits { ex_units: ExUnits {
mem: (ExBudget::default().mem - result.1.mem) as u32, mem: (initial_budget.mem - budget.mem) as u32,
steps: (ExBudget::default().cpu - result.1.cpu) as u64, steps: (initial_budget.cpu - budget.cpu) as u64,
}, },
}; };
@ -745,11 +745,11 @@ pub fn eval_redeemer(
.apply_data(redeemer.data.clone()) .apply_data(redeemer.data.clone())
.apply_data(script_context.to_plutus_data()); .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 { let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
costs costs
} else { } else {
return Err(anyhow::Error::msg("PlutusV1 cost model not found.")); return Err(Error::V2CostModelNotFound);
}; };
program.eval_as(&Language::PlutusV2, costs) program.eval_as(&Language::PlutusV2, costs)
@ -757,24 +757,24 @@ pub fn eval_redeemer(
program.eval() program.eval()
}; };
match result.0 { // TODO: do we want the logs in the error?
Ok(_) => {} result?;
Err(_err) => unreachable!("Error in Plutus core."), // TODO: Add the actual error message
} let initial_budget = ExBudget::default();
let new_redeemer = Redeemer { let new_redeemer = Redeemer {
tag: redeemer.tag.clone(), tag: redeemer.tag.clone(),
index: redeemer.index, index: redeemer.index,
data: redeemer.data.clone(), data: redeemer.data.clone(),
ex_units: ExUnits { ex_units: ExUnits {
mem: (ExBudget::default().mem - result.1.mem) as u32, mem: (initial_budget.mem - budget.mem) as u32,
steps: (ExBudget::default().cpu - result.1.cpu) as u64, steps: (initial_budget.cpu - budget.cpu) as u64,
}, },
}; };
Ok(new_redeemer) Ok(new_redeemer)
} }
ScriptVersion::Native(_) => unreachable!("Native script can't be executed in phase-two.") ScriptVersion::Native(_) => Err(Error::NativeScriptPhaseTwo),
}, },
} }
} }

View File

@ -40,7 +40,7 @@ pub fn validate_missing_scripts(
needed: &AlonzoScriptsNeeded, needed: &AlonzoScriptsNeeded,
txscripts: HashMap<ScriptHash, ScriptVersion>, txscripts: HashMap<ScriptHash, ScriptVersion>,
) -> Result<(), Error> { ) -> 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>>(); 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)) .map(|x| format!("[Extraneous (sh: {:?})]", x))
.collect(); .collect();
if missing.len() > 0 || extra.len() > 0 { if !missing.is_empty() || !extra.is_empty() {
let missing_errors = missing.join(" "); let missing_errors = missing.join(" ");
let extra_errors = extra.join(" "); let extra_errors = extra.join(" ");
@ -80,8 +80,8 @@ pub fn scripts_needed(
let mut spend = Vec::new(); let mut spend = Vec::new();
for input in txb.inputs { for input in txb.inputs.iter() {
let utxo = match utxos.iter().find(|utxo| utxo.input == input) { let utxo = match utxos.iter().find(|utxo| utxo.input == *input) {
Some(u) => u, Some(u) => u,
None => return Err(Error::ResolvedInputNotFound), None => return Err(Error::ResolvedInputNotFound),
}; };
@ -164,7 +164,7 @@ pub fn has_exact_set_of_redeemers(
for (script_purpose, script_hash) in needed { for (script_purpose, script_hash) in needed {
let redeemer_ptr = build_redeemer_ptr(tx, script_purpose)?; 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) { if let (Some(ptr), Some(script)) = (redeemer_ptr, script) {
match script { match script {
@ -200,9 +200,7 @@ pub fn has_exact_set_of_redeemers(
.map(|x| { .map(|x| {
format!( format!(
"[Missing (redeemer_ptr: {:?}, script_purpose: {:?}, script_hash: {})]", "[Missing (redeemer_ptr: {:?}, script_purpose: {:?}, script_hash: {})]",
x.0, x.0, x.1, x.2,
x.1,
x.2.to_string(),
) )
}) })
.collect(); .collect();
@ -213,10 +211,7 @@ pub fn has_exact_set_of_redeemers(
.map(|x| format!("[Extraneous (redeemer_ptr: {:?})]", x)) .map(|x| format!("[Extraneous (redeemer_ptr: {:?})]", x))
.collect(); .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(" ");
Err(Error::RequiredRedeemersMismatch { missing, extra }) Err(Error::RequiredRedeemersMismatch { missing, extra })
} else { } else {
Ok(()) Ok(())