From 680d6236b1f4387d7a124f989f25055bca7c3f67 Mon Sep 17 00:00:00 2001 From: Mike Voronov Date: Tue, 6 Jul 2021 13:54:12 +0300 Subject: [PATCH] Improve invalid executed state error (#121) * improve invalid executed state error * add changelog --- CHANGELOG.md | 8 ++ Cargo.lock | 82 +++++++++++---------- air/src/execution/air/call.rs | 2 +- air/src/execution/air/call/resolved_call.rs | 13 +++- air/src/execution/air/call/utils.rs | 14 +++- air/src/execution/air/par.rs | 13 +++- air/src/execution/air/xor.rs | 2 +- air/src/execution/errors.rs | 29 +++++++- 8 files changed, 111 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc683655..e238fcd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## Version 0.10.8 (2021-07-06) + +- improve the error message of the invalid executed state error ([PR 121](https://github.com/fluencelabs/aquavm/pull/121)) + +## Version 0.10.7 (2021-07-01) + +- add support of a particle file vault ([PR 120](https://github.com/fluencelabs/aquavm/pull/120)) + ## Version 0.10.6 (2021-06-10) - fixed the error message for incorrect json path in `%last_error%` ([PR 119](https://github.com/fluencelabs/aquavm/pull/119)) diff --git a/Cargo.lock b/Cargo.lock index 161f643e..af960ad9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" +checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" [[package]] name = "array_tool" @@ -253,11 +253,11 @@ dependencies = [ [[package]] name = "cast" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57cdfa5d50aad6cb4d44dcab6101a7f79925bd59d82ca42f38a9856a28865374" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" dependencies = [ - "rustc_version 0.3.3", + "rustc_version 0.4.0", ] [[package]] @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "erased-serde" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5b36e6f2295f393f44894c6031f67df4d185b984cd54d08f768ce678007efcd" +checksum = "3de9ad4541d99dc22b59134e7ff8dc3d6c988c89ecd7324bf10a8362b07a2afa" dependencies = [ "serde", ] @@ -830,9 +830,9 @@ checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "heck" @@ -845,9 +845,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -875,9 +875,9 @@ checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" [[package]] name = "indexmap" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", "hashbrown", @@ -1038,9 +1038,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.96" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5600b4e6efc5421841a2138a6b082e07fe12f9aaa12783d50e5d13325b26b4fc" +checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "lock_api" @@ -1105,9 +1105,9 @@ dependencies = [ [[package]] name = "marine-it-parser" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6be3cfa1905a63ebf925c4efc605cdd121ddfe86809aaec16ec9fe32443b4423" +checksum = "19a6606e472587b2e7b759b16d037a4ea951facc2a6650f668f22403978c2442" dependencies = [ "anyhow", "itertools 0.10.1", @@ -1163,9 +1163,9 @@ dependencies = [ [[package]] name = "marine-module-interface" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4920ea983e51f8f560e09d9d554035cd4ecd7d60940b352637c8c4c9d02f865" +checksum = "d8a5936273bebb523ed169863282dbc19fc66bb983c7031c5b8b0556584f2401" dependencies = [ "anyhow", "itertools 0.10.1", @@ -1320,9 +1320,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "oorandom" @@ -1399,7 +1399,7 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.8", + "redox_syscall 0.2.9", "smallvec", "winapi", ] @@ -1459,15 +1459,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" +checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" [[package]] name = "plotters-svg" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" +checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" dependencies = [ "plotters-backend", ] @@ -1583,9 +1583,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" +checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" dependencies = [ "bitflags", ] @@ -1597,7 +1597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ "getrandom 0.2.3", - "redox_syscall 0.2.8", + "redox_syscall 0.2.9", ] [[package]] @@ -1634,11 +1634,11 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 0.11.0", + "semver 1.0.3", ] [[package]] @@ -1692,6 +1692,12 @@ dependencies = [ "semver-parser 0.10.2", ] +[[package]] +name = "semver" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f3aac57ee7f3272d8395c6e4f502f434f0e289fcd62876f70daa008c20dcabe" + [[package]] name = "semver-parser" version = "0.7.0" @@ -1852,18 +1858,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2", "quote", @@ -1947,9 +1953,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" diff --git a/air/src/execution/air/call.rs b/air/src/execution/air/call.rs index 8494c130..4b79d568 100644 --- a/air/src/execution/air/call.rs +++ b/air/src/execution/air/call.rs @@ -44,7 +44,7 @@ impl<'i> super::ExecutableInstruction<'i> for Call<'i> { })?; let triplet = resolved_call.as_triplet(); - joinable_call!(resolved_call.execute(exec_ctx, trace_ctx), exec_ctx).map_err(|e| { + joinable_call!(resolved_call.execute(exec_ctx, trace_ctx, &self), exec_ctx).map_err(|e| { let tetraplet = SecurityTetraplet::from_triplet(triplet); set_last_error(self, exec_ctx, e.clone(), Some(tetraplet)); diff --git a/air/src/execution/air/call/resolved_call.rs b/air/src/execution/air/call/resolved_call.rs index bab6a870..bc4406d7 100644 --- a/air/src/execution/air/call/resolved_call.rs +++ b/air/src/execution/air/call/resolved_call.rs @@ -67,12 +67,13 @@ impl<'i> ResolvedCall<'i> { self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx, + instruction: &Call<'i>, ) -> ExecutionResult<()> { use CallResult::Executed; use ExecutedState::Call; use ExecutionError::CallServiceResultDeError as DeError; - let should_execute = self.prepare_executed_state(exec_ctx, trace_ctx)?; + let should_execute = self.prepare_executed_state(exec_ctx, trace_ctx, instruction)?; if !should_execute { return Ok(()); } @@ -129,6 +130,7 @@ impl<'i> ResolvedCall<'i> { &self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx, + instruction: &Call<'i>, ) -> ExecutionResult { if trace_ctx.current_subtree_size == 0 { log::trace!( @@ -149,7 +151,14 @@ impl<'i> ResolvedCall<'i> { prev_state ); - handle_prev_state(&self.triplet, &self.output, prev_state, exec_ctx, trace_ctx) + handle_prev_state( + &self.triplet, + &self.output, + prev_state, + exec_ctx, + trace_ctx, + instruction, + ) } /// Prepare arguments of this call instruction by resolving and preparing their security tetraplets. diff --git a/air/src/execution/air/call/utils.rs b/air/src/execution/air/call/utils.rs index 368a01ab..4a712d7a 100644 --- a/air/src/execution/air/call/utils.rs +++ b/air/src/execution/air/call/utils.rs @@ -14,6 +14,7 @@ * limitations under the License. */ +use super::Call; use super::ExecutionCtx; use super::ExecutionError; use super::ExecutionResult; @@ -119,6 +120,7 @@ pub(super) fn handle_prev_state<'i>( prev_state: ExecutedState, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut ExecutionTraceCtx, + instruction: &Call<'i>, ) -> ExecutionResult { use CallResult::*; use ExecutedState::*; @@ -152,9 +154,13 @@ pub(super) fn handle_prev_state<'i>( Ok(false) } // state has inconsistent order - return a error, call shouldn't be executed - par_state @ Par(..) => exec_err!(ExecutionError::InvalidExecutedState( - String::from("call"), - par_state.clone(), - )), + par_state @ Par(..) => exec_err!(ExecutionError::InvalidExecutedState { + instruction: instruction.to_string(), + expected_state: "call", + actual_state: par_state.clone(), + current_trace: trace_ctx.current_trace.clone(), + new_trace: trace_ctx.new_trace.clone(), + current_subtree_size: trace_ctx.current_subtree_size, + }), } } diff --git a/air/src/execution/air/par.rs b/air/src/execution/air/par.rs index 42658175..aee57821 100644 --- a/air/src/execution/air/par.rs +++ b/air/src/execution/air/par.rs @@ -46,7 +46,7 @@ impl<'i> ExecutableInstruction<'i> for Par<'i> { log_instruction!(par, exec_ctx, trace_ctx); - let (left_subtree_size, right_subtree_size) = extract_subtree_sizes(trace_ctx)?; + let (left_subtree_size, right_subtree_size) = extract_subtree_sizes(trace_ctx, &self)?; let par_pos = trace_ctx.new_trace.len(); trace_ctx.new_trace.push_back(ExecutedState::par(0, 0)); @@ -66,7 +66,7 @@ impl<'i> ExecutableInstruction<'i> for Par<'i> { } } -fn extract_subtree_sizes(trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<(usize, usize)> { +fn extract_subtree_sizes(trace_ctx: &mut ExecutionTraceCtx, instruction: &Par<'_>) -> ExecutionResult<(usize, usize)> { use super::ExecutionError::InvalidExecutedState; if trace_ctx.current_subtree_size == 0 { @@ -84,7 +84,14 @@ fn extract_subtree_sizes(trace_ctx: &mut ExecutionTraceCtx) -> ExecutionResult<( // unwrap is safe here because of length's been checked match trace_ctx.current_trace.pop_front().unwrap() { ExecutedState::Par(ParResult(left, right)) => Ok((left, right)), - state => crate::exec_err!(InvalidExecutedState(String::from("par"), state)), + state => crate::exec_err!(InvalidExecutedState { + instruction: instruction.to_string(), + expected_state: "par", + actual_state: state, + current_trace: trace_ctx.current_trace.clone(), + new_trace: trace_ctx.new_trace.clone(), + current_subtree_size: trace_ctx.current_subtree_size, + }), } } diff --git a/air/src/execution/air/xor.rs b/air/src/execution/air/xor.rs index fa41830d..60df3af3 100644 --- a/air/src/execution/air/xor.rs +++ b/air/src/execution/air/xor.rs @@ -43,7 +43,7 @@ impl<'i> super::ExecutableInstruction<'i> for Xor<'i> { /// Returns true, if this execution error type should be caught by xor. fn is_catchable_by_xor(exec_error: &ExecutionError) -> bool { // this type of errors related to invalid data and should treat as hard errors. - !matches!(exec_error, ExecutionError::InvalidExecutedState(..)) + !matches!(exec_error, ExecutionError::InvalidExecutedState { .. }) } fn print_xor_log(e: &ExecutionError) { diff --git a/air/src/execution/errors.rs b/air/src/execution/errors.rs index 7b830ddd..b2338709 100644 --- a/air/src/execution/errors.rs +++ b/air/src/execution/errors.rs @@ -18,6 +18,7 @@ use super::Joinable; use crate::build_targets::CallServiceResult; use crate::contexts::execution::ResolvedCallResult; use crate::contexts::execution_trace::ExecutedState; +use crate::contexts::execution_trace::ExecutionTrace; use crate::JValue; use jsonpath_lib::JsonPathError; @@ -78,8 +79,30 @@ pub(crate) enum ExecutionError { MultipleFoldStates(String), /// Expected executed state of a different type. - #[error("invalid executed state: expected '{0}', but actual {1:?}")] - InvalidExecutedState(String, ExecutedState), + #[error( + r#" + ====================================================================== + Below is a crucial debug information, please send this to the Fluence Labs: + + invalid executed state error: + current instruction: {instruction}, + expected state: {expected_state}, + actual_state: '{actual_state}', + current_trace: '{current_trace:?}', + new_trace: '{new_trace:?}', + current_subtree_size: {current_subtree_size}, + + ====================================================================== + "# + )] + InvalidExecutedState { + instruction: String, + expected_state: &'static str, + actual_state: ExecutedState, + current_trace: ExecutionTrace, + new_trace: ExecutionTrace, + current_subtree_size: usize, + }, /// Errors encountered while shadowing non-scalar values. #[error("variable with name '{0}' can't be shadowed, shadowing is supported only for scalar values")] @@ -122,7 +145,7 @@ impl ExecutionError { MultipleValuesInJsonPath(_) => 10, FoldStateNotFound(_) => 11, MultipleFoldStates(_) => 12, - InvalidExecutedState(..) => 13, + InvalidExecutedState { .. } => 13, ShadowingError(_) => 14, MatchWithoutXorError => 15, MismatchWithoutXorError => 16,