diff --git a/crates/aiken-project/src/blueprint/mod.rs b/crates/aiken-project/src/blueprint/mod.rs index a420d6a1..5eeef366 100644 --- a/crates/aiken-project/src/blueprint/mod.rs +++ b/crates/aiken-project/src/blueprint/mod.rs @@ -65,7 +65,7 @@ where let mut validator = None; for v in self.validators.iter() { let match_title = Some(&v.title) == title.or(Some(&v.title)); - let match_purpose = Some(&v.purpose) == purpose.or(Some(&v.purpose)); + let match_purpose = v.purpose.as_ref() == purpose.or(v.purpose.as_ref()); if match_title && match_purpose { validator = Some(if validator.is_none() { LookupResult::One(v) @@ -81,8 +81,8 @@ where &self, title: Option<&String>, purpose: Option<&Purpose>, - when_missing: fn(Vec<(String, Purpose)>) -> E, - when_too_many: fn(Vec<(String, Purpose)>) -> E, + when_missing: fn(Vec<(String, String)>) -> E, + when_too_many: fn(Vec<(String, String)>) -> E, action: F, ) -> Result where @@ -93,13 +93,27 @@ where Some(LookupResult::Many) => Err(when_too_many( self.validators .iter() - .map(|v| (v.title.clone(), v.purpose.clone())) + .map(|v| { + let mut title = v.title.split('-'); + + ( + title.next().unwrap().to_string(), + title.next().unwrap().to_string(), + ) + }) .collect(), )), None => Err(when_missing( self.validators .iter() - .map(|v| (v.title.clone(), v.purpose.clone())) + .map(|v| { + let mut title = v.title.split('-'); + + ( + title.next().unwrap().to_string(), + title.next().unwrap().to_string(), + ) + }) .collect(), )), } diff --git a/crates/aiken-project/src/blueprint/schema.rs b/crates/aiken-project/src/blueprint/schema.rs index edf5402c..0a974268 100644 --- a/crates/aiken-project/src/blueprint/schema.rs +++ b/crates/aiken-project/src/blueprint/schema.rs @@ -580,6 +580,7 @@ fn find_definition<'a>( match def { Definition::DataType(data_type) if name == data_type.name => return Some(data_type), Definition::Fn { .. } + | Definition::Validator { .. } | Definition::DataType { .. } | Definition::TypeAlias { .. } | Definition::Use { .. } diff --git a/crates/aiken-project/src/blueprint/validator.rs b/crates/aiken-project/src/blueprint/validator.rs index 528a79fe..44ed986b 100644 --- a/crates/aiken-project/src/blueprint/validator.rs +++ b/crates/aiken-project/src/blueprint/validator.rs @@ -1,9 +1,9 @@ use super::{ - error::{assert_min_arity, assert_return_bool, Error}, + error::Error, schema::{Annotated, Schema}, }; use crate::module::{CheckedModule, CheckedModules}; -use aiken_lang::{ast::TypedFunction, uplc::CodeGenerator}; +use aiken_lang::{ast::TypedValidator, uplc::CodeGenerator}; use miette::NamedSource; use serde; use std::{ @@ -15,7 +15,8 @@ use uplc::ast::{DeBruijn, Program, Term}; #[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)] pub struct Validator { pub title: String, - pub purpose: Purpose, + #[serde(skip_serializing_if = "Option::is_none")] + pub purpose: Option, #[serde(skip_serializing_if = "Option::is_none")] pub description: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -48,30 +49,21 @@ impl Validator { pub fn from_checked_module( modules: &CheckedModules, generator: &mut CodeGenerator, - validator: &CheckedModule, - def: &TypedFunction, + module: &CheckedModule, + def: &TypedValidator, ) -> Result, Error> { - let purpose: Purpose = def - .name - .clone() - .try_into() - .expect("unexpected validator name"); + let mut args = def.fun.arguments.iter().rev(); + let (_, redeemer, datum) = (args.next(), args.next().unwrap(), args.next()); - assert_return_bool(validator, def)?; - assert_min_arity(validator, def, purpose.min_arity())?; + let mut arguments = Vec::with_capacity(def.params.len() + def.fun.arguments.len()); - let mut args = def.arguments.iter().rev(); - let (_, redeemer) = (args.next(), args.next().unwrap()); - let datum = if purpose.min_arity() > 2 { - args.next() - } else { - None - }; + arguments.extend(def.params.clone()); + arguments.extend(def.fun.arguments.clone()); Ok(Validator { - title: validator.name.clone(), + title: format!("{}-{}", &module.name, &def.fun.name), description: None, - purpose, + purpose: None, parameters: args .rev() .map(|param| { @@ -81,8 +73,8 @@ impl Validator { error, location: param.location, source_code: NamedSource::new( - validator.input_path.display().to_string(), - validator.code.clone(), + module.input_path.display().to_string(), + module.code.clone(), ), }, ); @@ -101,8 +93,8 @@ impl Validator { error, location: datum.location, source_code: NamedSource::new( - validator.input_path.display().to_string(), - validator.code.clone(), + module.input_path.display().to_string(), + module.code.clone(), ), }, ) @@ -113,12 +105,12 @@ impl Validator { error, location: redeemer.location, source_code: NamedSource::new( - validator.input_path.display().to_string(), - validator.code.clone(), + module.input_path.display().to_string(), + module.code.clone(), ), })?, program: generator - .generate(&def.body, &def.arguments, true) + .generate(&def.fun.body, &arguments, true) .try_into() .unwrap(), }) diff --git a/crates/aiken-project/src/error.rs b/crates/aiken-project/src/error.rs index 56c99dcc..c2f82ac5 100644 --- a/crates/aiken-project/src/error.rs +++ b/crates/aiken-project/src/error.rs @@ -1,8 +1,5 @@ use crate::{ - blueprint::{error as blueprint, validator}, - deps::manifest::Package, - package_name::PackageName, - pretty, + blueprint::error as blueprint, deps::manifest::Package, package_name::PackageName, pretty, script::EvalHint, }; use aiken_lang::{ @@ -136,12 +133,12 @@ pub enum Error { #[error("I didn't find any validator matching your criteria.")] NoValidatorNotFound { - known_validators: Vec<(String, validator::Purpose)>, + known_validators: Vec<(String, String)>, }, #[error("I found multiple suitable validators and I need you to tell me which one to pick.")] MoreThanOneValidatorFound { - known_validators: Vec<(String, validator::Purpose)>, + known_validators: Vec<(String, String)>, }, } diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index da0923ef..8e53eeb4 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -175,16 +175,19 @@ where pub fn dump_uplc(&self, blueprint: &Blueprint) -> Result<(), Error> { let dir = self.root.join("artifacts"); + self.event_listener .handle_event(Event::DumpingUPLC { path: dir.clone() }); + fs::create_dir_all(&dir)?; + for validator in &blueprint.validators { - let path = dir - .clone() - .join(format!("{}::{}>.uplc", validator.title, validator.purpose)); + let path = dir.clone().join(format!("{}.uplc", validator.title)); + fs::write(&path, validator.program.to_pretty()) .map_err(|error| Error::FileIo { error, path })?; } + Ok(()) } diff --git a/crates/aiken-project/src/module.rs b/crates/aiken-project/src/module.rs index f4417276..34c34db8 100644 --- a/crates/aiken-project/src/module.rs +++ b/crates/aiken-project/src/module.rs @@ -1,13 +1,13 @@ use crate::error::Error; use aiken_lang::{ ast::{ - DataType, Definition, ModuleKind, TypedDataType, TypedFunction, TypedModule, UntypedModule, + DataType, Definition, ModuleKind, TypedDataType, TypedFunction, TypedModule, + TypedValidator, UntypedModule, }, builder::{DataTypeKey, FunctionAccessKey}, parser::extra::{comments_before, Comment, ModuleExtra}, tipo::TypeInfo, uplc::CodeGenerator, - VALIDATOR_NAMES, }; use indexmap::IndexMap; use petgraph::{algo, graph::NodeIndex, Direction, Graph}; @@ -251,17 +251,17 @@ impl CheckedModules { modules } - pub fn validators(&self) -> impl Iterator { + pub fn validators(&self) -> impl Iterator { let mut items = vec![]; - for validator in self.0.values().filter(|module| module.kind.is_validator()) { - for some_definition in validator.ast.definitions() { - if let Definition::Fn(def) = some_definition { - if VALIDATOR_NAMES.contains(&def.name.as_str()) { - items.push((validator, def)); - } + + for validator_module in self.0.values().filter(|module| module.kind.is_validator()) { + for some_definition in validator_module.ast.definitions() { + if let Definition::Validator(def) = some_definition { + items.push((validator_module, def)); } } } + items.into_iter() } @@ -313,6 +313,7 @@ impl CheckedModules { Definition::TypeAlias(_) | Definition::ModuleConstant(_) | Definition::Test(_) + | Definition::Validator { .. } | Definition::Use(_) => {} } } diff --git a/examples/hello_world/plutus.json b/examples/hello_world/plutus.json index d456df61..75c45432 100644 --- a/examples/hello_world/plutus.json +++ b/examples/hello_world/plutus.json @@ -6,8 +6,7 @@ }, "validators": [ { - "title": "hello_world", - "purpose": "spend", + "title": "hello_world-spend", "datum": { "title": "Datum", "anyOf": [