Skip to main content

hyperlight_wasm/
lib.rs

1/*
2Copyright 2024 The Hyperlight Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#![deny(dead_code, missing_docs, unused_mut)]
18//! This crate provides a Hyperlight implementation for WebAssembly (Wasm) guest code.
19
20/// provides details about the build
21pub mod build_info;
22mod sandbox;
23
24use build_info::BuildInfo;
25pub use sandbox::loaded_wasm_sandbox::LoadedWasmSandbox;
26pub use sandbox::proto_wasm_sandbox::ProtoWasmSandbox;
27pub use sandbox::sandbox_builder::SandboxBuilder;
28pub use sandbox::wasm_sandbox::WasmSandbox;
29
30// Re-export types from hyperlight-host so consumers don't need to depend on it directly
31
32/// The container to store the value of a single parameter to a guest
33/// function.
34pub type ParameterValue = hyperlight_host::func::ParameterValue;
35/// The container to store the return value from a guest function call.
36pub type ReturnValue = hyperlight_host::func::ReturnValue;
37/// The type of the return value from a guest function call.
38pub type ReturnType = hyperlight_host::func::ReturnType;
39/// The Result of a function call
40pub type Result<T> = hyperlight_host::Result<T>;
41
42/// The error type for Hyperlight operations
43pub use hyperlight_host::HyperlightError;
44/// A host function that can be registered with a sandbox
45pub use hyperlight_host::func::HostFunction;
46/// Trait bound for parameter tuples passed to guest/host functions
47pub use hyperlight_host::func::ParameterTuple;
48/// Trait for types that can register host functions
49pub use hyperlight_host::func::Registerable;
50/// Trait bound for return types from guest/host functions
51pub use hyperlight_host::func::SupportedReturnType;
52/// Handle for interrupting guest execution
53pub use hyperlight_host::hypervisor::InterruptHandle;
54/// Check if there is a hypervisor present
55pub use hyperlight_host::is_hypervisor_present;
56/// Create a generic HyperlightError
57pub use hyperlight_host::new_error;
58/// The lifecycle state of a sandbox.
59pub use hyperlight_host::sandbox::SandboxStatus;
60/// A snapshot of the memory of a sandbox at a given point in time.
61pub use hyperlight_host::sandbox::snapshot::Snapshot;
62/// OCI Image Layout reference types used by [`Snapshot::save`] /
63/// [`Snapshot::load`] to identify snapshots inside an OCI Image Layout
64/// directory. Re-exported here so downstream crates do not need a
65/// direct dependency on `hyperlight-host`.
66pub use hyperlight_host::sandbox::snapshot::{OciDigest, OciReference, OciTag};
67
68/// Get the build information for this version of hyperlight-wasm
69pub fn get_build_info() -> BuildInfo {
70    BuildInfo::get()
71}
72/// Get the wasmtime version used by this version of hyperlight-wasm
73pub fn get_wasmtime_version() -> &'static str {
74    BuildInfo::get_wasmtime_version()
75}
76
77#[cfg(test)]
78mod tests {
79    use std::env;
80
81    // Test that the build info is correct
82    #[test]
83    fn test_build_info() {
84        let build_info = super::get_build_info();
85        // calculate the blake3 hash of the hyperlight-wasm-runtime binary
86        let wasm_runtime_hash = blake3::hash(&super::sandbox::WASM_RUNTIME);
87        // check that the build info hash matches the hyperlight-wasm-runtime hash
88        assert_eq!(
89            build_info.wasm_runtime_blake3_hash,
90            &wasm_runtime_hash.to_string()
91        );
92        assert_eq!(build_info.package_version, env!("CARGO_PKG_VERSION"));
93    }
94    // Test that the wasmtime version is correct
95    #[test]
96    fn test_wasmtime_version() {
97        let wasmtime_version = super::get_wasmtime_version();
98        // get the wasmtime version from the hyperlight-wasm-runtime binary's Cargo.toml
99
100        let manifest_path = env!("CARGO_MANIFEST_PATH");
101        let output = std::process::Command::new("cargo")
102            .arg("metadata")
103            .arg("--manifest-path")
104            .arg(manifest_path)
105            .arg("--format-version=1")
106            .output()
107            .expect("Failed to get cargo metadata");
108
109        #[derive(serde::Deserialize)]
110        struct CargoMetadata {
111            packages: Vec<CargoPackage>,
112        }
113
114        #[derive(serde::Deserialize)]
115        struct CargoPackage {
116            name: String,
117            manifest_path: std::path::PathBuf,
118        }
119
120        let metadata: CargoMetadata =
121            serde_json::from_slice(&output.stdout).expect("Failed to parse cargo metadata");
122
123        // find the package entry for hyperlight-wasm-runtime and get its manifest_path
124        let hyperlight_wasm_runtime = metadata
125            .packages
126            .into_iter()
127            .find(|pkg| pkg.name == "hyperlight-wasm-runtime")
128            .expect("hyperlight-wasm-runtime crate not found in cargo metadata");
129
130        let cargo_toml_path = hyperlight_wasm_runtime.manifest_path;
131        let cargo_toml_content =
132            std::fs::read_to_string(cargo_toml_path).expect("Failed to read Cargo.toml");
133        let cargo_toml: toml::Value =
134            toml::from_str(&cargo_toml_content).expect("Failed to parse Cargo.toml");
135        // LTS is the default; wasmtime_latest opts into the latest dependency.
136        let dep_key = if cfg!(feature = "wasmtime_latest") {
137            "wasmtime"
138        } else {
139            "wasmtime_lts"
140        };
141        let wasmtime_version_requirement = cargo_toml
142            .get("target")
143            .and_then(|deps| deps.get("cfg(hyperlight)"))
144            .and_then(|cfg| cfg.get("dependencies"))
145            .and_then(|deps| deps.get(dep_key))
146            .and_then(|wasmtime| wasmtime.get("version"))
147            .and_then(|version| version.as_str())
148            .expect("Failed to find wasmtime version in Cargo.toml");
149        let wasmtime_version =
150            semver::Version::parse(wasmtime_version).expect("Failed to parse Wasmtime version");
151        let wasmtime_version_requirement = semver::VersionReq::parse(wasmtime_version_requirement)
152            .expect("Failed to parse Wasmtime version requirement");
153        assert!(
154            wasmtime_version_requirement.matches(&wasmtime_version),
155            "Wasmtime version {wasmtime_version} does not satisfy manifest requirement {wasmtime_version_requirement}"
156        );
157    }
158}