1use crate::{
4 prelude::{
5 InterpreterError,
6 RuntimeError,
7 },
8 storage::InterpreterStorage,
9};
10use alloc::{
11 borrow::Cow,
12 string::String,
13 vec::Vec,
14};
15use core::fmt::Debug;
16
17use fuel_asm::Word;
18use fuel_storage::{
19 Mappable,
20 StorageInspect,
21 StorageMutate,
22 StorageRead,
23 StorageSize,
24 StorageWrite,
25};
26use fuel_tx::ConsensusParameters;
27use fuel_types::{
28 BlobId,
29 BlockHeight,
30 Bytes32,
31 ContractId,
32};
33
34use super::{
35 interpreter::ContractsAssetsStorage,
36 BlobData,
37 ContractsAssets,
38 ContractsRawCode,
39 ContractsState,
40 ContractsStateData,
41 UploadedBytecodes,
42};
43
44pub fn empty_predicate_storage() -> PredicateStorage<EmptyStorage> {
46 PredicateStorage::new(EmptyStorage)
47}
48
49#[derive(Debug, Default)]
56pub struct PredicateStorage<D> {
57 storage: D,
58}
59
60impl<D> PredicateStorage<D> {
61 pub fn new(storage: D) -> Self {
63 Self { storage }
64 }
65}
66
67#[derive(Debug, Clone)]
69pub enum PredicateStorageError {
70 UnsupportedStorageOperation,
72 StorageError(String),
74}
75
76impl From<PredicateStorageError> for InterpreterError<PredicateStorageError> {
77 fn from(val: PredicateStorageError) -> Self {
78 let rt: RuntimeError<PredicateStorageError> = val.into();
79 rt.into()
80 }
81}
82
83impl From<PredicateStorageError> for RuntimeError<PredicateStorageError> {
84 fn from(val: PredicateStorageError) -> Self {
85 RuntimeError::Storage(val)
86 }
87}
88
89pub trait PredicateStorageRequirements
91where
92 Self: StorageRead<BlobData>,
93{
94 fn storage_error_to_string(error: Self::Error) -> String;
96}
97
98impl<D> PredicateStorageRequirements for &D
99where
100 D: PredicateStorageRequirements,
101{
102 fn storage_error_to_string(error: Self::Error) -> String {
103 D::storage_error_to_string(error)
104 }
105}
106
107pub trait PredicateStorageProvider: Sync {
109 type Storage: PredicateStorageRequirements + Send + Sync + 'static;
111
112 fn storage(&self) -> Self::Storage;
114}
115
116#[derive(Default, Debug, Clone, Copy)]
118pub struct EmptyStorage;
119
120impl StorageInspect<BlobData> for EmptyStorage {
121 type Error = PredicateStorageError;
122
123 fn get(
124 &self,
125 _: &BlobId,
126 ) -> Result<Option<Cow<<BlobData as Mappable>::OwnedValue>>, Self::Error> {
127 Err(Self::Error::UnsupportedStorageOperation)
128 }
129
130 fn contains_key(&self, _: &BlobId) -> Result<bool, Self::Error> {
131 Err(Self::Error::UnsupportedStorageOperation)
132 }
133}
134
135impl StorageSize<BlobData> for EmptyStorage {
136 fn size_of_value(&self, _: &BlobId) -> Result<Option<usize>, Self::Error> {
137 Err(Self::Error::UnsupportedStorageOperation)
138 }
139}
140
141impl StorageRead<BlobData> for EmptyStorage {
142 fn read(&self, _: &BlobId, _: usize, _: &mut [u8]) -> Result<bool, Self::Error> {
143 Err(Self::Error::UnsupportedStorageOperation)
144 }
145
146 fn read_alloc(&self, _: &BlobId) -> Result<Option<Vec<u8>>, Self::Error> {
147 Err(Self::Error::UnsupportedStorageOperation)
148 }
149}
150
151impl PredicateStorageRequirements for EmptyStorage {
152 fn storage_error_to_string(error: Self::Error) -> String {
153 alloc::format!("{:?}", error)
154 }
155}
156
157impl PredicateStorageProvider for EmptyStorage {
158 type Storage = Self;
159
160 fn storage(&self) -> Self::Storage {
161 *self
162 }
163}
164
165trait NoStorage {}
166
167impl NoStorage for ContractsState {}
168impl NoStorage for ContractsRawCode {}
169impl NoStorage for ContractsAssets {}
170impl NoStorage for UploadedBytecodes {}
171
172impl<Type, D> StorageInspect<Type> for PredicateStorage<D>
173where
174 Type: Mappable + NoStorage,
175{
176 type Error = PredicateStorageError;
177
178 fn get(
179 &self,
180 _key: &Type::Key,
181 ) -> Result<Option<Cow<'_, Type::OwnedValue>>, Self::Error> {
182 Err(Self::Error::UnsupportedStorageOperation)
183 }
184
185 fn contains_key(&self, _key: &Type::Key) -> Result<bool, Self::Error> {
186 Err(Self::Error::UnsupportedStorageOperation)
187 }
188}
189
190impl<D> StorageInspect<BlobData> for PredicateStorage<D>
191where
192 D: PredicateStorageRequirements,
193{
194 type Error = PredicateStorageError;
195
196 fn get(
197 &self,
198 key: &<BlobData as Mappable>::Key,
199 ) -> Result<Option<Cow<'_, <BlobData as Mappable>::OwnedValue>>, Self::Error> {
200 <D as StorageInspect<BlobData>>::get(&self.storage, key)
201 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
202 }
203
204 fn contains_key(
205 &self,
206 key: &<BlobData as Mappable>::Key,
207 ) -> Result<bool, Self::Error> {
208 <D as StorageInspect<BlobData>>::contains_key(&self.storage, key)
209 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
210 }
211}
212
213impl<Type, D> StorageMutate<Type> for PredicateStorage<D>
214where
215 Type: Mappable,
216 Self: StorageInspect<Type, Error = PredicateStorageError>,
217{
218 fn replace(
219 &mut self,
220 _key: &Type::Key,
221 _value: &Type::Value,
222 ) -> Result<Option<Type::OwnedValue>, Self::Error> {
223 Err(Self::Error::UnsupportedStorageOperation)
224 }
225
226 fn take(
227 &mut self,
228 _key: &Type::Key,
229 ) -> Result<Option<Type::OwnedValue>, Self::Error> {
230 Err(Self::Error::UnsupportedStorageOperation)
231 }
232}
233
234impl<D> StorageSize<ContractsRawCode> for PredicateStorage<D> {
235 fn size_of_value(&self, _key: &ContractId) -> Result<Option<usize>, Self::Error> {
236 Err(Self::Error::UnsupportedStorageOperation)
237 }
238}
239
240impl<D> StorageRead<ContractsRawCode> for PredicateStorage<D> {
241 fn read(
242 &self,
243 _key: &<ContractsRawCode as Mappable>::Key,
244 _offset: usize,
245 _buf: &mut [u8],
246 ) -> Result<bool, Self::Error> {
247 Err(Self::Error::UnsupportedStorageOperation)
248 }
249
250 fn read_alloc(
251 &self,
252 _key: &<ContractsRawCode as Mappable>::Key,
253 ) -> Result<Option<Vec<u8>>, Self::Error> {
254 Err(Self::Error::UnsupportedStorageOperation)
255 }
256}
257
258impl<D> StorageWrite<ContractsRawCode> for PredicateStorage<D> {
259 fn write_bytes(
260 &mut self,
261 _key: &<ContractsRawCode as Mappable>::Key,
262 _buf: &[u8],
263 ) -> Result<(), Self::Error> {
264 Err(Self::Error::UnsupportedStorageOperation)
265 }
266
267 fn replace_bytes(
268 &mut self,
269 _key: &<ContractsRawCode as Mappable>::Key,
270 _buf: &[u8],
271 ) -> Result<Option<Vec<u8>>, Self::Error> {
272 Err(Self::Error::UnsupportedStorageOperation)
273 }
274
275 fn take_bytes(
276 &mut self,
277 _key: &<ContractsRawCode as Mappable>::Key,
278 ) -> Result<Option<Vec<u8>>, Self::Error> {
279 Err(Self::Error::UnsupportedStorageOperation)
280 }
281}
282
283impl<D> StorageSize<ContractsState> for PredicateStorage<D> {
284 fn size_of_value(
285 &self,
286 _key: &<ContractsState as Mappable>::Key,
287 ) -> Result<Option<usize>, Self::Error> {
288 Err(Self::Error::UnsupportedStorageOperation)
289 }
290}
291
292impl<D> StorageRead<ContractsState> for PredicateStorage<D> {
293 fn read(
294 &self,
295 _key: &<ContractsState as Mappable>::Key,
296 _offset: usize,
297 _buf: &mut [u8],
298 ) -> Result<bool, Self::Error> {
299 Err(Self::Error::UnsupportedStorageOperation)
300 }
301
302 fn read_alloc(
303 &self,
304 _key: &<ContractsState as Mappable>::Key,
305 ) -> Result<Option<Vec<u8>>, Self::Error> {
306 Err(Self::Error::UnsupportedStorageOperation)
307 }
308}
309
310impl<D> StorageWrite<ContractsState> for PredicateStorage<D> {
311 fn write_bytes(
312 &mut self,
313 _key: &<ContractsState as Mappable>::Key,
314 _buf: &[u8],
315 ) -> Result<(), Self::Error> {
316 Err(Self::Error::UnsupportedStorageOperation)
317 }
318
319 fn replace_bytes(
320 &mut self,
321 _key: &<ContractsState as Mappable>::Key,
322 _buf: &[u8],
323 ) -> Result<Option<Vec<u8>>, Self::Error> {
324 Err(Self::Error::UnsupportedStorageOperation)
325 }
326
327 fn take_bytes(
328 &mut self,
329 _key: &<ContractsState as Mappable>::Key,
330 ) -> Result<Option<Vec<u8>>, Self::Error> {
331 Err(Self::Error::UnsupportedStorageOperation)
332 }
333}
334
335impl<D> StorageSize<BlobData> for PredicateStorage<D>
336where
337 D: PredicateStorageRequirements,
338{
339 fn size_of_value(
340 &self,
341 key: &<BlobData as Mappable>::Key,
342 ) -> Result<Option<usize>, Self::Error> {
343 StorageSize::<BlobData>::size_of_value(&self.storage, key)
344 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
345 }
346}
347
348impl<D> StorageRead<BlobData> for PredicateStorage<D>
349where
350 D: PredicateStorageRequirements,
351{
352 fn read(
353 &self,
354 key: &<BlobData as Mappable>::Key,
355 offset: usize,
356 buf: &mut [u8],
357 ) -> Result<bool, Self::Error> {
358 StorageRead::<BlobData>::read(&self.storage, key, offset, buf)
359 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
360 }
361
362 fn read_alloc(
363 &self,
364 key: &<BlobData as Mappable>::Key,
365 ) -> Result<Option<Vec<u8>>, Self::Error> {
366 StorageRead::<BlobData>::read_alloc(&self.storage, key)
367 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
368 }
369}
370
371impl<D> StorageWrite<BlobData> for PredicateStorage<D>
372where
373 D: PredicateStorageRequirements,
374{
375 fn write_bytes(
376 &mut self,
377 _key: &<BlobData as Mappable>::Key,
378 _buf: &[u8],
379 ) -> Result<(), Self::Error> {
380 Err(Self::Error::UnsupportedStorageOperation)
381 }
382
383 fn replace_bytes(
384 &mut self,
385 _key: &<BlobData as Mappable>::Key,
386 _buf: &[u8],
387 ) -> Result<Option<Vec<u8>>, Self::Error> {
388 Err(Self::Error::UnsupportedStorageOperation)
389 }
390
391 fn take_bytes(
392 &mut self,
393 _key: &<BlobData as Mappable>::Key,
394 ) -> Result<Option<Vec<u8>>, Self::Error> {
395 Err(Self::Error::UnsupportedStorageOperation)
396 }
397}
398
399impl<D> ContractsAssetsStorage for PredicateStorage<D> {}
400
401impl<D> InterpreterStorage for PredicateStorage<D>
402where
403 D: PredicateStorageRequirements,
404{
405 type DataError = PredicateStorageError;
406
407 fn block_height(&self) -> Result<BlockHeight, Self::DataError> {
408 Err(Self::DataError::UnsupportedStorageOperation)
409 }
410
411 fn consensus_parameters_version(&self) -> Result<u32, Self::DataError> {
412 Err(Self::DataError::UnsupportedStorageOperation)
413 }
414
415 fn state_transition_version(&self) -> Result<u32, Self::DataError> {
416 Err(Self::DataError::UnsupportedStorageOperation)
417 }
418
419 fn timestamp(&self, _height: BlockHeight) -> Result<Word, Self::DataError> {
420 Err(Self::DataError::UnsupportedStorageOperation)
421 }
422
423 fn block_hash(&self, _block_height: BlockHeight) -> Result<Bytes32, Self::DataError> {
424 Err(Self::DataError::UnsupportedStorageOperation)
425 }
426
427 fn coinbase(&self) -> Result<ContractId, Self::DataError> {
428 Err(Self::DataError::UnsupportedStorageOperation)
429 }
430
431 fn set_consensus_parameters(
432 &mut self,
433 _version: u32,
434 _consensus_parameters: &ConsensusParameters,
435 ) -> Result<Option<ConsensusParameters>, Self::DataError> {
436 Err(Self::DataError::UnsupportedStorageOperation)
437 }
438
439 fn set_state_transition_bytecode(
440 &mut self,
441 _version: u32,
442 _hash: &Bytes32,
443 ) -> Result<Option<Bytes32>, Self::DataError> {
444 Err(Self::DataError::UnsupportedStorageOperation)
445 }
446
447 fn contract_state_range(
448 &self,
449 _id: &ContractId,
450 _start_key: &Bytes32,
451 _range: usize,
452 ) -> Result<Vec<Option<Cow<ContractsStateData>>>, Self::DataError> {
453 Err(Self::DataError::UnsupportedStorageOperation)
454 }
455
456 fn contract_state_insert_range<'a, I>(
457 &mut self,
458 _: &ContractId,
459 _: &Bytes32,
460 _: I,
461 ) -> Result<usize, Self::DataError>
462 where
463 I: Iterator<Item = &'a [u8]>,
464 {
465 Err(Self::DataError::UnsupportedStorageOperation)
466 }
467
468 fn contract_state_remove_range(
469 &mut self,
470 _contract: &ContractId,
471 _start_key: &Bytes32,
472 _range: usize,
473 ) -> Result<Option<()>, Self::DataError> {
474 Err(Self::DataError::UnsupportedStorageOperation)
475 }
476}