mirror of
https://github.com/fluencelabs/aquavm
synced 2024-12-04 07:10:18 +00:00
Decouple trace handler (#150)
This commit is contained in:
parent
37ed77cb81
commit
adba9e8e65
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -19,6 +19,7 @@ dependencies = [
|
||||
"air-interpreter-interface",
|
||||
"air-parser",
|
||||
"air-test-utils",
|
||||
"air-trace-handler",
|
||||
"boolinator",
|
||||
"criterion",
|
||||
"csv",
|
||||
@ -107,6 +108,17 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "air-trace-handler"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"air-interpreter-data",
|
||||
"air-parser",
|
||||
"log",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
|
@ -9,6 +9,7 @@ members = [
|
||||
"crates/interpreter-data",
|
||||
"crates/test-module",
|
||||
"crates/test-utils",
|
||||
"crates/trace-handler",
|
||||
"avm/server",
|
||||
]
|
||||
|
||||
|
@ -12,10 +12,11 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
air-parser = { path = "../crates/air-parser" }
|
||||
polyplets = { path = "../crates/polyplets" }
|
||||
air-interpreter-data = { path = "../crates/interpreter-data" }
|
||||
air-interpreter-interface = { path = "../crates/interpreter-interface" }
|
||||
air-trace-handler = { path = "../crates/trace-handler" }
|
||||
marine-rs-sdk = { version = "0.6.11", features = ["logger"] }
|
||||
polyplets = { path = "../crates/polyplets" }
|
||||
|
||||
serde = { version = "1.0.118", features = [ "derive", "rc" ] }
|
||||
serde_json = "1.0.61"
|
||||
|
@ -24,8 +24,8 @@ use super::ExecutionResult;
|
||||
use super::TraceHandler;
|
||||
use crate::execution_step::air::ResolvedCallResult;
|
||||
use crate::execution_step::boxed_value::Variable;
|
||||
use crate::execution_step::trace_handler::MergerApResult;
|
||||
use crate::execution_step::utils::apply_json_path;
|
||||
use crate::trace_to_exec_err;
|
||||
use crate::JValue;
|
||||
use crate::SecurityTetraplet;
|
||||
use apply_to_arguments::*;
|
||||
@ -35,6 +35,7 @@ use air_parser::ast::ApArgument;
|
||||
use air_parser::ast::AstVariable;
|
||||
use air_parser::ast::JsonPath;
|
||||
use air_parser::ast::{Ap, LastErrorPath};
|
||||
use air_trace_handler::MergerApResult;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
@ -44,7 +45,7 @@ impl<'i> super::ExecutableInstruction<'i> for Ap<'i> {
|
||||
let should_touch_trace = should_touch_trace(self);
|
||||
|
||||
let merger_ap_result = if should_touch_trace {
|
||||
let merger_ap_result = trace_ctx.meet_ap_start()?;
|
||||
let merger_ap_result = trace_to_exec_err!(trace_ctx.meet_ap_start())?;
|
||||
try_match_result_to_instr(&merger_ap_result, self)?;
|
||||
merger_ap_result
|
||||
} else {
|
||||
|
@ -16,12 +16,12 @@
|
||||
|
||||
use super::ExecutionCtx;
|
||||
use super::ExecutionResult;
|
||||
use crate::execution_step::trace_handler::MergerApResult;
|
||||
use crate::execution_step::Generation;
|
||||
|
||||
use air_interpreter_data::ApResult;
|
||||
use air_parser::ast::Ap;
|
||||
use air_parser::ast::AstVariable;
|
||||
use air_trace_handler::MergerApResult;
|
||||
|
||||
pub(super) fn ap_result_to_generation(ap_result: &MergerApResult) -> Generation {
|
||||
match ap_result {
|
||||
|
@ -17,7 +17,6 @@
|
||||
use super::*;
|
||||
use crate::exec_err;
|
||||
use crate::execution_step::execution_context::*;
|
||||
use crate::execution_step::trace_handler::TraceHandler;
|
||||
use crate::execution_step::AstVariable;
|
||||
use crate::execution_step::Generation;
|
||||
use crate::execution_step::ResolvedCallResult;
|
||||
@ -27,6 +26,7 @@ use crate::execution_step::Stream;
|
||||
use air_interpreter_data::CallResult;
|
||||
use air_interpreter_data::Value;
|
||||
use air_parser::ast::CallOutputValue;
|
||||
use air_trace_handler::TraceHandler;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
|
@ -17,13 +17,13 @@
|
||||
use super::*;
|
||||
use crate::exec_err;
|
||||
use crate::execution_step::air::call::call_result_setter::set_result_from_value;
|
||||
use crate::execution_step::trace_handler::TraceHandler;
|
||||
use crate::execution_step::RSecurityTetraplet;
|
||||
|
||||
use air_interpreter_data::CallResult;
|
||||
use air_interpreter_data::Sender;
|
||||
use air_interpreter_interface::CallServiceResult;
|
||||
use air_parser::ast::CallOutputValue;
|
||||
use air_trace_handler::TraceHandler;
|
||||
|
||||
/// This function looks at the existing call state, validates it,
|
||||
/// and returns Ok(true) if the call should be executed further.
|
||||
|
@ -20,16 +20,17 @@ use super::call_result_setter::*;
|
||||
use super::prev_result_handler::*;
|
||||
use super::triplet::Triplet;
|
||||
use super::*;
|
||||
use crate::execution_step::trace_handler::MergerCallResult;
|
||||
use crate::execution_step::trace_handler::TraceHandler;
|
||||
use crate::execution_step::RSecurityTetraplet;
|
||||
use crate::execution_step::SecurityTetraplets;
|
||||
use crate::trace_to_exec_err;
|
||||
use crate::JValue;
|
||||
use crate::SecurityTetraplet;
|
||||
|
||||
use air_interpreter_data::CallResult;
|
||||
use air_interpreter_interface::CallRequestParams;
|
||||
use air_parser::ast::{AstVariable, CallInstrArgValue, CallOutputValue};
|
||||
use air_trace_handler::MergerCallResult;
|
||||
use air_trace_handler::TraceHandler;
|
||||
use polyplets::ResolvedTriplet;
|
||||
|
||||
use std::cell::RefCell;
|
||||
@ -125,7 +126,7 @@ impl<'i> ResolvedCall<'i> {
|
||||
exec_ctx: &mut ExecutionCtx<'i>,
|
||||
trace_ctx: &mut TraceHandler,
|
||||
) -> ExecutionResult<bool> {
|
||||
let (call_result, trace_pos) = match trace_ctx.meet_call_start(&self.output)? {
|
||||
let (call_result, trace_pos) = match trace_to_exec_err!(trace_ctx.meet_call_start(&self.output))? {
|
||||
MergerCallResult::CallResult { value, trace_pos } => (value, trace_pos),
|
||||
MergerCallResult::Empty => return Ok(true),
|
||||
};
|
||||
|
@ -21,6 +21,7 @@ use super::ExecutionCtx;
|
||||
use super::ExecutionResult;
|
||||
use super::TraceHandler;
|
||||
use crate::log_instruction;
|
||||
use crate::trace_to_exec_err;
|
||||
|
||||
use air_parser::ast::FoldStream;
|
||||
|
||||
@ -34,7 +35,7 @@ impl<'i> ExecutableInstruction<'i> for FoldStream<'i> {
|
||||
};
|
||||
|
||||
let fold_id = exec_ctx.tracker.fold.seen_stream_count;
|
||||
trace_ctx.meet_fold_start(fold_id)?;
|
||||
trace_to_exec_err!(trace_ctx.meet_fold_start(fold_id))?;
|
||||
|
||||
for iterable in iterables {
|
||||
let value = match iterable.peek() {
|
||||
@ -45,7 +46,7 @@ impl<'i> ExecutableInstruction<'i> for FoldStream<'i> {
|
||||
};
|
||||
|
||||
let value_pos = value.pos();
|
||||
trace_ctx.meet_iteration_start(fold_id, value_pos)?;
|
||||
trace_to_exec_err!(trace_ctx.meet_iteration_start(fold_id, value_pos))?;
|
||||
fold(
|
||||
iterable,
|
||||
IterableType::Stream(fold_id),
|
||||
@ -54,14 +55,14 @@ impl<'i> ExecutableInstruction<'i> for FoldStream<'i> {
|
||||
exec_ctx,
|
||||
trace_ctx,
|
||||
)?;
|
||||
trace_ctx.meet_generation_end(fold_id)?;
|
||||
trace_to_exec_err!(trace_ctx.meet_generation_end(fold_id))?;
|
||||
|
||||
if !exec_ctx.subtree_complete {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
trace_ctx.meet_fold_end(fold_id)?;
|
||||
trace_to_exec_err!(trace_ctx.meet_fold_end(fold_id))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ use super::Scalar;
|
||||
use super::TraceHandler;
|
||||
use crate::exec_err;
|
||||
use crate::log_instruction;
|
||||
use crate::trace_to_exec_err;
|
||||
|
||||
use air_parser::ast::Next;
|
||||
|
||||
@ -89,7 +90,7 @@ fn try_get_fold_state<'i, 'ctx>(
|
||||
|
||||
fn maybe_meet_iteration_start(fold_state: &FoldState<'_>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
|
||||
if let IterableType::Stream(fold_id) = &fold_state.iterable_type {
|
||||
trace_ctx.meet_iteration_start(*fold_id, fold_state.iterable.peek().unwrap().pos())?;
|
||||
trace_to_exec_err!(trace_ctx.meet_iteration_start(*fold_id, fold_state.iterable.peek().unwrap().pos()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -97,7 +98,7 @@ fn maybe_meet_iteration_start(fold_state: &FoldState<'_>, trace_ctx: &mut TraceH
|
||||
|
||||
fn maybe_meet_iteration_end(fold_state: &FoldState<'_>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
|
||||
if let IterableType::Stream(fold_id) = &fold_state.iterable_type {
|
||||
trace_ctx.meet_iteration_end(*fold_id)?;
|
||||
trace_to_exec_err!(trace_ctx.meet_iteration_end(*fold_id))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -105,7 +106,7 @@ fn maybe_meet_iteration_end(fold_state: &FoldState<'_>, trace_ctx: &mut TraceHan
|
||||
|
||||
fn maybe_meet_back_iterator(fold_state: &FoldState<'_>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
|
||||
if let IterableType::Stream(fold_id) = &fold_state.iterable_type {
|
||||
trace_ctx.meet_back_iterator(*fold_id)?;
|
||||
trace_to_exec_err!(trace_ctx.meet_back_iterator(*fold_id))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -23,11 +23,13 @@ use super::ExecutionError;
|
||||
use super::ExecutionResult;
|
||||
use super::Instruction;
|
||||
use super::TraceHandler;
|
||||
use crate::execution_step::trace_handler::SubtreeType;
|
||||
use crate::log_instruction;
|
||||
use crate::trace_to_exec_err;
|
||||
use completeness_updater::ParCompletenessUpdater;
|
||||
|
||||
use air_parser::ast::Par;
|
||||
use air_trace_handler::SubtreeType;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
#[rustfmt::skip]
|
||||
@ -36,7 +38,7 @@ impl<'i> ExecutableInstruction<'i> for Par<'i> {
|
||||
log_instruction!(par, exec_ctx, trace_ctx);
|
||||
|
||||
let mut completeness_updater = ParCompletenessUpdater::new();
|
||||
trace_ctx.meet_par_start()?;
|
||||
trace_to_exec_err!(trace_ctx.meet_par_start())?;
|
||||
|
||||
// execute a left subtree of par
|
||||
let left_result = execute_subtree(&self.0, exec_ctx, trace_ctx, &mut completeness_updater, SubtreeType::Left)?;
|
||||
@ -62,14 +64,14 @@ fn execute_subtree<'i>(
|
||||
// execute a subtree
|
||||
let result = match subtree.execute(exec_ctx, trace_ctx) {
|
||||
Ok(_) => {
|
||||
trace_ctx.meet_par_subtree_end(subtree_type)?;
|
||||
trace_to_exec_err!(trace_ctx.meet_par_subtree_end(subtree_type))?;
|
||||
SubtreeResult::Succeeded
|
||||
}
|
||||
Err(e) if !e.is_catchable() => {
|
||||
return Err(e);
|
||||
}
|
||||
Err(e) => {
|
||||
trace_ctx.meet_par_subtree_end(subtree_type)?;
|
||||
trace_to_exec_err!(trace_ctx.meet_par_subtree_end(subtree_type))?;
|
||||
SubtreeResult::Failed(e)
|
||||
}
|
||||
};
|
||||
|
@ -20,13 +20,13 @@ mod joinable;
|
||||
pub(crate) use catchable::Catchable;
|
||||
pub(crate) use joinable::Joinable;
|
||||
|
||||
use super::trace_handler::MergerApResult;
|
||||
use super::trace_handler::TraceHandlerError;
|
||||
use super::ResolvedCallResult;
|
||||
use super::Stream;
|
||||
use crate::JValue;
|
||||
|
||||
use air_interpreter_interface::CallResults;
|
||||
use air_trace_handler::MergerApResult;
|
||||
use air_trace_handler::TraceHandlerError;
|
||||
use jsonpath_lib::JsonPathError;
|
||||
use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumDiscriminants;
|
||||
@ -35,7 +35,7 @@ use thiserror::Error as ThisError;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Errors arised while executing AIR script.
|
||||
/// Errors arisen while executing AIR script.
|
||||
#[derive(ThisError, EnumDiscriminants, Debug)]
|
||||
#[strum_discriminants(derive(EnumIter))]
|
||||
pub(crate) enum ExecutionError {
|
||||
@ -134,10 +134,13 @@ pub(crate) enum ExecutionError {
|
||||
CallResultsNotEmpty(CallResults),
|
||||
}
|
||||
|
||||
impl From<TraceHandlerError> for Rc<ExecutionError> {
|
||||
fn from(trace_error: TraceHandlerError) -> Self {
|
||||
Rc::new(ExecutionError::TraceError(trace_error))
|
||||
}
|
||||
/// This macro is needed because it's impossible to implement
|
||||
/// From<TraceHandlerError> for Rc<ExecutionError> due to the orphan rule.
|
||||
#[macro_export]
|
||||
macro_rules! trace_to_exec_err {
|
||||
($trace_expr: expr) => {
|
||||
$trace_expr.map_err(|e| std::rc::Rc::new(crate::execution_step::ExecutionError::TraceError(e)))
|
||||
};
|
||||
}
|
||||
|
||||
impl ExecutionError {
|
||||
|
@ -18,7 +18,6 @@ mod air;
|
||||
mod boxed_value;
|
||||
mod errors;
|
||||
pub(crate) mod execution_context;
|
||||
mod trace_handler;
|
||||
mod utils;
|
||||
|
||||
pub(super) use self::air::ExecutableInstruction;
|
||||
@ -31,7 +30,8 @@ pub(crate) use errors::Catchable;
|
||||
pub(super) use errors::ExecutionError;
|
||||
pub(crate) use errors::Joinable;
|
||||
pub(crate) use execution_context::ExecutionCtx;
|
||||
pub(crate) use trace_handler::TraceHandler;
|
||||
|
||||
pub(crate) use air_trace_handler::TraceHandler;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
1
crates/trace-handler/.rustfmt.toml
Normal file
1
crates/trace-handler/.rustfmt.toml
Normal file
@ -0,0 +1 @@
|
||||
max_width = 120
|
23
crates/trace-handler/Cargo.toml
Normal file
23
crates/trace-handler/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "air-trace-handler"
|
||||
version = "0.1.0"
|
||||
description = "Implementation of AIR trace handler"
|
||||
authors = ["Fluence Labs"]
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/fluencelabs/air/crates/trace-handler"
|
||||
publish = false
|
||||
keywords = ["fluence", "air", "webassembly", "programming-language"]
|
||||
categories = ["wasm"]
|
||||
|
||||
[lib]
|
||||
name = "air_trace_handler"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
air-interpreter-data = { path = "../interpreter-data" }
|
||||
air-parser = { path = "../air-parser" }
|
||||
|
||||
serde_json = "1.0.68"
|
||||
log = "0.4.14"
|
||||
thiserror = "1.0.29"
|
41
crates/trace-handler/README.md
Normal file
41
crates/trace-handler/README.md
Normal file
@ -0,0 +1,41 @@
|
||||
## AIR trace handler
|
||||
|
||||
This crate contains implementation of the CRDT-based merging data algorithm. It exposes the `TraceHandler` struct that based on the visitor pattern and has public methods that should be called in certain places of AIR instructions execution. Internally `TraceHandler` contains several FSM and each such public methods do state transitioning of one or more these FSMs. Below are state transition sequences for all instructions that caller must follow.
|
||||
|
||||
### Ap instruction
|
||||
|
||||
Expected sequence of `TraceHandler` calls for the `ap` instruction:
|
||||
```
|
||||
meet_ap_start
|
||||
-> meet_ap_end
|
||||
```
|
||||
|
||||
### Call instruction
|
||||
|
||||
Expected sequence of `TraceHandler` calls for the `call` instruction:
|
||||
```
|
||||
meet_call_start
|
||||
-> meet_call_end
|
||||
```
|
||||
|
||||
### Par instruction
|
||||
|
||||
Expected sequence of `TraceHandler` calls for the `par` instruction:
|
||||
```
|
||||
meet_par_start
|
||||
-> meet_par_subtree_end(..., SubtreeType::Left)
|
||||
-> meet_par_subtree_end(..., SubtreeType::Right)
|
||||
```
|
||||
|
||||
### Fold instruction
|
||||
|
||||
Expected sequence of `TraceHandler` calls for the `fold` instruction:
|
||||
```
|
||||
meet_fold_start.1 ->
|
||||
meet_generation_start.N ->
|
||||
meet_next.M ->
|
||||
meet_prev.M ->
|
||||
meet_generation_end.N ->
|
||||
meet_fold_end.1
|
||||
```
|
||||
where .T means that this function should be called exactly T times.
|
@ -19,7 +19,7 @@ use thiserror::Error as ThisError;
|
||||
|
||||
/// Errors arose out while accessing various interpreter data.
|
||||
#[derive(ThisError, Debug, PartialEq, Eq)]
|
||||
pub(crate) enum KeeperError {
|
||||
pub enum KeeperError {
|
||||
/// Errors occurred when trace_len - trace_position < requested_subtrace_len.
|
||||
#[error(
|
||||
"executed trace has {trace_len} elements and current position is {trace_position}, \
|
@ -26,9 +26,9 @@ use std::collections::HashMap;
|
||||
|
||||
/// Contains all necessary information about data.
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
pub(crate) struct MergeCtx {
|
||||
pub(crate) slider: TraceSlider,
|
||||
pub(crate) streams: StreamGenerations,
|
||||
pub struct MergeCtx {
|
||||
pub slider: TraceSlider,
|
||||
pub streams: StreamGenerations,
|
||||
}
|
||||
|
||||
impl MergeCtx {
|
@ -19,11 +19,12 @@ mod keeper;
|
||||
mod merge_ctx;
|
||||
mod trace_slider;
|
||||
|
||||
pub(crate) use errors::KeeperError;
|
||||
pub use errors::KeeperError;
|
||||
pub use merge_ctx::MergeCtx;
|
||||
pub use trace_slider::TraceSlider;
|
||||
|
||||
pub(crate) use keeper::DataKeeper;
|
||||
pub(crate) use keeper::DataPositions;
|
||||
pub(super) use merge_ctx::MergeCtx;
|
||||
pub(super) use trace_slider::TraceSlider;
|
||||
|
||||
pub(self) type KeeperResult<T> = std::result::Result<T, KeeperError>;
|
||||
|
@ -23,7 +23,7 @@ use super::KeeperResult;
|
||||
/// is identified by position and len.
|
||||
// TODO: check for overflow
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub(crate) struct TraceSlider {
|
||||
pub struct TraceSlider {
|
||||
/// Trace that slider slide on.
|
||||
trace: ExecutionTrace,
|
||||
|
@ -23,7 +23,7 @@ use thiserror::Error as ThisError;
|
||||
/// Errors arose out of merging previous data with a new.
|
||||
#[derive(ThisError, Debug)]
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
pub(crate) enum TraceHandlerError {
|
||||
pub enum TraceHandlerError {
|
||||
#[error(transparent)]
|
||||
KeeperError(#[from] KeeperError),
|
||||
|
@ -15,20 +15,19 @@
|
||||
*/
|
||||
|
||||
use super::*;
|
||||
use crate::log_targets::EXECUTED_STATE_CHANGING;
|
||||
use merger::*;
|
||||
|
||||
use air_interpreter_data::InterpreterData;
|
||||
use air_parser::ast::CallOutputValue;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct TraceHandler {
|
||||
pub(crate) data_keeper: DataKeeper,
|
||||
pub struct TraceHandler {
|
||||
data_keeper: DataKeeper,
|
||||
fsm_keeper: FSMKeeper,
|
||||
}
|
||||
|
||||
impl TraceHandler {
|
||||
pub(crate) fn from_data(prev_data: InterpreterData, current_data: InterpreterData) -> Self {
|
||||
pub fn from_data(prev_data: InterpreterData, current_data: InterpreterData) -> Self {
|
||||
let data_keeper = DataKeeper::from_data(prev_data, current_data);
|
||||
|
||||
Self {
|
||||
@ -39,19 +38,19 @@ impl TraceHandler {
|
||||
|
||||
/// Returns size of elements inside result trace and intended to provide
|
||||
/// a position of next inserted elements.
|
||||
pub(crate) fn trace_pos(&self) -> usize {
|
||||
pub fn trace_pos(&self) -> usize {
|
||||
self.data_keeper.result_trace.len()
|
||||
}
|
||||
|
||||
pub(crate) fn into_result_trace(self) -> ExecutionTrace {
|
||||
pub fn into_result_trace(self) -> ExecutionTrace {
|
||||
self.data_keeper.result_trace
|
||||
}
|
||||
|
||||
pub(crate) fn as_result_trace(&self) -> &ExecutionTrace {
|
||||
pub fn as_result_trace(&self) -> &ExecutionTrace {
|
||||
&self.data_keeper.result_trace
|
||||
}
|
||||
|
||||
pub(crate) fn subtree_sizes(&self) -> (usize, usize) {
|
||||
pub fn subtree_sizes(&self) -> (usize, usize) {
|
||||
let prev_len = self.data_keeper.prev_slider().subtrace_len();
|
||||
let current_len = self.data_keeper.current_slider().subtrace_len();
|
||||
|
||||
@ -61,18 +60,15 @@ impl TraceHandler {
|
||||
|
||||
impl TraceHandler {
|
||||
/// Should be called at the beginning of a call execution.
|
||||
pub(crate) fn meet_call_start(
|
||||
&mut self,
|
||||
output_value: &CallOutputValue<'_>,
|
||||
) -> TraceHandlerResult<MergerCallResult> {
|
||||
pub fn meet_call_start(&mut self, output_value: &CallOutputValue<'_>) -> TraceHandlerResult<MergerCallResult> {
|
||||
try_merge_next_state_as_call(&mut self.data_keeper, output_value).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Should be called when a call instruction was executed successfully. It adds the supplied
|
||||
/// state to the result trace.
|
||||
pub(crate) fn meet_call_end(&mut self, call_result: CallResult) {
|
||||
pub fn meet_call_end(&mut self, call_result: CallResult) {
|
||||
log::trace!(
|
||||
target: EXECUTED_STATE_CHANGING,
|
||||
target: crate::EXECUTED_STATE_CHANGING,
|
||||
" adding new call executed state {:?}",
|
||||
call_result
|
||||
);
|
||||
@ -81,17 +77,17 @@ impl TraceHandler {
|
||||
}
|
||||
|
||||
impl TraceHandler {
|
||||
pub(crate) fn meet_ap_start(&mut self) -> TraceHandlerResult<MergerApResult> {
|
||||
pub fn meet_ap_start(&mut self) -> TraceHandlerResult<MergerApResult> {
|
||||
try_merge_next_state_as_ap(&mut self.data_keeper).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn meet_ap_end(&mut self, ap_result: ApResult) {
|
||||
pub fn meet_ap_end(&mut self, ap_result: ApResult) {
|
||||
self.data_keeper.result_trace.push(ExecutedState::Ap(ap_result));
|
||||
}
|
||||
}
|
||||
|
||||
impl TraceHandler {
|
||||
pub(crate) fn meet_par_start(&mut self) -> TraceHandlerResult<()> {
|
||||
pub fn meet_par_start(&mut self) -> TraceHandlerResult<()> {
|
||||
let ingredients = merger::try_merge_next_state_as_par(&mut self.data_keeper)?;
|
||||
let par_fsm = ParFSM::from_left_started(ingredients, &mut self.data_keeper)?;
|
||||
self.fsm_keeper.push_par(par_fsm);
|
||||
@ -99,7 +95,7 @@ impl TraceHandler {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn meet_par_subtree_end(&mut self, subtree_type: SubtreeType) -> TraceHandlerResult<()> {
|
||||
pub fn meet_par_subtree_end(&mut self, subtree_type: SubtreeType) -> TraceHandlerResult<()> {
|
||||
match subtree_type {
|
||||
SubtreeType::Left => {
|
||||
let par_fsm = self.fsm_keeper.last_par()?;
|
||||
@ -116,7 +112,7 @@ impl TraceHandler {
|
||||
}
|
||||
|
||||
impl TraceHandler {
|
||||
pub(crate) fn meet_fold_start(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
pub fn meet_fold_start(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
let ingredients = try_merge_next_state_as_fold(&mut self.data_keeper)?;
|
||||
let fold_fsm = FoldFSM::from_fold_start(ingredients, &mut self.data_keeper)?;
|
||||
self.fsm_keeper.add_fold(fold_id, fold_fsm);
|
||||
@ -124,42 +120,42 @@ impl TraceHandler {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn meet_iteration_start(&mut self, fold_id: u32, value_pos: usize) -> TraceHandlerResult<()> {
|
||||
pub fn meet_iteration_start(&mut self, fold_id: u32, value_pos: usize) -> TraceHandlerResult<()> {
|
||||
let fold_fsm = self.fsm_keeper.fold_mut(fold_id)?;
|
||||
fold_fsm.meet_iteration_start(value_pos, &mut self.data_keeper)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn meet_iteration_end(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
pub fn meet_iteration_end(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
let fold_fsm = self.fsm_keeper.fold_mut(fold_id)?;
|
||||
fold_fsm.meet_iteration_end(&mut self.data_keeper);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn meet_back_iterator(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
pub fn meet_back_iterator(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
let fold_fsm = self.fsm_keeper.fold_mut(fold_id)?;
|
||||
fold_fsm.meet_back_iterator(&mut self.data_keeper)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn meet_generation_end(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
pub fn meet_generation_end(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
let fold_fsm = self.fsm_keeper.fold_mut(fold_id)?;
|
||||
fold_fsm.meet_generation_end(&mut self.data_keeper);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn meet_fold_end(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
pub fn meet_fold_end(&mut self, fold_id: u32) -> TraceHandlerResult<()> {
|
||||
let fold_fsm = self.fsm_keeper.extract_fold(fold_id)?;
|
||||
fold_fsm.meet_fold_end(&mut self.data_keeper);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn fold_end_with_error(&mut self, fold_id: u32) {
|
||||
pub fn fold_end_with_error(&mut self, fold_id: u32) {
|
||||
let fold_fsm = match self.fsm_keeper.extract_fold(fold_id) {
|
||||
Ok(fold_fsm) => fold_fsm,
|
||||
// just passing here is ok, because error could be produced while fold initialization
|
@ -20,18 +20,24 @@ mod handler;
|
||||
mod merger;
|
||||
mod state_automata;
|
||||
|
||||
pub(crate) use errors::TraceHandlerError;
|
||||
pub(crate) use handler::TraceHandler;
|
||||
pub(crate) use merger::MergerApResult;
|
||||
pub(crate) use merger::MergerCallResult;
|
||||
pub(crate) use state_automata::SubtreeType;
|
||||
pub use errors::TraceHandlerError;
|
||||
pub use handler::TraceHandler;
|
||||
pub use merger::ApResultError;
|
||||
pub use merger::CallResultError;
|
||||
pub use merger::FoldResultError;
|
||||
pub use merger::MergeCtxType;
|
||||
pub use merger::MergeError;
|
||||
pub use merger::MergerApResult;
|
||||
pub use merger::MergerCallResult;
|
||||
pub use state_automata::SubtreeType;
|
||||
|
||||
pub(crate) type TraceHandlerResult<T> = std::result::Result<T, TraceHandlerError>;
|
||||
pub type TraceHandlerResult<T> = std::result::Result<T, TraceHandlerError>;
|
||||
|
||||
pub const EXECUTED_STATE_CHANGING: &str = "executed_state_changing";
|
||||
|
||||
use air_interpreter_data::*;
|
||||
use data_keeper::DataKeeper;
|
||||
use data_keeper::MergeCtx;
|
||||
use merger::MergeCtxType;
|
||||
use merger::MergerFoldResult;
|
||||
use merger::ResolvedFold;
|
||||
use merger::ResolvedSubTraceDescs;
|
@ -17,7 +17,7 @@
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum MergerApResult {
|
||||
pub enum MergerApResult {
|
||||
/// There is no corresponding state in a trace for this call.
|
||||
Empty,
|
||||
|
@ -23,7 +23,7 @@ use call_result_constructor::*;
|
||||
use utils::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum MergerCallResult {
|
||||
pub enum MergerCallResult {
|
||||
/// There is no corresponding state in a trace for this call.
|
||||
Empty,
|
||||
|
@ -15,7 +15,8 @@
|
||||
*/
|
||||
|
||||
use super::*;
|
||||
use crate::JValue;
|
||||
|
||||
type JValue = serde_json::Value;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
@ -26,7 +26,7 @@ use thiserror::Error as ThisError;
|
||||
|
||||
/// Errors arose out of merging previous data with a new.
|
||||
#[derive(ThisError, Debug)]
|
||||
pub(crate) enum MergeError {
|
||||
pub enum MergeError {
|
||||
/// Errors occurred when previous and current executed states are incompatible.
|
||||
#[error("previous and current data have incompatible states: '{0:?}' '{1:?}'")]
|
||||
IncompatibleExecutedStates(ExecutedState, ExecutedState),
|
||||
@ -50,14 +50,14 @@ pub(crate) enum MergeError {
|
||||
}
|
||||
|
||||
#[derive(ThisError, Debug)]
|
||||
pub(crate) enum ApResultError {
|
||||
pub enum ApResultError {
|
||||
/// Error occurred when Ap results contains more then 1 generation in destination.
|
||||
#[error("{0:?} ap result contains too many generations in destination")]
|
||||
TooManyDstGenerations(ApResult),
|
||||
}
|
||||
|
||||
#[derive(ThisError, Debug)]
|
||||
pub(crate) enum CallResultError {
|
||||
pub enum CallResultError {
|
||||
#[error("values in call results are not equal: {prev_value:?} != {current_value:?}")]
|
||||
ValuesNotEqual { prev_value: Value, current_value: Value },
|
||||
|
||||
@ -73,7 +73,7 @@ pub(crate) enum CallResultError {
|
||||
}
|
||||
|
||||
#[derive(ThisError, Debug)]
|
||||
pub(crate) enum FoldResultError {
|
||||
pub enum FoldResultError {
|
||||
#[error("the first {count} subtrace descriptors lens of fold {fold_result:?} overflows")]
|
||||
SubtraceLenOverflow { fold_result: FoldResult, count: usize },
|
||||
|
@ -17,12 +17,12 @@
|
||||
mod fold_lore_resolver;
|
||||
|
||||
use super::*;
|
||||
pub(crate) use fold_lore_resolver::*;
|
||||
pub use fold_lore_resolver::*;
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub(crate) struct MergerFoldResult {
|
||||
pub(crate) prev_fold_lore: ResolvedFold,
|
||||
pub(crate) current_fold_lore: ResolvedFold,
|
||||
pub struct MergerFoldResult {
|
||||
pub prev_fold_lore: ResolvedFold,
|
||||
pub current_fold_lore: ResolvedFold,
|
||||
}
|
||||
|
||||
pub(crate) fn try_merge_next_state_as_fold(data_keeper: &mut DataKeeper) -> MergeResult<MergerFoldResult> {
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
use super::*;
|
||||
use crate::execution_step::trace_handler::data_keeper::MergeCtx;
|
||||
use crate::data_keeper::MergeCtx;
|
||||
|
||||
use air_interpreter_data::FoldSubTraceLore;
|
||||
use air_interpreter_data::SubTraceDesc;
|
||||
@ -23,15 +23,15 @@ use air_interpreter_data::SubTraceDesc;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub(crate) struct ResolvedFold {
|
||||
pub(crate) lore: HashMap<usize, ResolvedSubTraceDescs>,
|
||||
pub(crate) fold_states_count: usize,
|
||||
pub struct ResolvedFold {
|
||||
pub lore: HashMap<usize, ResolvedSubTraceDescs>,
|
||||
pub fold_states_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(crate) struct ResolvedSubTraceDescs {
|
||||
pub(crate) before_subtrace: SubTraceDesc,
|
||||
pub(crate) after_subtrace: SubTraceDesc,
|
||||
pub struct ResolvedSubTraceDescs {
|
||||
pub before_subtrace: SubTraceDesc,
|
||||
pub after_subtrace: SubTraceDesc,
|
||||
}
|
||||
|
||||
pub(super) fn resolve_fold_lore(fold: &FoldResult, merge_ctx: &MergeCtx) -> MergeResult<ResolvedFold> {
|
@ -20,20 +20,23 @@ mod errors;
|
||||
mod fold_merger;
|
||||
mod par_merger;
|
||||
|
||||
pub use ap_merger::MergerApResult;
|
||||
pub use call_merger::MergerCallResult;
|
||||
pub use fold_merger::MergerFoldResult;
|
||||
pub use par_merger::MergerParResult;
|
||||
|
||||
pub use errors::ApResultError;
|
||||
pub use errors::CallResultError;
|
||||
pub use errors::FoldResultError;
|
||||
pub use errors::MergeError;
|
||||
|
||||
pub use fold_merger::ResolvedFold;
|
||||
pub use fold_merger::ResolvedSubTraceDescs;
|
||||
|
||||
pub(super) use ap_merger::try_merge_next_state_as_ap;
|
||||
pub(crate) use ap_merger::MergerApResult;
|
||||
pub(super) use call_merger::try_merge_next_state_as_call;
|
||||
pub(crate) use call_merger::MergerCallResult;
|
||||
pub(crate) use errors::ApResultError;
|
||||
pub(crate) use errors::CallResultError;
|
||||
pub(crate) use errors::FoldResultError;
|
||||
pub(crate) use errors::MergeError;
|
||||
pub(crate) use fold_merger::try_merge_next_state_as_fold;
|
||||
pub(crate) use fold_merger::MergerFoldResult;
|
||||
pub(crate) use fold_merger::ResolvedFold;
|
||||
pub(crate) use fold_merger::ResolvedSubTraceDescs;
|
||||
pub(crate) use par_merger::try_merge_next_state_as_par;
|
||||
pub(crate) use par_merger::MergerParResult;
|
||||
|
||||
type MergeResult<T> = std::result::Result<T, MergeError>;
|
||||
|
||||
@ -44,7 +47,7 @@ use super::DataKeeper;
|
||||
use air_interpreter_data::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) enum MergeCtxType {
|
||||
pub enum MergeCtxType {
|
||||
Current,
|
||||
Previous,
|
||||
}
|
@ -18,9 +18,9 @@ use super::*;
|
||||
use ExecutedState::Par;
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone)]
|
||||
pub(crate) struct MergerParResult {
|
||||
pub(crate) prev_par: Option<ParResult>,
|
||||
pub(crate) current_par: Option<ParResult>,
|
||||
pub struct MergerParResult {
|
||||
pub prev_par: Option<ParResult>,
|
||||
pub current_par: Option<ParResult>,
|
||||
}
|
||||
|
||||
pub(crate) fn try_merge_next_state_as_par(data_keeper: &mut DataKeeper) -> MergeResult<MergerParResult> {
|
@ -16,17 +16,17 @@
|
||||
|
||||
use super::KeeperError;
|
||||
use super::ParResult;
|
||||
use crate::execution_step::trace_handler::MergeCtxType;
|
||||
use crate::execution_step::trace_handler::ResolvedFold;
|
||||
use crate::MergeCtxType;
|
||||
use crate::ResolvedFold;
|
||||
|
||||
use thiserror::Error as ThisError;
|
||||
|
||||
/// Errors arose out of merging previous data with a new.
|
||||
#[derive(ThisError, Debug)]
|
||||
pub(crate) enum StateFSMError {
|
||||
pub enum StateFSMError {
|
||||
/// Error occurred while trying to access or pop elements from an empty par queue.
|
||||
#[error("par queue is empty, while par FSM is requested")]
|
||||
ParQueueIsEmpty(),
|
||||
ParQueueIsEmpty,
|
||||
|
||||
/// Errors occurred while trying to access or pop elements from queue,
|
||||
/// which contains element of different type.
|
@ -15,8 +15,8 @@
|
||||
*/
|
||||
|
||||
use super::*;
|
||||
use crate::execution_step::trace_handler::MergeCtxType;
|
||||
use crate::execution_step::trace_handler::ResolvedFold;
|
||||
use crate::MergeCtxType;
|
||||
use crate::ResolvedFold;
|
||||
|
||||
/// This state updater manage to do the same thing as SubTreeStateUpdater in ParFSM,
|
||||
/// for details please see its detailed comment.
|
@ -37,11 +37,11 @@ impl FSMKeeper {
|
||||
}
|
||||
|
||||
pub(crate) fn last_par(&mut self) -> FSMResult<&mut ParFSM> {
|
||||
self.par_stack.last_mut().ok_or(StateFSMError::ParQueueIsEmpty())
|
||||
self.par_stack.last_mut().ok_or(StateFSMError::ParQueueIsEmpty)
|
||||
}
|
||||
|
||||
pub(crate) fn pop_par(&mut self) -> FSMResult<ParFSM> {
|
||||
self.par_stack.pop().ok_or(StateFSMError::ParQueueIsEmpty())
|
||||
self.par_stack.pop().ok_or(StateFSMError::ParQueueIsEmpty)
|
||||
}
|
||||
|
||||
pub(crate) fn fold_mut(&mut self, fold_id: u32) -> FSMResult<&mut FoldFSM> {
|
@ -21,8 +21,9 @@ mod par_fsm;
|
||||
mod state_inserter;
|
||||
mod utils;
|
||||
|
||||
pub(crate) use errors::StateFSMError;
|
||||
pub(crate) use par_fsm::SubtreeType;
|
||||
pub use errors::StateFSMError;
|
||||
pub use par_fsm::SubtreeType;
|
||||
|
||||
pub(crate) type FSMResult<T> = std::result::Result<T, StateFSMError>;
|
||||
|
||||
pub(super) use fold_fsm::FoldFSM;
|
@ -23,9 +23,8 @@ use state_handler::CtxStateHandler;
|
||||
|
||||
/// Manages a par state, its state transitioning functions must be called in the following way:
|
||||
/// from_left_started
|
||||
/// -> left_completed(_with_error)
|
||||
/// -> right_started
|
||||
/// -> right_completed(_with_error)
|
||||
/// -> left_completed
|
||||
/// -> right_completed
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub(crate) struct ParFSM {
|
||||
prev_par: ParResult,
|
||||
@ -36,7 +35,7 @@ pub(crate) struct ParFSM {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub(crate) enum SubtreeType {
|
||||
pub enum SubtreeType {
|
||||
Left,
|
||||
Right,
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
use super::*;
|
||||
use crate::execution_step::trace_handler::data_keeper::TraceSlider;
|
||||
use crate::data_keeper::TraceSlider;
|
||||
|
||||
pub(super) fn compute_new_states(
|
||||
data_keeper: &DataKeeper,
|
Loading…
Reference in New Issue
Block a user