mirror of
https://github.com/fluencelabs/aquavm
synced 2024-12-04 23:20:18 +00:00
Fix Par state serialization in xor with inner par (#19)
This commit is contained in:
parent
19ff54e66e
commit
bcb0f18e9e
59
Cargo.lock
generated
59
Cargo.lock
generated
@ -67,7 +67,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "aquamarine-vm"
|
name = "aquamarine-vm"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "git+https://github.com/fluencelabs/fce#c8114d48c6de55fea75f04c6998df7c685e8ce7b"
|
source = "git+https://github.com/fluencelabs/fce#ddd3448af7b63017f68205c62ec7591888499a70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-faas",
|
"fluence-faas",
|
||||||
"maplit",
|
"maplit",
|
||||||
@ -638,10 +638,11 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fce"
|
name = "fce"
|
||||||
version = "0.1.9"
|
version = "0.1.10"
|
||||||
source = "git+https://github.com/fluencelabs/fce#c8114d48c6de55fea75f04c6998df7c685e8ce7b"
|
source = "git+https://github.com/fluencelabs/fce#ddd3448af7b63017f68205c62ec7591888499a70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"boolinator",
|
"boolinator",
|
||||||
|
"fce-utils",
|
||||||
"fce-wit-interfaces",
|
"fce-wit-interfaces",
|
||||||
"fce-wit-parser",
|
"fce-wit-parser",
|
||||||
"log",
|
"log",
|
||||||
@ -657,10 +658,15 @@ dependencies = [
|
|||||||
"wasmer-wasi-fl",
|
"wasmer-wasi-fl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fce-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/fluencelabs/fce#ddd3448af7b63017f68205c62ec7591888499a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fce-wit-interfaces"
|
name = "fce-wit-interfaces"
|
||||||
version = "0.1.6"
|
version = "0.1.7"
|
||||||
source = "git+https://github.com/fluencelabs/fce#c8114d48c6de55fea75f04c6998df7c685e8ce7b"
|
source = "git+https://github.com/fluencelabs/fce#ddd3448af7b63017f68205c62ec7591888499a70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"multimap",
|
"multimap",
|
||||||
"wasmer-interface-types-fl",
|
"wasmer-interface-types-fl",
|
||||||
@ -668,8 +674,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fce-wit-parser"
|
name = "fce-wit-parser"
|
||||||
version = "0.1.8"
|
version = "0.1.9"
|
||||||
source = "git+https://github.com/fluencelabs/fce#c8114d48c6de55fea75f04c6998df7c685e8ce7b"
|
source = "git+https://github.com/fluencelabs/fce#ddd3448af7b63017f68205c62ec7591888499a70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"fce-wit-interfaces",
|
"fce-wit-interfaces",
|
||||||
@ -695,11 +701,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-faas"
|
name = "fluence-faas"
|
||||||
version = "0.1.10"
|
version = "0.1.11"
|
||||||
source = "git+https://github.com/fluencelabs/fce#c8114d48c6de55fea75f04c6998df7c685e8ce7b"
|
source = "git+https://github.com/fluencelabs/fce#ddd3448af7b63017f68205c62ec7591888499a70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cmd_lib",
|
"cmd_lib",
|
||||||
"fce",
|
"fce",
|
||||||
|
"fce-utils",
|
||||||
"fluence-sdk-main 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fluence-sdk-main 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itertools",
|
"itertools",
|
||||||
"log",
|
"log",
|
||||||
@ -714,6 +721,14 @@ dependencies = [
|
|||||||
"wasmer-wasi-fl",
|
"wasmer-wasi-fl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluence-sdk-macro"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
|
||||||
|
dependencies = [
|
||||||
|
"fluence-sdk-wit 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-sdk-macro"
|
name = "fluence-sdk-macro"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
@ -724,11 +739,13 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-sdk-macro"
|
name = "fluence-sdk-main"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
|
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-sdk-wit 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
|
"fluence-sdk-macro 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -742,21 +759,10 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fluence-sdk-main"
|
|
||||||
version = "0.2.8"
|
|
||||||
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
|
|
||||||
dependencies = [
|
|
||||||
"fluence-sdk-macro 0.2.8 (git+https://github.com/fluencelabs/rust-sdk)",
|
|
||||||
"log",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-sdk-wit"
|
name = "fluence-sdk-wit"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
|
||||||
checksum = "560baf91197ded38a99a5c94ff366a3dd971ebf33f5d987ecce31d3dedf86d17"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -769,7 +775,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-sdk-wit"
|
name = "fluence-sdk-wit"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
source = "git+https://github.com/fluencelabs/rust-sdk#a6c587db0b6f22c3d3af81f10b187f148f8e9d30"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "560baf91197ded38a99a5c94ff366a3dd971ebf33f5d987ecce31d3dedf86d17"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1981,9 +1988,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-interface-types-fl"
|
name = "wasmer-interface-types-fl"
|
||||||
version = "0.17.10"
|
version = "0.17.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1de496e366bd1c198942248fc1de4b94e4647b263dd60099d5f7776f0d621656"
|
checksum = "e916b92f2d315ea27d5ff1d3d6410fe852c51d21bb91a8d1ba7adbf701de7f53"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"nom",
|
"nom",
|
||||||
|
@ -108,13 +108,13 @@ impl<'i> ParsedCall<'i> {
|
|||||||
use crate::call_evidence::CallResult::*;
|
use crate::call_evidence::CallResult::*;
|
||||||
use crate::call_evidence::EvidenceState::*;
|
use crate::call_evidence::EvidenceState::*;
|
||||||
|
|
||||||
if call_ctx.current_subtree_elements_count == 0 {
|
if call_ctx.current_subtree_size == 0 {
|
||||||
log::info!(target: EVIDENCE_CHANGING, " previous call evidence state wasn't found");
|
log::info!(target: EVIDENCE_CHANGING, " previous call evidence state wasn't found");
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
call_ctx.current_subtree_elements_count -= 1;
|
call_ctx.current_subtree_size -= 1;
|
||||||
// unwrap is safe here, because current_subtree_elements_count depends on current_path len,
|
// unwrap is safe here, because current_subtree_size depends on current_path len,
|
||||||
// and it's been checked previously
|
// and it's been checked previously
|
||||||
let prev_state = call_ctx.current_path.pop_front().unwrap();
|
let prev_state = call_ctx.current_path.pop_front().unwrap();
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ pub(crate) trait ExecutableInstruction<'i> {
|
|||||||
impl<'i> ExecutableInstruction<'i> for Instruction<'i> {
|
impl<'i> ExecutableInstruction<'i> for Instruction<'i> {
|
||||||
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> {
|
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Instruction::Seq(seq) => seq.execute(exec_ctx, call_ctx),
|
|
||||||
Instruction::Call(call) => call.execute(exec_ctx, call_ctx),
|
Instruction::Call(call) => call.execute(exec_ctx, call_ctx),
|
||||||
Instruction::Null(null) => null.execute(exec_ctx, call_ctx),
|
|
||||||
Instruction::Fold(fold) => fold.execute(exec_ctx, call_ctx),
|
Instruction::Fold(fold) => fold.execute(exec_ctx, call_ctx),
|
||||||
Instruction::Next(next) => next.execute(exec_ctx, call_ctx),
|
Instruction::Next(next) => next.execute(exec_ctx, call_ctx),
|
||||||
|
Instruction::Null(null) => null.execute(exec_ctx, call_ctx),
|
||||||
Instruction::Par(par) => par.execute(exec_ctx, call_ctx),
|
Instruction::Par(par) => par.execute(exec_ctx, call_ctx),
|
||||||
|
Instruction::Seq(seq) => seq.execute(exec_ctx, call_ctx),
|
||||||
Instruction::Xor(xor) => xor.execute(exec_ctx, call_ctx),
|
Instruction::Xor(xor) => xor.execute(exec_ctx, call_ctx),
|
||||||
Instruction::Error => unreachable!("should not execute if parsing failed. QED."),
|
Instruction::Error => unreachable!("should not execute if parsing failed. QED."),
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ macro_rules! log_instruction {
|
|||||||
log::info!(
|
log::info!(
|
||||||
target: crate::log_targets::SUBTREE_ELEMENTS,
|
target: crate::log_targets::SUBTREE_ELEMENTS,
|
||||||
" subtree elements count: {:?}",
|
" subtree elements count: {:?}",
|
||||||
$call_ctx.current_subtree_elements_count
|
$call_ctx.current_subtree_size
|
||||||
);
|
);
|
||||||
log::info!(
|
log::info!(
|
||||||
target: crate::log_targets::NEW_CALL_EVIDENCE_PATH,
|
target: crate::log_targets::NEW_CALL_EVIDENCE_PATH,
|
||||||
|
@ -25,37 +25,49 @@ use crate::Result;
|
|||||||
|
|
||||||
use air_parser::ast::Par;
|
use air_parser::ast::Par;
|
||||||
|
|
||||||
|
enum SubtreeType {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for SubtreeType {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Left => write!(f, "left"),
|
||||||
|
Self::Right => write!(f, "right"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'i> ExecutableInstruction<'i> for Par<'i> {
|
impl<'i> ExecutableInstruction<'i> for Par<'i> {
|
||||||
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> {
|
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, call_ctx: &mut CallEvidenceCtx) -> Result<()> {
|
||||||
|
use SubtreeType::*;
|
||||||
|
|
||||||
log_instruction!(par, exec_ctx, call_ctx);
|
log_instruction!(par, exec_ctx, call_ctx);
|
||||||
|
|
||||||
let (left_subtree_size, right_subtree_size) = extract_subtree_sizes(call_ctx)?;
|
let (left_subtree_size, right_subtree_size) = extract_subtree_sizes(call_ctx)?;
|
||||||
|
|
||||||
let pre_states_count = call_ctx.current_path.len();
|
let before_path_size = call_ctx.current_path.len();
|
||||||
let pre_unused_elements = call_ctx.current_subtree_elements_count;
|
let before_subtree_size = call_ctx.current_subtree_size;
|
||||||
|
|
||||||
let pre_new_states_count = call_ctx.new_path.len();
|
let par_pos = call_ctx.new_path.len();
|
||||||
call_ctx.new_path.push_back(EvidenceState::Par(0, 0));
|
call_ctx.new_path.push_back(EvidenceState::Par(0, 0));
|
||||||
|
|
||||||
let new_left_subtree_size = execute_subtree(&self.0, left_subtree_size, exec_ctx, call_ctx)?;
|
// execute a left subtree of this par
|
||||||
|
execute_subtree(&self.0, left_subtree_size, exec_ctx, call_ctx, par_pos, Left)?;
|
||||||
let left_subtree_complete = exec_ctx.subtree_complete;
|
let left_subtree_complete = exec_ctx.subtree_complete;
|
||||||
|
|
||||||
let new_right_subtree_size = execute_subtree(&self.1, right_subtree_size, exec_ctx, call_ctx)?;
|
// execute a right subtree of this par
|
||||||
|
execute_subtree(&self.1, right_subtree_size, exec_ctx, call_ctx, par_pos, Right)?;
|
||||||
let right_subtree_complete = exec_ctx.subtree_complete;
|
let right_subtree_complete = exec_ctx.subtree_complete;
|
||||||
|
|
||||||
// par is completed if at least one of its subtrees is completed
|
// par is completed if at least one of its subtrees is completed
|
||||||
exec_ctx.subtree_complete = left_subtree_complete || right_subtree_complete;
|
exec_ctx.subtree_complete = left_subtree_complete || right_subtree_complete;
|
||||||
|
|
||||||
let new_par_evidence_state = EvidenceState::Par(new_left_subtree_size, new_right_subtree_size);
|
// decrease current subtree size by used elements from current_path
|
||||||
log::info!(
|
let after_path_size = call_ctx.current_path.len();
|
||||||
target: EVIDENCE_CHANGING,
|
let used_path_elements = before_path_size - after_path_size;
|
||||||
" adding new call evidence state {:?}",
|
call_ctx.current_subtree_size = before_subtree_size - used_path_elements;
|
||||||
new_par_evidence_state
|
|
||||||
);
|
|
||||||
call_ctx.new_path[pre_new_states_count] = new_par_evidence_state;
|
|
||||||
|
|
||||||
let post_states_count = call_ctx.current_path.len();
|
|
||||||
call_ctx.current_subtree_elements_count = pre_unused_elements - (pre_states_count - post_states_count);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -64,11 +76,10 @@ impl<'i> ExecutableInstruction<'i> for Par<'i> {
|
|||||||
fn extract_subtree_sizes(call_ctx: &mut CallEvidenceCtx) -> Result<(usize, usize)> {
|
fn extract_subtree_sizes(call_ctx: &mut CallEvidenceCtx) -> Result<(usize, usize)> {
|
||||||
use crate::AquamarineError::InvalidEvidenceState;
|
use crate::AquamarineError::InvalidEvidenceState;
|
||||||
|
|
||||||
if call_ctx.current_subtree_elements_count == 0 {
|
if call_ctx.current_subtree_size == 0 {
|
||||||
return Ok((0, 0));
|
return Ok((0, 0));
|
||||||
}
|
}
|
||||||
|
call_ctx.current_subtree_size -= 1;
|
||||||
call_ctx.current_subtree_elements_count -= 1;
|
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
target: EVIDENCE_CHANGING,
|
target: EVIDENCE_CHANGING,
|
||||||
@ -83,21 +94,36 @@ fn extract_subtree_sizes(call_ctx: &mut CallEvidenceCtx) -> Result<(usize, usize
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Execute provided subtree and update Par state in call_ctx.new_path.
|
||||||
fn execute_subtree<'i>(
|
fn execute_subtree<'i>(
|
||||||
subtree: &Instruction<'i>,
|
subtree: &Instruction<'i>,
|
||||||
subtree_size: usize,
|
subtree_size: usize,
|
||||||
exec_ctx: &mut ExecutionCtx<'i>,
|
exec_ctx: &mut ExecutionCtx<'i>,
|
||||||
call_ctx: &mut CallEvidenceCtx,
|
call_ctx: &mut CallEvidenceCtx,
|
||||||
) -> Result<usize> {
|
current_par_pos: usize,
|
||||||
call_ctx.current_subtree_elements_count = subtree_size;
|
subtree_type: SubtreeType,
|
||||||
let before_states_count = call_ctx.new_path.len();
|
) -> Result<()> {
|
||||||
|
use crate::AquamarineError::LocalServiceError;
|
||||||
|
|
||||||
|
call_ctx.current_subtree_size = subtree_size;
|
||||||
|
let before_new_path_len = call_ctx.new_path.len();
|
||||||
|
|
||||||
exec_ctx.subtree_complete = determine_subtree_complete(&subtree);
|
exec_ctx.subtree_complete = determine_subtree_complete(&subtree);
|
||||||
|
|
||||||
// execute subtree
|
// execute subtree
|
||||||
subtree.execute(exec_ctx, call_ctx)?;
|
match subtree.execute(exec_ctx, call_ctx) {
|
||||||
|
res @ Ok(_) => {
|
||||||
Ok(call_ctx.new_path.len() - before_states_count)
|
update_par_state(call_ctx, subtree_type, current_par_pos, before_new_path_len);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
// if there is a service error, update already added Par state
|
||||||
|
// and then bubble the error up
|
||||||
|
err @ Err(LocalServiceError(_)) => {
|
||||||
|
update_par_state(call_ctx, subtree_type, current_par_pos, before_new_path_len);
|
||||||
|
err
|
||||||
|
}
|
||||||
|
err @ Err(_) => err,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn determine_subtree_complete(next_instruction: &Instruction<'_>) -> bool {
|
fn determine_subtree_complete(next_instruction: &Instruction<'_>) -> bool {
|
||||||
@ -108,10 +134,40 @@ fn determine_subtree_complete(next_instruction: &Instruction<'_>) -> bool {
|
|||||||
// (next i)
|
// (next i)
|
||||||
// )
|
// )
|
||||||
// )
|
// )
|
||||||
// par will be executed after the last next that wouldn't change subtree_complete
|
// par will be completed after the last next that wouldn't change subtree_complete
|
||||||
!matches!(next_instruction, Instruction::Next(_))
|
!matches!(next_instruction, Instruction::Next(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set left or right fields of a Par identified by current_par_pos.
|
||||||
|
fn update_par_state(
|
||||||
|
call_ctx: &mut CallEvidenceCtx,
|
||||||
|
subtree_type: SubtreeType,
|
||||||
|
current_par_pos: usize,
|
||||||
|
before_new_path_len: usize,
|
||||||
|
) {
|
||||||
|
let new_subtree_size = call_ctx.new_path.len() - before_new_path_len;
|
||||||
|
|
||||||
|
// unwrap is safe here, because this par is added at the beginning of this par instruction.
|
||||||
|
let par_state = call_ctx.new_path.get_mut(current_par_pos).unwrap();
|
||||||
|
match par_state {
|
||||||
|
EvidenceState::Par(left, right) => {
|
||||||
|
if let SubtreeType::Left = subtree_type {
|
||||||
|
*left = new_subtree_size;
|
||||||
|
} else {
|
||||||
|
*right = new_subtree_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!(
|
||||||
|
target: EVIDENCE_CHANGING,
|
||||||
|
" set {} par subtree size to {}",
|
||||||
|
subtree_type,
|
||||||
|
new_subtree_size
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => unreachable!("current_pas_pos must point to a par state"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use aqua_test_utils::call_vm;
|
use aqua_test_utils::call_vm;
|
||||||
|
@ -50,19 +50,15 @@ mod tests {
|
|||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[test]
|
fn fallible_call_service(fallible_service_id: String) -> HostExportedFunc {
|
||||||
fn xor() {
|
Box::new(move |_, args| -> Option<IValue> {
|
||||||
use crate::call_evidence::CallResult::*;
|
|
||||||
use crate::call_evidence::EvidenceState::*;
|
|
||||||
|
|
||||||
let call_service: HostExportedFunc = Box::new(|_, args| -> Option<IValue> {
|
|
||||||
let builtin_service = match &args[0] {
|
let builtin_service = match &args[0] {
|
||||||
IValue::String(str) => str,
|
IValue::String(str) => str,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if builtin_service == "service_id_1" {
|
// return a error for service with such id
|
||||||
// return a error for service with id service_id_1
|
if builtin_service == &fallible_service_id {
|
||||||
Some(IValue::Record(
|
Some(IValue::Record(
|
||||||
Vec1::new(vec![IValue::S32(1), IValue::String(String::from(r#""error""#))]).unwrap(),
|
Vec1::new(vec![IValue::S32(1), IValue::String(String::from(r#""error""#))]).unwrap(),
|
||||||
))
|
))
|
||||||
@ -72,9 +68,16 @@ mod tests {
|
|||||||
Vec1::new(vec![IValue::S32(0), IValue::String(String::from(r#""res""#))]).unwrap(),
|
Vec1::new(vec![IValue::S32(0), IValue::String(String::from(r#""res""#))]).unwrap(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
|
||||||
let mut vm = create_aqua_vm(call_service, "");
|
#[test]
|
||||||
|
fn xor() {
|
||||||
|
use crate::call_evidence::CallResult::*;
|
||||||
|
use crate::call_evidence::EvidenceState::*;
|
||||||
|
|
||||||
|
let fallible_service_id = String::from("service_id_1");
|
||||||
|
let mut vm = create_aqua_vm(fallible_call_service(fallible_service_id), "");
|
||||||
|
|
||||||
let script = String::from(
|
let script = String::from(
|
||||||
r#"
|
r#"
|
||||||
@ -111,4 +114,54 @@ mod tests {
|
|||||||
Call(Executed(Rc::new(JValue::String(String::from("res")))))
|
Call(Executed(Rc::new(JValue::String(String::from("res")))))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn xor_par() {
|
||||||
|
use crate::call_evidence::CallResult::*;
|
||||||
|
use crate::call_evidence::EvidenceState::*;
|
||||||
|
|
||||||
|
let fallible_service_id = String::from("service_id_1");
|
||||||
|
let mut vm = create_aqua_vm(fallible_call_service(fallible_service_id), "");
|
||||||
|
|
||||||
|
let script = String::from(
|
||||||
|
r#"
|
||||||
|
(xor
|
||||||
|
(par
|
||||||
|
(seq
|
||||||
|
(call %current_peer_id% ("service_id_2" "local_fn_name") [] result_1)
|
||||||
|
(call %current_peer_id% ("service_id_2" "local_fn_name") [] result_2)
|
||||||
|
)
|
||||||
|
(par
|
||||||
|
(call %current_peer_id% ("service_id_1" "local_fn_name") [] result_3)
|
||||||
|
(call %current_peer_id% ("service_id_2" "local_fn_name") [] result_4)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(seq
|
||||||
|
(call %current_peer_id% ("service_id_2" "local_fn_name") [] result_4)
|
||||||
|
(call %current_peer_id% ("service_id_2" "local_fn_name") [] result_5)
|
||||||
|
)
|
||||||
|
)"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
let result = call_vm!(vm, "asd", script.clone(), "[]", "[]");
|
||||||
|
let result_path: CallEvidencePath = serde_json::from_str(&result.data).expect("should be valid json");
|
||||||
|
|
||||||
|
let res = String::from("res");
|
||||||
|
|
||||||
|
let right_path = vec![
|
||||||
|
Par(2, 2),
|
||||||
|
Call(Executed(Rc::new(JValue::String(res.clone())))),
|
||||||
|
Call(Executed(Rc::new(JValue::String(res.clone())))),
|
||||||
|
Par(1, 0),
|
||||||
|
Call(CallServiceFailed(String::from(r#""error""#))),
|
||||||
|
Call(Executed(Rc::new(JValue::String(res.clone())))),
|
||||||
|
Call(Executed(Rc::new(JValue::String(res)))),
|
||||||
|
];
|
||||||
|
|
||||||
|
assert_eq!(result_path, right_path);
|
||||||
|
|
||||||
|
let result = call_vm!(vm, "asd", script, "[]", result.data);
|
||||||
|
let result_path: CallEvidencePath = serde_json::from_str(&result.data).expect("should be valid json");
|
||||||
|
assert_eq!(result_path, right_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,17 +24,17 @@ use std::fmt::Formatter;
|
|||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
pub(crate) struct CallEvidenceCtx {
|
pub(crate) struct CallEvidenceCtx {
|
||||||
pub(crate) current_path: CallEvidencePath,
|
pub(crate) current_path: CallEvidencePath,
|
||||||
pub(crate) current_subtree_elements_count: usize,
|
pub(crate) current_subtree_size: usize,
|
||||||
// TODO: consider change it to Vec for optimization
|
// TODO: consider change it to Vec for optimization
|
||||||
pub(crate) new_path: CallEvidencePath,
|
pub(crate) new_path: CallEvidencePath,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallEvidenceCtx {
|
impl CallEvidenceCtx {
|
||||||
pub fn new(current_path: CallEvidencePath) -> Self {
|
pub fn new(current_path: CallEvidencePath) -> Self {
|
||||||
let current_subtree_elements_count = current_path.len();
|
let current_subtree_size = current_path.len();
|
||||||
Self {
|
Self {
|
||||||
current_path,
|
current_path,
|
||||||
current_subtree_elements_count,
|
current_subtree_size,
|
||||||
new_path: CallEvidencePath::new(),
|
new_path: CallEvidencePath::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,11 +43,7 @@ impl CallEvidenceCtx {
|
|||||||
impl Display for CallEvidenceCtx {
|
impl Display for CallEvidenceCtx {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
writeln!(f, "current path:\n{:?}", self.current_path)?;
|
writeln!(f, "current path:\n{:?}", self.current_path)?;
|
||||||
writeln!(
|
writeln!(f, "current subtree elements count:\n{:?}", self.current_subtree_size)?;
|
||||||
f,
|
|
||||||
"current subtree elements count:\n{:?}",
|
|
||||||
self.current_subtree_elements_count
|
|
||||||
)?;
|
|
||||||
writeln!(f, "new path:\n{:?}", self.new_path)
|
writeln!(f, "new path:\n{:?}", self.new_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user