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