diff --git a/multi-service/math/scripts/math.clj b/multi-service/math/scripts/math.clj new file mode 100644 index 0000000..1a6d3d9 --- /dev/null +++ b/multi-service/math/scripts/math.clj @@ -0,0 +1,15 @@ +;; handle possible errors via xor +(xor + (seq + (seq + ;; add + (call relay (service_id "add_u256") [number_1 number_2] result_1) + ;; square result + (call relay (service_id "mul_u256") [result_1.$.["u256"] result_1.$.["u256"]] result) + ) + ;; return result back to the client + (call %init_peer_id% (returnService "run") [result_1]) + ) + ;; if error, return it to the client (`returnService` is service on client with `run` action) + (call %init_peer_id% (returnService "run") [%last_error%]) +) diff --git a/multi-service/math/src/main.rs b/multi-service/math/src/main.rs index 63c8a2f..42aea6d 100644 --- a/multi-service/math/src/main.rs +++ b/multi-service/math/src/main.rs @@ -24,70 +24,104 @@ module_manifest!(); pub fn main() {} +/// Result like +#[marine] +pub struct MathResult { + /// u256 string representation + pub u256: String, + pub ret_code: u8, + /// error string representation + pub err_msg: String, +} + +mod math_result { + use ethnum::u256; + + use crate::MathResult; + + pub fn ok(ok: u256) -> MathResult { + MathResult { + u256: ok.to_string(), + ret_code: 0, + err_msg: Default::default(), + } + } + + pub fn err(err: &str) -> MathResult { + MathResult { + u256: Default::default(), + ret_code: 1, + err_msg: err.to_string(), + } + } +} + +use math_result::{err, ok}; + /// adds 2 256 bits integers (ETH compatible) /// return number or error (failed to parse input or overflow of output) #[marine] -pub fn add_u256(number_1: String, number_2: String) -> String { +pub fn add_u256(number_1: String, number_2: String) -> MathResult { let number_1 = number_1.parse::(); let number_2 = number_2.parse::(); if let (Ok(number_1), Ok(number_2)) = (number_1, number_2) { let number = number_1.checked_add(number_2); if let Some(number) = number { - return number.to_string(); + return ok(number); } - return "Overflow".to_string(); + return err("Overflow"); } - "InputNonAU256Number".to_string() + err("InputNonAU256Number") } #[marine] -pub fn sub_u256(number_1: String, number_2: String) -> String { +pub fn sub_u256(number_1: String, number_2: String) -> MathResult { let number_1 = number_1.parse::(); let number_2 = number_2.parse::(); if let (Ok(number_1), Ok(number_2)) = (number_1, number_2) { let number = number_1.checked_sub(number_2); if let Some(number) = number { - return number.to_string(); + return ok(number); } - return "Underflow".to_string(); + return err("Underflow"); } - "InputNonAU256Number".to_string() + err("InputNonAU256Number") } #[marine] -pub fn mul_u256(number_1: String, number_2: String) -> String { +pub fn mul_u256(number_1: String, number_2: String) -> MathResult { let number_1 = number_1.parse::(); let number_2 = number_2.parse::(); if let (Ok(number_1), Ok(number_2)) = (number_1, number_2) { let number = number_1.checked_mul(number_2); if let Some(number) = number { - return number.to_string(); + return ok(number); } - return "Overflow".to_string(); + return err("Overflow"); } - "InputNonAU256Number".to_string() + err("InputNonAU256Number") } #[marine] -pub fn div_u256(number_1: String, number_2: String) -> String { +pub fn div_u256(number_1: String, number_2: String) -> MathResult { let number_1 = number_1.parse::(); let number_2 = number_2.parse::(); if let (Ok(number_1), Ok(number_2)) = (number_1, number_2) { let number = number_1.checked_div(number_2); if let Some(number) = number { - return number.to_string(); + return ok(number); } - return "DivisionByZero".to_string(); + return err("DivisionByZero"); } - "InputNonAU256Number".to_string() + err("InputNonAU256Number") } #[cfg(test)]