numbat_wasm_debug/api/
storage_api_mock.rs1use crate::{TxContext, TxPanic};
2use alloc::vec::Vec;
3use numbat_wasm::api::{BigIntApi, Handle, ManagedBufferApi, StorageReadApi, StorageWriteApi};
4use num_bigint::{BigInt, BigUint, Sign};
5use num_traits::ToPrimitive;
6
7impl StorageReadApi for TxContext {
8 fn storage_load_len(&self, key: &[u8]) -> usize {
9 self.storage_load_vec_u8(key).len()
10 }
11
12 fn storage_load_vec_u8(&self, key: &[u8]) -> Vec<u8> {
13 let tx_output = self.tx_output_cell.borrow();
14 match tx_output.contract_storage.get(&key.to_vec()) {
15 None => Vec::with_capacity(0),
16 Some(value) => value.clone(),
17 }
18 }
19
20 fn storage_load_big_uint_raw(&self, key: &[u8]) -> Handle {
21 let bytes = self.storage_load_vec_u8(key);
22 let bi = BigInt::from_bytes_be(Sign::Plus, bytes.as_slice());
23 let mut tx_output = self.tx_output_cell.borrow_mut();
24 tx_output.managed_types.big_int_map.insert_new_handle(bi)
25 }
26
27 fn storage_load_managed_buffer_raw(&self, key_handle: Handle) -> Handle {
28 let key_bytes = self.mb_to_boxed_bytes(key_handle);
29 let bytes = self.storage_load_vec_u8(key_bytes.as_slice());
30 self.mb_new_from_bytes(bytes.as_slice())
31 }
32
33 fn storage_load_managed_buffer_len(&self, key_handle: Handle) -> usize {
34 let key_bytes = self.mb_to_boxed_bytes(key_handle);
35 let bytes = self.storage_load_vec_u8(key_bytes.as_slice());
36 bytes.len()
37 }
38
39 fn storage_load_u64(&self, key: &[u8]) -> u64 {
40 let value = self.storage_load_vec_u8(key);
41 let bu = BigUint::from_bytes_be(value.as_slice());
42 if let Some(v) = bu.to_u64() {
43 v
44 } else {
45 std::panic::panic_any(TxPanic {
46 status: 10,
47 message: b"storage value out of range".to_vec(),
48 })
49 }
50 }
51
52 fn storage_load_i64(&self, key: &[u8]) -> i64 {
53 let value = self.storage_load_vec_u8(key);
54 let bi = BigInt::from_signed_bytes_be(value.as_slice());
55 if let Some(v) = bi.to_i64() {
56 v
57 } else {
58 std::panic::panic_any(TxPanic {
59 status: 10,
60 message: b"storage value out of range".to_vec(),
61 })
62 }
63 }
64}
65
66impl StorageWriteApi for TxContext {
67 fn storage_store_slice_u8(&self, key: &[u8], value: &[u8]) {
68 if key.starts_with(&b"NUMBAT"[..]) {
70 std::panic::panic_any(TxPanic {
71 status: 10,
72 message: b"cannot write to storage under Numbat reserved key".to_vec(),
73 });
74 }
75
76 let mut tx_output = self.tx_output_cell.borrow_mut();
77 tx_output
78 .contract_storage
79 .insert(key.to_vec(), value.to_vec());
80 }
81
82 fn storage_store_big_uint_raw(&self, key: &[u8], handle: i32) {
83 self.storage_store_slice_u8(key, self.bi_get_signed_bytes(handle).as_slice());
84 }
85
86 fn storage_store_managed_buffer_raw(&self, key_handle: Handle, value_handle: Handle) {
87 let key_bytes = self.mb_to_boxed_bytes(key_handle);
88 let value_bytes = self.mb_to_boxed_bytes(value_handle);
89 self.storage_store_slice_u8(key_bytes.as_slice(), value_bytes.as_slice());
90 }
91
92 fn storage_store_managed_buffer_clear(&self, key_handle: Handle) {
93 let key_bytes = self.mb_to_boxed_bytes(key_handle);
94 self.storage_store_slice_u8(key_bytes.as_slice(), &[]);
95 }
96
97 fn storage_store_u64(&self, key: &[u8], value: u64) {
98 if value == 0 {
99 self.storage_store_slice_u8(key, &[]);
100 } else {
101 self.storage_store_slice_u8(key, &BigUint::from(value).to_bytes_be());
102 }
103 }
104
105 fn storage_store_i64(&self, key: &[u8], value: i64) {
106 if value == 0 {
107 self.storage_store_slice_u8(key, &[]);
108 } else {
109 self.storage_store_slice_u8(key, &BigInt::from(value).to_signed_bytes_be());
110 }
111 }
112}