Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reuse atom signatures #4627

Merged
merged 11 commits into from
May 3, 2024
6 changes: 4 additions & 2 deletions lib/cli/src/commands/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -705,9 +705,10 @@ impl ExecutableTarget {
.load_module_sync(&wasm)
.with_context(|| format!("Unable to compile \"{}\"", path.display()))?;

// FIXME: Amin
Ok(ExecutableTarget::WebAssembly {
module,
module_hash: ModuleHash::hash(&wasm),
module_hash: ModuleHash::xxhash(&wasm),
path: path.to_path_buf(),
})
}
Expand All @@ -717,7 +718,8 @@ impl ExecutableTarget {
let module = unsafe { Module::deserialize_from_file(&engine, path)? };
let module_hash = {
let wasm = std::fs::read(path)?;
ModuleHash::hash(wasm)
// FIXME: Amin
ModuleHash::xxhash(wasm)
maminrayej marked this conversation as resolved.
Show resolved Hide resolved
};

Ok(ExecutableTarget::WebAssembly {
Expand Down
7 changes: 4 additions & 3 deletions lib/wasix/src/bin_factory/binary_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{
Runtime,
};

// FIXME: Amin
#[derive(Derivative, Clone)]
#[derivative(Debug)]
pub struct BinaryPackageCommand {
Expand Down Expand Up @@ -52,7 +53,7 @@ impl BinaryPackageCommand {
}

pub fn hash(&self) -> &ModuleHash {
self.hash.get_or_init(|| ModuleHash::hash(self.atom()))
self.hash.get_or_init(|| ModuleHash::xxhash(self.atom()))
}
}

Expand Down Expand Up @@ -146,9 +147,9 @@ impl BinaryPackage {
pub fn hash(&self) -> ModuleHash {
*self.hash.get_or_init(|| {
if let Some(entry) = self.entrypoint_bytes() {
ModuleHash::hash(entry)
ModuleHash::xxhash(entry)
} else {
ModuleHash::hash(self.id.to_string())
ModuleHash::xxhash(self.id.to_string())
}
})
}
Expand Down
8 changes: 4 additions & 4 deletions lib/wasix/src/os/task/control_plane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ mod tests {
enable_exponential_cpu_backoff: None,
});

let p1 = p.new_process(ModuleHash::random()).unwrap();
let p1 = p.new_process(ModuleHash::xxhash_random()).unwrap();
let _t1 = p1
.new_thread(WasiMemoryLayout::default(), ThreadStartType::MainThread)
.unwrap();
Expand All @@ -234,7 +234,7 @@ mod tests {
.unwrap();

assert_eq!(
p.new_process(ModuleHash::random()).unwrap_err(),
p.new_process(ModuleHash::xxhash_random()).unwrap_err(),
ControlPlaneError::TaskLimitReached { max: 2 }
);
}
Expand All @@ -248,7 +248,7 @@ mod tests {
enable_exponential_cpu_backoff: None,
});

let p1 = p.new_process(ModuleHash::random()).unwrap();
let p1 = p.new_process(ModuleHash::xxhash_random()).unwrap();

for _ in 0..10 {
let _thread = p1
Expand All @@ -264,7 +264,7 @@ mod tests {
.unwrap();

assert_eq!(
p.new_process(ModuleHash::random()).unwrap_err(),
p.new_process(ModuleHash::xxhash_random()).unwrap_err(),
ControlPlaneError::TaskLimitReached { max: 2 }
);
}
Expand Down
6 changes: 4 additions & 2 deletions lib/wasix/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ where
fn load_module<'a>(&'a self, wasm: &'a [u8]) -> BoxFuture<'a, Result<Module, SpawnError>> {
let engine = self.engine();
let module_cache = self.module_cache();
let hash = ModuleHash::hash(wasm);
// FIXME: Amin
let hash = ModuleHash::xxhash(wasm);

let task = async move { load_module(&engine, &module_cache, wasm, hash).await };

Expand Down Expand Up @@ -553,7 +554,8 @@ impl Runtime for OverriddenRuntime {
if self.engine.is_some() || self.module_cache.is_some() {
let engine = self.engine();
let module_cache = self.module_cache();
let hash = ModuleHash::hash(wasm);
// FIXME: Amin
let hash = ModuleHash::xxhash(wasm);

let task = async move { load_module(&engine, &module_cache, wasm, hash).await };
Box::pin(task)
Expand Down
6 changes: 3 additions & 3 deletions lib/wasix/src/runtime/module_cache/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ mod tests {
async fn load_from_primary() {
let engine = Engine::default();
let module = Module::new(&engine, ADD_WAT).unwrap();
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);
let primary = SharedCache::default();
let fallback = SharedCache::default();
primary.save(key, &engine, &module).await.unwrap();
Expand All @@ -204,7 +204,7 @@ mod tests {
async fn loading_from_fallback_also_populates_primary() {
let engine = Engine::default();
let module = Module::new(&engine, ADD_WAT).unwrap();
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);
let primary = SharedCache::default();
let fallback = SharedCache::default();
fallback.save(key, &engine, &module).await.unwrap();
Expand All @@ -230,7 +230,7 @@ mod tests {
async fn saving_will_update_both() {
let engine = Engine::default();
let module = Module::new(&engine, ADD_WAT).unwrap();
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);
let primary = SharedCache::default();
let fallback = SharedCache::default();
let cache = FallbackCache::new(&primary, &fallback);
Expand Down
10 changes: 5 additions & 5 deletions lib/wasix/src/runtime/module_cache/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ mod tests {
let engine = Engine::default();
let module = Module::new(&engine, ADD_WAT).unwrap();
let cache = FileSystemCache::new(temp.path(), create_tokio_task_manager());
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);
let expected_path = cache.path(key, engine.deterministic_id());

cache.save(key, &engine, &module).await.unwrap();
Expand All @@ -236,7 +236,7 @@ mod tests {
let cache_dir = temp.path().join("this").join("doesn't").join("exist");
assert!(!cache_dir.exists());
let cache = FileSystemCache::new(&cache_dir, create_tokio_task_manager());
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);

cache.save(key, &engine, &module).await.unwrap();

Expand All @@ -247,7 +247,7 @@ mod tests {
async fn missing_file() {
let temp = TempDir::new().unwrap();
let engine = Engine::default();
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);
let cache = FileSystemCache::new(temp.path(), create_tokio_task_manager());

let err = cache.load(key, &engine).await.unwrap_err();
Expand All @@ -260,7 +260,7 @@ mod tests {
let temp = TempDir::new().unwrap();
let engine = Engine::default();
let module = Module::new(&engine, ADD_WAT).unwrap();
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);
let cache = FileSystemCache::new(temp.path(), create_tokio_task_manager());
let expected_path = cache.path(key, engine.deterministic_id());
std::fs::create_dir_all(expected_path.parent().unwrap()).unwrap();
Expand All @@ -283,7 +283,7 @@ mod tests {
let temp = TempDir::new().unwrap();
let engine = Engine::default();
let module = Module::new(&engine, ADD_WAT).unwrap();
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);
let cache = FileSystemCache::new(temp.path(), create_tokio_task_manager());
let expected_path = cache.path(key, engine.deterministic_id());
std::fs::create_dir_all(expected_path.parent().unwrap()).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion lib/wasix/src/runtime/module_cache/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ mod tests {
let engine = Engine::default();
let module = Module::new(&engine, ADD_WAT).unwrap();
let cache = SharedCache::default();
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);

cache.save(key, &engine, &module).await.unwrap();
let round_tripped = cache.load(key, &engine).await.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion lib/wasix/src/runtime/module_cache/thread_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ mod tests {
let engine = Engine::default();
let module = Module::new(&engine, ADD_WAT).unwrap();
let cache = ThreadLocalCache::default();
let key = ModuleHash::from_bytes([0; 8]);
let key = ModuleHash::xxhash_from_bytes([0; 8]);

cache.save(key, &engine, &module).await.unwrap();
let round_tripped = cache.load(key, &engine).await.unwrap();
Expand Down
111 changes: 92 additions & 19 deletions lib/wasix/src/runtime/module_cache/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
};

use rand::RngCore;
use sha2::Digest;
use wasmer::{Engine, Module};

use crate::runtime::module_cache::FallbackCache;
Expand Down Expand Up @@ -127,50 +128,122 @@ impl CacheError {
}
}

/// The XXHash hash of a WebAssembly module.
/// The hash of a WebAssembly module.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ModuleHash([u8; 8]);
pub enum ModuleHash {
XXHash([u8; 8]),
Sha256([u8; 32]),
}

impl ModuleHash {
/// Create a new [`ModuleHash`] from the raw XXHash hash.
pub fn from_bytes(key: [u8; 8]) -> Self {
ModuleHash(key)
/// Create a new [`ModuleHash`] from the raw xxhash hash.
pub fn xxhash_from_bytes(key: [u8; 8]) -> Self {
Self::from_bytes(key)
}

/// Create a new [`ModuleHash`] from the raw sha256 hash.
pub fn sha256_from_bytes(key: [u8; 32]) -> Self {
Self::from_bytes(key)
}

fn from_bytes<const N: usize>(key: [u8; N]) -> Self {
if N == 8 {
let key = key.as_slice().try_into().unwrap();
ModuleHash::XXHash(key)
} else if N == 32 {
let key = key.as_slice().try_into().unwrap();
ModuleHash::Sha256(key)
} else {
panic!("Only keys with size 8 or 32 are accepted")
}
}
maminrayej marked this conversation as resolved.
Show resolved Hide resolved

/// Creates a random xxhash for the module
pub fn xxhash_random() -> Self {
Self::random::<8>()
maminrayej marked this conversation as resolved.
Show resolved Hide resolved
}

/// Creates a random sha256 hash for the module
pub fn sha256_random() -> Self {
Self::random::<32>()
maminrayej marked this conversation as resolved.
Show resolved Hide resolved
}

// Creates a random hash for the module
pub fn random() -> Self {
fn random<const N: usize>() -> Self {
let mut rand = rand::thread_rng();
let mut key = [0u8; 8];
let mut key = [0u8; N];
rand.fill_bytes(&mut key);
Self(key)
Self::from_bytes(key)
}

/// Parse a XXHash hash from a hex-encoded string.
pub fn parse_hex(hex_str: &str) -> Result<Self, hex::FromHexError> {
let mut hash = [0_u8; 8];
pub fn xxhash_parse_hex(hex_str: &str) -> Result<Self, hex::FromHexError> {
Self::parse_hex::<8>(hex_str)
}

/// Parse a Sha256 hash from a hex-encoded string.
pub fn sha256_parse_hex(hex_str: &str) -> Result<Self, hex::FromHexError> {
Self::parse_hex::<32>(hex_str)
}

fn parse_hex<const N: usize>(hex_str: &str) -> Result<Self, hex::FromHexError> {
let mut hash = [0_u8; N];
hex::decode_to_slice(hex_str, &mut hash)?;
Ok(Self(hash))
Ok(Self::from_bytes(hash))
}

/// Generate a new [`ModuleCache`] based on the XXHash hash of some bytes.
pub fn hash(wasm: impl AsRef<[u8]>) -> Self {
pub fn xxhash(wasm: impl AsRef<[u8]>) -> Self {
let wasm = wasm.as_ref();

let hash = xxhash_rust::xxh64::xxh64(wasm, 0);

Self(hash.to_ne_bytes())
Self::XXHash(hash.to_ne_bytes())
}

/// Get the raw XXHash hash.
pub fn as_bytes(self) -> [u8; 8] {
self.0
/// Generate a new [`ModuleCache`] based on the Sha256 hash of some bytes.
pub fn sha256(wasm: impl AsRef<[u8]>) -> Self {
let wasm = wasm.as_ref();

let hash: [u8; 32] = sha2::Sha256::digest(wasm).into();

Self::Sha256(hash)
}

/// Get the raw hash.
pub fn as_bytes<const N: usize>(self) -> [u8; N] {
match self {
ModuleHash::XXHash(bytes) => {
if N == 8 {
bytes.as_slice().try_into().unwrap()
} else {
panic!("Requested for {N} bytes, byt XXHash is 8 bytes");
maminrayej marked this conversation as resolved.
Show resolved Hide resolved
}
}
ModuleHash::Sha256(bytes) => {
if N == 32 {
bytes.as_slice().try_into().unwrap()
} else {
panic!("Requested for {N} bytes, but Sha256 is 32 bytes")
}
}
}
maminrayej marked this conversation as resolved.
Show resolved Hide resolved
}
}

impl Display for ModuleHash {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
for byte in self.0 {
write!(f, "{byte:02X}")?;
fn format<const N: usize>(f: &mut Formatter<'_>, bytes: &[u8; N]) -> fmt::Result {
for byte in bytes {
write!(f, "{byte:02X}")?;
}

Ok(())
}

match self {
ModuleHash::XXHash(bytes) => format(f, bytes)?,
ModuleHash::Sha256(bytes) => format(f, bytes)?,
}

Ok(())
Expand Down Expand Up @@ -200,7 +273,7 @@ mod tests {
let wasm = b"\0asm...";
let raw = [0x0c, 0xc7, 0x88, 0x60, 0xd4, 0x14, 0x71, 0x4c];

let hash = ModuleHash::hash(wasm);
let hash = ModuleHash::xxhash(wasm);

assert_eq!(hash.as_bytes(), raw);
}
Expand Down
10 changes: 5 additions & 5 deletions lib/wasix/src/state/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ impl WasiEnvBuilder {

#[allow(clippy::result_large_err)]
pub fn build(self) -> Result<WasiEnv, WasiRuntimeError> {
let module_hash = self.module_hash.unwrap_or_else(ModuleHash::random);
let module_hash = self.module_hash.unwrap_or_else(ModuleHash::xxhash_random);
let init = self.build_init()?;
WasiEnv::from_init(init, module_hash)
}
Expand All @@ -925,7 +925,7 @@ impl WasiEnvBuilder {
self,
store: &mut impl AsStoreMut,
) -> Result<WasiFunctionEnv, WasiRuntimeError> {
let module_hash = self.module_hash.unwrap_or_else(ModuleHash::random);
let module_hash = self.module_hash.unwrap_or_else(ModuleHash::xxhash_random);
let init = self.build_init()?;
let env = WasiEnv::from_init(init, module_hash)?;
let func_env = WasiFunctionEnv::new(store, env);
Expand All @@ -943,7 +943,7 @@ impl WasiEnvBuilder {
module: Module,
store: &mut impl AsStoreMut,
) -> Result<(Instance, WasiFunctionEnv), WasiRuntimeError> {
self.instantiate_ext(module, ModuleHash::random(), store)
self.instantiate_ext(module, ModuleHash::xxhash_random(), store)
}

#[allow(clippy::result_large_err)]
Expand All @@ -959,7 +959,7 @@ impl WasiEnvBuilder {

#[allow(clippy::result_large_err)]
pub fn run(self, module: Module) -> Result<(), WasiRuntimeError> {
self.run_ext(module, ModuleHash::random())
self.run_ext(module, ModuleHash::xxhash_random())
}

#[allow(clippy::result_large_err)]
Expand All @@ -971,7 +971,7 @@ impl WasiEnvBuilder {
#[allow(clippy::result_large_err)]
#[tracing::instrument(level = "debug", skip_all)]
pub fn run_with_store(self, module: Module, store: &mut Store) -> Result<(), WasiRuntimeError> {
self.run_with_store_ext(module, ModuleHash::random(), store)
self.run_with_store_ext(module, ModuleHash::xxhash_random(), store)
}

#[allow(clippy::result_large_err)]
Expand Down
Loading