Remove now-unnecessary blueprint generics.

These were needed before as a way to _partially deserialize_
  blueprints. Indeed, some commands required accessing information of
  the blueprint, but not necessarily the schema. So out of laziness (or
  cleverness?), we only deserialized validators as serde::Value and
  achieved that through the use of generics.

  Now that validators and schemas have proper deserialisers, we can
  simply deserialize a blueprint.

  TODO: Our serialisation/deserialisation is safe with regards to
  itself; i.e. it roundtrips. However, we only supports a subset of the
  specified blueprint format. For example, we would fail to deserialize
  blueprints that have inline data-schemas (we only use references).
This commit is contained in:
KtorZ 2023-04-05 11:51:26 +02:00
parent f0d2d20a4c
commit cdc7ebf9a0
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
4 changed files with 28 additions and 45 deletions

View File

@ -5,18 +5,18 @@ pub mod validator;
use crate::{config::Config, module::CheckedModules}; use crate::{config::Config, module::CheckedModules};
use aiken_lang::gen_uplc::CodeGenerator; use aiken_lang::gen_uplc::CodeGenerator;
use definitions::{Definitions, Reference}; use definitions::Definitions;
use error::Error; use error::Error;
use schema::{Annotated, Schema}; use schema::{Annotated, Schema};
use std::fmt::Debug; use std::fmt::Debug;
use validator::Validator; use validator::Validator;
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
pub struct Blueprint<R: Default, S: Default> { pub struct Blueprint {
pub preamble: Preamble, pub preamble: Preamble,
pub validators: Vec<Validator<R, S>>, pub validators: Vec<Validator>,
#[serde(skip_serializing_if = "Definitions::is_empty", default)] #[serde(skip_serializing_if = "Definitions::is_empty", default)]
pub definitions: Definitions<S>, pub definitions: Definitions<Annotated<Schema>>,
} }
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
@ -48,7 +48,7 @@ pub enum LookupResult<'a, T> {
Many, Many,
} }
impl Blueprint<Reference, Annotated<Schema>> { impl Blueprint {
pub fn new( pub fn new(
config: &Config, config: &Config,
modules: &CheckedModules, modules: &CheckedModules,
@ -82,12 +82,8 @@ impl Blueprint<Reference, Annotated<Schema>> {
} }
} }
impl<R, S> Blueprint<R, S> impl Blueprint {
where pub fn lookup(&self, title: Option<&String>) -> Option<LookupResult<Validator>> {
R: Clone + Default,
S: Clone + Default,
{
pub fn lookup(&self, title: Option<&String>) -> Option<LookupResult<Validator<R, S>>> {
let mut validator = None; let mut validator = None;
for v in self.validators.iter() { for v in self.validators.iter() {
@ -112,7 +108,7 @@ where
action: F, action: F,
) -> Result<A, E> ) -> Result<A, E>
where where
F: Fn(Validator<R, S>) -> Result<A, E>, F: Fn(Validator) -> Result<A, E>,
{ {
match self.lookup(title) { match self.lookup(title) {
Some(LookupResult::One(validator)) => action(validator.to_owned()), Some(LookupResult::One(validator)) => action(validator.to_owned()),
@ -152,7 +148,7 @@ mod test {
#[test] #[test]
fn serialize_no_description() { fn serialize_no_description() {
let blueprint: Blueprint<Reference, Annotated<Schema>> = Blueprint { let blueprint = Blueprint {
preamble: Preamble { preamble: Preamble {
title: "Foo".to_string(), title: "Foo".to_string(),
description: None, description: None,
@ -179,7 +175,7 @@ mod test {
#[test] #[test]
fn serialize_with_description() { fn serialize_with_description() {
let blueprint: Blueprint<Reference, Annotated<Schema>> = Blueprint { let blueprint = Blueprint {
preamble: Preamble { preamble: Preamble {
title: "Foo".to_string(), title: "Foo".to_string(),
description: Some("Lorem ipsum".to_string()), description: Some("Lorem ipsum".to_string()),
@ -227,7 +223,7 @@ mod test {
) )
.unwrap(); .unwrap();
let blueprint: Blueprint<Reference, Annotated<Schema>> = Blueprint { let blueprint = Blueprint {
preamble: Preamble { preamble: Preamble {
title: "Foo".to_string(), title: "Foo".to_string(),
description: None, description: None,

View File

@ -13,44 +13,44 @@ use serde;
use uplc::ast::{DeBruijn, Program, Term}; use uplc::ast::{DeBruijn, Program, Term};
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
pub struct Validator<R, S> { pub struct Validator {
pub title: String, pub title: String,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>, pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub datum: Option<Argument<R>>, pub datum: Option<Argument>,
pub redeemer: Argument<R>, pub redeemer: Argument,
#[serde(skip_serializing_if = "Vec::is_empty")] #[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)] #[serde(default)]
pub parameters: Vec<Argument<R>>, pub parameters: Vec<Argument>,
#[serde(flatten)] #[serde(flatten)]
pub program: Program<DeBruijn>, pub program: Program<DeBruijn>,
#[serde(skip_serializing_if = "Definitions::is_empty")] #[serde(skip_serializing_if = "Definitions::is_empty")]
#[serde(default)] #[serde(default)]
pub definitions: Definitions<S>, pub definitions: Definitions<Annotated<Schema>>,
} }
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
pub struct Argument<T> { pub struct Argument {
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>, pub title: Option<String>,
pub schema: T, pub schema: Reference,
} }
impl Validator<Reference, Annotated<Schema>> { impl Validator {
pub fn from_checked_module( pub fn from_checked_module(
modules: &CheckedModules, modules: &CheckedModules,
generator: &mut CodeGenerator, generator: &mut CodeGenerator,
module: &CheckedModule, module: &CheckedModule,
def: &TypedValidator, def: &TypedValidator,
) -> Vec<Result<Validator<Reference, Annotated<Schema>>, Error>> { ) -> Vec<Result<Validator, Error>> {
let program = generator.generate(def).try_into().unwrap(); let program = generator.generate(def).try_into().unwrap();
let is_multi_validator = def.other_fun.is_some(); let is_multi_validator = def.other_fun.is_some();
@ -85,7 +85,7 @@ impl Validator<Reference, Annotated<Schema>> {
params: &[TypedArg], params: &[TypedArg],
func: &TypedFunction, func: &TypedFunction,
is_multi_validator: bool, is_multi_validator: bool,
) -> Result<Validator<Reference, Annotated<Schema>>, Error> { ) -> Result<Validator, Error> {
let mut args = func.arguments.iter().rev(); let mut args = func.arguments.iter().rev();
let (_, redeemer, datum) = (args.next(), args.next().unwrap(), args.next()); let (_, redeemer, datum) = (args.next(), args.next().unwrap(), args.next());
@ -160,11 +160,7 @@ impl Validator<Reference, Annotated<Schema>> {
} }
} }
impl<R, S> Validator<R, S> impl Validator {
where
S: Clone,
R: Clone,
{
pub fn apply(self, arg: &Term<DeBruijn>) -> Result<Self, Error> { pub fn apply(self, arg: &Term<DeBruijn>) -> Result<Self, Error> {
match self.parameters.split_first() { match self.parameters.split_first() {
None => Err(Error::NoParametersToApply), None => Err(Error::NoParametersToApply),

View File

@ -12,11 +12,7 @@ pub mod pretty;
pub mod script; pub mod script;
pub mod telemetry; pub mod telemetry;
use crate::blueprint::{ use crate::blueprint::Blueprint;
definitions::Reference,
schema::{Annotated, Schema},
Blueprint,
};
use aiken_lang::{ use aiken_lang::{
ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction}, ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction},
builtins, builtins,
@ -218,10 +214,7 @@ where
self.compile(options) self.compile(options)
} }
pub fn dump_uplc( pub fn dump_uplc(&self, blueprint: &Blueprint) -> Result<(), Error> {
&self,
blueprint: &Blueprint<Reference, Annotated<Schema>>,
) -> Result<(), Error> {
let dir = self.root.join("artifacts"); let dir = self.root.join("artifacts");
self.event_listener self.event_listener
@ -362,8 +355,7 @@ where
// Read blueprint // Read blueprint
let blueprint = File::open(self.blueprint_path()) let blueprint = File::open(self.blueprint_path())
.map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?; .map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?;
let blueprint: Blueprint<serde_json::Value, serde_json::Value> = let blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?;
serde_json::from_reader(BufReader::new(blueprint))?;
// Calculate the address // Calculate the address
let when_too_many = let when_too_many =
@ -386,12 +378,11 @@ where
&self, &self,
title: Option<&String>, title: Option<&String>,
param: &Term<DeBruijn>, param: &Term<DeBruijn>,
) -> Result<Blueprint<serde_json::Value, serde_json::Value>, Error> { ) -> Result<Blueprint, Error> {
// Read blueprint // Read blueprint
let blueprint = File::open(self.blueprint_path()) let blueprint = File::open(self.blueprint_path())
.map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?; .map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?;
let mut blueprint: Blueprint<serde_json::Value, serde_json::Value> = let mut blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?;
serde_json::from_reader(BufReader::new(blueprint))?;
// Apply parameters // Apply parameters
let when_too_many = let when_too_many =

View File

@ -65,7 +65,7 @@ pub fn exec(
.map_err(|_| BlueprintError::InvalidOrMissingFile) .map_err(|_| BlueprintError::InvalidOrMissingFile)
.into_diagnostic()?; .into_diagnostic()?;
let blueprint: Blueprint<serde_json::Value, serde_json::Value> = let blueprint: Blueprint =
serde_json::from_reader(BufReader::new(blueprint)).into_diagnostic()?; serde_json::from_reader(BufReader::new(blueprint)).into_diagnostic()?;
// Perform the conversion // Perform the conversion