Skip to content

Commit

Permalink
[Tests]: Additional tests + package-loader build-time logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
0xOmarA committed Jan 17, 2024
1 parent 2fda924 commit 9d7943d
Show file tree
Hide file tree
Showing 10 changed files with 646 additions and 73 deletions.
2 changes: 1 addition & 1 deletion Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ default_to_workspace = false

[tasks.test]
command = "cargo"
args = ["nextest", "run"]
args = ["nextest", "run", "--features", "package-loader/build-time-blueprints"]

[tasks.check]
install_crate = "clippy"
Expand Down
6 changes: 4 additions & 2 deletions libraries/package-loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ getrandom = { version = "0.2.12", features = ["js"] }

[build-dependencies]
walkdir = { version = "2.3.3", optional = true }
wasm-opt = { version = "0.116.0", optional = true }
cargo_toml = { version = "0.18.0", optional = true }

scrypto-unit = { workspace = true, optional = true }
radix-engine = { workspace = true, optional = true }
radix-engine-interface = { workspace = true, optional = true }

[features]
Expand All @@ -26,8 +27,9 @@ build-time-blueprints = [
"dep:lazy_static",
"dep:walkdir",
"dep:cargo_toml",
"dep:radix-engine",
"dep:radix-engine-interface",
"dep:scrypto-unit",
"dep:wasm-opt",
]

[lib]
Expand Down
198 changes: 151 additions & 47 deletions libraries/package-loader/build.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,172 @@
fn main() {
build_blueprints();
fn main() -> Result<(), Error> {
build_blueprints()?;
Ok(())
}

#[cfg(not(feature = "build-time-blueprints"))]
fn build_blueprints() {}
fn build_blueprints() -> Result<(), Error> {
Ok(())
}

#[cfg(feature = "build-time-blueprints")]
fn build_blueprints() {
use std::env;
use std::path::PathBuf;
fn build_blueprints() -> Result<(), Error> {
use std::env::*;
use std::fs::*;
use std::path::*;
use std::process::*;
use std::*;

use cargo_toml::{Manifest, Package};
use cargo_toml::Manifest;
use radix_engine_interface::prelude::*;

let manifest_dir = PathBuf::from_str(env!("CARGO_MANIFEST_DIR")).unwrap();
let blueprints_dir = manifest_dir
.parent()
.unwrap()
.parent()
.unwrap()
.join("packages");
println!("cargo:rerun-if-changed=\"{:?}\"", blueprints_dir);

let mut scrypto_packages_manifest_paths = vec![];
for entry in walkdir::WalkDir::new(blueprints_dir) {
let Ok(entry) = entry else {
continue;
};
let path = entry.path();
if !path
.file_name()
.map_or(false, |file_name| file_name == "Cargo.toml")
{
continue;
// All of the blueprints are in the `packages` subdirectory of the project.
// So, we get the path to it so that we can start finding the blueprints
// here.
let root_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(2)
.ok_or(Error::FailedToFindAncestor {
path: PathBuf::from(env!("CARGO_MANIFEST_DIR")),
ancestor: 2,
})?
.to_owned();

let packages_path = root_path.join("packages");
let target_path = root_path.join("target");
let builds_target_path = target_path.join("package-loader-target");
if !builds_target_path.exists() {
create_dir(&builds_target_path)?;
}

// Getting the name of all of the blueprints found in the packages directory
let package_names = read_dir(&packages_path)?
.filter_map(Result::ok)
.filter_map(|entry| {
if entry.file_type().is_ok_and(|ty| ty.is_dir()) {
Some(entry.path())
} else {
None
}
})
.map(|path| {
Manifest::from_path(path.join("Cargo.toml"))
.map(|manifest| manifest.package.map(|package| package.name))
})
.filter_map(Result::ok)
.flatten()
.collect::<Vec<_>>();

// Building each of the packages that have been discovered.
let mut packages = HashMap::new();
for package_name in package_names {
// Build the package
let status = Command::new("cargo")
.args([
"build",
"--target",
"wasm32-unknown-unknown",
"--release",
"--target-dir",
builds_target_path.as_path().display().to_string().as_str(),
"--package",
package_name.as_str(),
])
.status()?;
if !status.success() {
return Err(Error::CompilationOfPackageFailed(package_name));
}

let manifest = Manifest::from_path(path).unwrap();
if !manifest
.dependencies
.into_iter()
.any(|(name, _)| name == "scrypto")
{
continue;
// Construct the path to the WASM file.
let wasm_path = builds_target_path
.join("wasm32-unknown-unknown")
.join("release")
.join(format!("{}.wasm", package_name.replace('-', "_")));

// Extract the package definition
let package_definition =
radix_engine::utils::extract_definition(&read(&wasm_path)?)?;

// Build a new WASM build without any of the schema information
let status = Command::new("cargo")
.args([
"build",
"--target",
"wasm32-unknown-unknown",
"--release",
"--target-dir",
builds_target_path.as_path().display().to_string().as_str(),
"--package",
package_name.as_str(),
"--features",
"scrypto/no-schema",
])
.status()?;
if !status.success() {
return Err(Error::CompilationOfPackageFailed(package_name));
}

let Some(Package { name, .. }) = manifest.package else {
continue;
};
// Optimize the WASM using wasm-opt for size
wasm_opt::OptimizationOptions::new_optimize_for_size_aggressively()
.add_pass(wasm_opt::Pass::StripDebug)
.add_pass(wasm_opt::Pass::StripDwarf)
.add_pass(wasm_opt::Pass::StripProducers)
.run(&wasm_path, &wasm_path)?;

scrypto_packages_manifest_paths
.push((name, path.parent().unwrap().to_owned()));
}
// Read the final wasm.
let wasm = read(wasm_path)?;

let mut packages = HashMap::new();
for (name, manifest_file_path) in scrypto_packages_manifest_paths {
let (code, definition) =
scrypto_unit::Compile::compile(manifest_file_path);
packages.insert(name, (code, definition));
packages.insert(package_name, (wasm, package_definition));
}

let out_dir =
PathBuf::from_str(env::var("OUT_DIR").unwrap().as_str()).unwrap();
PathBuf::from(var("OUT_DIR").expect("out dir must be defined!"));
let compilation_path = out_dir.join("compiled_packages.bin");

let encoded_packages = scrypto_encode(&packages).unwrap();
std::fs::write(compilation_path, encoded_packages).unwrap();
write(compilation_path, encoded_packages).unwrap();

Ok(())
}

#[derive(Debug)]
pub enum Error {
FailedToFindAncestor {
path: std::path::PathBuf,
ancestor: usize,
},
IoError(std::io::Error),
#[cfg(feature = "build-time-blueprints")]
ManifestError(cargo_toml::Error),
CompilationOfPackageFailed(String),
#[cfg(feature = "build-time-blueprints")]
ExtractSchemaError(radix_engine::utils::ExtractSchemaError),
#[cfg(feature = "build-time-blueprints")]
OptimizationError(wasm_opt::OptimizationError),
}

impl From<std::io::Error> for Error {
fn from(value: std::io::Error) -> Self {
Self::IoError(value)
}
}

#[cfg(feature = "build-time-blueprints")]
impl From<cargo_toml::Error> for Error {
fn from(value: cargo_toml::Error) -> Self {
Self::ManifestError(value)
}
}

#[cfg(feature = "build-time-blueprints")]
impl From<radix_engine::utils::ExtractSchemaError> for Error {
fn from(value: radix_engine::utils::ExtractSchemaError) -> Self {
Self::ExtractSchemaError(value)
}
}

#[cfg(feature = "build-time-blueprints")]
impl From<wasm_opt::OptimizationError> for Error {
fn from(value: wasm_opt::OptimizationError) -> Self {
Self::OptimizationError(value)
}
}
6 changes: 6 additions & 0 deletions packages/ignition/src/blueprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,12 @@ mod ignition {
|| resource2 == user_resource_address,
"{}",
USER_ASSET_DOES_NOT_BELONG_TO_POOL_ERROR
);

assert!(
user_resource_address != self.protocol_resource.address(),
"{}",
USER_MUST_NOT_PROVIDE_PROTOCOL_ASSET_ERROR
)
}

Expand Down
2 changes: 2 additions & 0 deletions packages/ignition/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ define_error! {
=> "Not a valid liquidity receipt resource.";
LIQUIDITY_POSITION_HAS_NOT_MATURED_ERROR
=> "Can't close a liquidity position before it has matured.";
USER_MUST_NOT_PROVIDE_PROTOCOL_ASSET_ERROR
=> "The user has provided the protocol asset, which is not allowed";
}
6 changes: 4 additions & 2 deletions packages/ociswap-adapter-v1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ macro_rules! define_error {
)*
) => {
$(
const $name: &'static str = concat!("[Ociswap Adapter]", " ", $item);
pub const $name: &'static str = concat!("[Ociswap Adapter]", " ", $item);
)*
};
}
Expand All @@ -22,6 +22,8 @@ define_error! {
=> "Failed to get resource addresses - unexpected error.";
FAILED_TO_GET_VAULT_ERROR
=> "Failed to get vault - unexpected error.";
PRICE_IS_UNDEFINED
=> "Price is undefined.";
}

#[blueprint_with_traits]
Expand Down Expand Up @@ -118,7 +120,7 @@ pub mod adapter {
Price {
base: resource_address1,
quote: resource_address2,
price: amount2 / amount1,
price: amount2.checked_div(amount1).expect(PRICE_IS_UNDEFINED),
}
}

Expand Down
Loading

0 comments on commit 9d7943d

Please sign in to comment.