1use crate::types::{
16 Balance,
17 H160,
18};
19use ink_primitives::{
20 AccountId,
21 H256,
22 U256,
23};
24use scale::KeyedVec;
25use std::collections::HashMap;
26
27const BALANCE_OF: &[u8] = b"balance:";
28const STORAGE_OF: &[u8] = b"contract-storage:";
29const CONTRACT_PREFIX: &[u8] = b"contract:";
30const MSG_HANDLER_OF: &[u8] = b"message-handler:";
31const CODE_HASH_OF: &[u8] = b"code-hash:";
32
33pub fn balance_of_key(who: &H160) -> [u8; 32] {
35 let keyed = who.0.to_vec().to_keyed_vec(BALANCE_OF);
36 let mut hashed_key: [u8; 32] = [0; 32];
37 super::hashing::blake2b_256(&keyed[..], &mut hashed_key);
38 hashed_key
39}
40
41pub fn storage_of_contract_key(who: &H160, key: &[u8]) -> [u8; 32] {
43 let keyed = who
44 .as_bytes()
45 .to_vec()
46 .to_keyed_vec(key)
47 .to_keyed_vec(STORAGE_OF);
48 let mut hashed_key: [u8; 32] = [0; 32];
49 super::hashing::blake2b_256(&keyed[..], &mut hashed_key);
50 hashed_key
51}
52
53pub type MessageHandler = fn(Vec<u8>) -> Vec<u8>;
54
55pub fn contract_key(f: MessageHandler) -> [u8; 32] {
56 let f = f as usize;
57 let f = f.to_le_bytes();
58 let keyed = f.to_vec().to_keyed_vec(CONTRACT_PREFIX);
59 let mut ret: [u8; 32] = [0; 32];
60 super::hashing::blake2b_256(&keyed[..], &mut ret);
61 ret
62}
63
64pub fn message_handler_of_contract_key(key: &[u8]) -> [u8; 32] {
65 let keyed = key.to_vec().to_keyed_vec(MSG_HANDLER_OF);
66 let mut hashed_key: [u8; 32] = [0; 32];
67 super::hashing::blake2b_256(&keyed[..], &mut hashed_key);
68 hashed_key
69}
70
71pub fn code_hash_for_addr(addr: &H160) -> [u8; 32] {
72 let key = addr.0;
73 let keyed = key.to_keyed_vec(CODE_HASH_OF);
74 let mut hashed_key: [u8; 32] = [0; 32];
75 super::hashing::blake2b_256(&keyed[..], &mut hashed_key);
76 hashed_key
77}
78
79#[derive(Default)]
84pub struct Database {
85 hmap: HashMap<Vec<u8>, Vec<u8>>,
86 fmap: HashMap<Vec<u8>, MessageHandler>,
87}
88
89impl Database {
90 pub fn new() -> Self {
92 Database {
93 hmap: HashMap::new(),
94 fmap: HashMap::new(),
95 }
96 }
97
98 #[cfg(test)]
100 fn len(&self) -> usize {
101 self.hmap.len()
102 }
103
104 fn get(&self, key: &[u8]) -> Option<&Vec<u8>> {
106 self.hmap.get(key)
107 }
108
109 pub fn get_from_contract_storage(&self, addr: &H160, key: &[u8]) -> Option<&Vec<u8>> {
111 let hashed_key = storage_of_contract_key(addr, key);
112 self.hmap.get(hashed_key.as_slice())
113 }
114
115 pub fn insert_into_contract_storage(
117 &mut self,
118 addr: &H160,
119 key: &[u8],
120 value: Vec<u8>,
121 ) -> Option<Vec<u8>> {
122 let hashed_key = storage_of_contract_key(addr, key);
123 self.hmap.insert(hashed_key.to_vec(), value)
124 }
125
126 pub fn remove_contract_storage(
128 &mut self,
129 addr: &H160,
130 key: &[u8],
131 ) -> Option<Vec<u8>> {
132 let hashed_key = storage_of_contract_key(addr, key);
133 self.hmap.remove(hashed_key.as_slice())
134 }
135
136 pub fn remove(&mut self, key: &[u8]) -> Option<Vec<u8>> {
139 self.hmap.remove(key)
140 }
141
142 pub fn insert(&mut self, key: Vec<u8>, value: Vec<u8>) -> Option<Vec<u8>> {
144 self.hmap.insert(key, value)
145 }
146
147 pub fn clear(&mut self) {
149 self.hmap.clear();
150 }
151
152 pub fn get_acc_balance(&self, _addr: &AccountId) -> Option<Balance> {
154 todo!()
155 }
156
157 pub fn set_acc_balance(&mut self, _addr: &AccountId, _new_balance: Balance) {
159 todo!()
160 }
161
162 pub fn get_balance(&self, addr: &H160) -> Option<U256> {
163 let hashed_key = balance_of_key(addr);
164 self.get(&hashed_key).map(|encoded_balance| {
165 scale::Decode::decode(&mut &encoded_balance[..])
166 .expect("unable to decode balance from database")
167 })
168 }
169
170 pub fn set_balance(&mut self, addr: &H160, new_balance: U256) {
172 let hashed_key = balance_of_key(addr);
173 let encoded_balance = scale::Encode::encode(&new_balance);
174 self.hmap
175 .entry(hashed_key.to_vec())
176 .and_modify(|v| *v = encoded_balance.clone())
177 .or_insert(encoded_balance);
178 }
179
180 pub fn set_contract_message_handler(&mut self, handler: MessageHandler) -> [u8; 32] {
181 let key = contract_key(handler);
182 let hashed_key = message_handler_of_contract_key(&key);
183 self.fmap
184 .entry(hashed_key.to_vec())
185 .and_modify(|x| *x = handler)
186 .or_insert(handler);
187 key
188 }
189
190 pub fn get_contract_message_handler(&mut self, code_hash: &H256) -> MessageHandler {
192 let hashed_key = message_handler_of_contract_key(&code_hash.0);
193 *self.fmap.get(hashed_key.as_slice()).unwrap()
194 }
195
196 pub fn set_code_hash(&mut self, addr: &H160, code_hash: &H256) {
197 let hashed_key = code_hash_for_addr(addr);
198 self.hmap
199 .entry(hashed_key.to_vec())
200 .and_modify(|x| *x = code_hash.as_bytes().to_vec())
201 .or_insert(code_hash.as_bytes().to_vec());
202 }
203
204 pub fn get_code_hash(&self, addr: &H160) -> Option<H256> {
205 let hashed_key = code_hash_for_addr(addr);
206 self.get(&hashed_key)
207 .cloned()
208 .map(|v| H256::from_slice(v.as_slice()))
209 }
210}
211
212#[cfg(test)]
213mod tests {
214 use super::Database;
215 use crate::types::H160;
216
217 #[test]
218 fn basic_operations() {
219 let mut database = Database::new();
220 let key1 = vec![42];
221 let key2 = vec![43];
222 let val1 = vec![44];
223 let val2 = vec![45];
224 let val3 = vec![46];
225
226 assert_eq!(database.len(), 0);
227 assert_eq!(database.get(&key1), None);
228 assert_eq!(database.insert(key1.clone(), val1.clone()), None);
229 assert_eq!(database.get(&key1), Some(&val1));
230 assert_eq!(database.insert(key1.clone(), val2.clone()), Some(val1));
231 assert_eq!(database.get(&key1), Some(&val2));
232 assert_eq!(database.insert(key2.clone(), val3.clone()), None);
233 assert_eq!(database.len(), 2);
234 assert_eq!(database.remove(&key2), Some(val3));
235 assert_eq!(database.len(), 1);
236 database.clear();
237 assert_eq!(database.len(), 0);
238 }
239
240 #[test]
241 fn contract_storage() {
242 let addr = H160::from([1; 20]);
243 let mut storage = Database::new();
244 let key1 = vec![42];
245 let key2 = vec![43];
246 let val1 = vec![44];
247 let val2 = vec![45];
248 let val3 = vec![46];
249
250 assert_eq!(storage.len(), 0);
251 assert_eq!(storage.get_from_contract_storage(&addr, &key1), None);
252 assert_eq!(
253 storage.insert_into_contract_storage(&addr, &key1, val1.clone()),
254 None
255 );
256 assert_eq!(storage.get_from_contract_storage(&addr, &key1), Some(&val1));
257 assert_eq!(
258 storage.insert_into_contract_storage(&addr, &key1, val2.clone()),
259 Some(val1)
260 );
261 assert_eq!(storage.get_from_contract_storage(&addr, &key1), Some(&val2));
262 assert_eq!(
263 storage.insert_into_contract_storage(&addr, &key2, val3.clone()),
264 None
265 );
266 assert_eq!(storage.len(), 2);
267 assert_eq!(storage.remove_contract_storage(&addr, &key2), Some(val3));
268 assert_eq!(storage.len(), 1);
269 assert_eq!(storage.remove_contract_storage(&addr, &key1), Some(val2));
270 assert_eq!(storage.len(), 0);
271 }
272}