2021-08-24 16:14:15 +03:00
/*
* Copyright 2021 Fluence Labs Limited
*
* Licensed under the Apache License , Version 2.0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http ://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
use super ::call_merger ::ValueType ;
use super ::ApResult ;
use super ::CallResult ;
use super ::ExecutedState ;
use super ::FoldResult ;
use super ::KeeperError ;
use super ::Value ;
2022-08-26 00:43:43 +03:00
use air_interpreter_data ::CanonResult ;
2022-06-10 08:29:56 +03:00
use air_interpreter_data ::TracePos ;
2021-08-24 16:14:15 +03:00
use thiserror ::Error as ThisError ;
/// Errors arose out of merging previous data with a new.
#[ derive(ThisError, Debug) ]
2021-10-05 14:07:38 +03:00
pub enum MergeError {
2021-08-24 16:14:15 +03:00
/// Errors occurred when previous and current executed states are incompatible.
#[ error( " previous and current data have incompatible states: '{0:?}' '{1:?}' " ) ]
IncompatibleExecutedStates ( ExecutedState , ExecutedState ) ,
/// Merger was expected to see other state that was obtained from one of traces
/// (the other state was absent).
#[ error( " state from {1} `{0:?}` is incompatible with expected {2} " ) ]
DifferentExecutedStateExpected ( ExecutedState , DataType , & 'static str ) ,
2021-09-20 14:49:20 +03:00
#[ error(transparent) ]
2021-08-24 16:14:15 +03:00
KeeperError ( #[ from ] KeeperError ) ,
2021-09-20 14:49:20 +03:00
#[ error(transparent) ]
2021-08-24 16:14:15 +03:00
IncorrectApResult ( #[ from ] ApResultError ) ,
2021-09-20 14:49:20 +03:00
#[ error(transparent) ]
2021-08-24 16:14:15 +03:00
IncorrectCallResult ( #[ from ] CallResultError ) ,
2021-09-20 14:49:20 +03:00
2022-08-26 00:43:43 +03:00
#[ error(transparent) ]
IncorrectCanonResult ( #[ from ] CanonResultError ) ,
2021-09-20 14:49:20 +03:00
#[ error(transparent) ]
IncorrectFoldResult ( #[ from ] FoldResultError ) ,
2021-08-24 16:14:15 +03:00
}
#[ derive(ThisError, Debug) ]
2021-10-05 14:07:38 +03:00
pub enum ApResultError {
2021-08-24 16:14:15 +03:00
/// 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) ]
2021-10-05 14:07:38 +03:00
pub enum CallResultError {
2021-08-24 16:14:15 +03:00
#[ error( " values in call results are not equal: {prev_value:?} != {current_value:?} " ) ]
ValuesNotEqual { prev_value : Value , current_value : Value } ,
/// Errors occurred when previous and current call results are incompatible.
#[ error( " previous and current call results are incompatible: '{prev_call:?}' '{current_call:?}' " ) ]
IncompatibleCallResults {
prev_call : CallResult ,
current_call : CallResult ,
} ,
#[ error( " air scripts has the following value type '{air_type}' while data other '{data_value:?}' " ) ]
DataNotMatchAIR { air_type : String , data_value : Value } ,
}
2022-08-26 00:43:43 +03:00
#[ derive(ThisError, Debug) ]
pub enum CanonResultError {
#[ error( " canon results have different length: {prev_canon_result:?} != {current_canon_result:?} " ) ]
LensNotEqual {
prev_canon_result : CanonResult ,
current_canon_result : CanonResult ,
} ,
#[ error( " canon results {prev_canon_result:?} {current_canon_result:?} at position {position} points to incompatible execution states: {prev_state:?} {current_state:?} " ) ]
IncompatibleState {
prev_canon_result : CanonResult ,
current_canon_result : CanonResult ,
prev_state : Option < ExecutedState > ,
current_state : Option < ExecutedState > ,
position : usize ,
} ,
#[ error( " position {position} from canon result {canon_result:?} hasn't been met yet " ) ]
NotMetPosition {
canon_result : CanonResult ,
position : TracePos ,
} ,
}
2021-09-20 14:49:20 +03:00
#[ derive(ThisError, Debug) ]
2021-10-05 14:07:38 +03:00
pub enum FoldResultError {
2021-09-20 14:49:20 +03:00
#[ error( " the first {count} subtrace descriptors lens of fold {fold_result:?} overflows " ) ]
SubtraceLenOverflow { fold_result : FoldResult , count : usize } ,
/// There are several lores with the same value_pos.
#[ error( " {0:?} contains several subtraces with the same value_pos {1} " ) ]
2022-06-10 08:29:56 +03:00
SeveralRecordsWithSamePos ( FoldResult , TracePos ) ,
2021-09-20 14:49:20 +03:00
/// Errors occurred when one of the fold subtrace lore doesn't contain 2 descriptors.
#[ error( " fold contains {0} sublore descriptors, but 2 is expected " ) ]
FoldIncorrectSubtracesCount ( usize ) ,
}
2021-08-24 16:14:15 +03:00
impl MergeError {
// shouldn't be called with both Nones
pub ( crate ) fn incompatible_states (
prev_state : Option < ExecutedState > ,
current_state : Option < ExecutedState > ,
expected_state : & 'static str ,
) -> Self {
match ( prev_state , current_state ) {
( Some ( prev_state ) , Some ( current_state ) ) = > {
MergeError ::IncompatibleExecutedStates ( prev_state , current_state )
}
( None , Some ( current_state ) ) = > {
MergeError ::DifferentExecutedStateExpected ( current_state , DataType ::Current , expected_state )
}
( Some ( prev_state ) , None ) = > {
MergeError ::DifferentExecutedStateExpected ( prev_state , DataType ::Previous , expected_state )
}
( None , None ) = > unreachable! ( " shouldn't be called with both None " ) ,
}
}
}
// these impl methods allow construction of MergeError and are used to make code more clean
impl CallResultError {
pub ( crate ) fn not_equal_values ( prev_value : Value , current_value : Value ) -> MergeError {
let call_result_error = CallResultError ::ValuesNotEqual {
prev_value ,
current_value ,
} ;
MergeError ::IncorrectCallResult ( call_result_error )
}
pub ( crate ) fn incompatible_calls ( prev_call : CallResult , current_call : CallResult ) -> MergeError {
let call_result_error = CallResultError ::IncompatibleCallResults {
prev_call ,
current_call ,
} ;
MergeError ::IncorrectCallResult ( call_result_error )
}
pub ( crate ) fn data_not_match ( data_value : Value , air_type : ValueType < '_ > ) -> MergeError {
let air_type = air_type . to_string ( ) ;
let call_result_error = CallResultError ::DataNotMatchAIR { air_type , data_value } ;
MergeError ::IncorrectCallResult ( call_result_error )
}
}
2022-08-26 00:43:43 +03:00
impl CanonResultError {
pub ( crate ) fn different_lens ( prev_canon_result : CanonResult , current_canon_result : CanonResult ) -> Self {
Self ::LensNotEqual {
prev_canon_result ,
current_canon_result ,
}
}
pub ( crate ) fn incompatible_state (
prev_canon_result : CanonResult ,
current_canon_result : CanonResult ,
prev_state : Option < ExecutedState > ,
current_state : Option < ExecutedState > ,
position : usize ,
) -> Self {
Self ::IncompatibleState {
prev_canon_result ,
current_canon_result ,
prev_state ,
current_state ,
position ,
}
}
pub ( crate ) fn not_met_position ( canon_result : CanonResult , position : TracePos ) -> Self {
Self ::NotMetPosition { canon_result , position }
}
}
2021-08-24 16:14:15 +03:00
#[ derive(Clone, Copy, Debug) ]
pub enum DataType {
Previous ,
Current ,
}
use std ::fmt ;
impl fmt ::Display for DataType {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
match self {
DataType ::Previous = > write! ( f , " previous " ) ,
DataType ::Current = > write! ( f , " current " ) ,
}
}
}