Frank => FCE

This commit is contained in:
vms 2020-05-08 20:38:29 +03:00
parent fa4b06c52f
commit dd001db7ad
15 changed files with 122 additions and 130 deletions

1
Cargo.lock generated
View File

@ -1657,6 +1657,7 @@ name = "wasmer-runtime-core"
version = "0.16.2" version = "0.16.2"
source = "git+http://github.com/fluencelabs/wasmer?branch=fluence#c3e9e367828d5c3a8d2e96e9ea6a09224e872a59" source = "git+http://github.com/fluencelabs/wasmer?branch=fluence#c3e9e367828d5c3a8d2e96e9ea6a09224e872a59"
dependencies = [ dependencies = [
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"blake3 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "blake3 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -37,9 +37,9 @@ bytes = "0.5.4"
tokio = { version = "0.2.20", features = ["blocking", "macros"] } tokio = { version = "0.2.20", features = ["blocking", "macros"] }
[profile.release] [profile.release]
opt-level = 3 #opt-level = 3
debug = false #debug = false
lto = true #lto = true
debug-assertions = false #debug-assertions = false
overflow-checks = false #overflow-checks = false
panic = "abort" #panic = "abort"

View File

@ -27,5 +27,5 @@ mod misc;
mod vm; mod vm;
pub use vm::config::Config; pub use vm::config::Config;
pub use vm::frank::Frank; pub use vm::fce::FCE;
pub use vm::service::FrankService; pub use vm::service::FCEService;

View File

@ -25,13 +25,13 @@
#![warn(rust_2018_idioms)] #![warn(rust_2018_idioms)]
mod misc; mod misc;
/// Command-line tool intended to test Frank VM. /// Command-line tool intended to test FCE VM.
mod vm; mod vm;
use crate::misc::SlicePrettyPrinter; use crate::misc::SlicePrettyPrinter;
use crate::vm::config::Config; use crate::vm::config::Config;
use crate::vm::frank::Frank; use crate::vm::fce::FCE;
use crate::vm::service::FrankService; use crate::vm::service::FCEService;
use exitfailure::ExitFailure; use exitfailure::ExitFailure;
use std::fs; use std::fs;
@ -39,7 +39,7 @@ use std::fs;
fn main() -> Result<(), ExitFailure> { fn main() -> Result<(), ExitFailure> {
println!("Welcome to the FCE CLI:"); println!("Welcome to the FCE CLI:");
let mut rl = rustyline::Editor::<()>::new(); let mut rl = rustyline::Editor::<()>::new();
let mut frank = Frank::new(); let mut fce = FCE::new();
loop { loop {
let readline = rl.readline(">> "); let readline = rl.readline(">> ");
@ -57,20 +57,17 @@ fn main() -> Result<(), ExitFailure> {
} }
let config = Config::default(); let config = Config::default();
let result_msg = match frank.register_module( let result_msg =
module_name, match fce.register_module(module_name, &wasm_bytes.unwrap(), config) {
&wasm_bytes.unwrap(), Ok(_) => "module successfully registered in FCE".to_string(),
config,
) {
Ok(_) => "module successfully registered in Frank".to_string(),
Err(e) => format!("module registration failed with: {:?}", e), Err(e) => format!("module registration failed with: {:?}", e),
}; };
println!("{}", result_msg); println!("{}", result_msg);
} }
"del" => { "del" => {
let module_name = cmd[1]; let module_name = cmd[1];
let result_msg = match frank.unregister_module(module_name) { let result_msg = match fce.unregister_module(module_name) {
Ok(_) => "module successfully deleted from Frank".to_string(), Ok(_) => "module successfully deleted from FCE".to_string(),
Err(e) => format!("module deletion failed with: {:?}", e), Err(e) => format!("module deletion failed with: {:?}", e),
}; };
println!("{}", result_msg); println!("{}", result_msg);
@ -78,7 +75,7 @@ fn main() -> Result<(), ExitFailure> {
"execute" => { "execute" => {
let module_name = cmd[1]; let module_name = cmd[1];
let arg = cmd[2..].join(" "); let arg = cmd[2..].join(" ");
let result = match frank.invoke(module_name, arg.as_bytes()) { let result = match fce.invoke(module_name, arg.as_bytes()) {
Ok(result) => { Ok(result) => {
let outcome_copy = result.outcome.clone(); let outcome_copy = result.outcome.clone();
match String::from_utf8(result.outcome) { match String::from_utf8(result.outcome) {
@ -91,7 +88,7 @@ fn main() -> Result<(), ExitFailure> {
println!("{}", result); println!("{}", result);
} }
"hash" => { "hash" => {
let hash = frank.compute_state_hash(); let hash = fce.compute_state_hash();
println!( println!(
"vm state hash is {:2x}", "vm state hash is {:2x}",
SlicePrettyPrinter(hash.as_slice()) SlicePrettyPrinter(hash.as_slice())
@ -100,8 +97,8 @@ fn main() -> Result<(), ExitFailure> {
"help" => { "help" => {
println!( println!(
"Enter:\n\ "Enter:\n\
add <module_name> <module_path> - to add a new Wasm module to Frank\n\ add <module_name> <module_path> - to add a new Wasm module to FCE\n\
del <module_name> - to delete Wasm module to Frank\n\ del <module_name> - to delete Wasm module to FCE\n\
execute <module_name> <arg> - to call invoke on module with module_name\n\ execute <module_name> <arg> - to call invoke on module with module_name\n\
hash - to compute hash of internal Wasm state\n\ hash - to compute hash of internal Wasm state\n\
help - to print this message\n\ help - to print this message\n\

View File

@ -21,7 +21,7 @@ use wasmer_runtime::error::{
use std::error::Error; use std::error::Error;
#[derive(Debug)] #[derive(Debug)]
pub enum FrankError { pub enum FCEError {
/// Errors for I/O errors raising while opening a file. /// Errors for I/O errors raising while opening a file.
IOError(String), IOError(String),
@ -47,72 +47,72 @@ pub enum FrankError {
NoSuchModule, NoSuchModule,
} }
impl Error for FrankError {} impl Error for FCEError {}
impl std::fmt::Display for FrankError { impl std::fmt::Display for FCEError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self { match self {
FrankError::IOError(msg) => write!(f, "IOError: {}", msg), FCEError::IOError(msg) => write!(f, "IOError: {}", msg),
FrankError::WasmerResolveError(msg) => write!(f, "WasmerResolveError: {}", msg), FCEError::WasmerResolveError(msg) => write!(f, "WasmerResolveError: {}", msg),
FrankError::WasmerInvokeError(msg) => write!(f, "WasmerInvokeError: {}", msg), FCEError::WasmerInvokeError(msg) => write!(f, "WasmerInvokeError: {}", msg),
FrankError::WasmerCompileError(msg) => write!(f, "WasmerCompileError: {}", msg), FCEError::WasmerCompileError(msg) => write!(f, "WasmerCompileError: {}", msg),
FrankError::WasmerCreationError(msg) => write!(f, "WasmerCreationError: {}", msg), FCEError::WasmerCreationError(msg) => write!(f, "WasmerCreationError: {}", msg),
FrankError::PrepareError(msg) => { FCEError::PrepareError(msg) => {
write!(f, "Prepare error: {}, probably module is mailformed", msg) write!(f, "Prepare error: {}, probably module is mailformed", msg)
} }
FrankError::NonUniqueModuleName => write!(f, "Frank already has module with such name"), FCEError::NonUniqueModuleName => write!(f, "FCE already has module with such name"),
FrankError::NoSuchModule => write!(f, "Frank doesn't have a module with such name"), FCEError::NoSuchModule => write!(f, "FCE doesn't have a module with such name"),
} }
} }
} }
impl From<CreationError> for FrankError { impl From<CreationError> for FCEError {
fn from(err: CreationError) -> Self { fn from(err: CreationError) -> Self {
FrankError::WasmerCreationError(format!("{}", err)) FCEError::WasmerCreationError(format!("{}", err))
} }
} }
impl From<CompileError> for FrankError { impl From<CompileError> for FCEError {
fn from(err: CompileError) -> Self { fn from(err: CompileError) -> Self {
FrankError::WasmerCompileError(format!("{}", err)) FCEError::WasmerCompileError(format!("{}", err))
} }
} }
impl From<parity_wasm::elements::Error> for FrankError { impl From<parity_wasm::elements::Error> for FCEError {
fn from(err: parity_wasm::elements::Error) -> Self { fn from(err: parity_wasm::elements::Error) -> Self {
FrankError::PrepareError(format!("{}", err)) FCEError::PrepareError(format!("{}", err))
} }
} }
impl From<CallError> for FrankError { impl From<CallError> for FCEError {
fn from(err: CallError) -> Self { fn from(err: CallError) -> Self {
match err { match err {
CallError::Resolve(err) => FrankError::WasmerResolveError(format!("{}", err)), CallError::Resolve(err) => FCEError::WasmerResolveError(format!("{}", err)),
CallError::Runtime(err) => FrankError::WasmerInvokeError(format!("{}", err)), CallError::Runtime(err) => FCEError::WasmerInvokeError(format!("{}", err)),
} }
} }
} }
impl From<ResolveError> for FrankError { impl From<ResolveError> for FCEError {
fn from(err: ResolveError) -> Self { fn from(err: ResolveError) -> Self {
FrankError::WasmerResolveError(format!("{}", err)) FCEError::WasmerResolveError(format!("{}", err))
} }
} }
impl From<RuntimeError> for FrankError { impl From<RuntimeError> for FCEError {
fn from(err: RuntimeError) -> Self { fn from(err: RuntimeError) -> Self {
FrankError::WasmerInvokeError(format!("{}", err)) FCEError::WasmerInvokeError(format!("{}", err))
} }
} }
impl From<WasmerError> for FrankError { impl From<WasmerError> for FCEError {
fn from(err: WasmerError) -> Self { fn from(err: WasmerError) -> Self {
FrankError::WasmerInvokeError(format!("{}", err)) FCEError::WasmerInvokeError(format!("{}", err))
} }
} }
impl From<std::io::Error> for FrankError { impl From<std::io::Error> for FCEError {
fn from(err: std::io::Error) -> Self { fn from(err: std::io::Error) -> Self {
FrankError::IOError(format!("{}", err)) FCEError::IOError(format!("{}", err))
} }
} }

View File

@ -14,9 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
use crate::vm::module::frank_result::FrankResult; use crate::vm::module::fce_result::FCEResult;
use crate::vm::module::{FrankModule, ModuleAPI}; use crate::vm::module::{FCEModule, ModuleAPI};
use crate::vm::{config::Config, errors::FrankError, service::FrankService}; use crate::vm::{config::Config, errors::FCEError, service::FCEService};
use sha2::{digest::generic_array::GenericArray, digest::FixedOutput}; use sha2::{digest::generic_array::GenericArray, digest::FixedOutput};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
@ -24,15 +24,15 @@ use std::collections::HashMap;
use wasmer_runtime::func; use wasmer_runtime::func;
use wasmer_runtime_core::import::{ImportObject, Namespace}; use wasmer_runtime_core::import::{ImportObject, Namespace};
pub struct Frank { pub struct FCE {
// set of modules registered inside Frank // set of modules registered inside FCE
modules: HashMap<String, FrankModule>, modules: HashMap<String, FCEModule>,
// contains ABI of each registered module in specific format for Wasmer // contains ABI of each registered module in specific format for Wasmer
abi_import_object: ImportObject, abi_import_object: ImportObject,
} }
impl Frank { impl FCE {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
modules: HashMap::new(), modules: HashMap::new(),
@ -41,7 +41,7 @@ impl Frank {
} }
/// Extracts ABI of a module into Namespace. /// Extracts ABI of a module into Namespace.
fn create_import_object(module: &FrankModule, config: &Config) -> Namespace { fn create_import_object(module: &FCEModule, config: &Config) -> Namespace {
let mut namespace = Namespace::new(); let mut namespace = Namespace::new();
let module_abi = module.get_abi(); let module_abi = module.get_abi();
@ -86,17 +86,17 @@ impl Frank {
} }
} }
impl Default for Frank { impl Default for FCE {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl FrankService for Frank { impl FCEService for FCE {
fn invoke(&mut self, module_name: &str, argument: &[u8]) -> Result<FrankResult, FrankError> { fn invoke(&mut self, module_name: &str, argument: &[u8]) -> Result<FCEResult, FCEError> {
match self.modules.get_mut(module_name) { match self.modules.get_mut(module_name) {
Some(module) => module.invoke(argument), Some(module) => module.invoke(argument),
None => Err(FrankError::NoSuchModule), None => Err(FCEError::NoSuchModule),
} }
} }
@ -105,21 +105,21 @@ impl FrankService for Frank {
module_name: S, module_name: S,
wasm_bytes: &[u8], wasm_bytes: &[u8],
config: Config, config: Config,
) -> Result<(), FrankError> ) -> Result<(), FCEError>
where where
S: Into<String>, S: Into<String>,
{ {
let prepared_wasm_bytes = let prepared_wasm_bytes =
crate::vm::prepare::prepare_module(wasm_bytes, config.mem_pages_count)?; crate::vm::prepare::prepare_module(wasm_bytes, config.mem_pages_count)?;
let module = FrankModule::new( let module = FCEModule::new(
&prepared_wasm_bytes, &prepared_wasm_bytes,
config.clone(), config.clone(),
self.abi_import_object.clone(), self.abi_import_object.clone(),
)?; )?;
// registers ABI of newly registered module in abi_import_object // registers ABI of newly registered module in abi_import_object
let namespace = Frank::create_import_object(&module, &config); let namespace = FCE::create_import_object(&module, &config);
let module_name: String = module_name.into(); let module_name: String = module_name.into();
self.abi_import_object self.abi_import_object
.register(module_name.clone(), namespace); .register(module_name.clone(), namespace);
@ -129,14 +129,14 @@ impl FrankService for Frank {
entry.insert(module); entry.insert(module);
Ok(()) Ok(())
} }
Entry::Occupied(_) => Err(FrankError::NonUniqueModuleName), Entry::Occupied(_) => Err(FCEError::NonUniqueModuleName),
} }
} }
fn unregister_module(&mut self, module_name: &str) -> Result<(), FrankError> { fn unregister_module(&mut self, module_name: &str) -> Result<(), FCEError> {
self.modules self.modules
.remove(module_name) .remove(module_name)
.ok_or_else(|| FrankError::NoSuchModule)?; .ok_or_else(|| FCEError::NoSuchModule)?;
// unregister abi from a dispatcher // unregister abi from a dispatcher
Ok(()) Ok(())

View File

@ -16,7 +16,7 @@
pub mod config; pub mod config;
pub mod errors; pub mod errors;
pub mod frank; pub mod fce;
pub mod service; pub mod service;
mod module; mod module;

View File

@ -16,7 +16,7 @@
use wasmer_runtime::Func; use wasmer_runtime::Func;
/// Application binary interface of a Frank module. Different module could use such scheme for /// Application binary interface of a FCE module. Different module could use such scheme for
/// communicate with each other. /// communicate with each other.
/// ///
/// Given char string req as a request, the general scheme to use this ABI by other module /// Given char string req as a request, the general scheme to use this ABI by other module
@ -32,7 +32,7 @@ use wasmer_runtime::Func;
pub(crate) struct ModuleABI<'a> { pub(crate) struct ModuleABI<'a> {
// It is safe to use unwrap() while calling these functions because Option is used here // It is safe to use unwrap() while calling these functions because Option is used here
// just to allow partially initialization. And all Option fields will contain Some if // just to allow partially initialization. And all Option fields will contain Some if
// invoking Frank::new has been succeed. // invoking FCE::new has been succeed.
/// Allocates a region of memory inside a module. Used for passing argument inside the module. /// Allocates a region of memory inside a module. Used for passing argument inside the module.
pub(crate) allocate: Option<Func<'a, i32, i32>>, pub(crate) allocate: Option<Func<'a, i32, i32>>,

View File

@ -14,16 +14,16 @@
* limitations under the License. * limitations under the License.
*/ */
use crate::vm::errors::FrankError; use crate::vm::errors::FCEError;
use crate::vm::module::frank_result::FrankResult; use crate::vm::module::fce_result::FCEResult;
use sha2::digest::generic_array::GenericArray; use sha2::digest::generic_array::GenericArray;
use sha2::digest::FixedOutput; use sha2::digest::FixedOutput;
/// Application interface of a Frank module. Intended to use by Frank instance itself. /// Application interface of a FCE module. Intended to use by FCE instance itself.
pub(crate) trait ModuleAPI { pub(crate) trait ModuleAPI {
/// Invokes a module supplying byte array and expecting byte array with some outcome back. /// Invokes a module supplying byte array and expecting byte array with some outcome back.
fn invoke(&mut self, argument: &[u8]) -> Result<FrankResult, FrankError>; fn invoke(&mut self, argument: &[u8]) -> Result<FCEResult, FCEError>;
/// Computes hash of the internal modules state. /// Computes hash of the internal modules state.
fn compute_state_hash(&mut self) fn compute_state_hash(&mut self)

View File

@ -15,8 +15,8 @@
*/ */
use crate::vm::config::Config; use crate::vm::config::Config;
use crate::vm::errors::FrankError; use crate::vm::errors::FCEError;
use crate::vm::module::frank_result::FrankResult; use crate::vm::module::fce_result::FCEResult;
use crate::vm::module::{ModuleABI, ModuleAPI}; use crate::vm::module::{ModuleABI, ModuleAPI};
use sha2::digest::generic_array::GenericArray; use sha2::digest::generic_array::GenericArray;
@ -26,21 +26,17 @@ use wasmer_runtime_core::import::ImportObject;
use wasmer_runtime_core::memory::ptr::{Array, WasmPtr}; use wasmer_runtime_core::memory::ptr::{Array, WasmPtr};
use wasmer_wasi::generate_import_object_for_version; use wasmer_wasi::generate_import_object_for_version;
pub(crate) struct FrankModule { pub(crate) struct FCEModule {
instance: &'static Instance, instance: &'static Instance,
abi: ModuleABI<'static>, abi: ModuleABI<'static>,
} }
impl FrankModule { impl FCEModule {
/// Creates a new virtual machine executor. /// Creates a new virtual machine executor.
pub fn new( pub fn new(wasm_bytes: &[u8], config: Config, imports: ImportObject) -> Result<Self, FCEError> {
wasm_bytes: &[u8],
config: Config,
imports: ImportObject,
) -> Result<Self, FrankError> {
let logger_imports = imports! { let logger_imports = imports! {
"logger" => { "logger" => {
"log_utf8_string" => func!(FrankModule::logger_log_utf8_string), "log_utf8_string" => func!(FCEModule::logger_log_utf8_string),
}, },
}; };
@ -77,12 +73,12 @@ impl FrankModule {
let wasm_ptr = WasmPtr::<u8, Array>::new(offset as _); let wasm_ptr = WasmPtr::<u8, Array>::new(offset as _);
match wasm_ptr.get_utf8_string(ctx.memory(0), size as _) { match wasm_ptr.get_utf8_string(ctx.memory(0), size as _) {
Some(msg) => print!("{}", msg), Some(msg) => print!("{}", msg),
None => print!("frank logger: incorrect UTF8 string's been supplied to logger"), None => print!("fce logger: incorrect UTF8 string's been supplied to logger"),
} }
} }
/// Writes given value on the given address to module memory. /// Writes given value on the given address to module memory.
fn write_to_mem(&mut self, address: usize, value: &[u8]) -> Result<(), FrankError> { fn write_to_mem(&mut self, address: usize, value: &[u8]) -> Result<(), FCEError> {
let memory = self.instance.context().memory(0); let memory = self.instance.context().memory(0);
for (byte_id, cell) in memory.view::<u8>()[address..(address + value.len())] for (byte_id, cell) in memory.view::<u8>()[address..(address + value.len())]
@ -96,7 +92,7 @@ impl FrankModule {
} }
/// Reads invocation result from specified address of memory. /// Reads invocation result from specified address of memory.
fn read_result_from_mem(&self, address: usize) -> Result<Vec<u8>, FrankError> { fn read_result_from_mem(&self, address: usize) -> Result<Vec<u8>, FCEError> {
let memory = self.instance.context().memory(0); let memory = self.instance.context().memory(0);
let mut result_size: usize = 0; let mut result_size: usize = 0;
@ -114,8 +110,8 @@ impl FrankModule {
} }
} }
impl ModuleAPI for FrankModule { impl ModuleAPI for FCEModule {
fn invoke(&mut self, argument: &[u8]) -> Result<FrankResult, FrankError> { fn invoke(&mut self, argument: &[u8]) -> Result<FCEResult, FCEError> {
// allocate memory for the given argument and write it to memory // allocate memory for the given argument and write it to memory
let argument_len = argument.len() as i32; let argument_len = argument.len() as i32;
let argument_address = if argument_len != 0 { let argument_address = if argument_len != 0 {
@ -141,7 +137,7 @@ impl ModuleAPI for FrankModule {
.unwrap() .unwrap()
.call(result_address, result.len() as i32)?; .call(result_address, result.len() as i32)?;
Ok(FrankResult::new(result)) Ok(FCEResult::new(result))
} }
fn compute_state_hash( fn compute_state_hash(
@ -155,7 +151,7 @@ impl ModuleAPI for FrankModule {
let wasm_ptr = WasmPtr::<u8, Array>::new(0 as _); let wasm_ptr = WasmPtr::<u8, Array>::new(0 as _);
let raw_mem = wasm_ptr let raw_mem = wasm_ptr
.deref(memory, 0, (memory.size().bytes().0 - 1) as _) .deref(memory, 0, (memory.size().bytes().0 - 1) as _)
.expect("frank: internal error in compute_vm_state_hash"); .expect("fce: internal error in compute_vm_state_hash");
let raw_mem: &[u8] = unsafe { &*(raw_mem as *const [std::cell::Cell<u8>] as *const [u8]) }; let raw_mem: &[u8] = unsafe { &*(raw_mem as *const [std::cell::Cell<u8>] as *const [u8]) };
hasher.input(raw_mem); hasher.input(raw_mem);
@ -163,6 +159,6 @@ impl ModuleAPI for FrankModule {
} }
} }
impl Drop for FrankModule { impl Drop for FCEModule {
fn drop(&mut self) {} fn drop(&mut self) {}
} }

View File

@ -15,11 +15,11 @@
*/ */
#[derive(Clone, Debug, PartialEq, Default)] #[derive(Clone, Debug, PartialEq, Default)]
pub struct FrankResult { pub struct FCEResult {
pub outcome: Vec<u8>, pub outcome: Vec<u8>,
} }
impl FrankResult { impl FCEResult {
pub fn new(outcome: Vec<u8>) -> Self { pub fn new(outcome: Vec<u8>) -> Self {
Self { outcome } Self { outcome }
} }

View File

@ -16,9 +16,9 @@
mod abi; mod abi;
mod api; mod api;
mod frank_module; mod fce_module;
pub mod frank_result; pub mod fce_result;
pub(crate) use abi::ModuleABI; pub(crate) use abi::ModuleABI;
pub(crate) use api::ModuleAPI; pub(crate) use api::ModuleAPI;
pub(crate) use frank_module::FrankModule; pub(crate) use fce_module::FCEModule;

View File

@ -18,7 +18,7 @@
// https://github.com/paritytech/substrate/blob/master/srml/contracts/src/wasm/prepare.rs // https://github.com/paritytech/substrate/blob/master/srml/contracts/src/wasm/prepare.rs
// https://github.com/nearprotocol/nearcore/blob/master/runtime/near-vm-runner/src/prepare.rs // https://github.com/nearprotocol/nearcore/blob/master/runtime/near-vm-runner/src/prepare.rs
use crate::vm::errors::FrankError; use crate::vm::errors::FCEError;
use parity_wasm::{ use parity_wasm::{
builder, elements, builder, elements,
@ -30,7 +30,7 @@ struct ModuleBootstrapper {
} }
impl<'a> ModuleBootstrapper { impl<'a> ModuleBootstrapper {
fn init(module_code: &[u8]) -> Result<Self, FrankError> { fn init(module_code: &[u8]) -> Result<Self, FCEError> {
let module = elements::deserialize_buffer(module_code)?; let module = elements::deserialize_buffer(module_code)?;
Ok(Self { module }) Ok(Self { module })
@ -66,14 +66,14 @@ impl<'a> ModuleBootstrapper {
} }
} }
fn into_wasm(self) -> Result<Vec<u8>, FrankError> { fn into_wasm(self) -> Result<Vec<u8>, FCEError> {
elements::serialize(self.module).map_err(Into::into) elements::serialize(self.module).map_err(Into::into)
} }
} }
/// Prepares a Wasm module: /// Prepares a Wasm module:
/// - set memory page count /// - set memory page count
pub fn prepare_module(module: &[u8], mem_pages_count: u32) -> Result<Vec<u8>, FrankError> { pub fn prepare_module(module: &[u8], mem_pages_count: u32) -> Result<Vec<u8>, FCEError> {
ModuleBootstrapper::init(module)? ModuleBootstrapper::init(module)?
.set_mem_pages_count(mem_pages_count) .set_mem_pages_count(mem_pages_count)
.into_wasm() .into_wasm()

View File

@ -15,28 +15,28 @@
*/ */
use crate::vm::config::Config; use crate::vm::config::Config;
use crate::vm::errors::FrankError; use crate::vm::errors::FCEError;
use crate::vm::module::frank_result::FrankResult; use crate::vm::module::fce_result::FCEResult;
use sha2::digest::generic_array::GenericArray; use sha2::digest::generic_array::GenericArray;
/// Describes a service behaviour in the Fluence network. /// Describes a service behaviour in the Fluence network.
pub trait FrankService { pub trait FCEService {
/// Invokes a module supplying byte array and expecting byte array with some outcome back. /// Invokes a module supplying byte array and expecting byte array with some outcome back.
fn invoke(&mut self, module_name: &str, argument: &[u8]) -> Result<FrankResult, FrankError>; fn invoke(&mut self, module_name: &str, argument: &[u8]) -> Result<FCEResult, FCEError>;
/// Registers new module in the Frank Service. /// Registers new module in the FCE Service.
fn register_module<S>( fn register_module<S>(
&mut self, &mut self,
module_name: S, module_name: S,
wasm_bytes: &[u8], wasm_bytes: &[u8],
config: Config, config: Config,
) -> Result<(), FrankError> ) -> Result<(), FCEError>
where where
S: Into<String>; S: Into<String>;
/// Unregisters previously registered module. /// Unregisters previously registered module.
fn unregister_module(&mut self, module_name: &str) -> Result<(), FrankError>; fn unregister_module(&mut self, module_name: &str) -> Result<(), FCEError>;
/// Computes hash of the internal modules state. /// Computes hash of the internal modules state.
fn compute_state_hash( fn compute_state_hash(

View File

@ -16,7 +16,7 @@
mod downloader; mod downloader;
use fce::{Config, Frank, FrankService}; use fce::{Config, FCEService, FCE};
const REDIS_DOWNLOAD_URL: &str = const REDIS_DOWNLOAD_URL: &str =
"https://github.com/fluencelabs/redis/releases/download/0.8.0_w/redis.wasm"; "https://github.com/fluencelabs/redis/releases/download/0.8.0_w/redis.wasm";
@ -27,27 +27,26 @@ const SQLITE_DOWNLOAD_URL: &str =
async fn redis() { async fn redis() {
let wasm_bytes = downloader::download(REDIS_DOWNLOAD_URL).await; let wasm_bytes = downloader::download(REDIS_DOWNLOAD_URL).await;
let mut frank = Frank::new(); let mut fce = FCE::new();
let module_name = "redis"; let module_name = "redis";
let config = Config::default(); let config = Config::default();
frank fce.register_module(module_name, wasm_bytes.as_ref(), config)
.register_module(module_name, wasm_bytes.as_ref(), config) .unwrap_or_else(|e| panic!("can't create FCE: {:?}", e));
.unwrap_or_else(|e| panic!("can't create Frank: {:?}", e));
let result1 = frank let result1 = fce
.invoke(module_name, "SET A 10".as_bytes()) .invoke(module_name, "SET A 10".as_bytes())
.unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e)); .unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e));
let result2 = frank let result2 = fce
.invoke(module_name, "SADD B 20".as_bytes()) .invoke(module_name, "SADD B 20".as_bytes())
.unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e)); .unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e));
let result3 = frank let result3 = fce
.invoke(module_name, "GET A".as_bytes()) .invoke(module_name, "GET A".as_bytes())
.unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e)); .unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e));
let result4 = frank let result4 = fce
.invoke(module_name, "SMEMBERS B".as_bytes()) .invoke(module_name, "SMEMBERS B".as_bytes())
.unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e)); .unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e));
let result5 = frank let result5 = fce
.invoke( .invoke(
module_name, module_name,
"eval \"redis.call('incr', 'A') return redis.call('get', 'A') * 8 + 5\" 0".as_bytes(), "eval \"redis.call('incr', 'A') return redis.call('get', 'A') * 8 + 5\" 0".as_bytes(),
@ -71,27 +70,26 @@ async fn redis() {
async fn sqlite() { async fn sqlite() {
let wasm_bytes = downloader::download(SQLITE_DOWNLOAD_URL).await; let wasm_bytes = downloader::download(SQLITE_DOWNLOAD_URL).await;
let mut frank = Frank::new(); let mut fce = FCE::new();
let module_name = "sqlite"; let module_name = "sqlite";
let config = Config::default(); let config = Config::default();
frank fce.register_module(module_name, wasm_bytes.as_ref(), config)
.register_module(module_name, wasm_bytes.as_ref(), config) .unwrap_or_else(|e| panic!("can't create FCE: {:?}", e));
.unwrap_or_else(|e| panic!("can't create Frank: {:?}", e));
let result1 = frank let result1 = fce
.invoke( .invoke(
module_name, module_name,
"CREATE VIRTUAL TABLE users USING FTS5(body)".as_bytes(), "CREATE VIRTUAL TABLE users USING FTS5(body)".as_bytes(),
) )
.unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e)); .unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e));
let result2 = frank let result2 = fce
.invoke( .invoke(
module_name, module_name,
"INSERT INTO users(body) VALUES('AB'), ('BC'), ('CD'), ('DE')".as_bytes(), "INSERT INTO users(body) VALUES('AB'), ('BC'), ('CD'), ('DE')".as_bytes(),
) )
.unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e)); .unwrap_or_else(|e| panic!("error while FCE invocation: {:?}", e));
let result3 = frank let result3 = fce
.invoke( .invoke(
module_name, module_name,
"SELECT * FROM users WHERE users MATCH 'A* OR B*'".as_bytes(), "SELECT * FROM users WHERE users MATCH 'A* OR B*'".as_bytes(),