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 StorageReadError,
24 StorageSize,
25 StorageWrite,
26};
27use fuel_tx::ConsensusParameters;
28use fuel_types::{
29 BlobId,
30 BlockHeight,
31 Bytes32,
32 ContractId,
33};
34
35use super::{
36 BlobData,
37 ContractsAssets,
38 ContractsRawCode,
39 ContractsState,
40 UploadedBytecodes,
41 interpreter::ContractsAssetsStorage,
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_exact(
143 &self,
144 _: &BlobId,
145 _: usize,
146 _: &mut [u8],
147 ) -> Result<Result<usize, StorageReadError>, Self::Error> {
148 Err(Self::Error::UnsupportedStorageOperation)
149 }
150
151 fn read_zerofill(
152 &self,
153 _: &BlobId,
154 _: usize,
155 _: &mut [u8],
156 ) -> Result<Result<usize, StorageReadError>, Self::Error> {
157 Err(Self::Error::UnsupportedStorageOperation)
158 }
159
160 fn read_alloc(&self, _: &BlobId) -> Result<Option<Vec<u8>>, Self::Error> {
161 Err(Self::Error::UnsupportedStorageOperation)
162 }
163}
164
165impl PredicateStorageRequirements for EmptyStorage {
166 fn storage_error_to_string(error: Self::Error) -> String {
167 alloc::format!("{:?}", error)
168 }
169}
170
171impl PredicateStorageProvider for EmptyStorage {
172 type Storage = Self;
173
174 fn storage(&self) -> Self::Storage {
175 *self
176 }
177}
178
179trait NoStorage {}
180
181impl NoStorage for ContractsState {}
182impl NoStorage for ContractsRawCode {}
183impl NoStorage for ContractsAssets {}
184impl NoStorage for UploadedBytecodes {}
185
186impl<Type, D> StorageInspect<Type> for PredicateStorage<D>
187where
188 Type: Mappable + NoStorage,
189{
190 type Error = PredicateStorageError;
191
192 fn get(
193 &self,
194 _key: &Type::Key,
195 ) -> Result<Option<Cow<'_, Type::OwnedValue>>, Self::Error> {
196 Err(Self::Error::UnsupportedStorageOperation)
197 }
198
199 fn contains_key(&self, _key: &Type::Key) -> Result<bool, Self::Error> {
200 Err(Self::Error::UnsupportedStorageOperation)
201 }
202}
203
204impl<D> StorageInspect<BlobData> for PredicateStorage<D>
205where
206 D: PredicateStorageRequirements,
207{
208 type Error = PredicateStorageError;
209
210 fn get(
211 &self,
212 key: &<BlobData as Mappable>::Key,
213 ) -> Result<Option<Cow<'_, <BlobData as Mappable>::OwnedValue>>, Self::Error> {
214 <D as StorageInspect<BlobData>>::get(&self.storage, key)
215 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
216 }
217
218 fn contains_key(
219 &self,
220 key: &<BlobData as Mappable>::Key,
221 ) -> Result<bool, Self::Error> {
222 <D as StorageInspect<BlobData>>::contains_key(&self.storage, key)
223 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
224 }
225}
226
227impl<Type, D> StorageMutate<Type> for PredicateStorage<D>
228where
229 Type: Mappable,
230 Self: StorageInspect<Type, Error = PredicateStorageError>,
231{
232 fn replace(
233 &mut self,
234 _key: &Type::Key,
235 _value: &Type::Value,
236 ) -> Result<Option<Type::OwnedValue>, Self::Error> {
237 Err(Self::Error::UnsupportedStorageOperation)
238 }
239
240 fn take(
241 &mut self,
242 _key: &Type::Key,
243 ) -> Result<Option<Type::OwnedValue>, Self::Error> {
244 Err(Self::Error::UnsupportedStorageOperation)
245 }
246}
247
248impl<D> StorageSize<ContractsRawCode> for PredicateStorage<D> {
249 fn size_of_value(&self, _key: &ContractId) -> Result<Option<usize>, Self::Error> {
250 Err(Self::Error::UnsupportedStorageOperation)
251 }
252}
253
254impl<D> StorageRead<ContractsRawCode> for PredicateStorage<D> {
255 fn read_exact(
256 &self,
257 _key: &<ContractsRawCode as Mappable>::Key,
258 _offset: usize,
259 _buf: &mut [u8],
260 ) -> Result<Result<usize, StorageReadError>, Self::Error> {
261 Err(Self::Error::UnsupportedStorageOperation)
262 }
263
264 fn read_zerofill(
265 &self,
266 _key: &<ContractsRawCode as Mappable>::Key,
267 _offset: usize,
268 _buf: &mut [u8],
269 ) -> Result<Result<usize, StorageReadError>, Self::Error> {
270 Err(Self::Error::UnsupportedStorageOperation)
271 }
272
273 fn read_alloc(
274 &self,
275 _key: &<ContractsRawCode as Mappable>::Key,
276 ) -> Result<Option<Vec<u8>>, Self::Error> {
277 Err(Self::Error::UnsupportedStorageOperation)
278 }
279}
280
281impl<D> StorageWrite<ContractsRawCode> for PredicateStorage<D> {
282 fn write_bytes(
283 &mut self,
284 _key: &<ContractsRawCode as Mappable>::Key,
285 _buf: &[u8],
286 ) -> Result<(), Self::Error> {
287 Err(Self::Error::UnsupportedStorageOperation)
288 }
289
290 fn replace_bytes(
291 &mut self,
292 _key: &<ContractsRawCode as Mappable>::Key,
293 _buf: &[u8],
294 ) -> Result<Option<Vec<u8>>, Self::Error> {
295 Err(Self::Error::UnsupportedStorageOperation)
296 }
297
298 fn take_bytes(
299 &mut self,
300 _key: &<ContractsRawCode as Mappable>::Key,
301 ) -> Result<Option<Vec<u8>>, Self::Error> {
302 Err(Self::Error::UnsupportedStorageOperation)
303 }
304}
305
306impl<D> StorageSize<ContractsState> for PredicateStorage<D> {
307 fn size_of_value(
308 &self,
309 _key: &<ContractsState as Mappable>::Key,
310 ) -> Result<Option<usize>, Self::Error> {
311 Err(Self::Error::UnsupportedStorageOperation)
312 }
313}
314
315impl<D> StorageRead<ContractsState> for PredicateStorage<D> {
316 fn read_exact(
317 &self,
318 _key: &<ContractsState as Mappable>::Key,
319 _offset: usize,
320 _buf: &mut [u8],
321 ) -> Result<Result<usize, StorageReadError>, Self::Error> {
322 Err(Self::Error::UnsupportedStorageOperation)
323 }
324
325 fn read_zerofill(
326 &self,
327 _key: &<ContractsState as Mappable>::Key,
328 _offset: usize,
329 _buf: &mut [u8],
330 ) -> Result<Result<usize, StorageReadError>, Self::Error> {
331 Err(Self::Error::UnsupportedStorageOperation)
332 }
333
334 fn read_alloc(
335 &self,
336 _key: &<ContractsState as Mappable>::Key,
337 ) -> Result<Option<Vec<u8>>, Self::Error> {
338 Err(Self::Error::UnsupportedStorageOperation)
339 }
340}
341
342impl<D> StorageWrite<ContractsState> for PredicateStorage<D> {
343 fn write_bytes(
344 &mut self,
345 _key: &<ContractsState as Mappable>::Key,
346 _buf: &[u8],
347 ) -> Result<(), Self::Error> {
348 Err(Self::Error::UnsupportedStorageOperation)
349 }
350
351 fn replace_bytes(
352 &mut self,
353 _key: &<ContractsState as Mappable>::Key,
354 _buf: &[u8],
355 ) -> Result<Option<Vec<u8>>, Self::Error> {
356 Err(Self::Error::UnsupportedStorageOperation)
357 }
358
359 fn take_bytes(
360 &mut self,
361 _key: &<ContractsState as Mappable>::Key,
362 ) -> Result<Option<Vec<u8>>, Self::Error> {
363 Err(Self::Error::UnsupportedStorageOperation)
364 }
365}
366
367impl<D> StorageSize<BlobData> for PredicateStorage<D>
368where
369 D: PredicateStorageRequirements,
370{
371 fn size_of_value(
372 &self,
373 key: &<BlobData as Mappable>::Key,
374 ) -> Result<Option<usize>, Self::Error> {
375 StorageSize::<BlobData>::size_of_value(&self.storage, key)
376 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
377 }
378}
379
380impl<D> StorageRead<BlobData> for PredicateStorage<D>
381where
382 D: PredicateStorageRequirements,
383{
384 fn read_exact(
385 &self,
386 key: &<BlobData as Mappable>::Key,
387 offset: usize,
388 buf: &mut [u8],
389 ) -> Result<Result<usize, StorageReadError>, Self::Error> {
390 StorageRead::<BlobData>::read_exact(&self.storage, key, offset, buf)
391 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
392 }
393
394 fn read_zerofill(
395 &self,
396 key: &<BlobData as Mappable>::Key,
397 offset: usize,
398 buf: &mut [u8],
399 ) -> Result<Result<usize, StorageReadError>, Self::Error> {
400 StorageRead::<BlobData>::read_zerofill(&self.storage, key, offset, buf)
401 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
402 }
403
404 fn read_alloc(
405 &self,
406 key: &<BlobData as Mappable>::Key,
407 ) -> Result<Option<Vec<u8>>, Self::Error> {
408 StorageRead::<BlobData>::read_alloc(&self.storage, key)
409 .map_err(|e| Self::Error::StorageError(D::storage_error_to_string(e)))
410 }
411}
412
413impl<D> StorageWrite<BlobData> for PredicateStorage<D>
414where
415 D: PredicateStorageRequirements,
416{
417 fn write_bytes(
418 &mut self,
419 _key: &<BlobData as Mappable>::Key,
420 _buf: &[u8],
421 ) -> Result<(), Self::Error> {
422 Err(Self::Error::UnsupportedStorageOperation)
423 }
424
425 fn replace_bytes(
426 &mut self,
427 _key: &<BlobData as Mappable>::Key,
428 _buf: &[u8],
429 ) -> Result<Option<Vec<u8>>, Self::Error> {
430 Err(Self::Error::UnsupportedStorageOperation)
431 }
432
433 fn take_bytes(
434 &mut self,
435 _key: &<BlobData as Mappable>::Key,
436 ) -> Result<Option<Vec<u8>>, Self::Error> {
437 Err(Self::Error::UnsupportedStorageOperation)
438 }
439}
440
441impl<D> ContractsAssetsStorage for PredicateStorage<D> {}
442
443impl<D> InterpreterStorage for PredicateStorage<D>
444where
445 D: PredicateStorageRequirements,
446{
447 type DataError = PredicateStorageError;
448
449 fn block_height(&self) -> Result<BlockHeight, Self::DataError> {
450 Err(Self::DataError::UnsupportedStorageOperation)
451 }
452
453 fn consensus_parameters_version(&self) -> Result<u32, Self::DataError> {
454 Err(Self::DataError::UnsupportedStorageOperation)
455 }
456
457 fn state_transition_version(&self) -> Result<u32, Self::DataError> {
458 Err(Self::DataError::UnsupportedStorageOperation)
459 }
460
461 fn timestamp(&self, _height: BlockHeight) -> Result<Word, Self::DataError> {
462 Err(Self::DataError::UnsupportedStorageOperation)
463 }
464
465 fn block_hash(&self, _block_height: BlockHeight) -> Result<Bytes32, Self::DataError> {
466 Err(Self::DataError::UnsupportedStorageOperation)
467 }
468
469 fn coinbase(&self) -> Result<ContractId, Self::DataError> {
470 Err(Self::DataError::UnsupportedStorageOperation)
471 }
472
473 fn set_consensus_parameters(
474 &mut self,
475 _version: u32,
476 _consensus_parameters: &ConsensusParameters,
477 ) -> Result<Option<ConsensusParameters>, Self::DataError> {
478 Err(Self::DataError::UnsupportedStorageOperation)
479 }
480
481 fn set_state_transition_bytecode(
482 &mut self,
483 _version: u32,
484 _hash: &Bytes32,
485 ) -> Result<Option<Bytes32>, Self::DataError> {
486 Err(Self::DataError::UnsupportedStorageOperation)
487 }
488
489 fn contract_state_remove_range(
490 &mut self,
491 _contract: &ContractId,
492 _start_key: &Bytes32,
493 _range: usize,
494 ) -> Result<(), Self::DataError> {
495 Err(Self::DataError::UnsupportedStorageOperation)
496 }
497}