From 95b2d154ff84caf5efe7a3960922d1d6c39a9ed2 Mon Sep 17 00:00:00 2001 From: Mike Voronov Date: Thu, 2 Mar 2023 22:22:13 +0300 Subject: [PATCH] =?UTF-8?q?feat(execution-engine)!:=20make=20StreamDontHav?= =?UTF-8?q?eSuchGeneration=20uncatchable=E2=80=A6=20(#492)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `StreamDontHaveSuchGeneration` is a catchable error that could be caught by a xor instruction and then handled by a user. But it makes no sense because this error could arise only iff smth went wrong during merging or when data is corrupted. --- Cargo.lock | 16 ++++----- .../boxed_value/jvaluable/stream.rs | 13 +++---- air/src/execution_step/boxed_value/stream.rs | 35 +++++++++++++------ .../execution_step/errors/catchable_errors.rs | 5 --- .../errors/uncatchable_errors.rs | 10 ++++++ 5 files changed, 47 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5be5114d..f1968cb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ dependencies = [ [[package]] name = "air-beautifier" -version = "0.1.1" +version = "0.1.2" dependencies = [ "air-parser", "itertools", @@ -61,7 +61,7 @@ dependencies = [ [[package]] name = "air-beautify" -version = "0.1.1" +version = "0.1.2" dependencies = [ "air-beautifier", "anyhow", @@ -70,7 +70,7 @@ dependencies = [ [[package]] name = "air-beautify-wasm" -version = "0.1.0" +version = "0.1.1" dependencies = [ "air-beautifier", "wasm-bindgen", @@ -78,7 +78,7 @@ dependencies = [ [[package]] name = "air-execution-info-collector" -version = "0.7.2" +version = "0.7.3" dependencies = [ "air-parser", ] @@ -111,7 +111,7 @@ dependencies = [ [[package]] name = "air-interpreter-data" -version = "0.6.2" +version = "0.6.3" dependencies = [ "air-interpreter-cid", "air-interpreter-interface", @@ -168,7 +168,7 @@ version = "0.1.0" [[package]] name = "air-parser" -version = "0.7.2" +version = "0.7.3" dependencies = [ "air-lambda-ast", "air-lambda-parser", @@ -242,7 +242,7 @@ dependencies = [ [[package]] name = "air-trace-handler" -version = "0.1.1" +version = "0.1.2" dependencies = [ "air-interpreter-cid", "air-interpreter-data", @@ -341,7 +341,7 @@ dependencies = [ [[package]] name = "avm-interface" -version = "0.28.1" +version = "0.28.2" dependencies = [ "air-interpreter-interface", "air-utils", diff --git a/air/src/execution_step/boxed_value/jvaluable/stream.rs b/air/src/execution_step/boxed_value/jvaluable/stream.rs index e3e441d3..ceff163a 100644 --- a/air/src/execution_step/boxed_value/jvaluable/stream.rs +++ b/air/src/execution_step/boxed_value/jvaluable/stream.rs @@ -94,18 +94,15 @@ impl<'stream> StreamJvaluableIngredients<'stream> { } pub(self) fn iter(&self) -> ExecutionResult> { - use crate::execution_step::CatchableError::StreamDontHaveSuchGeneration; + use crate::execution_step::UncatchableError::StreamDontHaveSuchGeneration; match self.stream.iter(self.generation) { Some(iter) => Ok(iter), - None => { - let generation = match self.generation { - Generation::Nth(generation) => generation, - Generation::Last => unreachable!(), - }; - - Err(StreamDontHaveSuchGeneration(self.stream.clone(), generation as usize).into()) + None => Err(StreamDontHaveSuchGeneration { + stream: self.stream.clone(), + generation: self.generation, } + .into()), } } } diff --git a/air/src/execution_step/boxed_value/stream.rs b/air/src/execution_step/boxed_value/stream.rs index f4dd3152..400f9fe2 100644 --- a/air/src/execution_step/boxed_value/stream.rs +++ b/air/src/execution_step/boxed_value/stream.rs @@ -16,7 +16,6 @@ use super::ExecutionResult; use super::ValueAggregate; -use crate::execution_step::CatchableError; use crate::ExecutionError; use crate::JValue; use crate::UncatchableError; @@ -26,7 +25,6 @@ use air_trace_handler::merger::ValueSource; use air_trace_handler::TraceHandler; use std::collections::HashMap; -use std::fmt::Formatter; /// Streams are CRDT-like append only data structures. They are guaranteed to have the same order /// of values on each peer. @@ -83,21 +81,27 @@ impl Stream { generation: Generation, source: ValueSource, ) -> ExecutionResult { - let generation = match (generation, source) { + let generation_number = match (generation, source) { (Generation::Last, _) => self.values.len() - 1, (Generation::Nth(previous_gen), ValueSource::PreviousData) => previous_gen as usize, (Generation::Nth(current_gen), ValueSource::CurrentData) => self.previous_gens_count + current_gen as usize, }; - if generation >= self.values.len() { - return Err(CatchableError::StreamDontHaveSuchGeneration(self.clone(), generation).into()); + if generation_number >= self.values.len() { + return Err(UncatchableError::StreamDontHaveSuchGeneration { + stream: self.clone(), + generation, + } + .into()); } - let values = &mut self.values[generation]; - self.values_by_pos - .insert(value.trace_pos, StreamValueLocation::new(generation, values.len())); + let values = &mut self.values[generation_number]; + self.values_by_pos.insert( + value.trace_pos, + StreamValueLocation::new(generation_number, values.len()), + ); values.push(value); - Ok(generation as u32) + Ok(generation_number as u32) } pub(crate) fn generations_count(&self) -> usize { @@ -244,7 +248,7 @@ impl Stream { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub(crate) enum Generation { +pub enum Generation { Last, Nth(u32), } @@ -309,7 +313,7 @@ impl StreamValueLocation { use std::fmt; impl fmt::Display for Stream { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.values.is_empty() { return write!(f, "[]"); } @@ -327,6 +331,15 @@ impl fmt::Display for Stream { } } +impl fmt::Display for Generation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Generation::Nth(generation) => write!(f, "{}", generation), + Generation::Last => write!(f, "Last"), + } + } +} + #[cfg(test)] mod test { use super::Generation; diff --git a/air/src/execution_step/errors/catchable_errors.rs b/air/src/execution_step/errors/catchable_errors.rs index 2460290b..9eb60189 100644 --- a/air/src/execution_step/errors/catchable_errors.rs +++ b/air/src/execution_step/errors/catchable_errors.rs @@ -16,7 +16,6 @@ use super::Joinable; use super::LastErrorAffectable; -use super::Stream; use crate::execution_step::execution_context::LastErrorObjectError; use crate::execution_step::lambda_applier::LambdaError; use crate::JValue; @@ -75,10 +74,6 @@ pub enum CatchableError { #[error(transparent)] LambdaApplierError(#[from] LambdaError), - /// Errors occurred while insertion of a value inside stream that doesn't have corresponding generation. - #[error("stream {0:?} doesn't have generation with number {1}, probably a supplied to the interpreter data is corrupted")] - StreamDontHaveSuchGeneration(Stream, usize), - /// This error type is produced by a fail instruction that tries to throw a scalar that have inappropriate type. #[error(transparent)] InvalidLastErrorObjectError(#[from] LastErrorObjectError), diff --git a/air/src/execution_step/errors/uncatchable_errors.rs b/air/src/execution_step/errors/uncatchable_errors.rs index 0ebf5c54..6aaba00a 100644 --- a/air/src/execution_step/errors/uncatchable_errors.rs +++ b/air/src/execution_step/errors/uncatchable_errors.rs @@ -14,6 +14,8 @@ * limitations under the License. */ +use super::Stream; +use crate::execution_step::Generation; use crate::JValue; use crate::ToErrorCode; @@ -23,6 +25,7 @@ use air_interpreter_data::ValueRef; use air_trace_handler::merger::MergerApResult; use air_trace_handler::GenerationCompatificationError; use air_trace_handler::TraceHandlerError; + use strum::IntoEnumIterator; use strum_macros::EnumDiscriminants; use strum_macros::EnumIter; @@ -99,6 +102,13 @@ pub enum UncatchableError { /// and not having any CID is considered a non-catching error. #[error("{0} for CID {1:?} not found")] ValueForCidNotFound(&'static str, String), + + /// Errors occurred while insertion of a value inside stream that doesn't have corresponding generation. + #[error( + "stream doesn't have generation with number {generation}, supplied to the interpreter data is corrupted,\n\ + stream is {stream:?}" + )] + StreamDontHaveSuchGeneration { stream: Stream, generation: Generation }, } impl ToErrorCode for UncatchableError {