sui_adapter_latest/
error.rs1use move_binary_format::{
5 errors::{Location, VMError},
6 file_format::FunctionDefinitionIndex,
7};
8use move_core_types::{
9 language_storage::ModuleId,
10 vm_status::{StatusCode, StatusType},
11};
12use sui_types::error::ExecutionError;
13use sui_types::execution_status::{ExecutionFailureStatus, MoveLocation, MoveLocationOpt};
14
15pub(crate) fn convert_vm_error_impl(
16 error: VMError,
17 abort_module_id_relocation_fn: &impl Fn(&ModuleId) -> ModuleId,
18 function_name_resolution_fn: &impl Fn(&ModuleId, FunctionDefinitionIndex) -> Option<String>,
19) -> ExecutionError {
20 let kind = match (error.major_status(), error.sub_status(), error.location()) {
21 (StatusCode::EXECUTED, _, _) => {
22 debug_assert!(false, "VmError shouldn't ever report successful execution");
24 ExecutionFailureStatus::VMInvariantViolation
25 }
26 (StatusCode::ABORTED, None, _) => {
27 debug_assert!(false, "No abort code");
28 ExecutionFailureStatus::VMInvariantViolation
30 }
31 (StatusCode::ABORTED, Some(code), Location::Module(id)) => {
32 let abort_location_id = abort_module_id_relocation_fn(id);
33 let offset = error.offsets().first().copied().map(|(f, i)| (f.0, i));
34 debug_assert!(offset.is_some(), "Move should set the location on aborts");
35 let (function, instruction) = offset.unwrap_or((0, 0));
36 let function_name = function_name_resolution_fn(id, FunctionDefinitionIndex(function));
37 ExecutionFailureStatus::MoveAbort(
38 MoveLocation {
39 module: abort_location_id,
40 function,
41 instruction,
42 function_name,
43 },
44 code,
45 )
46 }
47 (StatusCode::OUT_OF_GAS, _, _) => ExecutionFailureStatus::InsufficientGas,
48 (_, _, location) => match error.major_status().status_type() {
49 StatusType::Execution => {
50 debug_assert!(error.major_status() != StatusCode::ABORTED);
51 let location = match location {
52 Location::Module(id) => {
53 let offset = error.offsets().first().copied().map(|(f, i)| (f.0, i));
54 debug_assert!(
55 offset.is_some(),
56 "Move should set the location on all execution errors. Error {error}"
57 );
58 let (function, instruction) = offset.unwrap_or((0, 0));
59 let function_name =
60 function_name_resolution_fn(id, FunctionDefinitionIndex(function));
61 Some(MoveLocation {
62 module: id.clone(),
63 function,
64 instruction,
65 function_name,
66 })
67 }
68 _ => None,
69 };
70 ExecutionFailureStatus::MovePrimitiveRuntimeError(MoveLocationOpt(location))
71 }
72 StatusType::Validation
73 | StatusType::Verification
74 | StatusType::Deserialization
75 | StatusType::Unknown => ExecutionFailureStatus::VMVerificationOrDeserializationError,
76 StatusType::InvariantViolation => ExecutionFailureStatus::VMInvariantViolation,
77 },
78 };
79 ExecutionError::new_with_source(kind, error)
80}