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::{
12 KeyValueDatabase, KeyValueStoreError, ReadableKeyValueStore, WithError,
13 WritableKeyValueStore,
14 },
15 views::MIN_VIEW_TAG,
16};
17
18#[derive(Default, Debug, Clone, derive_more::From)]
20pub struct BaseKey {
21 #[from]
23 #[debug(with = "hex_debug")]
24 pub bytes: Vec<u8>,
25}
26
27impl BaseKey {
28 pub fn base_tag(&self, tag: u8) -> Vec<u8> {
30 assert!(tag >= MIN_VIEW_TAG, "tag should be at least MIN_VIEW_TAG");
31 let mut key = Vec::with_capacity(self.bytes.len() + 1);
32 key.extend_from_slice(&self.bytes);
33 key.push(tag);
34 key
35 }
36
37 pub fn base_tag_index(&self, tag: u8, index: &[u8]) -> Vec<u8> {
39 assert!(tag >= MIN_VIEW_TAG, "tag should be at least MIN_VIEW_TAG");
40 let mut key = Vec::with_capacity(self.bytes.len() + 1 + index.len());
41 key.extend_from_slice(&self.bytes);
42 key.push(tag);
43 key.extend_from_slice(index);
44 key
45 }
46
47 pub fn base_index(&self, index: &[u8]) -> Vec<u8> {
49 let mut key = Vec::with_capacity(self.bytes.len() + index.len());
50 key.extend_from_slice(&self.bytes);
51 key.extend_from_slice(index);
52 key
53 }
54
55 pub fn derive_tag_key<I: Serialize>(&self, tag: u8, index: &I) -> Result<Vec<u8>, bcs::Error> {
57 assert!(tag >= MIN_VIEW_TAG, "tag should be at least MIN_VIEW_TAG");
58 let mut key = self.base_tag(tag);
59 bcs::serialize_into(&mut key, index)?;
60 Ok(key)
61 }
62
63 fn trimmed_key(&self, n: usize) -> Result<Vec<u8>, bcs::Error> {
65 if self.bytes.len() < n {
66 return Err(bcs::Error::Custom(format!(
67 "attempted to trim {} bytes from key of length {}",
68 n,
69 self.bytes.len()
70 )));
71 }
72 Ok(self.bytes[0..self.bytes.len() - n].to_vec())
73 }
74
75 pub fn derive_short_key<I: Serialize + ?Sized>(index: &I) -> Result<Vec<u8>, bcs::Error> {
77 bcs::to_bytes(index)
78 }
79
80 pub fn deserialize_value<Item: DeserializeOwned>(bytes: &[u8]) -> Result<Item, bcs::Error> {
82 bcs::from_bytes(bytes)
83 }
84}
85
86#[cfg_attr(not(web), trait_variant::make(Send + Sync))]
89pub trait Context: Clone
90where
91 crate::ViewError: From<Self::Error>,
92{
93 type Store: ReadableKeyValueStore + WritableKeyValueStore + WithError<Error = Self::Error>;
95
96 type Extra: Clone + linera_base::util::traits::AutoTraits;
98
99 type Error: KeyValueStoreError;
102
103 fn store(&self) -> &Self::Store;
105
106 fn extra(&self) -> &Self::Extra;
108
109 fn base_key(&self) -> &BaseKey;
111
112 fn base_key_mut(&mut self) -> &mut BaseKey;
114
115 fn clone_with_base_key(&self, base_key: Vec<u8>) -> Self {
117 let mut context = self.clone();
118 context.base_key_mut().bytes = base_key;
119 context
120 }
121
122 fn clone_with_trimmed_key(&self, n: usize) -> Self {
125 let mut context = self.clone();
126 let key = context.base_key().trimmed_key(n).unwrap();
127 context.base_key_mut().bytes = key;
128 context
129 }
130}
131
132#[derive(Debug, Default, Clone)]
134pub struct InactiveContext(pub BaseKey);
135
136impl Context for InactiveContext {
137 type Store = crate::store::inactive_store::InactiveStore;
138 type Extra = ();
139
140 type Error = crate::store::inactive_store::InactiveStoreError;
141
142 fn store(&self) -> &Self::Store {
143 &crate::store::inactive_store::InactiveStore
144 }
145
146 fn extra(&self) -> &Self::Extra {
147 &()
148 }
149
150 fn base_key(&self) -> &BaseKey {
151 &self.0
152 }
153
154 fn base_key_mut(&mut self) -> &mut BaseKey {
155 &mut self.0
156 }
157}
158
159#[derive(Debug, Default, Clone)]
162pub struct ViewContext<E, S> {
163 store: S,
165 base_key: BaseKey,
167 extra: E,
169}
170
171impl<E, S> ViewContext<E, S>
172where
173 S: ReadableKeyValueStore + WritableKeyValueStore,
174{
175 pub async fn create_root_context<D>(
182 database: &D,
183 root_key: &[u8],
184 extra: E,
185 ) -> Result<Self, S::Error>
186 where
187 D: KeyValueDatabase<Store = S> + WithError<Error = S::Error>,
188 {
189 let store = database.open_exclusive(root_key)?;
190 store.clear_journal().await?;
191 Ok(Self::new_unchecked(store, Vec::new(), extra))
192 }
193}
194
195impl<E, S> ViewContext<E, S> {
196 pub fn new_unchecked(store: S, base_key: Vec<u8>, extra: E) -> Self {
200 Self {
201 store,
202 base_key: BaseKey { bytes: base_key },
203 extra,
204 }
205 }
206}
207
208impl<E, S> Context for ViewContext<E, S>
209where
210 E: Clone + linera_base::util::traits::AutoTraits,
211 S: ReadableKeyValueStore + WritableKeyValueStore + Clone,
212 S::Error: From<bcs::Error> + Send + Sync + std::error::Error + 'static,
213{
214 type Extra = E;
215 type Store = S;
216
217 type Error = S::Error;
218
219 fn store(&self) -> &Self::Store {
220 &self.store
221 }
222
223 fn extra(&self) -> &E {
224 &self.extra
225 }
226
227 fn base_key(&self) -> &BaseKey {
228 &self.base_key
229 }
230
231 fn base_key_mut(&mut self) -> &mut BaseKey {
232 &mut self.base_key
233 }
234}
235
236pub type MemoryContext<E> = ViewContext<E, MemoryStore>;
238
239impl<E> MemoryContext<E> {
240 #[cfg(with_testing)]
242 pub fn new_for_testing(extra: E) -> Self {
243 Self {
244 store: MemoryStore::new_for_testing(),
245 base_key: BaseKey::default(),
246 extra,
247 }
248 }
249}
250
251impl DeletePrefixExpander for MemoryContext<()> {
252 type Error = crate::memory::MemoryStoreError;
253
254 async fn expand_delete_prefix(&self, key_prefix: &[u8]) -> Result<Vec<Vec<u8>>, Self::Error> {
255 self.store().find_keys_by_prefix(key_prefix).await
256 }
257}