diff --git a/air/tests/test_module/issues/issue_295.rs b/air/tests/test_module/issues/issue_295.rs new file mode 100644 index 00000000..ee00f499 --- /dev/null +++ b/air/tests/test_module/issues/issue_295.rs @@ -0,0 +1,52 @@ +/* + * Copyright 2022 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 air::UncatchableError; +use air_test_utils::prelude::*; +use air_trace_handler::MergeError; +use air_trace_handler::TraceHandlerError; + +use std::rc::Rc; + +#[test] +// test for github.com/fluencelabs/aquavm/issues/295 +fn issue_295() { + let vm_peer_id = "vm_peer_id"; + let mut vm = create_avm(echo_call_service(), vm_peer_id); + + let script = f!(r#" + (seq + (call "{vm_peer_id}" ("" "") [] scalar) + (ap scalar $stream) + ) + "#); + + let prev_trace = vec![executed_state::scalar_string(""), executed_state::ap(Some(1))]; + let current_trace = vec![executed_state::scalar_string(""), executed_state::scalar_string("")]; + let prev_data = raw_data_from_trace(prev_trace); + let current_data = raw_data_from_trace(current_trace); + let result = call_vm!(vm, <_>::default(), &script, prev_data, current_data); + + let expected_error = UncatchableError::TraceError { + trace_error: TraceHandlerError::MergeError(MergeError::IncompatibleExecutedStates( + ExecutedState::Ap(ApResult::new(vec![1])), + ExecutedState::Call(CallResult::Executed(Value::Scalar(Rc::new(json!(""))))), + )), + instruction: "ap scalar $stream".to_string(), + }; + + assert!(check_error(&result, expected_error)); +} diff --git a/air/tests/test_module/issues/mod.rs b/air/tests/test_module/issues/mod.rs index 52bc0a85..8c86a629 100644 --- a/air/tests/test_module/issues/mod.rs +++ b/air/tests/test_module/issues/mod.rs @@ -26,3 +26,4 @@ mod issue_216; mod issue_221; mod issue_222; mod issue_241; +mod issue_295; diff --git a/crates/air-lib/air-parser/src/parser/air.rs b/crates/air-lib/air-parser/src/parser/air.rs index e1be589b..c2342ed9 100644 --- a/crates/air-lib/air-parser/src/parser/air.rs +++ b/crates/air-lib/air-parser/src/parser/air.rs @@ -1,5 +1,5 @@ -// auto-generated: "lalrpop 0.19.7" -// sha3: bd63e614fda5f25993172a583a29b4959c0d2cdba69f5e5343f48f72b98ee +// auto-generated: "lalrpop 0.19.8" +// sha3: bd630e614fda5f25993172a583a29b4959c0d20cdba69f5e05343f48f72b98ee use crate::ast::*; use crate::parser::ParserError; use crate::parser::VariableValidator; diff --git a/crates/air-lib/lambda/parser/src/parser/va_lambda.rs b/crates/air-lib/lambda/parser/src/parser/va_lambda.rs index c74ee0ac..3ed2f46a 100644 --- a/crates/air-lib/lambda/parser/src/parser/va_lambda.rs +++ b/crates/air-lib/lambda/parser/src/parser/va_lambda.rs @@ -1,5 +1,5 @@ -// auto-generated: "lalrpop 0.19.7" -// sha3: 517c7e1bd341e1434f9ffcbf3c72151e4b928e7befd38c6ee2e3e734565b +// auto-generated: "lalrpop 0.19.8" +// sha3: 517c7e1bd341e104034f9ffcbf3c072151e4b9028e7befd38c6ee2e3e734565b use crate::ValueAccessor; use crate::parser::lexer::LexerError; use crate::parser::lexer::Token; diff --git a/crates/air-lib/trace-handler/src/merger/ap_merger.rs b/crates/air-lib/trace-handler/src/merger/ap_merger.rs index 101842b3..6f3061f3 100644 --- a/crates/air-lib/trace-handler/src/merger/ap_merger.rs +++ b/crates/air-lib/trace-handler/src/merger/ap_merger.rs @@ -36,7 +36,7 @@ pub(crate) fn try_merge_next_state_as_ap(data_keeper: &mut DataKeeper) -> MergeR let current_state = data_keeper.current_slider_mut().next_state(); match (prev_state, current_state) { - (Some(Ap(prev_ap)), Some(_)) => prepare_merge_result(Some(prev_ap), Both, data_keeper), + (Some(Ap(prev_ap)), Some(Ap(_))) => prepare_merge_result(Some(prev_ap), Both, data_keeper), (Some(Ap(prev_ap)), None) => prepare_merge_result(Some(prev_ap), Previous, data_keeper), // check that current state is Ap, but it's impossible to use it, because prev_data // could not have streams with such generations