feat(execution-engine)!: make StreamDontHaveSuchGeneration uncatchable… (#492)

`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.
This commit is contained in:
Mike Voronov 2023-03-02 22:22:13 +03:00 committed by GitHub
parent 4a35dbffb7
commit 95b2d154ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 32 deletions

16
Cargo.lock generated
View File

@ -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",

View File

@ -94,18 +94,15 @@ impl<'stream> StreamJvaluableIngredients<'stream> {
}
pub(self) fn iter(&self) -> ExecutionResult<StreamIter<'_>> {
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()),
}
}
}

View File

@ -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<u32> {
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;

View File

@ -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),

View File

@ -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 {