Fix Plutus v3 validator hash calculation in blueprint.
This commit is contained in:
@@ -5,14 +5,13 @@ pub mod parameter;
|
||||
pub mod schema;
|
||||
pub mod validator;
|
||||
|
||||
pub use error::Error;
|
||||
|
||||
use crate::{
|
||||
config::{self, Config, PlutusVersion},
|
||||
module::CheckedModules,
|
||||
};
|
||||
use aiken_lang::gen_uplc::CodeGenerator;
|
||||
use definitions::Definitions;
|
||||
pub use error::Error;
|
||||
use schema::{Annotated, Schema};
|
||||
use std::fmt::Debug;
|
||||
use validator::Validator;
|
||||
@@ -70,7 +69,7 @@ impl Blueprint {
|
||||
let validators: Result<Vec<_>, Error> = modules
|
||||
.validators()
|
||||
.flat_map(|(validator, def)| {
|
||||
Validator::from_checked_module(modules, generator, validator, def)
|
||||
Validator::from_checked_module(modules, generator, validator, def, &config.plutus)
|
||||
.into_iter()
|
||||
.map(|result| {
|
||||
result.map(|mut schema| {
|
||||
|
||||
@@ -9,13 +9,14 @@ use crate::module::{CheckedModule, CheckedModules};
|
||||
use aiken_lang::{
|
||||
ast::{Annotation, TypedArg, TypedFunction, TypedValidator},
|
||||
gen_uplc::CodeGenerator,
|
||||
plutus_version::PlutusVersion,
|
||||
tipo::Type,
|
||||
};
|
||||
use miette::NamedSource;
|
||||
use serde;
|
||||
use std::borrow::Borrow;
|
||||
use uplc::{
|
||||
ast::{Constant, DeBruijn, Program},
|
||||
ast::{Constant, SerializableProgram},
|
||||
PlutusData,
|
||||
};
|
||||
|
||||
@@ -36,7 +37,7 @@ pub struct Validator {
|
||||
pub parameters: Vec<Parameter>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub program: Program<DeBruijn>,
|
||||
pub program: SerializableProgram,
|
||||
|
||||
#[serde(skip_serializing_if = "Definitions::is_empty")]
|
||||
#[serde(default)]
|
||||
@@ -49,6 +50,7 @@ impl Validator {
|
||||
generator: &mut CodeGenerator,
|
||||
module: &CheckedModule,
|
||||
def: &TypedValidator,
|
||||
plutus_version: &PlutusVersion,
|
||||
) -> Vec<Result<Validator, Error>> {
|
||||
let is_multi_validator = def.other_fun.is_some();
|
||||
|
||||
@@ -62,6 +64,7 @@ impl Validator {
|
||||
&def.fun,
|
||||
is_multi_validator,
|
||||
&mut program,
|
||||
plutus_version,
|
||||
)];
|
||||
|
||||
if let Some(ref other_func) = def.other_fun {
|
||||
@@ -73,12 +76,14 @@ impl Validator {
|
||||
other_func,
|
||||
is_multi_validator,
|
||||
&mut program,
|
||||
plutus_version,
|
||||
));
|
||||
}
|
||||
|
||||
validators
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn create_validator_blueprint(
|
||||
generator: &mut CodeGenerator,
|
||||
modules: &CheckedModules,
|
||||
@@ -87,6 +92,7 @@ impl Validator {
|
||||
func: &TypedFunction,
|
||||
is_multi_validator: bool,
|
||||
program: &mut MemoProgram,
|
||||
plutus_version: &PlutusVersion,
|
||||
) -> Result<Validator, Error> {
|
||||
let mut args = func.arguments.iter().rev();
|
||||
let (_, redeemer, datum) = (args.next(), args.next().unwrap(), args.next());
|
||||
@@ -168,7 +174,11 @@ impl Validator {
|
||||
parameters,
|
||||
datum,
|
||||
redeemer,
|
||||
program: program.get(generator, def, &module.name),
|
||||
program: match plutus_version {
|
||||
PlutusVersion::V1 => SerializableProgram::PlutusV1Program,
|
||||
PlutusVersion::V2 => SerializableProgram::PlutusV2Program,
|
||||
PlutusVersion::V3 => SerializableProgram::PlutusV3Program,
|
||||
}(program.get(generator, def, &module.name)),
|
||||
definitions,
|
||||
})
|
||||
}
|
||||
@@ -208,7 +218,7 @@ impl Validator {
|
||||
Some((head, tail)) => {
|
||||
head.validate(definitions, &Constant::Data(arg.clone()))?;
|
||||
Ok(Self {
|
||||
program: self.program.apply_data(arg.clone()),
|
||||
program: self.program.map(|program| program.apply_data(arg.clone())),
|
||||
parameters: tail.to_vec(),
|
||||
..self
|
||||
})
|
||||
@@ -284,7 +294,7 @@ mod tests {
|
||||
.next()
|
||||
.expect("source code did no yield any validator");
|
||||
|
||||
let validators = Validator::from_checked_module(&modules, &mut generator, validator, def);
|
||||
let validators = Validator::from_checked_module(&modules, &mut generator, validator, def, &PlutusVersion::default());
|
||||
|
||||
if validators.len() > 1 {
|
||||
panic!("Multi-validator given to test bench. Don't do that.")
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
use aiken_lang::{ast::TypedFunction, gen_uplc::CodeGenerator};
|
||||
use miette::NamedSource;
|
||||
use uplc::ast::{DeBruijn, Program};
|
||||
|
||||
use crate::{
|
||||
blueprint::{
|
||||
self,
|
||||
@@ -11,6 +7,9 @@ use crate::{
|
||||
},
|
||||
module::{CheckedModule, CheckedModules},
|
||||
};
|
||||
use aiken_lang::{ast::TypedFunction, gen_uplc::CodeGenerator, plutus_version::PlutusVersion};
|
||||
use miette::NamedSource;
|
||||
use uplc::ast::SerializableProgram;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Export {
|
||||
@@ -24,7 +23,7 @@ pub struct Export {
|
||||
pub parameters: Vec<Parameter>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub program: Program<DeBruijn>,
|
||||
pub program: SerializableProgram,
|
||||
|
||||
#[serde(skip_serializing_if = "Definitions::is_empty")]
|
||||
#[serde(default)]
|
||||
@@ -37,6 +36,7 @@ impl Export {
|
||||
module: &CheckedModule,
|
||||
generator: &mut CodeGenerator,
|
||||
modules: &CheckedModules,
|
||||
plutus_version: &PlutusVersion,
|
||||
) -> Result<Export, blueprint::Error> {
|
||||
let mut definitions = Definitions::new();
|
||||
|
||||
@@ -64,10 +64,16 @@ impl Export {
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
let program = generator
|
||||
.generate_raw(&func.body, &func.arguments, &module.name)
|
||||
.to_debruijn()
|
||||
.unwrap();
|
||||
let program = match plutus_version {
|
||||
PlutusVersion::V1 => SerializableProgram::PlutusV1Program,
|
||||
PlutusVersion::V2 => SerializableProgram::PlutusV2Program,
|
||||
PlutusVersion::V3 => SerializableProgram::PlutusV3Program,
|
||||
}(
|
||||
generator
|
||||
.generate_raw(&func.body, &func.arguments, &module.name)
|
||||
.to_debruijn()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
Ok(Export {
|
||||
name: format!("{}.{}", &module.name, &func.name),
|
||||
@@ -86,6 +92,7 @@ mod tests {
|
||||
use aiken_lang::{
|
||||
self,
|
||||
ast::{TraceLevel, Tracing},
|
||||
plutus_version::PlutusVersion,
|
||||
};
|
||||
|
||||
macro_rules! assert_export {
|
||||
@@ -103,7 +110,7 @@ mod tests {
|
||||
.next()
|
||||
.expect("source code did no yield any exports");
|
||||
|
||||
let export = Export::from_function(func, module, &mut generator, &modules);
|
||||
let export = Export::from_function(func, module, &mut generator, &modules, &PlutusVersion::default());
|
||||
|
||||
match export {
|
||||
Err(e) => insta::with_settings!({
|
||||
|
||||
@@ -40,7 +40,6 @@ use aiken_lang::{
|
||||
format::{Formatter, MAX_COLUMNS},
|
||||
gen_uplc::CodeGenerator,
|
||||
line_numbers::LineNumbers,
|
||||
plutus_version::PlutusVersion,
|
||||
tipo::{Type, TypeInfo},
|
||||
IdGenerator,
|
||||
};
|
||||
@@ -50,8 +49,7 @@ use miette::NamedSource;
|
||||
use options::{CodeGenMode, Options};
|
||||
use package_name::PackageName;
|
||||
use pallas_addresses::{Address, Network, ShelleyAddress, ShelleyDelegationPart, StakePayload};
|
||||
use pallas_primitives::conway::{self as cardano, PolicyId};
|
||||
use pallas_traverse::ComputeHash;
|
||||
use pallas_primitives::conway::PolicyId;
|
||||
use std::{
|
||||
collections::{BTreeSet, HashMap},
|
||||
fs::{self, File},
|
||||
@@ -298,7 +296,7 @@ where
|
||||
let path = dir.clone().join(format!("{}.uplc", validator.title));
|
||||
|
||||
let program = &validator.program;
|
||||
let program: Program<Name> = program.try_into().unwrap();
|
||||
let program: Program<Name> = program.inner().try_into().unwrap();
|
||||
|
||||
fs::write(&path, program.to_pretty()).map_err(|error| Error::FileIo { error, path })?;
|
||||
}
|
||||
@@ -490,7 +488,7 @@ where
|
||||
Network::Testnet
|
||||
};
|
||||
|
||||
Ok(validator.program.address(
|
||||
Ok(validator.program.inner().address(
|
||||
network,
|
||||
delegation_part.to_owned(),
|
||||
&self.config.plutus.into(),
|
||||
@@ -520,15 +518,7 @@ where
|
||||
if n > 0 {
|
||||
Err(blueprint::error::Error::ParameterizedValidator { n }.into())
|
||||
} else {
|
||||
let cbor = validator.program.to_cbor().unwrap();
|
||||
|
||||
let validator_hash = match self.config.plutus {
|
||||
PlutusVersion::V1 => cardano::PlutusV1Script(cbor.into()).compute_hash(),
|
||||
PlutusVersion::V2 => cardano::PlutusV2Script(cbor.into()).compute_hash(),
|
||||
PlutusVersion::V3 => cardano::PlutusV3Script(cbor.into()).compute_hash(),
|
||||
};
|
||||
|
||||
Ok(validator_hash)
|
||||
Ok(validator.program.compiled_code_and_hash().1)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -552,7 +542,13 @@ where
|
||||
.map(|(checked_module, func)| {
|
||||
let mut generator = self.new_generator(tracing);
|
||||
|
||||
Export::from_function(func, checked_module, &mut generator, &self.checked_modules)
|
||||
Export::from_function(
|
||||
func,
|
||||
checked_module,
|
||||
&mut generator,
|
||||
&self.checked_modules,
|
||||
&self.config.plutus,
|
||||
)
|
||||
})
|
||||
.transpose()?
|
||||
.ok_or_else(|| Error::ExportNotFound {
|
||||
|
||||
Reference in New Issue
Block a user