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