From 98adcefa56ae40b34af7f76597f582ea28181d9c Mon Sep 17 00:00:00 2001 From: vms Date: Mon, 5 Oct 2020 15:12:38 +0300 Subject: [PATCH] convert RawStepperOutcome to Result based on the ret_code (#32) --- aquamarine-vm/src/aquamarine_stepper_vm.rs | 20 ++-- aquamarine-vm/src/errors.rs | 11 ++ aquamarine-vm/src/lib.rs | 6 +- aquamarine-vm/src/stepper_outcome.rs | 114 +++++++++++++++++++++ fluence-faas/src/raw_toml_config.rs | 4 +- 5 files changed, 137 insertions(+), 18 deletions(-) create mode 100644 aquamarine-vm/src/stepper_outcome.rs diff --git a/aquamarine-vm/src/aquamarine_stepper_vm.rs b/aquamarine-vm/src/aquamarine_stepper_vm.rs index db3482eb..a61d89d2 100644 --- a/aquamarine-vm/src/aquamarine_stepper_vm.rs +++ b/aquamarine-vm/src/aquamarine_stepper_vm.rs @@ -17,11 +17,13 @@ use crate::Result; use crate::AquamarineVMError; use crate::config::AquamarineVMConfig; +use crate::stepper_outcome::StepperOutcome; +use crate::stepper_outcome::RawStepperOutcome; use fluence_faas::FluenceFaaS; use std::collections::HashMap; -use std::path::PathBuf; +use std::convert::TryInto; const AQUAMARINE_WASM_FILE_NAME: &str = "aquamarine"; const CALL_SERVICE_NAME: &str = "call_service"; @@ -29,14 +31,6 @@ const CURRENT_PEER_ID_ENV_NAME: &str = "CURRENT_PEER_ID"; unsafe impl Send for AquamarineVM {} -// delete this once aquamarine become public -#[derive(serde::Serialize, serde::Deserialize, Debug)] -pub struct StepperOutcome { - pub ret_code: i32, - pub data: String, - pub next_peer_pks: Vec, -} - pub struct AquamarineVM { faas: FluenceFaaS, } @@ -69,7 +63,7 @@ impl AquamarineVM { aquamarine_wasm_dir.pop(); let faas_config = FaaSConfig { - modules_dir: Some(PathBuf::from(aquamarine_wasm_dir)), + modules_dir: Some(aquamarine_wasm_dir), modules_config: vec![( String::from(AQUAMARINE_WASM_FILE_NAME), aquamarine_module_config, @@ -90,7 +84,7 @@ impl AquamarineVM { .faas .call_with_json(AQUAMARINE_WASM_FILE_NAME, "invoke", args, <_>::default())?; - let outcome = match result.remove(0) { + let raw_outcome = match result.remove(0) { IValue::Record(record_values) => { let mut record_values = record_values.into_vec(); if record_values.len() != 3 { @@ -122,7 +116,7 @@ impl AquamarineVM { v => Err(AquamarineVMError::AquamarineResultError(format!("expected array for next_peer_pks, got {:?}", v))), }?; - StepperOutcome { + RawStepperOutcome { ret_code, data, next_peer_pks, @@ -131,6 +125,6 @@ impl AquamarineVM { v => return Err(AquamarineVMError::AquamarineResultError(format!("expected record for StepperOutcome, got {:?}", v))), }; - Ok(outcome) + raw_outcome.try_into() } } diff --git a/aquamarine-vm/src/errors.rs b/aquamarine-vm/src/errors.rs index 6d23c79d..92c213e3 100644 --- a/aquamarine-vm/src/errors.rs +++ b/aquamarine-vm/src/errors.rs @@ -14,6 +14,7 @@ * limitations under the License. */ +use crate::stepper_outcome::StepperError; use fluence_faas::FaaSError; use std::error::Error; @@ -25,6 +26,9 @@ pub enum AquamarineVMError { /// Aquamarine result deserialization errors. AquamarineResultError(String), + + /// Errors related to stepper execution. + StepperError(StepperError), } impl Error for AquamarineVMError {} @@ -34,6 +38,7 @@ impl std::fmt::Display for AquamarineVMError { match self { AquamarineVMError::FaaSError(err) => write!(f, "{}", err), AquamarineVMError::AquamarineResultError(err_msg) => write!(f, "{}", err_msg), + AquamarineVMError::StepperError(err) => write!(f, "{}", err), } } } @@ -44,6 +49,12 @@ impl From for AquamarineVMError { } } +impl From for AquamarineVMError { + fn from(err: StepperError) -> Self { + AquamarineVMError::StepperError(err) + } +} + impl From for AquamarineVMError { fn from(_: std::convert::Infallible) -> Self { unreachable!() diff --git a/aquamarine-vm/src/lib.rs b/aquamarine-vm/src/lib.rs index d3a3692d..615e6a20 100644 --- a/aquamarine-vm/src/lib.rs +++ b/aquamarine-vm/src/lib.rs @@ -27,13 +27,13 @@ mod aquamarine_stepper_vm; mod config; mod errors; +mod stepper_outcome; pub use aquamarine_stepper_vm::AquamarineVM; -pub use aquamarine_stepper_vm::StepperOutcome; - pub use config::AquamarineVMConfig; - pub use errors::AquamarineVMError; +pub use stepper_outcome::StepperOutcome; +pub use stepper_outcome::StepperError; // Re-exports pub use fluence_faas::HostImportDescriptor; diff --git a/aquamarine-vm/src/stepper_outcome.rs b/aquamarine-vm/src/stepper_outcome.rs new file mode 100644 index 00000000..0818a36b --- /dev/null +++ b/aquamarine-vm/src/stepper_outcome.rs @@ -0,0 +1,114 @@ +/* + * Copyright 2020 Fluence Labs Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This file is an adapted copy of the StepperOutcome structure and stepper errors. +// Maybe it is better to depend on aquamarine when it become public. + +use crate::AquamarineVMError; + +use std::convert::TryFrom; +use std::error::Error; + +#[derive(Debug)] +pub(crate) struct RawStepperOutcome { + pub ret_code: i32, + pub data: String, + pub next_peer_pks: Vec, +} + +#[derive(Debug)] +pub struct StepperOutcome { + pub data: String, + pub next_peer_pks: Vec, +} + +#[derive(Debug)] +pub enum StepperError { + /// Errors occurred while parsing aqua script in the form of S expressions. + SExprParseError(String), + + /// Errors occurred while parsing supplied data. + DataParseError(String), + + /// Indicates that environment variable with name CURRENT_PEER_ID isn't set. + CurrentPeerIdNotSet(String), + + /// Semantic errors in instructions. + InstructionError(String), + + /// Semantic errors in instructions. + LocalServiceError(String), + + /// Value with such name isn't presence in data. + VariableNotFound(String), + + /// Value with such path wasn't found in data. + VariableNotInJsonPath(String), + + /// Multiple values found for such json path. + MultipleValuesInJsonPath(String), + + /// Related to such ret_code that doesn't have match with current StepperError. + UnknownError(String), +} + +impl Error for StepperError {} + +impl std::fmt::Display for StepperError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + match self { + StepperError::SExprParseError(err_msg) => write!(f, "{}", err_msg), + StepperError::DataParseError(err_msg) => write!(f, "{}", err_msg), + StepperError::CurrentPeerIdNotSet(err_msg) => write!(f, "{}", err_msg), + StepperError::InstructionError(err_msg) => write!(f, "{}", err_msg), + StepperError::LocalServiceError(err_msg) => write!(f, "{}", err_msg), + StepperError::VariableNotFound(err_msg) => write!(f, "{}", err_msg), + StepperError::VariableNotInJsonPath(err_msg) => write!(f, "{}", err_msg), + StepperError::MultipleValuesInJsonPath(err_msg) => write!(f, "{}", err_msg), + StepperError::UnknownError(err_msg) => write!(f, "{}", err_msg), + } + } +} + +impl TryFrom for StepperOutcome { + type Error = AquamarineVMError; + + fn try_from(raw_outcome: RawStepperOutcome) -> Result { + macro_rules! to_vm_error { + ($error_variant:ident) => { + Err(AquamarineVMError::StepperError( + StepperError::$error_variant(raw_outcome.data), + )) + }; + } + + match raw_outcome.ret_code { + 0 => Ok(StepperOutcome { + data: raw_outcome.data, + next_peer_pks: raw_outcome.next_peer_pks, + }), + 1 => to_vm_error!(SExprParseError), + 2 => to_vm_error!(DataParseError), + 3 => to_vm_error!(CurrentPeerIdNotSet), + 4 => to_vm_error!(InstructionError), + 5 => to_vm_error!(LocalServiceError), + 6 => to_vm_error!(VariableNotFound), + 7 => to_vm_error!(VariableNotInJsonPath), + 8 => to_vm_error!(MultipleValuesInJsonPath), + _ => to_vm_error!(UnknownError), + } + } +} diff --git a/fluence-faas/src/raw_toml_config.rs b/fluence-faas/src/raw_toml_config.rs index 579ab782..d5de09b3 100644 --- a/fluence-faas/src/raw_toml_config.rs +++ b/fluence-faas/src/raw_toml_config.rs @@ -189,7 +189,7 @@ pub fn from_toml_wasi_config(wasi: TomlWASIConfig) -> Result { let to = elem .1 .try_into::() - .map_err(|e| FaaSError::ParseConfigError(e))?; + .map_err(FaaSError::ParseConfigError)?; Ok((elem.0.into_bytes(), to.into_bytes())) }; @@ -197,7 +197,7 @@ pub fn from_toml_wasi_config(wasi: TomlWASIConfig) -> Result { let to = elem .1 .try_into::() - .map_err(|e| FaaSError::ParseConfigError(e))?; + .map_err(FaaSError::ParseConfigError)?; Ok((elem.0, PathBuf::from(to))) };