fix(aquavm): temporary fix entire value in canon (#358)

This commit is contained in:
Mike Voronov 2022-10-10 22:15:28 +03:00 committed by GitHub
parent 076045124c
commit eafdec5d86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 128 additions and 192 deletions

View File

@ -40,7 +40,7 @@ jobs:
uses: fluencelabs/fluence-js/.github/workflows/tests.yml@master
with:
avm-version: ${{ needs.snapshot.outputs.avm-version }}
avm-version: "${{ needs.snapshot.outputs.avm-version }}"
fluence-js-snapshot:
name: "fluence-js"
@ -49,7 +49,7 @@ jobs:
uses: fluencelabs/fluence-js/.github/workflows/snapshot.yml@master
with:
avm-version: ${{ needs.snapshot.outputs.avm-version }}
avm-version: "${{ needs.snapshot.outputs.avm-version }}"
aqua-snapshot:
name: "aqua"
@ -58,7 +58,7 @@ jobs:
uses: fluencelabs/aqua/.github/workflows/snapshot.yml@main
with:
fluence-js-version: ${{ needs.fluence-js-snapshot.outputs.fluence-js-version }}
fluence-js-version: "${{ needs.fluence-js-snapshot.outputs.fluence-js-version }}"
aqua-playground:
needs:
@ -68,9 +68,9 @@ jobs:
uses: fluencelabs/aqua-playground/.github/workflows/tests.yml@master
with:
fluence-js-version: ${{ needs.fluence-js-snapshot.outputs.fluence-js-version }}
aqua-version: ${{ needs.aqua-snapshot.outputs.aqua-version }}
rust-peer-image: ${{ needs.rust-peer.outputs.rust-peer-image }}
fluence-js-version: "${{ needs.fluence-js-snapshot.outputs.fluence-js-version }}"
aqua-version: "${{ needs.aqua-snapshot.outputs.aqua-version }}"
rust-peer-image: "${{ needs.rust-peer.outputs.rust-peer-image }}"
registry:
needs:
@ -79,7 +79,7 @@ jobs:
uses: fluencelabs/registry/.github/workflows/tests.yml@main
with:
aqua-version: ${{ needs.aqua-snapshot.outputs.aqua-version }}
rust-peer-image: ${{ needs.rust-peer.outputs.rust-peer-image }}
aqua-version: "${{ needs.aqua-snapshot.outputs.aqua-version }}"
rust-peer-image: "${{ needs.rust-peer.outputs.rust-peer-image }}"
# uncomment and change to branch name to run against
# ref: some-branch
# ref: show-aqua-version

View File

@ -18,15 +18,14 @@ use super::ExecutionCtx;
use super::ExecutionResult;
use super::TraceHandler;
use crate::execution_step::boxed_value::CanonStream;
use crate::execution_step::Generation;
use crate::execution_step::Stream;
use crate::log_instruction;
use crate::trace_to_exec_err;
use crate::ExecutionError;
use crate::JValue;
use crate::UncatchableError;
use air_interpreter_data::CanonResult;
use air_interpreter_data::TracePos;
use air_parser::ast;
use air_trace_handler::merger::MergerCanonResult;
@ -39,8 +38,8 @@ impl<'i> super::ExecutableInstruction<'i> for ast::Canon<'i> {
let canon_result = trace_to_exec_err!(trace_ctx.meet_canon_start(), self)?;
match canon_result {
MergerCanonResult::CanonResult { stream_elements_pos } => {
handle_seen_canon(self, stream_elements_pos, exec_ctx, trace_ctx)
MergerCanonResult::CanonResult { canonicalized_element } => {
handle_seen_canon(self, canonicalized_element, exec_ctx, trace_ctx)
}
MergerCanonResult::Empty => handle_unseen_canon(self, exec_ctx, trace_ctx),
}
@ -49,17 +48,22 @@ impl<'i> super::ExecutableInstruction<'i> for ast::Canon<'i> {
fn handle_seen_canon(
ast_canon: &ast::Canon<'_>,
stream_elements_pos: Vec<TracePos>,
se_canon_stream: JValue,
exec_ctx: &mut ExecutionCtx<'_>,
trace_ctx: &mut TraceHandler,
) -> ExecutionResult<()> {
let canon_stream = create_canon_stream_from_pos(&stream_elements_pos, ast_canon, exec_ctx)?;
let stream_with_positions = StreamWithPositions {
let canon_stream = serde_json::from_value(se_canon_stream.clone()).map_err(|de_error| {
ExecutionError::Uncatchable(UncatchableError::InvalidCanonStreamInData {
canonicalized_stream: se_canon_stream.clone(),
de_error,
})
})?;
let canon_stream_with_se = StreamWithSerializedView {
canon_stream,
stream_elements_pos,
se_canon_stream,
};
epilog(ast_canon.canon_stream.name, stream_with_positions, exec_ctx, trace_ctx)
epilog(ast_canon.canon_stream.name, canon_stream_with_se, exec_ctx, trace_ctx)
}
fn handle_unseen_canon(
@ -85,72 +89,43 @@ fn handle_unseen_canon(
epilog(ast_canon.canon_stream.name, stream_with_positions, exec_ctx, trace_ctx)
}
fn create_canon_stream_from_pos(
stream_elements_pos: &[TracePos],
ast_canon: &ast::Canon<'_>,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<CanonStream> {
let stream = get_stream_or_default(ast_canon, exec_ctx);
let values = stream_elements_pos
.iter()
.map(|&position| {
stream
.get_value_by_pos(position)
.ok_or(ExecutionError::Uncatchable(UncatchableError::VariableNotFoundByPos(
position,
)))
.cloned()
})
.collect::<Result<Vec<_>, _>>()?;
let peer_id = crate::execution_step::air::resolve_to_string(&ast_canon.peer_pk, exec_ctx)?;
let canon_stream = CanonStream::new(values, peer_id);
Ok(canon_stream)
}
fn epilog(
canon_stream_name: &str,
stream_with_positions: StreamWithPositions,
stream_with_positions: StreamWithSerializedView,
exec_ctx: &mut ExecutionCtx<'_>,
trace_ctx: &mut TraceHandler,
) -> ExecutionResult<()> {
let StreamWithPositions {
let StreamWithSerializedView {
canon_stream,
stream_elements_pos,
se_canon_stream,
} = stream_with_positions;
exec_ctx
.scalars
.set_canon_value(canon_stream_name, canon_stream)
.map(|_| ())?;
trace_ctx.meet_canon_end(CanonResult::new(stream_elements_pos));
trace_ctx.meet_canon_end(CanonResult::new(se_canon_stream));
Ok(())
}
struct StreamWithPositions {
struct StreamWithSerializedView {
canon_stream: CanonStream,
stream_elements_pos: Vec<TracePos>,
se_canon_stream: JValue,
}
fn create_canon_stream_from_name(
ast_canon: &ast::Canon<'_>,
peer_id: String,
exec_ctx: &ExecutionCtx<'_>,
) -> ExecutionResult<StreamWithPositions> {
) -> ExecutionResult<StreamWithSerializedView> {
let stream = get_stream_or_default(ast_canon, exec_ctx);
let canon_stream = CanonStream::from_stream(stream.as_ref(), peer_id);
let stream_elements_pos = stream
.iter(Generation::Last)
// it's always safe to iter over all generations
.unwrap()
.map(|value| value.trace_pos)
.collect::<Vec<_>>();
let se_canon_stream = serde_json::to_value(&canon_stream).expect("default serialized shouldn't fail");
let result = StreamWithPositions {
let result = StreamWithSerializedView {
canon_stream,
stream_elements_pos,
se_canon_stream,
};
Ok(result)

View File

@ -20,12 +20,14 @@ use crate::execution_step::Generation;
use crate::JValue;
use polyplets::SecurityTetraplet;
use serde::Deserialize;
use serde::Serialize;
use std::rc::Rc;
/// Canon stream is a value type lies between a scalar and a stream, it has the same algebra as
/// scalars, and represent a stream fixed at some execution point.
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
pub struct CanonStream {
values: Vec<ValueAggregate>,
// tetraplet is needed to handle adding canon streams as a whole to a stream
@ -33,15 +35,6 @@ pub struct CanonStream {
}
impl CanonStream {
pub(crate) fn new(values: Vec<ValueAggregate>, peer_pk: String) -> Self {
// tetraplet is comprised only from peer_pk here
let tetraplet = SecurityTetraplet::new(peer_pk, "", "", "");
Self {
values,
tetraplet: Rc::new(tetraplet),
}
}
pub(crate) fn from_stream(stream: &Stream, peer_pk: String) -> Self {
// it's always possible to iter over all generations of a stream
let values = stream.iter(Generation::Last).unwrap().cloned().collect::<Vec<_>>();

View File

@ -156,6 +156,7 @@ impl Stream {
Some(JValue::Array(jvalue_array))
}
#[allow(dead_code)]
pub(crate) fn get_value_by_pos(&self, position: TracePos) -> Option<&ValueAggregate> {
let StreamValueLocation {
generation,

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
use crate::JValue;
use crate::ToErrorCode;
use air_interpreter_data::TracePos;
@ -83,6 +84,12 @@ pub enum UncatchableError {
/// as a hard error.
#[error("variable with position '{0}' wasn't defined during script execution")]
VariableNotFoundByPos(TracePos),
#[error("can't deserialize stream {canonicalized_stream:?} with error: {de_error}")]
InvalidCanonStreamInData {
canonicalized_stream: JValue,
de_error: serde_json::Error,
},
}
impl ToErrorCode for UncatchableError {

View File

@ -265,7 +265,9 @@ fn canon_with_empty_behaviour() {
let expected_trace = vec![
executed_state::par(1, 1),
executed_state::request_sent_by(peer_2_id),
executed_state::canon(vec![]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_2_id", "service_id": ""}, "values": []}),
),
];
assert_eq!(actual_trace, expected_trace);

View File

@ -133,7 +133,12 @@ fn length_functor_for_canon_stream() {
let expected_trace = vec![
executed_state::ap(0),
executed_state::ap(0),
executed_state::canon(vec![0.into(), 1.into()]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "init_peer_id", "service_id": ""},
"values": [{"result": 1, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "init_peer_id", "service_id": ""}, "trace_pos": 0},
{"result": 1, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "init_peer_id", "service_id": ""}, "trace_pos": 1}
]} ),
),
executed_state::scalar_number(2),
];
assert_eq!(actual_trace, expected_trace);
@ -157,7 +162,12 @@ fn length_functor_for_empty_canon_stream() {
let result = executor.execute_one(init_peer_id).unwrap();
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::canon(vec![]), executed_state::scalar_number(0)];
let expected_trace = vec![
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "init_peer_id", "service_id": ""}, "values": []} ),
),
executed_state::scalar_number(0),
];
assert_eq!(actual_trace, expected_trace);
}

View File

@ -236,7 +236,11 @@ fn ap_canon_stream_with_lambda() {
let expected_state = vec![
executed_state::stream_number(0, 0),
executed_state::stream_number(1, 1),
executed_state::canon(vec![0.into(), 1.into()]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": ""},
"values": [{"result": 0, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": ""}, "trace_pos": 0},
{"result": 1, "tetraplet": {"function_name": "some_function_name", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": "some_service_name"}, "trace_pos": 1}]}),
),
executed_state::ap(0),
executed_state::scalar(json!([1])),
];
@ -277,7 +281,11 @@ fn ap_canon_stream() {
let expected_state = vec![
executed_state::stream_number(0, 0),
executed_state::stream_number(1, 1),
executed_state::canon(vec![0.into(), 1.into()]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": ""},
"values": [{"result": 0, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": ""}, "trace_pos": 0},
{"result": 1, "tetraplet": {"function_name": "some_function_name", "json_path": "", "peer_pk": "vm_1_peer_id", "service_id": "some_service_name"}, "trace_pos": 1}]}),
),
executed_state::ap(0),
executed_state::scalar(json!([[0, 1]])),
];

View File

@ -18,7 +18,6 @@ use air_test_utils::prelude::*;
use fstrings::f;
use fstrings::format_args_f;
use pretty_assertions::assert_eq;
use std::ops::Deref;
@ -62,7 +61,14 @@ fn basic_canon() {
let result = checked_call_vm!(vm, <_>::default(), script, "", result.data);
let actual_state = &trace_from_result(&result)[6.into()];
let expected_state = executed_state::canon(vec![1.into(), 2.into(), 3.into(), 4.into(), 5.into()]);
let expected_state = executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "A", "service_id": ""},
"values": [{"result": "1", "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "A", "service_id": ""}, "trace_pos": 1},
{"result": "2", "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "A", "service_id": ""}, "trace_pos": 2},
{"result": "3", "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "A", "service_id": ""}, "trace_pos": 3},
{"result": "4", "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "A", "service_id": ""}, "trace_pos": 4},
{"result": "5", "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "A", "service_id": ""}, "trace_pos": 5}]}),
);
assert_eq!(actual_state, &expected_state);
}
@ -106,7 +112,11 @@ fn canon_fixes_stream_correct() {
executed_state::stream_number(2, 0),
executed_state::stream_number(3, 1),
executed_state::scalar_number(4),
executed_state::canon(vec![3.into(), 4.into()]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_3", "service_id": ""},
"values": [{"result": 2, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_2", "service_id": ""}, "trace_pos": 3},
{"result": 3, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_3", "service_id": ""}, "trace_pos": 4}]}),
),
executed_state::par(1, 1),
executed_state::scalar(json!([2, 3])),
executed_state::request_sent_by(peer_id_3),
@ -122,7 +132,11 @@ fn canon_fixes_stream_correct() {
executed_state::stream_number(2, 1),
executed_state::stream_number(3, 2),
executed_state::scalar_number(4),
executed_state::canon(vec![3.into(), 4.into()]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_3", "service_id": ""},
"values": [{"result": 2, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_2", "service_id": ""}, "trace_pos": 3},
{"result": 3, "tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_3", "service_id": ""}, "trace_pos": 4}]}),
),
executed_state::par(1, 1),
executed_state::scalar(json!([2, 3])),
executed_state::scalar(json!([2, 3])),
@ -228,12 +242,22 @@ fn canon_empty_stream() {
let result = checked_call_vm!(vm_1, <_>::default(), &script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::canon(vec![]), executed_state::scalar(json!([]))];
let expected_trace = vec![
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_1", "service_id": ""}, "values": []}),
),
executed_state::scalar(json!([])),
];
assert_eq!(actual_trace, expected_trace);
let result = checked_call_vm!(vm_2, <_>::default(), script, "", result.data);
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::canon(vec![]), executed_state::scalar(json!([]))];
let expected_trace = vec![
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id_1", "service_id": ""}, "values": []} ),
),
executed_state::scalar(json!([])),
];
assert_eq!(actual_trace, expected_trace);
}
@ -248,7 +272,9 @@ fn canon_empty_not_writable_stream() {
let result = checked_call_vm!(vm, <_>::default(), &script, "", "");
let actual_trace = trace_from_result(&result);
let expected_trace = vec![executed_state::canon(vec![])];
let expected_trace = vec![executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "peer_id", "service_id": ""}, "values": []} ),
)];
assert_eq!(actual_trace, expected_trace);
}
@ -281,7 +307,9 @@ fn canon_over_later_defined_stream() {
let expected_trace = vec![
executed_state::par(1, 2),
executed_state::stream_number(1, 0),
executed_state::canon(vec![]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id_1", "service_id": ""},"values": []}),
),
executed_state::scalar(json!([])),
];
assert_eq!(actual_trace, expected_trace);

View File

@ -582,7 +582,9 @@ fn fold_scalar_seq_next_completes_with_null() {
executed_state::stream(service_result.clone(), 0),
executed_state::par(1, 0),
executed_state::stream(service_result.clone(), 0),
executed_state::canon(vec![]),
executed_state::canon(
json!({"tetraplet": {"function_name": "", "json_path": "", "peer_pk": "vm_peer_id", "service_id": ""}, "values": []}),
),
executed_state::scalar(service_result),
];
assert_eq!(actual_trace, expected_trace);

View File

@ -128,8 +128,7 @@ pub struct ApResult {
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct CanonResult {
#[serde(rename = "ids")]
pub stream_elements_pos: Vec<TracePos>,
pub canonicalized_element: JValue,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]

View File

@ -87,9 +87,9 @@ impl ApResult {
}
impl CanonResult {
pub fn new(stream_elements_pos: Vec<TracePos>) -> Self {
pub fn new(canonicalized_element: JValue) -> Self {
Self {
stream_elements_pos,
canonicalized_element,
}
}
}
@ -129,8 +129,8 @@ impl std::fmt::Display for ExecutedState {
Ap(ap) => {
write!(f, "ap: _ -> {:?}", ap.res_generations)
}
Canon(canon) => {
write!(f, "canon {:?}", canon.stream_elements_pos)
Canon(_) => {
write!(f, "canon [<object>]")
}
}
}

View File

@ -137,7 +137,7 @@ pub fn ap(generation: u32) -> ExecutedState {
ExecutedState::Ap(ap_result)
}
pub fn canon(stream_elements_pos: Vec<TracePos>) -> ExecutedState {
let canon_result = CanonResult::new(stream_elements_pos);
pub fn canon(canonicalized_element: JValue) -> ExecutedState {
let canon_result = CanonResult::new(canonicalized_element);
ExecutedState::Canon(canon_result)
}

View File

@ -17,7 +17,7 @@
use super::*;
use crate::merger::errors::CanonResultError;
use bimap::BiHashMap;
use serde_json::Value as JValue;
const EXPECTED_STATE_NAME: &str = "canon";
@ -28,8 +28,7 @@ pub enum MergerCanonResult {
/// There was a state in at least one of the contexts. If there were two states in
/// both contexts, they were successfully merged.
/// Positions correspond to a new data trace.
CanonResult { stream_elements_pos: Vec<TracePos> },
CanonResult { canonicalized_element: JValue },
}
pub(crate) fn try_merge_next_state_as_canon(data_keeper: &mut DataKeeper) -> MergeResult<MergerCanonResult> {
@ -39,13 +38,9 @@ pub(crate) fn try_merge_next_state_as_canon(data_keeper: &mut DataKeeper) -> Mer
let current_state = data_keeper.current_slider_mut().next_state();
match (prev_state, current_state) {
(Some(Canon(prev_canon)), Some(Canon(current_canon))) => {
prepare_both_canon_result(&prev_canon, &current_canon, data_keeper)
}
(Some(Canon(prev_canon)), None) => prepare_single_canon_result(&prev_canon, &data_keeper.new_to_prev_pos),
(None, Some(Canon(current_canon))) => {
prepare_single_canon_result(&current_canon, &data_keeper.new_to_current_pos)
}
(Some(Canon(prev_canon)), Some(Canon(current_canon))) => prepare_both_canon_result(prev_canon, &current_canon),
(Some(Canon(prev_canon)), None) => prepare_single_canon_result(prev_canon),
(None, Some(Canon(current_canon))) => prepare_single_canon_result(current_canon),
(None, None) => Ok(MergerCanonResult::Empty),
(prev_state, current_state) => Err(MergeError::incompatible_states(
prev_state,
@ -56,78 +51,29 @@ pub(crate) fn try_merge_next_state_as_canon(data_keeper: &mut DataKeeper) -> Mer
}
fn prepare_both_canon_result(
prev_canon_result: &CanonResult,
prev_canon_result: CanonResult,
current_canon_result: &CanonResult,
data_keeper: &DataKeeper,
) -> MergeResult<MergerCanonResult> {
check_canon_results(prev_canon_result, current_canon_result, data_keeper)
.map_err(MergeError::IncorrectCanonResult)?;
prepare_single_canon_result(prev_canon_result, &data_keeper.new_to_prev_pos)
check_canon_results(&prev_canon_result, current_canon_result).map_err(MergeError::IncorrectCanonResult)?;
prepare_single_canon_result(prev_canon_result)
}
fn prepare_single_canon_result(
canon_result: &CanonResult,
new_to_other_pos: &BiHashMap<TracePos, TracePos>,
) -> MergeResult<MergerCanonResult> {
let new_positions = canon_result
.stream_elements_pos
.iter()
.map(|pos| {
new_to_other_pos
.get_by_right(pos)
.cloned()
.ok_or_else(|| CanonResultError::not_met_position(canon_result.clone(), *pos))
})
.collect::<Result<Vec<_>, _>>()?;
fn prepare_single_canon_result(canon_result: CanonResult) -> MergeResult<MergerCanonResult> {
Ok(MergerCanonResult::CanonResult {
stream_elements_pos: new_positions,
canonicalized_element: canon_result.canonicalized_element,
})
}
fn check_canon_results(
prev_canon_result: &CanonResult,
current_canon_result: &CanonResult,
data_keeper: &DataKeeper,
) -> Result<(), CanonResultError> {
if prev_canon_result.stream_elements_pos.len() != current_canon_result.stream_elements_pos.len() {
return Err(CanonResultError::different_lens(
if prev_canon_result.canonicalized_element != current_canon_result.canonicalized_element {
return Err(CanonResultError::incompatible_state(
prev_canon_result.clone(),
current_canon_result.clone(),
));
}
let prev_slider = data_keeper.prev_slider();
let current_slider = data_keeper.current_slider();
for (position, (prev_idx, current_idx)) in prev_canon_result
.stream_elements_pos
.iter()
.zip(current_canon_result.stream_elements_pos.iter())
.enumerate()
{
let prev_state = prev_slider.state_at_position(*prev_idx);
let current_state = current_slider.state_at_position(*current_idx);
match (prev_state, current_state) {
(Some(ExecutedState::Call(prev_call_result)), Some(ExecutedState::Call(current_call_result)))
if prev_call_result == current_call_result =>
{
continue;
}
(Some(ExecutedState::Ap(_)), Some(ExecutedState::Ap(_))) => {
continue;
}
_ => {
return Err(CanonResultError::incompatible_state(
prev_canon_result.clone(),
current_canon_result.clone(),
prev_state.cloned(),
current_state.cloned(),
position,
))
}
}
}
Ok(())
}

View File

@ -75,25 +75,10 @@ pub enum CallResultError {
#[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:?}")]
#[error("canon results {prev_canon_result:?} {current_canon_result:?} points to incompatible execution states")]
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,
},
}
@ -155,32 +140,12 @@ impl CallResultError {
}
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 {
pub(crate) fn incompatible_state(prev_canon_result: CanonResult, current_canon_result: CanonResult) -> 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 }
}
}
#[derive(Clone, Copy, Debug)]