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
use move_binary_format::errors::{PartialVMError, VMResult};
use move_core_types::{effects::ChangeSet, language_storage::ModuleId, resolver::MoveResolver};
pub fn adapt_move_vm_result<T>(result: VMResult<T>) -> VMResult<T> {
result.map_err(|err| {
let (status_code, sub_status, _, location, _, _) = err.all_data();
let adapted = PartialVMError::new(status_code);
let adapted = match sub_status {
None => adapted,
Some(status_code) => adapted.with_sub_status(status_code),
};
adapted.finish(location)
})
}
pub fn adapt_move_vm_change_set<S: MoveResolver>(
change_set_result: VMResult<ChangeSet>,
old_storage: &S,
) -> VMResult<ChangeSet> {
change_set_result.map(|change_set| adapt_move_vm_change_set_internal(change_set, old_storage))
}
fn adapt_move_vm_change_set_internal<S: MoveResolver>(
change_set: ChangeSet,
old_storage: &S,
) -> ChangeSet {
let mut adapted = ChangeSet::new();
for (addr, state) in change_set.into_inner() {
let (modules, resources) = state.into_inner();
for (tag, val) in resources {
match val {
None => adapted.unpublish_resource(addr, tag).unwrap(),
Some(new_val) => match old_storage.get_resource(&addr, &tag).unwrap() {
None => adapted.publish_resource(addr, tag, new_val).unwrap(),
Some(old_val) => {
if new_val != old_val {
adapted.publish_resource(addr, tag, new_val).unwrap();
}
}
},
}
}
for (module_name, blob_opt) in modules {
let module_id = ModuleId::new(addr, module_name);
match blob_opt {
None => adapted.unpublish_module(module_id).unwrap(),
Some(blob) => adapted.publish_module(module_id, blob).unwrap(),
}
}
}
adapted
}