Skip to content

Commit

Permalink
Merge pull request #288 from dusk-network/diff-archs-287
Browse files Browse the repository at this point in the history
Fix loading state from other archs
  • Loading branch information
Eduardo Leegwater Simões authored Oct 31, 2023
2 parents 189d265 + 0b8d6d0 commit 9020fbe
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
6 changes: 6 additions & 0 deletions piecrust/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `SerializeError`
* `Trap`

## Fixed

- Fix loading of compiled contracts from state transported from different
platforms [#287]

## [0.11.0] - 2023-10-11

### Added
Expand Down Expand Up @@ -287,6 +292,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#234]: https://github.com/dusk-network/piecrust/pull/234

<!-- ISSUES -->
[#287]: https://github.com/dusk-network/piecrust/issues/287
[#281]: https://github.com/dusk-network/piecrust/issues/281
[#271]: https://github.com/dusk-network/piecrust/issues/271
[#268]: https://github.com/dusk-network/piecrust/issues/268
Expand Down
48 changes: 42 additions & 6 deletions piecrust/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::sync::mpsc;
use std::{fs, io, thread};

pub use bytecode::Bytecode;
use dusk_wasmtime::{Engine, Module};
pub use memory::{Memory, MAX_MEM_SIZE, PAGE_SIZE};
pub use metadata::Metadata;
pub use objectcode::Objectcode;
Expand Down Expand Up @@ -52,13 +53,13 @@ impl ContractStore {
/// [`commit`]: ContractSession::commit
/// [`delete`]: ContractStore::delete_commit
/// [`session spawning`]: ContractStore::session
pub fn new<P: AsRef<Path>>(dir: P) -> io::Result<Self> {
pub fn new<P: AsRef<Path>>(engine: &Engine, dir: P) -> io::Result<Self> {
let root_dir = dir.as_ref();

fs::create_dir_all(root_dir)?;

let (call, calls) = mpsc::channel();
let commits = read_all_commits(root_dir)?;
let commits = read_all_commits(engine, root_dir)?;

let loop_root_dir = root_dir.to_path_buf();

Expand Down Expand Up @@ -148,6 +149,7 @@ impl ContractStore {
}

fn read_all_commits<P: AsRef<Path>>(
engine: &Engine,
root_dir: P,
) -> io::Result<BTreeMap<Hash, Commit>> {
let root_dir = root_dir.as_ref();
Expand All @@ -156,7 +158,7 @@ fn read_all_commits<P: AsRef<Path>>(
for entry in fs::read_dir(root_dir)? {
let entry = entry?;
if entry.path().is_dir() {
let commit = read_commit(entry.path())?;
let commit = read_commit(engine, entry.path())?;
let root = *commit.index.root();
commits.insert(root, commit);
}
Expand All @@ -165,17 +167,23 @@ fn read_all_commits<P: AsRef<Path>>(
Ok(commits)
}

fn read_commit<P: AsRef<Path>>(commit_dir: P) -> io::Result<Commit> {
fn read_commit<P: AsRef<Path>>(
engine: &Engine,
commit_dir: P,
) -> io::Result<Commit> {
let commit_dir = commit_dir.as_ref();
let commit = commit_from_dir(commit_dir)?;
let commit = commit_from_dir(engine, commit_dir)?;
Ok(commit)
}

fn page_path<P: AsRef<Path>>(memory_dir: P, page_index: usize) -> PathBuf {
memory_dir.as_ref().join(format!("{page_index}"))
}

fn commit_from_dir<P: AsRef<Path>>(dir: P) -> io::Result<Commit> {
fn commit_from_dir<P: AsRef<Path>>(
engine: &Engine,
dir: P,
) -> io::Result<Commit> {
let dir = dir.as_ref();

let index_path = dir.join(INDEX_FILE);
Expand All @@ -197,6 +205,34 @@ fn commit_from_dir<P: AsRef<Path>>(dir: P) -> io::Result<Commit> {
));
}

let objectcode_path =
bytecode_path.with_extension(OBJECTCODE_EXTENSION);

if !objectcode_path.is_file() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Non-existing objectcode for contract: {contract_hex}"),
));
}

// SAFETY it is safe to deserialize the file here, since we don't use
// the module here. We just want to check if the file is valid.
if unsafe {
Module::deserialize_file(engine, &objectcode_path).is_err()
} {
let bytecode = Bytecode::from_file(bytecode_path)?;
let module =
Module::new(engine, bytecode.as_ref()).map_err(|err| {
io::Error::new(io::ErrorKind::InvalidData, err)
})?;
fs::write(
objectcode_path,
module.serialize().map_err(|err| {
io::Error::new(io::ErrorKind::InvalidData, err)
})?,
)?;
}

let memory_dir = memory_dir.join(&contract_hex);

for page_index in &contract_index.page_indices {
Expand Down
24 changes: 19 additions & 5 deletions piecrust/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use std::sync::Arc;
use std::thread;

use dusk_wasmtime::{
Config, ModuleVersionStrategy, OptLevel, Strategy, WasmBacktraceDetails,
Config, Engine, ModuleVersionStrategy, OptLevel, Strategy,
WasmBacktraceDetails,
};
use tempfile::tempdir;

Expand Down Expand Up @@ -94,10 +95,17 @@ impl VM {
/// # Errors
/// If the directory contains unparseable or inconsistent data.
pub fn new<P: AsRef<Path>>(root_dir: P) -> Result<Self, Error> {
let store = ContractStore::new(root_dir)
let config = config();

let engine = Engine::new(&config).expect(
"Configuration should be valid since its set at compile time",
);

let store = ContractStore::new(&engine, root_dir)
.map_err(|err| PersistenceError(Arc::new(err)))?;

Ok(Self {
config: config(),
config,
host_queries: HostQueries::default(),
store,
})
Expand All @@ -114,11 +122,17 @@ impl VM {
let tmp = tempdir().map_err(|err| PersistenceError(Arc::new(err)))?;
let tmp = tmp.path().to_path_buf();

let store = ContractStore::new(tmp)
let config = config();

let engine = Engine::new(&config).expect(
"Configuration should be valid since its set at compile time",
);

let store = ContractStore::new(&engine, tmp)
.map_err(|err| PersistenceError(Arc::new(err)))?;

Ok(Self {
config: config(),
config,
host_queries: HostQueries::default(),
store,
})
Expand Down

0 comments on commit 9020fbe

Please sign in to comment.