fuel_vm/storage/
contracts_state.rs

1use crate::double_key;
2use fuel_storage::Mappable;
3use fuel_types::{
4    fmt_truncated_hex,
5    Bytes32,
6    ContractId,
7};
8
9use alloc::{
10    vec,
11    vec::Vec,
12};
13use educe::Educe;
14
15#[cfg(feature = "random")]
16use rand::{
17    distributions::{
18        Distribution,
19        Standard,
20    },
21    Rng,
22};
23
24/// The storage table for contract's hashed key-value state.
25///
26/// Lifetime is for optimization to avoid `clone`.
27pub struct ContractsState;
28
29impl Mappable for ContractsState {
30    type Key = Self::OwnedKey;
31    /// The table key is combination of the `ContractId` and `Bytes32` hash of the value's
32    /// key.
33    type OwnedKey = ContractsStateKey;
34    type OwnedValue = ContractsStateData;
35    type Value = [u8];
36}
37
38double_key!(
39    ContractsStateKey,
40    ContractId,
41    contract_id,
42    Bytes32,
43    state_key
44);
45
46/// Storage type for contract state
47#[derive(Educe, Clone, PartialEq, Eq, Hash)]
48#[educe(Debug)]
49#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
50pub struct ContractsStateData(
51    #[educe(Debug(method(fmt_truncated_hex::<16>)))] pub Vec<u8>,
52);
53
54// TODO: Remove fixed size default when adding support for dynamic storage
55impl Default for ContractsStateData {
56    fn default() -> Self {
57        Self(vec![0u8; 32])
58    }
59}
60
61impl From<Vec<u8>> for ContractsStateData {
62    fn from(c: Vec<u8>) -> Self {
63        Self(c)
64    }
65}
66
67impl From<&[u8]> for ContractsStateData {
68    fn from(c: &[u8]) -> Self {
69        Self(c.into())
70    }
71}
72
73impl From<&mut [u8]> for ContractsStateData {
74    fn from(c: &mut [u8]) -> Self {
75        Self(c.into())
76    }
77}
78
79impl From<ContractsStateData> for Vec<u8> {
80    fn from(c: ContractsStateData) -> Vec<u8> {
81        c.0
82    }
83}
84
85impl AsRef<[u8]> for ContractsStateData {
86    fn as_ref(&self) -> &[u8] {
87        self.0.as_ref()
88    }
89}
90
91impl AsMut<[u8]> for ContractsStateData {
92    fn as_mut(&mut self) -> &mut [u8] {
93        self.0.as_mut()
94    }
95}
96
97#[cfg(feature = "random")]
98impl Distribution<ContractsStateData> for Standard {
99    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ContractsStateData {
100        ContractsStateData(rng.gen::<Bytes32>().to_vec())
101    }
102}
103
104impl IntoIterator for ContractsStateData {
105    type IntoIter = alloc::vec::IntoIter<Self::Item>;
106    type Item = u8;
107
108    fn into_iter(self) -> Self::IntoIter {
109        self.0.into_iter()
110    }
111}