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_key<I: Serialize>(&self, index: &I) -> Result<Vec<u8>, bcs::Error> {
54 let mut key = self.bytes.clone();
55 bcs::serialize_into(&mut key, index)?;
56 assert!(
57 key.len() > self.bytes.len(),
58 "Empty indices are not allowed"
59 );
60 Ok(key)
61 }
62
63 pub fn derive_tag_key<I: Serialize>(&self, tag: u8, index: &I) -> Result<Vec<u8>, bcs::Error> {
65 assert!(tag >= MIN_VIEW_TAG, "tag should be at least MIN_VIEW_TAG");
66 let mut key = self.base_tag(tag);
67 bcs::serialize_into(&mut key, index)?;
68 Ok(key)
69 }
70
71 pub fn derive_short_key<I: Serialize + ?Sized>(index: &I) -> Result<Vec<u8>, bcs::Error> {
73 bcs::to_bytes(index)
74 }
75
76 pub fn deserialize_value<Item: DeserializeOwned>(bytes: &[u8]) -> Result<Item, bcs::Error> {
78 bcs::from_bytes(bytes)
79 }
80}
81
82#[cfg_attr(not(web), trait_variant::make(Send + Sync))]
85pub trait Context: Clone
86where
87 crate::ViewError: From<Self::Error>,
88{
89 type Store: ReadableKeyValueStore + WritableKeyValueStore + WithError<Error = Self::Error>;
91
92 type Extra: Clone + linera_base::util::traits::AutoTraits;
94
95 type Error: KeyValueStoreError;
98
99 fn store(&self) -> &Self::Store;
101
102 fn extra(&self) -> &Self::Extra;
104
105 fn base_key(&self) -> &BaseKey;
107
108 fn base_key_mut(&mut self) -> &mut BaseKey;
110
111 fn clone_with_base_key(&self, base_key: Vec<u8>) -> Self {
113 let mut context = self.clone();
114 context.base_key_mut().bytes = base_key;
115 context
116 }
117}
118
119#[derive(Debug, Default, Clone)]
121pub struct InactiveContext(pub BaseKey);
122
123impl Context for InactiveContext {
124 type Store = crate::store::inactive_store::InactiveStore;
125 type Extra = ();
126
127 type Error = crate::store::inactive_store::InactiveStoreError;
128
129 fn store(&self) -> &Self::Store {
130 &crate::store::inactive_store::InactiveStore
131 }
132
133 fn extra(&self) -> &Self::Extra {
134 &()
135 }
136
137 fn base_key(&self) -> &BaseKey {
138 &self.0
139 }
140
141 fn base_key_mut(&mut self) -> &mut BaseKey {
142 &mut self.0
143 }
144}
145
146#[derive(Debug, Default, Clone)]
149pub struct ViewContext<E, S> {
150 store: S,
152 base_key: BaseKey,
154 extra: E,
156}
157
158impl<E, S> ViewContext<E, S>
159where
160 S: ReadableKeyValueStore + WritableKeyValueStore,
161{
162 pub async fn create_root_context(store: S, extra: E) -> Result<Self, S::Error> {
166 store.clear_journal().await?;
167 Ok(Self::new_unchecked(store, Vec::new(), extra))
168 }
169}
170
171impl<E, S> ViewContext<E, S> {
172 pub fn new_unchecked(store: S, base_key: Vec<u8>, extra: E) -> Self {
176 Self {
177 store,
178 base_key: BaseKey { bytes: base_key },
179 extra,
180 }
181 }
182}
183
184impl<E, S> Context for ViewContext<E, S>
185where
186 E: Clone + linera_base::util::traits::AutoTraits,
187 S: ReadableKeyValueStore + WritableKeyValueStore + Clone,
188 S::Error: From<bcs::Error> + Send + Sync + std::error::Error + 'static,
189{
190 type Extra = E;
191 type Store = S;
192
193 type Error = S::Error;
194
195 fn store(&self) -> &Self::Store {
196 &self.store
197 }
198
199 fn extra(&self) -> &E {
200 &self.extra
201 }
202
203 fn base_key(&self) -> &BaseKey {
204 &self.base_key
205 }
206
207 fn base_key_mut(&mut self) -> &mut BaseKey {
208 &mut self.base_key
209 }
210}
211
212pub type MemoryContext<E> = ViewContext<E, MemoryStore>;
214
215impl<E> MemoryContext<E> {
216 #[cfg(with_testing)]
218 pub fn new_for_testing(extra: E) -> Self {
219 Self {
220 store: MemoryStore::new_for_testing(),
221 base_key: BaseKey::default(),
222 extra,
223 }
224 }
225}
226
227impl DeletePrefixExpander for MemoryContext<()> {
228 type Error = crate::memory::MemoryStoreError;
229
230 async fn expand_delete_prefix(&self, key_prefix: &[u8]) -> Result<Vec<Vec<u8>>, Self::Error> {
231 self.store().find_keys_by_prefix(key_prefix).await
232 }
233}