1use darkfi_serial::Encodable;
20
21use crate::{
22 crypto::ContractId,
23 error::{ContractError, GenericResult},
24 wasm,
25};
26
27pub type DbHandle = u32;
28
29pub fn db_init(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle> {
37 let mut len = 0;
38 let mut buf = vec![];
39 len += contract_id.encode(&mut buf)?;
40 len += db_name.to_string().encode(&mut buf)?;
41
42 let ret = unsafe { db_init_(buf.as_ptr(), len as u32) };
43
44 if ret < 0 {
45 return Err(ContractError::from(ret))
46 }
47
48 Ok(ret as u32)
49}
50
51pub fn db_lookup(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle> {
62 db_lookup_internal(contract_id, db_name, false)
63}
64
65pub fn db_lookup_local(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle> {
79 db_lookup_internal(contract_id, db_name, true)
80}
81
82fn db_lookup_internal(
85 contract_id: ContractId,
86 db_name: &str,
87 local: bool,
88) -> GenericResult<DbHandle> {
89 let mut len = 0;
90 let mut buf = vec![];
91 len += contract_id.encode(&mut buf)?;
92 len += db_name.to_string().encode(&mut buf)?;
93
94 let ret = unsafe {
95 if local {
96 db_lookup_local_(buf.as_ptr(), len as u32)
97 } else {
98 db_lookup_(buf.as_ptr(), len as u32)
99 }
100 };
101
102 if ret < 0 {
103 return Err(ContractError::from(ret))
104 }
105
106 Ok(ret as u32)
107}
108
109pub fn db_get(db_handle: DbHandle, key: &[u8]) -> GenericResult<Option<Vec<u8>>> {
118 db_get_internal(db_handle, key, false)
119}
120
121pub fn db_get_local(db_handle: DbHandle, key: &[u8]) -> GenericResult<Option<Vec<u8>>> {
130 db_get_internal(db_handle, key, true)
131}
132
133fn db_get_internal(db_handle: DbHandle, key: &[u8], local: bool) -> GenericResult<Option<Vec<u8>>> {
136 let mut len = 0;
137 let mut buf = vec![];
138 len += db_handle.encode(&mut buf)?;
139 len += key.encode(&mut buf)?;
140
141 let ret = unsafe {
142 if local {
143 db_get_local_(buf.as_ptr(), len as u32)
144 } else {
145 db_get_(buf.as_ptr(), len as u32)
146 }
147 };
148
149 wasm::util::parse_ret(ret)
150}
151
152pub fn db_contains_key(db_handle: DbHandle, key: &[u8]) -> GenericResult<bool> {
162 db_contains_key_internal(db_handle, key, false)
163}
164
165pub fn db_contains_key_local(db_handle: DbHandle, key: &[u8]) -> GenericResult<bool> {
175 db_contains_key_internal(db_handle, key, true)
176}
177
178fn db_contains_key_internal(db_handle: DbHandle, key: &[u8], local: bool) -> GenericResult<bool> {
181 let mut len = 0;
182 let mut buf = vec![];
183 len += db_handle.encode(&mut buf)?;
184 len += key.encode(&mut buf)?;
185
186 let ret = unsafe {
187 if local {
188 db_contains_key_local_(buf.as_ptr(), len as u32)
189 } else {
190 db_contains_key_(buf.as_ptr(), len as u32)
191 }
192 };
193
194 if ret < 0 {
195 return Err(ContractError::from(ret))
196 }
197
198 match ret {
199 0 => Ok(false),
200 1 => Ok(true),
201 _ => unreachable!(),
202 }
203}
204
205pub fn db_set(db_handle: DbHandle, key: &[u8], value: &[u8]) -> GenericResult<()> {
213 db_set_internal(db_handle, key, value, false)
214}
215
216pub fn db_set_local(db_handle: DbHandle, key: &[u8], value: &[u8]) -> GenericResult<()> {
224 db_set_internal(db_handle, key, value, true)
225}
226
227fn db_set_internal(
230 db_handle: DbHandle,
231 key: &[u8],
232 value: &[u8],
233 local: bool,
234) -> GenericResult<()> {
235 let mut len = 0;
236 let mut buf = vec![];
237 len += db_handle.encode(&mut buf)?;
238 len += key.encode(&mut buf)?;
239 len += value.encode(&mut buf)?;
240
241 let ret = unsafe {
242 if local {
243 db_set_local_(buf.as_ptr(), len as u32)
244 } else {
245 db_set_(buf.as_ptr(), len as u32)
246 }
247 };
248
249 if ret != wasm::entrypoint::SUCCESS {
250 return Err(ContractError::from(ret))
251 }
252
253 Ok(())
254}
255
256pub fn db_del(db_handle: DbHandle, key: &[u8]) -> GenericResult<()> {
264 db_del_internal(db_handle, key, false)
265}
266
267pub fn db_del_local(db_handle: DbHandle, key: &[u8]) -> GenericResult<()> {
275 db_del_internal(db_handle, key, true)
276}
277
278fn db_del_internal(db_handle: DbHandle, key: &[u8], local: bool) -> GenericResult<()> {
281 let mut len = 0;
282 let mut buf = vec![];
283 len += db_handle.encode(&mut buf)?;
284 len += key.encode(&mut buf)?;
285
286 let ret = unsafe {
287 if local {
288 db_del_local_(buf.as_ptr(), len as u32)
289 } else {
290 db_del_(buf.as_ptr(), len as u32)
291 }
292 };
293
294 if ret != wasm::entrypoint::SUCCESS {
295 return Err(ContractError::from(ret))
296 }
297
298 Ok(())
299}
300
301pub fn zkas_db_set(bincode: &[u8]) -> GenericResult<()> {
309 let mut len = 0;
310 let mut buf = vec![];
311 len += bincode.encode(&mut buf)?;
312
313 let ret = unsafe { zkas_db_set_(buf.as_ptr(), len as u32) };
314
315 if ret != wasm::entrypoint::SUCCESS {
316 return Err(ContractError::from(ret))
317 }
318
319 Ok(())
320}
321
322extern "C" {
323 fn db_init_(ptr: *const u8, len: u32) -> i64;
324
325 fn db_lookup_(ptr: *const u8, len: u32) -> i64;
326 fn db_lookup_local_(ptr: *const u8, len: u32) -> i64;
327
328 fn db_get_(ptr: *const u8, len: u32) -> i64;
329 fn db_get_local_(ptr: *const u8, len: u32) -> i64;
330
331 fn db_contains_key_(ptr: *const u8, len: u32) -> i64;
332 fn db_contains_key_local_(ptr: *const u8, len: u32) -> i64;
333
334 fn db_set_(ptr: *const u8, len: u32) -> i64;
335 fn db_set_local_(ptr: *const u8, len: u32) -> i64;
336
337 fn db_del_(ptr: *const u8, len: u32) -> i64;
338 fn db_del_local_(ptr: *const u8, len: u32) -> i64;
339
340 fn zkas_db_set_(ptr: *const u8, len: u32) -> i64;
341}