sui_adapter_latest/data_store/
linked_data_store.rs1use crate::{
5 data_store::PackageStore,
6 static_programmable_transactions::linkage::resolved_linkage::RootedLinkage,
7};
8use move_binary_format::errors::{Location, PartialVMError, PartialVMResult, VMResult};
9use move_core_types::{
10 account_address::AccountAddress,
11 identifier::IdentStr,
12 language_storage::ModuleId,
13 resolver::{LinkageResolver, ModuleResolver},
14 vm_status::StatusCode,
15};
16use move_vm_types::data_store::DataStore;
17use sui_types::{
18 base_types::ObjectID,
19 error::{ExecutionErrorKind, SuiError},
20};
21
22pub struct LinkedDataStore<'a> {
29 pub linkage: &'a RootedLinkage,
30 pub store: &'a dyn PackageStore,
31}
32
33impl<'a> LinkedDataStore<'a> {
34 pub fn new(linkage: &'a RootedLinkage, store: &'a dyn PackageStore) -> Self {
35 Self { linkage, store }
36 }
37}
38
39impl DataStore for LinkedDataStore<'_> {
40 fn link_context(&self) -> PartialVMResult<AccountAddress> {
41 Ok(self.linkage.link_context)
42 }
43
44 fn relocate(&self, module_id: &ModuleId) -> PartialVMResult<ModuleId> {
45 self.linkage
46 .resolved_linkage
47 .linkage
48 .get(&ObjectID::from(*module_id.address()))
49 .map(|obj_id| ModuleId::new(**obj_id, module_id.name().to_owned()))
50 .ok_or_else(|| {
51 PartialVMError::new(StatusCode::LINKER_ERROR).with_message(format!(
52 "Error relocating {module_id} -- could not find linkage"
53 ))
54 })
55 }
56
57 fn defining_module(
58 &self,
59 module_id: &ModuleId,
60 struct_: &IdentStr,
61 ) -> PartialVMResult<ModuleId> {
62 self.store
63 .resolve_type_to_defining_id(
64 ObjectID::from(*module_id.address()),
65 module_id.name(),
66 struct_,
67 )
68 .ok()
69 .flatten()
70 .map(|obj_id| ModuleId::new(*obj_id, module_id.name().to_owned()))
71 .ok_or_else(|| {
72 PartialVMError::new(StatusCode::LINKER_ERROR).with_message(format!(
73 "Error finding defining module for {module_id}::{struct_} -- could nod find linkage"
74 ))
75 })
76 }
77
78 fn load_module(&self, module_id: &ModuleId) -> VMResult<Vec<u8>> {
80 let package_storage_id = ObjectID::from(*module_id.address());
81 match self
82 .store
83 .get_package(&package_storage_id)
84 .map(|pkg| pkg.and_then(|pkg| pkg.get_module(module_id).cloned()))
85 {
86 Ok(Some(bytes)) => Ok(bytes),
87 Ok(None) => Err(PartialVMError::new(StatusCode::LINKER_ERROR)
88 .with_message(format!("Cannot find {:?} in data cache", module_id))
89 .finish(Location::Undefined)),
90 Err(err) => {
91 let msg = format!("Unexpected storage error: {:?}", err);
92 Err(
93 PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR)
94 .with_message(msg)
95 .finish(Location::Undefined),
96 )
97 }
98 }
99 }
100
101 fn publish_module(&mut self, _module_id: &ModuleId, _blob: Vec<u8>) -> VMResult<()> {
102 Ok(())
103 }
104}
105
106impl DataStore for &LinkedDataStore<'_> {
107 fn link_context(&self) -> PartialVMResult<AccountAddress> {
108 DataStore::link_context(*self)
109 }
110
111 fn relocate(&self, module_id: &ModuleId) -> PartialVMResult<ModuleId> {
112 DataStore::relocate(*self, module_id)
113 }
114
115 fn defining_module(
116 &self,
117 module_id: &ModuleId,
118 struct_: &IdentStr,
119 ) -> PartialVMResult<ModuleId> {
120 DataStore::defining_module(*self, module_id, struct_)
121 }
122
123 fn load_module(&self, module_id: &ModuleId) -> VMResult<Vec<u8>> {
124 DataStore::load_module(*self, module_id)
125 }
126
127 fn publish_module(&mut self, _module_id: &ModuleId, _blob: Vec<u8>) -> VMResult<()> {
128 Ok(())
129 }
130}
131
132impl ModuleResolver for LinkedDataStore<'_> {
133 type Error = SuiError;
134
135 fn get_module(&self, id: &ModuleId) -> Result<Option<Vec<u8>>, Self::Error> {
136 self.load_module(id)
137 .map(Some)
138 .map_err(|_| SuiError::from(ExecutionErrorKind::VMVerificationOrDeserializationError))
139 }
140}
141
142impl LinkageResolver for LinkedDataStore<'_> {
143 type Error = SuiError;
144
145 fn link_context(&self) -> AccountAddress {
146 DataStore::link_context(self).unwrap()
148 }
149
150 fn relocate(&self, module_id: &ModuleId) -> Result<ModuleId, Self::Error> {
151 DataStore::relocate(self, module_id).map_err(|err| {
152 make_invariant_violation!("Error relocating {}: {:?}", module_id, err).into()
153 })
154 }
155
156 fn defining_module(
157 &self,
158 runtime_id: &ModuleId,
159 struct_: &IdentStr,
160 ) -> Result<ModuleId, Self::Error> {
161 DataStore::defining_module(self, runtime_id, struct_).map_err(|err| {
162 make_invariant_violation!(
163 "Error finding defining module for {}::{}: {:?}",
164 runtime_id,
165 struct_,
166 err
167 )
168 .into()
169 })
170 }
171}