1use sha2::{Digest, Sha256};
6use std::collections::BTreeMap;
7
8#[derive(Debug, Clone, Default)]
10pub struct StorageContext {
11 pub script_hash: [u8; 20],
13 pub read_only: bool,
15}
16
17pub trait StorageBackend {
19 fn get(&self, context: &StorageContext, key: &[u8]) -> Option<Vec<u8>>;
20 fn put(&mut self, context: &StorageContext, key: &[u8], value: &[u8]);
21 fn delete(&mut self, context: &StorageContext, key: &[u8]);
22 fn find(&self, context: &StorageContext, prefix: &[u8]) -> Vec<(Vec<u8>, Vec<u8>)>;
23}
24
25#[derive(Debug, Clone, Default)]
27pub struct MemoryStorage {
28 data: BTreeMap<Vec<u8>, Vec<u8>>,
29}
30
31impl MemoryStorage {
32 #[inline]
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 #[inline]
38 fn make_key(context: &StorageContext, key: &[u8]) -> Vec<u8> {
39 let mut full_key = context.script_hash.to_vec();
40 full_key.extend_from_slice(key);
41 full_key
42 }
43
44 #[inline]
46 pub fn merkle_root(&self) -> [u8; 32] {
47 if self.data.is_empty() {
48 return [0u8; 32];
49 }
50
51 let mut leaves: Vec<[u8; 32]> = self
54 .data
55 .iter()
56 .map(|(k, v)| {
57 let mut hasher = Sha256::new();
58 hasher.update(k);
59 hasher.update(v);
60 hasher.finalize().into()
61 })
62 .collect();
63
64 leaves.sort();
66
67 Self::compute_merkle_root(&leaves)
68 }
69
70 #[inline]
71 fn compute_merkle_root(leaves: &[[u8; 32]]) -> [u8; 32] {
72 if leaves.is_empty() {
73 return [0u8; 32];
74 }
75 if leaves.len() == 1 {
76 return leaves[0];
77 }
78
79 let mut current: Vec<[u8; 32]> = leaves.to_vec();
80 while current.len() > 1 {
81 let mut next_level = Vec::with_capacity(current.len().div_ceil(2));
82 for chunk in current.chunks(2) {
83 let mut hasher = Sha256::new();
84 hasher.update(chunk[0]);
85 if chunk.len() > 1 {
86 hasher.update(chunk[1]);
87 } else {
88 hasher.update([0u8; 32]);
89 }
90 next_level.push(hasher.finalize().into());
91 }
92 current = next_level;
93 }
94 current.first().copied().unwrap_or([0u8; 32])
95 }
96}
97
98impl StorageBackend for MemoryStorage {
99 fn get(&self, context: &StorageContext, key: &[u8]) -> Option<Vec<u8>> {
100 let full_key = Self::make_key(context, key);
101 self.data.get(&full_key).cloned()
102 }
103
104 fn put(&mut self, context: &StorageContext, key: &[u8], value: &[u8]) {
105 if context.read_only {
106 return;
107 }
108 let full_key = Self::make_key(context, key);
109 self.data.insert(full_key, value.to_vec());
110 }
111
112 fn delete(&mut self, context: &StorageContext, key: &[u8]) {
113 if context.read_only {
114 return;
115 }
116 let full_key = Self::make_key(context, key);
117 self.data.remove(&full_key);
118 }
119
120 fn find(&self, context: &StorageContext, prefix: &[u8]) -> Vec<(Vec<u8>, Vec<u8>)> {
121 let full_prefix = Self::make_key(context, prefix);
122 self.data
123 .range(full_prefix.clone()..)
124 .take_while(|(k, _)| k.starts_with(&full_prefix))
125 .map(|(k, v)| {
126 let key = k[context.script_hash.len()..].to_vec();
127 (key, v.clone())
128 })
129 .collect()
130 }
131}
132
133#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
135pub struct StorageProof {
136 pub key: Vec<u8>,
137 pub value: Option<Vec<u8>>,
138 pub merkle_path: Vec<[u8; 32]>,
139 pub root: [u8; 32],
140}
141
142impl StorageProof {
143 pub fn verify(&self, expected_root: [u8; 32]) -> bool {
145 let leaf = if let Some(ref value) = self.value {
147 let mut hasher = Sha256::new();
148 hasher.update(&self.key);
149 hasher.update(value);
150 hasher.finalize().into()
151 } else {
152 let mut hasher = Sha256::new();
154 hasher.update(&self.key);
155 hasher.update([0u8; 32]);
156 hasher.finalize().into()
157 };
158
159 let computed_root = Self::compute_root_from_path(&leaf, &self.merkle_path);
161
162 computed_root == expected_root
163 }
164
165 fn compute_root_from_path(leaf: &[u8; 32], path: &[[u8; 32]]) -> [u8; 32] {
167 let mut current = *leaf;
168 for sibling in path {
169 let mut hasher = Sha256::new();
170 if current < *sibling {
172 hasher.update(current);
173 hasher.update(*sibling);
174 } else {
175 hasher.update(*sibling);
176 hasher.update(current);
177 }
178 current = hasher.finalize().into();
179 }
180 current
181 }
182}
183
184#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
186pub struct StorageChange {
187 pub script_hash: [u8; 20],
188 pub key: Vec<u8>,
189 pub old_value: Option<Vec<u8>>,
190 pub new_value: Option<Vec<u8>>,
191}
192
193#[derive(Debug, Clone, Default)]
195pub struct TrackedStorage {
196 inner: MemoryStorage,
197 changes: Vec<StorageChange>,
198}
199
200impl TrackedStorage {
201 pub fn new() -> Self {
202 Self::default()
203 }
204
205 pub fn changes(&self) -> &[StorageChange] {
206 &self.changes
207 }
208
209 pub fn merkle_root(&self) -> [u8; 32] {
210 self.inner.merkle_root()
211 }
212}
213
214impl StorageBackend for TrackedStorage {
215 fn get(&self, context: &StorageContext, key: &[u8]) -> Option<Vec<u8>> {
216 self.inner.get(context, key)
217 }
218
219 fn put(&mut self, context: &StorageContext, key: &[u8], value: &[u8]) {
220 if context.read_only {
221 return;
222 }
223 let old_value = self.inner.get(context, key);
224 self.inner.put(context, key, value);
225 self.changes.push(StorageChange {
226 script_hash: context.script_hash,
227 key: key.to_vec(),
228 old_value,
229 new_value: Some(value.to_vec()),
230 });
231 }
232
233 fn delete(&mut self, context: &StorageContext, key: &[u8]) {
234 if context.read_only {
235 return;
236 }
237 let old_value = self.inner.get(context, key);
238 self.inner.delete(context, key);
239 self.changes.push(StorageChange {
240 script_hash: context.script_hash,
241 key: key.to_vec(),
242 old_value,
243 new_value: None,
244 });
245 }
246
247 fn find(&self, context: &StorageContext, prefix: &[u8]) -> Vec<(Vec<u8>, Vec<u8>)> {
248 self.inner.find(context, prefix)
249 }
250}