1use custom_debug_derive::Debug;
5use linera_base::hex_debug;
6use serde::{de::DeserializeOwned, Serialize};
7
8use crate::{
9 batch::DeletePrefixExpander,
10 memory::MemoryStore,
11 store::{KeyValueStoreError, ReadableKeyValueStore, WithError, WritableKeyValueStore},
12 views::MIN_VIEW_TAG,
13};
14
15#[derive(Default, Debug, Clone, derive_more::From)]
17pub struct BaseKey {
18 #[from]
20 #[debug(with = "hex_debug")]
21 pub bytes: Vec<u8>,
22}
23
24impl BaseKey {
25 pub fn base_tag(&self, tag: u8) -> Vec<u8> {
27 assert!(tag >= MIN_VIEW_TAG, "tag should be at least MIN_VIEW_TAG");
28 let mut key = Vec::with_capacity(self.bytes.len() + 1);
29 key.extend_from_slice(&self.bytes);
30 key.push(tag);
31 key
32 }
33
34 pub fn base_tag_index(&self, tag: u8, index: &[u8]) -> Vec<u8> {
36 assert!(tag >= MIN_VIEW_TAG, "tag should be at least MIN_VIEW_TAG");
37 let mut key = Vec::with_capacity(self.bytes.len() + 1 + index.len());
38 key.extend_from_slice(&self.bytes);
39 key.push(tag);
40 key.extend_from_slice(index);
41 key
42 }
43
44 pub fn base_index(&self, index: &[u8]) -> Vec<u8> {
46 let mut key = Vec::with_capacity(self.bytes.len() + index.len());
47 key.extend_from_slice(&self.bytes);
48 key.extend_from_slice(index);
49 key
50 }
51
52 pub fn derive_tag_key<I: Serialize>(&self, tag: u8, index: &I) -> Result<Vec<u8>, bcs::Error> {
54 assert!(tag >= MIN_VIEW_TAG, "tag should be at least MIN_VIEW_TAG");
55 let mut key = self.base_tag(tag);
56 bcs::serialize_into(&mut key, index)?;
57 Ok(key)
58 }
59
60 fn trimmed_key(&self, n: usize) -> Result<Vec<u8>, bcs::Error> {
62 if self.bytes.len() < n {
63 return Err(bcs::Error::Custom(format!(
64 "attempted to trim {} bytes from key of length {}",
65 n,
66 self.bytes.len()
67 )));
68 }
69 Ok(self.bytes[0..self.bytes.len() - n].to_vec())
70 }
71
72 pub fn derive_short_key<I: Serialize + ?Sized>(index: &I) -> Result<Vec<u8>, bcs::Error> {
74 bcs::to_bytes(index)
75 }
76
77 pub fn deserialize_value<Item: DeserializeOwned>(bytes: &[u8]) -> Result<Item, bcs::Error> {
79 bcs::from_bytes(bytes)
80 }
81}
82
83#[cfg_attr(not(web), trait_variant::make(Send + Sync))]
86pub trait Context: Clone
87where
88 crate::ViewError: From<Self::Error>,
89{
90 type Store: ReadableKeyValueStore + WritableKeyValueStore + WithError<Error = Self::Error>;
92
93 type Extra: Clone + linera_base::util::traits::AutoTraits;
95
96 type Error: KeyValueStoreError;
99
100 fn store(&self) -> &Self::Store;
102
103 fn extra(&self) -> &Self::Extra;
105
106 fn base_key(&self) -> &BaseKey;
108
109 fn base_key_mut(&mut self) -> &mut BaseKey;
111
112 fn clone_with_base_key(&self, base_key: Vec<u8>) -> Self {
114 let mut context = self.clone();
115 context.base_key_mut().bytes = base_key;
116 context
117 }
118
119 fn clone_with_trimmed_key(&self, n: usize) -> Self {
122 let mut context = self.clone();
123 let key = context.base_key().trimmed_key(n).unwrap();
124 context.base_key_mut().bytes = key;
125 context
126 }
127}
128
129#[derive(Debug, Default, Clone)]
131pub struct InactiveContext(pub BaseKey);
132
133impl Context for InactiveContext {
134 type Store = crate::store::inactive_store::InactiveStore;
135 type Extra = ();
136
137 type Error = crate::store::inactive_store::InactiveStoreError;
138
139 fn store(&self) -> &Self::Store {
140 &crate::store::inactive_store::InactiveStore
141 }
142
143 fn extra(&self) -> &Self::Extra {
144 &()
145 }
146
147 fn base_key(&self) -> &BaseKey {
148 &self.0
149 }
150
151 fn base_key_mut(&mut self) -> &mut BaseKey {
152 &mut self.0
153 }
154}
155
156#[derive(Debug, Default, Clone)]
159pub struct ViewContext<E, S> {
160 store: S,
162 base_key: BaseKey,
164 extra: E,
166}
167
168impl<E, S> ViewContext<E, S>
169where
170 S: ReadableKeyValueStore + WritableKeyValueStore,
171{
172 pub async fn create_root_context(store: S, extra: E) -> Result<Self, S::Error> {
176 store.clear_journal().await?;
177 Ok(Self::new_unchecked(store, Vec::new(), extra))
178 }
179}
180
181impl<E, S> ViewContext<E, S> {
182 pub fn new_unchecked(store: S, base_key: Vec<u8>, extra: E) -> Self {
186 Self {
187 store,
188 base_key: BaseKey { bytes: base_key },
189 extra,
190 }
191 }
192}
193
194impl<E, S> Context for ViewContext<E, S>
195where
196 E: Clone + linera_base::util::traits::AutoTraits,
197 S: ReadableKeyValueStore + WritableKeyValueStore + Clone,
198 S::Error: From<bcs::Error> + Send + Sync + std::error::Error + 'static,
199{
200 type Extra = E;
201 type Store = S;
202
203 type Error = S::Error;
204
205 fn store(&self) -> &Self::Store {
206 &self.store
207 }
208
209 fn extra(&self) -> &E {
210 &self.extra
211 }
212
213 fn base_key(&self) -> &BaseKey {
214 &self.base_key
215 }
216
217 fn base_key_mut(&mut self) -> &mut BaseKey {
218 &mut self.base_key
219 }
220}
221
222pub type MemoryContext<E> = ViewContext<E, MemoryStore>;
224
225impl<E> MemoryContext<E> {
226 #[cfg(with_testing)]
228 pub fn new_for_testing(extra: E) -> Self {
229 Self {
230 store: MemoryStore::new_for_testing(),
231 base_key: BaseKey::default(),
232 extra,
233 }
234 }
235}
236
237impl DeletePrefixExpander for MemoryContext<()> {
238 type Error = crate::memory::MemoryStoreError;
239
240 async fn expand_delete_prefix(&self, key_prefix: &[u8]) -> Result<Vec<Vec<u8>>, Self::Error> {
241 self.store().find_keys_by_prefix(key_prefix).await
242 }
243}