feat: new error for bad term
This commit is contained in:
parent
30ed8d9150
commit
f10e3836ad
|
@ -54,7 +54,27 @@ fn main() -> anyhow::Result<()> {
|
||||||
slot_length,
|
slot_length,
|
||||||
};
|
};
|
||||||
|
|
||||||
tx::eval_phase_two(tx_babbage, &resolved_inputs, None, &slot_config, true)?;
|
let result = tx::eval_phase_two(
|
||||||
|
tx_babbage,
|
||||||
|
&resolved_inputs,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
&slot_config,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(redeemers) => {
|
||||||
|
println!("\nResult\n------\n\n");
|
||||||
|
|
||||||
|
for redeemer in redeemers {
|
||||||
|
println!("{:#?}", redeemer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("\nError\n-----\n\n{}\n", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -526,7 +526,7 @@ impl Program<NamedDeBruijn> {
|
||||||
Vec<String>,
|
Vec<String>,
|
||||||
) {
|
) {
|
||||||
let budget = match initial_budget {
|
let budget = match initial_budget {
|
||||||
Some(b) => b.clone(),
|
Some(b) => *b,
|
||||||
None => ExBudget::default(),
|
None => ExBudget::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -556,3 +556,9 @@ impl Program<DeBruijn> {
|
||||||
program.eval()
|
program.eval()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Term<NamedDeBruijn> {
|
||||||
|
pub fn is_valid_script_result(&self) -> bool {
|
||||||
|
matches!(self, Term::Constant(Constant::Unit))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
use crate::machine;
|
use crate::{
|
||||||
|
ast::{NamedDeBruijn, Term},
|
||||||
|
machine::{self, cost_model::ExBudget},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
Address(#[from] pallas_addresses::Error),
|
Address(#[from] pallas_addresses::Error),
|
||||||
|
#[error("{}\n\n{:#?}\n\n{}", .0, .1, .2.join("\n"))]
|
||||||
|
BadTerm(Term<NamedDeBruijn>, ExBudget, Vec<String>),
|
||||||
#[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),
|
FlatDecode(#[from] flat_rs::de::Error),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
FragmentDecode(#[from] pallas_primitives::Error),
|
FragmentDecode(#[from] pallas_primitives::Error),
|
||||||
#[error("{0}")]
|
#[error("{}\n\n{:#?}\n\n{}", .0, .1, .2.join("\n"))]
|
||||||
Machine(#[from] machine::Error),
|
Machine(machine::Error, ExBudget, Vec<String>),
|
||||||
#[error("Native script can't be executed in phase-two")]
|
#[error("Native script can't be executed in phase-two")]
|
||||||
NativeScriptPhaseTwo,
|
NativeScriptPhaseTwo,
|
||||||
#[error("Can't eval without redeemers")]
|
#[error("Can't eval without redeemers")]
|
||||||
|
|
|
@ -168,12 +168,10 @@ fn get_script_purpose(
|
||||||
policy_ids.sort();
|
policy_ids.sort();
|
||||||
match policy_ids.get(index as usize) {
|
match policy_ids.get(index as usize) {
|
||||||
Some(policy_id) => Ok(ScriptPurpose::Minting(*policy_id)),
|
Some(policy_id) => Ok(ScriptPurpose::Minting(*policy_id)),
|
||||||
None => {
|
None => Err(Error::ExtraneousRedeemer {
|
||||||
return Err(Error::ExtraneousRedeemer {
|
|
||||||
tag: "Mint".to_string(),
|
tag: "Mint".to_string(),
|
||||||
index,
|
index,
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RedeemerTag::Spend => {
|
RedeemerTag::Spend => {
|
||||||
|
@ -182,12 +180,10 @@ fn get_script_purpose(
|
||||||
inputs.sort();
|
inputs.sort();
|
||||||
match inputs.get(index as usize) {
|
match inputs.get(index as usize) {
|
||||||
Some(input) => Ok(ScriptPurpose::Spending(input.clone())),
|
Some(input) => Ok(ScriptPurpose::Spending(input.clone())),
|
||||||
None => {
|
None => Err(Error::ExtraneousRedeemer {
|
||||||
return Err(Error::ExtraneousRedeemer {
|
|
||||||
tag: "Spend".to_string(),
|
tag: "Spend".to_string(),
|
||||||
index,
|
index,
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RedeemerTag::Reward => {
|
RedeemerTag::Reward => {
|
||||||
|
@ -228,12 +224,10 @@ fn get_script_purpose(
|
||||||
.get(index as usize)
|
.get(index as usize)
|
||||||
{
|
{
|
||||||
Some(cert) => Ok(ScriptPurpose::Certifying(cert.clone())),
|
Some(cert) => Ok(ScriptPurpose::Certifying(cert.clone())),
|
||||||
None => {
|
None => Err(Error::ExtraneousRedeemer {
|
||||||
return Err(Error::ExtraneousRedeemer {
|
|
||||||
tag: "Cert".to_string(),
|
tag: "Cert".to_string(),
|
||||||
index,
|
index,
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -436,7 +430,7 @@ fn get_execution_purpose(
|
||||||
|
|
||||||
Ok(ExecutionPurpose::WithDatum(script, datum))
|
Ok(ExecutionPurpose::WithDatum(script, datum))
|
||||||
}
|
}
|
||||||
_ => return Err(Error::ScriptKeyHash),
|
_ => Err(Error::ScriptKeyHash),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TransactionOutput::PostAlonzo(output) => {
|
TransactionOutput::PostAlonzo(output) => {
|
||||||
|
@ -470,7 +464,7 @@ fn get_execution_purpose(
|
||||||
|
|
||||||
Ok(ExecutionPurpose::WithDatum(script, datum))
|
Ok(ExecutionPurpose::WithDatum(script, datum))
|
||||||
}
|
}
|
||||||
_ => return Err(Error::ScriptKeyHash),
|
_ => Err(Error::ScriptKeyHash),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,7 +521,7 @@ fn get_execution_purpose(
|
||||||
|
|
||||||
Ok(ExecutionPurpose::NoDatum(script))
|
Ok(ExecutionPurpose::NoDatum(script))
|
||||||
}
|
}
|
||||||
_ => return Err(Error::OnlyStakeDeregAndDelegAllowed),
|
_ => Err(Error::OnlyStakeDeregAndDelegAllowed),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -645,7 +639,7 @@ 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, budget, _) = if let Some(cost_mdls) = cost_mdls_opt {
|
let (result, budget, logs) = 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 {
|
||||||
|
@ -657,11 +651,17 @@ pub fn eval_redeemer(
|
||||||
program.eval_v1()
|
program.eval_v1()
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: do we want the logs in the error?
|
match result {
|
||||||
result?;
|
Ok(term) => {
|
||||||
|
if !term.is_valid_script_result() {
|
||||||
|
return Err(Error::BadTerm(term, budget, logs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => return Err(Error::Machine(err, budget, logs)),
|
||||||
|
}
|
||||||
|
|
||||||
let initial_budget = match initial_budget {
|
let initial_budget = match initial_budget {
|
||||||
Some(b) => b.clone(),
|
Some(b) => *b,
|
||||||
None => ExBudget::default(),
|
None => ExBudget::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -694,7 +694,7 @@ 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, budget, _) = if let Some(cost_mdls) = cost_mdls_opt {
|
let (result, budget, logs) = if let Some(cost_mdls) = cost_mdls_opt {
|
||||||
let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
|
let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
|
||||||
costs
|
costs
|
||||||
} else {
|
} else {
|
||||||
|
@ -706,11 +706,17 @@ pub fn eval_redeemer(
|
||||||
program.eval()
|
program.eval()
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: do we want the logs in the error?
|
match result {
|
||||||
result?;
|
Ok(term) => {
|
||||||
|
if !term.is_valid_script_result() {
|
||||||
|
return Err(Error::BadTerm(term, budget, logs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => return Err(Error::Machine(err, budget, logs)),
|
||||||
|
}
|
||||||
|
|
||||||
let initial_budget = match initial_budget {
|
let initial_budget = match initial_budget {
|
||||||
Some(b) => b.clone(),
|
Some(b) => *b,
|
||||||
None => ExBudget::default(),
|
None => ExBudget::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -745,7 +751,7 @@ 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, budget, _) = if let Some(cost_mdls) = cost_mdls_opt {
|
let (result, budget, logs) = 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 {
|
||||||
|
@ -757,11 +763,17 @@ pub fn eval_redeemer(
|
||||||
program.eval_v1()
|
program.eval_v1()
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: do we want the logs in the error?
|
match result {
|
||||||
result?;
|
Ok(term) => {
|
||||||
|
if !term.is_valid_script_result() {
|
||||||
|
return Err(Error::BadTerm(term, budget, logs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => return Err(Error::Machine(err, budget, logs)),
|
||||||
|
}
|
||||||
|
|
||||||
let initial_budget = match initial_budget {
|
let initial_budget = match initial_budget {
|
||||||
Some(b) => b.clone(),
|
Some(b) => *b,
|
||||||
None => ExBudget::default(),
|
None => ExBudget::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -793,7 +805,7 @@ 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, budget, _) = if let Some(cost_mdls) = cost_mdls_opt {
|
let (result, budget, logs) = if let Some(cost_mdls) = cost_mdls_opt {
|
||||||
let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
|
let costs = if let Some(costs) = &cost_mdls.plutus_v2 {
|
||||||
costs
|
costs
|
||||||
} else {
|
} else {
|
||||||
|
@ -805,11 +817,17 @@ pub fn eval_redeemer(
|
||||||
program.eval()
|
program.eval()
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: do we want the logs in the error?
|
match result {
|
||||||
result?;
|
Ok(term) => {
|
||||||
|
if !term.is_valid_script_result() {
|
||||||
|
return Err(Error::BadTerm(term, budget, logs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => return Err(Error::Machine(err, budget, logs)),
|
||||||
|
}
|
||||||
|
|
||||||
let initial_budget = match initial_budget {
|
let initial_budget = match initial_budget {
|
||||||
Some(b) => b.clone(),
|
Some(b) => *b,
|
||||||
None => ExBudget::default(),
|
None => ExBudget::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue