feat: Add tracing for common multivalidator issues

This commit is contained in:
microproofs 2023-10-07 15:52:28 -04:00 committed by Kasey
parent 68d9a21c6a
commit 8964675670
3 changed files with 88 additions and 20 deletions

View File

@ -156,17 +156,18 @@ impl<'a> CodeGenerator<'a> {
let other_term = self.uplc_code_gen(full_vec_other); let other_term = self.uplc_code_gen(full_vec_other);
let (spend, mint) = if other.arguments.len() > fun.arguments.len() { let (spend, spend_name, mint, mint_name) =
(other_term, term) if other.arguments.len() > fun.arguments.len() {
} else { (other_term, other.name.clone(), term, fun.name.clone())
(term, other_term) } else {
}; (term, fun.name.clone(), other_term, other.name.clone())
};
// Special Case with multi_validators // Special Case with multi_validators
self.special_functions.use_function(CONSTR_FIELDS_EXPOSER); self.special_functions.use_function(CONSTR_FIELDS_EXPOSER);
self.special_functions.use_function(CONSTR_INDEX_EXPOSER); self.special_functions.use_function(CONSTR_INDEX_EXPOSER);
term = wrap_as_multi_validator(spend, mint); term = wrap_as_multi_validator(spend, mint, self.tracing, spend_name, mint_name);
} }
term = cast_validator_args(term, params); term = cast_validator_args(term, params);

View File

@ -1699,20 +1699,68 @@ pub fn special_case_builtin(
} }
} }
pub fn wrap_as_multi_validator(spend: Term<Name>, mint: Term<Name>) -> Term<Name> { pub fn wrap_as_multi_validator(
Term::equals_integer() spend: Term<Name>,
.apply(Term::integer(0.into())) mint: Term<Name>,
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("__second_arg"))) trace: bool,
.delayed_if_else( spend_name: String,
mint.apply(Term::var("__first_arg")) mint_name: String,
.apply(Term::var("__second_arg")), ) -> Term<Name> {
spend.apply(Term::var("__first_arg")).apply( if trace {
Term::head_list() let trace_string = format!(
.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("__second_arg"))), "Incorrect redeemer type for validator {}.
), Double check you have wrapped the redeemer type as specified in your plutus.json",
) spend_name
.lambda("__second_arg") );
.lambda("__first_arg")
let error_term = Term::Error.trace(Term::var("__incorrect_second_arg_type"));
Term::var("__second_arg")
.delayed_choose_data(
Term::equals_integer()
.apply(Term::integer(0.into()))
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("__second_arg")))
.delayed_if_else(
mint.apply(Term::var("__first_arg"))
.apply(Term::var("__second_arg"))
.trace(Term::string(format!(
"Running 2 arg validator {}",
mint_name
))),
spend
.apply(Term::var("__first_arg"))
.apply(Term::head_list().apply(
Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("__second_arg")),
))
.trace(Term::string(format!(
"Running 3 arg validator {}",
spend_name
))),
),
error_term.clone(),
error_term.clone(),
error_term.clone(),
error_term,
)
.lambda("__incorrect_second_arg_type")
.apply(Term::string(trace_string))
.lambda("__second_arg")
.lambda("__first_arg")
} else {
Term::equals_integer()
.apply(Term::integer(0.into()))
.apply(Term::var(CONSTR_INDEX_EXPOSER).apply(Term::var("__second_arg")))
.delayed_if_else(
mint.apply(Term::var("__first_arg"))
.apply(Term::var("__second_arg")),
spend.apply(Term::var("__first_arg")).apply(
Term::head_list()
.apply(Term::var(CONSTR_FIELDS_EXPOSER).apply(Term::var("__second_arg"))),
),
)
.lambda("__second_arg")
.lambda("__first_arg")
}
} }
/// If the pattern is a list the return the number of elements and if it has a tail /// If the pattern is a list the return the number of elements and if it has a tail

View File

@ -296,6 +296,25 @@ impl<T> Term<T> {
.force() .force()
} }
pub fn delayed_choose_data(
self,
constr_case: Self,
map_case: Self,
array_case: Self,
int_case: Self,
bytes_case: Self,
) -> Self {
Term::Builtin(DefaultFunction::ChooseData)
.force()
.apply(self)
.apply(constr_case.delay())
.apply(map_case.delay())
.apply(array_case.delay())
.apply(int_case.delay())
.apply(bytes_case.delay())
.force()
}
pub fn trace(self, msg_term: Self) -> Self { pub fn trace(self, msg_term: Self) -> Self {
Term::Builtin(DefaultFunction::Trace) Term::Builtin(DefaultFunction::Trace)
.force() .force()