Generate empty redeemer for `else` handler, to keep full compliance with the blueprint spec

This commit is contained in:
KtorZ 2024-10-01 19:03:34 +02:00
parent e8d97028ad
commit 513ca27717
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
5 changed files with 75 additions and 32 deletions

View File

@ -8,6 +8,7 @@
### Changed
- **aiken-project**: Generate empty redeemer for `else` handler, to keep full compliance with the blueprint spec. @KtorZ
- **aiken-lang**: Forbid constants evaluating to generic or unbound functions. Same restrictions as for validators or any exported UPLC programs apply here. @KtorZ & @MicroProofs
- **aiken-lang**: Fix compiler crash on trace + expect as last expression of a clause. See #1029. @KtorZ
- **aiken-lang**: Fix redundant warning on introduced identifiers when destructuring validator params. @KtorZ

View File

@ -14,14 +14,14 @@ pub struct Parameter {
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
pub schema: Reference,
pub schema: Declaration<Schema>,
}
impl From<Reference> for Parameter {
fn from(schema: Reference) -> Parameter {
Parameter {
title: None,
schema,
schema: Declaration::Referenced(schema),
}
}
}
@ -32,15 +32,20 @@ impl Parameter {
definitions: &Definitions<Annotated<Schema>>,
constant: &Constant,
) -> Result<(), Error> {
let schema = &definitions
.lookup(&self.schema)
let schema = match &self.schema {
Declaration::Inline(schema) => schema,
Declaration::Referenced(ref link) => {
&definitions
.lookup(link)
.map(Ok)
.unwrap_or_else(|| {
Err(Error::UnresolvedSchemaReference {
reference: self.schema.clone(),
reference: link.clone(),
})
})?
.annotated;
.annotated
}
};
validate_schema(schema, definitions, constant)
}

View File

@ -0,0 +1,12 @@
---
source: crates/aiken-project/src/blueprint/validator.rs
description: "Code:\n\nvalidator always_true {\n else(_) {\n True\n }\n}\n"
---
{
"title": "test_module.always_true.else",
"redeemer": {
"schema": {}
},
"compiledCode": "<redacted>",
"hash": "<redacted>"
}

View File

@ -3,7 +3,7 @@ use super::{
error::Error,
memo_program::MemoProgram,
parameter::Parameter,
schema::{Annotated, Schema},
schema::{Annotated, Data, Declaration, Schema},
};
use crate::module::{CheckedModule, CheckedModules};
use aiken_lang::{
@ -111,7 +111,7 @@ impl Validator {
)
.map(|schema| Parameter {
title: Some(param.arg_name.get_label()),
schema,
schema: Declaration::Referenced(schema),
})
.map_err(|error| Error::Schema {
error,
@ -173,7 +173,7 @@ impl Validator {
.transpose()?
.map(|schema| Parameter {
title: datum.map(|datum| datum.arg_name.get_label()),
schema,
schema: Declaration::Referenced(schema),
});
let redeemer = Annotated::from_type(
@ -191,12 +191,17 @@ impl Validator {
})
.map(|schema| Parameter {
title: Some(redeemer.arg_name.get_label()),
schema,
schema: Declaration::Referenced(schema),
})?;
(datum, Some(redeemer))
};
let redeemer = redeemer.or(Some(Parameter {
title: None,
schema: Declaration::Inline(Box::new(Schema::Data(Data::Opaque))),
}));
Ok(Validator {
title: format!("{}.{}.{}", &module.name, &def.name, &func.name,),
description: func.doc.clone(),
@ -266,8 +271,14 @@ impl Validator {
match self.parameters.split_first() {
None => Err(Error::NoParametersToApply),
Some((head, _)) => {
let schema = definitions
.lookup(&head.schema)
let schema = match &head.schema {
Declaration::Inline(schema) => Annotated {
title: head.title.clone(),
description: None,
annotated: schema.as_ref().clone(),
},
Declaration::Referenced(ref link) => definitions
.lookup(link)
.map(|s| {
Ok(Annotated {
title: s.title.clone().or_else(|| head.title.clone()),
@ -277,9 +288,10 @@ impl Validator {
})
.unwrap_or_else(|| {
Err(Error::UnresolvedSchemaReference {
reference: head.schema.clone(),
reference: link.clone(),
})
})?;
})?,
};
let data = ask(&schema, definitions)?;
@ -724,6 +736,19 @@ mod tests {
);
}
#[test]
fn else_redeemer() {
assert_validator!(
r#"
validator always_true {
else(_) {
True
}
}
"#
);
}
#[test]
fn validate_arguments_integer() {
let definitions = fixture_definitions();
@ -732,7 +757,7 @@ mod tests {
let param = Parameter {
title: None,
schema: Reference::new("Int"),
schema: Declaration::Referenced(Reference::new("Int")),
};
assert!(matches!(param.validate(&definitions, &term), Ok { .. }))
@ -746,7 +771,7 @@ mod tests {
let param = Parameter {
title: None,
schema: Reference::new("ByteArray"),
schema: Declaration::Referenced(Reference::new("ByteArray")),
};
assert!(matches!(param.validate(&definitions, &term), Ok { .. }))

View File

@ -3,7 +3,7 @@ use crate::{
self,
definitions::Definitions,
parameter::Parameter,
schema::{Annotated, Schema},
schema::{Annotated, Declaration, Schema},
},
module::{CheckedModule, CheckedModules},
};
@ -51,7 +51,7 @@ impl Export {
)
.map(|schema| Parameter {
title: Some(param.arg_name.get_label()),
schema,
schema: Declaration::Referenced(schema),
})
.map_err(|error| blueprint::Error::Schema {
error,