1#[cfg(with_testing)]
7use std::sync::Arc;
8
9use linera_base::ensure;
10use linera_views::{
11 batch::Batch,
12 store::{ReadableKeyValueStore, WithError, WritableKeyValueStore},
13};
14use thiserror::Error;
15
16#[cfg(with_testing)]
17use super::mock_key_value_store::MockKeyValueStore;
18use crate::{
19 contract::wit::{
20 base_runtime_api::{self as contract_wit},
21 contract_runtime_api::{self, WriteOperation},
22 },
23 service::wit::base_runtime_api as service_wit,
24};
25
26const MAX_KEY_SIZE: usize = 900;
33
34#[derive(Clone)]
36pub struct KeyValueStore {
37 wit_api: WitInterface,
38}
39
40#[cfg_attr(with_testing, allow(dead_code))]
41impl KeyValueStore {
42 pub(crate) fn for_contracts() -> Self {
44 KeyValueStore {
45 wit_api: WitInterface::Contract,
46 }
47 }
48
49 pub(crate) fn for_services() -> Self {
51 KeyValueStore {
52 wit_api: WitInterface::Service,
53 }
54 }
55
56 #[cfg(with_testing)]
58 pub fn mock() -> Self {
59 KeyValueStore {
60 wit_api: WitInterface::Mock {
61 store: Arc::new(MockKeyValueStore::default()),
62 read_only: true,
63 },
64 }
65 }
66
67 #[cfg(with_testing)]
70 pub fn to_mut(&self) -> Self {
71 let WitInterface::Mock { store, .. } = &self.wit_api else {
72 panic!("Real `KeyValueStore` should not be used in unit tests");
73 };
74
75 KeyValueStore {
76 wit_api: WitInterface::Mock {
77 store: store.clone(),
78 read_only: false,
79 },
80 }
81 }
82}
83
84impl WithError for KeyValueStore {
85 type Error = KeyValueStoreError;
86}
87
88#[derive(Error, Debug)]
90pub enum KeyValueStoreError {
91 #[error("Key too long")]
93 KeyTooLong,
94
95 #[error(transparent)]
97 BcsError(#[from] bcs::Error),
98}
99
100impl linera_views::store::KeyValueStoreError for KeyValueStoreError {
101 const BACKEND: &'static str = "key_value_store";
102}
103
104impl ReadableKeyValueStore for KeyValueStore {
105 const MAX_KEY_SIZE: usize = MAX_KEY_SIZE;
108
109 fn root_key(&self) -> Result<Vec<u8>, KeyValueStoreError> {
110 Ok(Vec::new())
111 }
112
113 async fn contains_key(&self, key: &[u8]) -> Result<bool, KeyValueStoreError> {
114 ensure!(
115 key.len() <= Self::MAX_KEY_SIZE,
116 KeyValueStoreError::KeyTooLong
117 );
118 let promise = self.wit_api.contains_key_new(key);
119 Ok(self.wit_api.contains_key_wait(promise))
120 }
121
122 async fn contains_keys(&self, keys: &[Vec<u8>]) -> Result<Vec<bool>, KeyValueStoreError> {
123 for key in keys {
124 ensure!(
125 key.len() <= Self::MAX_KEY_SIZE,
126 KeyValueStoreError::KeyTooLong
127 );
128 }
129 let promise = self.wit_api.contains_keys_new(keys);
130 Ok(self.wit_api.contains_keys_wait(promise))
131 }
132
133 async fn read_multi_values_bytes(
134 &self,
135 keys: &[Vec<u8>],
136 ) -> Result<Vec<Option<Vec<u8>>>, KeyValueStoreError> {
137 for key in keys {
138 ensure!(
139 key.len() <= Self::MAX_KEY_SIZE,
140 KeyValueStoreError::KeyTooLong
141 );
142 }
143 let promise = self.wit_api.read_multi_values_bytes_new(keys);
144 Ok(self.wit_api.read_multi_values_bytes_wait(promise))
145 }
146
147 async fn read_value_bytes(&self, key: &[u8]) -> Result<Option<Vec<u8>>, KeyValueStoreError> {
148 ensure!(
149 key.len() <= Self::MAX_KEY_SIZE,
150 KeyValueStoreError::KeyTooLong
151 );
152 let promise = self.wit_api.read_value_bytes_new(key);
153 Ok(self.wit_api.read_value_bytes_wait(promise))
154 }
155
156 async fn find_keys_by_prefix(
157 &self,
158 key_prefix: &[u8],
159 ) -> Result<Vec<Vec<u8>>, KeyValueStoreError> {
160 ensure!(
161 key_prefix.len() <= Self::MAX_KEY_SIZE,
162 KeyValueStoreError::KeyTooLong
163 );
164 let promise = self.wit_api.find_keys_new(key_prefix);
165 Ok(self.wit_api.find_keys_wait(promise))
166 }
167
168 async fn find_key_values_by_prefix(
169 &self,
170 key_prefix: &[u8],
171 ) -> Result<Vec<(Vec<u8>, Vec<u8>)>, KeyValueStoreError> {
172 ensure!(
173 key_prefix.len() <= Self::MAX_KEY_SIZE,
174 KeyValueStoreError::KeyTooLong
175 );
176 let promise = self.wit_api.find_key_values_new(key_prefix);
177 Ok(self.wit_api.find_key_values_wait(promise))
178 }
179}
180
181impl WritableKeyValueStore for KeyValueStore {
182 const MAX_VALUE_SIZE: usize = usize::MAX;
183
184 async fn write_batch(&self, batch: Batch) -> Result<(), KeyValueStoreError> {
185 self.wit_api.write_batch(batch);
186 Ok(())
187 }
188
189 async fn clear_journal(&self) -> Result<(), KeyValueStoreError> {
190 Ok(())
191 }
192}
193
194#[derive(Clone)]
196#[cfg_attr(with_testing, allow(dead_code))]
197enum WitInterface {
198 Contract,
200 Service,
202 #[cfg(with_testing)]
203 Mock {
205 store: Arc<MockKeyValueStore>,
206 read_only: bool,
207 },
208}
209
210impl WitInterface {
211 fn contains_key_new(&self, key: &[u8]) -> u32 {
213 match self {
214 WitInterface::Contract => contract_wit::contains_key_new(key),
215 WitInterface::Service => service_wit::contains_key_new(key),
216 #[cfg(with_testing)]
217 WitInterface::Mock { store, .. } => store.contains_key_new(key),
218 }
219 }
220
221 fn contains_key_wait(&self, promise: u32) -> bool {
223 match self {
224 WitInterface::Contract => contract_wit::contains_key_wait(promise),
225 WitInterface::Service => service_wit::contains_key_wait(promise),
226 #[cfg(with_testing)]
227 WitInterface::Mock { store, .. } => store.contains_key_wait(promise),
228 }
229 }
230
231 fn contains_keys_new(&self, keys: &[Vec<u8>]) -> u32 {
233 match self {
234 WitInterface::Contract => contract_wit::contains_keys_new(keys),
235 WitInterface::Service => service_wit::contains_keys_new(keys),
236 #[cfg(with_testing)]
237 WitInterface::Mock { store, .. } => store.contains_keys_new(keys),
238 }
239 }
240
241 fn contains_keys_wait(&self, promise: u32) -> Vec<bool> {
243 match self {
244 WitInterface::Contract => contract_wit::contains_keys_wait(promise),
245 WitInterface::Service => service_wit::contains_keys_wait(promise),
246 #[cfg(with_testing)]
247 WitInterface::Mock { store, .. } => store.contains_keys_wait(promise),
248 }
249 }
250
251 fn read_multi_values_bytes_new(&self, keys: &[Vec<u8>]) -> u32 {
253 match self {
254 WitInterface::Contract => contract_wit::read_multi_values_bytes_new(keys),
255 WitInterface::Service => service_wit::read_multi_values_bytes_new(keys),
256 #[cfg(with_testing)]
257 WitInterface::Mock { store, .. } => store.read_multi_values_bytes_new(keys),
258 }
259 }
260
261 fn read_multi_values_bytes_wait(&self, promise: u32) -> Vec<Option<Vec<u8>>> {
263 match self {
264 WitInterface::Contract => contract_wit::read_multi_values_bytes_wait(promise),
265 WitInterface::Service => service_wit::read_multi_values_bytes_wait(promise),
266 #[cfg(with_testing)]
267 WitInterface::Mock { store, .. } => store.read_multi_values_bytes_wait(promise),
268 }
269 }
270
271 fn read_value_bytes_new(&self, key: &[u8]) -> u32 {
273 match self {
274 WitInterface::Contract => contract_wit::read_value_bytes_new(key),
275 WitInterface::Service => service_wit::read_value_bytes_new(key),
276 #[cfg(with_testing)]
277 WitInterface::Mock { store, .. } => store.read_value_bytes_new(key),
278 }
279 }
280
281 fn read_value_bytes_wait(&self, promise: u32) -> Option<Vec<u8>> {
283 match self {
284 WitInterface::Contract => contract_wit::read_value_bytes_wait(promise),
285 WitInterface::Service => service_wit::read_value_bytes_wait(promise),
286 #[cfg(with_testing)]
287 WitInterface::Mock { store, .. } => store.read_value_bytes_wait(promise),
288 }
289 }
290
291 fn find_keys_new(&self, key_prefix: &[u8]) -> u32 {
293 match self {
294 WitInterface::Contract => contract_wit::find_keys_new(key_prefix),
295 WitInterface::Service => service_wit::find_keys_new(key_prefix),
296 #[cfg(with_testing)]
297 WitInterface::Mock { store, .. } => store.find_keys_new(key_prefix),
298 }
299 }
300
301 fn find_keys_wait(&self, promise: u32) -> Vec<Vec<u8>> {
303 match self {
304 WitInterface::Contract => contract_wit::find_keys_wait(promise),
305 WitInterface::Service => service_wit::find_keys_wait(promise),
306 #[cfg(with_testing)]
307 WitInterface::Mock { store, .. } => store.find_keys_wait(promise),
308 }
309 }
310
311 fn find_key_values_new(&self, key_prefix: &[u8]) -> u32 {
313 match self {
314 WitInterface::Contract => contract_wit::find_key_values_new(key_prefix),
315 WitInterface::Service => service_wit::find_key_values_new(key_prefix),
316 #[cfg(with_testing)]
317 WitInterface::Mock { store, .. } => store.find_key_values_new(key_prefix),
318 }
319 }
320
321 fn find_key_values_wait(&self, promise: u32) -> Vec<(Vec<u8>, Vec<u8>)> {
323 match self {
324 WitInterface::Contract => contract_wit::find_key_values_wait(promise),
325 WitInterface::Service => service_wit::find_key_values_wait(promise),
326 #[cfg(with_testing)]
327 WitInterface::Mock { store, .. } => store.find_key_values_wait(promise),
328 }
329 }
330
331 fn write_batch(&self, batch: Batch) {
333 match self {
334 WitInterface::Contract => {
335 let batch_operations = batch
336 .operations
337 .into_iter()
338 .map(WriteOperation::from)
339 .collect::<Vec<_>>();
340
341 contract_runtime_api::write_batch(&batch_operations);
342 }
343 WitInterface::Service => panic!("Attempt to modify storage from a service"),
344 #[cfg(with_testing)]
345 WitInterface::Mock {
346 store,
347 read_only: false,
348 } => {
349 store.write_batch(batch);
350 }
351 #[cfg(with_testing)]
352 WitInterface::Mock {
353 read_only: true, ..
354 } => {
355 panic!("Attempt to modify storage from a service")
356 }
357 }
358 }
359}
360
361pub type ViewStorageContext = linera_views::context::ViewContext<(), KeyValueStore>;
364
365#[cfg(all(test, not(target_arch = "wasm32")))]
366mod tests {
367 use super::*;
368
369 #[tokio::test]
370 async fn test_key_value_store_mock() -> anyhow::Result<()> {
371 let store = KeyValueStore::mock();
373 let mock_store = store.to_mut();
374
375 let is_key_existing = mock_store.contains_key(b"foo").await?;
377 assert!(!is_key_existing);
378
379 let is_keys_existing = mock_store
381 .contains_keys(&[b"foo".to_vec(), b"bar".to_vec()])
382 .await?;
383 assert!(!is_keys_existing[0]);
384 assert!(!is_keys_existing[1]);
385
386 let mut batch = Batch::new();
388 batch.put_key_value(b"foo".to_vec(), &32_u128)?;
389 batch.put_key_value(b"bar".to_vec(), &42_u128)?;
390 mock_store.write_batch(batch).await?;
391
392 let is_key_existing = mock_store.contains_key(b"foo").await?;
393 assert!(is_key_existing);
394
395 let value = mock_store.read_value(b"foo").await?;
396 assert_eq!(value, Some(32_u128));
397
398 let value = mock_store.read_value(b"bar").await?;
399 assert_eq!(value, Some(42_u128));
400
401 Ok(())
402 }
403}