1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use crate::sandbox::utils::on_disk_state_view::OnDiskStateView;
use move_binary_format::{access::ModuleAccess, errors::PartialVMError};
use move_bytecode_utils::Modules;
use move_core_types::vm_status::StatusCode;
use anyhow::{bail, Result};
use std::{ffi::OsStr, path::Path};
pub fn doctor(state: &OnDiskStateView) -> Result<()> {
fn parent_addr(p: &Path) -> &OsStr {
p.parent().unwrap().parent().unwrap().file_name().unwrap()
}
let all_modules = state.get_all_modules()?;
let code_cache = Modules::new(&all_modules);
for module in &all_modules {
if bytecode_verifier::verify_module(module).is_err() {
bail!("Failed to verify module {:?}", module.self_id())
}
let imm_deps = code_cache.get_immediate_dependencies(&module.self_id())?;
if bytecode_verifier::dependencies::verify_module(module, imm_deps).is_err() {
bail!(
"Failed to link module {:?} against its dependencies",
module.self_id()
)
}
let cyclic_check_result = bytecode_verifier::cyclic_dependencies::verify_module(
module,
|module_id| {
code_cache
.get_module(module_id)
.map_err(|_| PartialVMError::new(StatusCode::MISSING_DEPENDENCY))
.map(|m| m.immediate_dependencies())
},
|module_id| {
code_cache
.get_module(module_id)
.map_err(|_| PartialVMError::new(StatusCode::MISSING_DEPENDENCY))
.map(|m| m.immediate_friends())
},
);
if let Err(cyclic_check_error) = cyclic_check_result {
assert_eq!(
cyclic_check_error.major_status(),
StatusCode::CYCLIC_MODULE_DEPENDENCY
);
bail!(
"Cyclic module dependencies are detected with module {} in the loop",
module.self_id()
)
}
}
for resource_path in state.resource_paths() {
let resource = state.view_resource(&resource_path);
if resource.is_err() {
bail!(
"Failed to deserialize resource {:?} stored under address {:?}",
resource_path.file_name().unwrap(),
parent_addr(&resource_path)
)
}
}
for event_path in state.event_paths() {
let event = state.view_events(&event_path);
if event.is_err() {
bail!(
"Failed to deserialize event {:?} stored under address {:?}",
event_path.file_name().unwrap(),
parent_addr(&event_path)
)
}
}
Ok(())
}