1use std::sync::Arc;
2
3use cita_trie::{PatriciaTrie, Trie, DB};
4use ethereum_types::{H256, U256};
5use hashbrown::HashMap;
6
7use super::err::Error;
8use super::hashlib;
9
10#[derive(Debug)]
14pub struct Account {
15 pub balance: U256,
16 pub nonce: U256,
17 pub storage_root: H256,
18 pub code_hash: H256,
19}
20
21impl rlp::Encodable for Account {
23 fn rlp_append(&self, s: &mut rlp::RlpStream) {
24 s.begin_list(4)
25 .append(&self.nonce)
26 .append(&self.balance)
27 .append(&self.storage_root)
28 .append(&self.code_hash);
29 }
30}
31
32impl rlp::Decodable for Account {
34 fn decode(data: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
35 Ok(Account {
36 nonce: data.val_at(0)?,
37 balance: data.val_at(1)?,
38 storage_root: data.val_at(2)?,
39 code_hash: data.val_at(3)?,
40 })
41 }
42}
43
44#[derive(PartialEq, Eq, Clone, Copy, Debug)]
45pub enum CodeState {
46 Clean,
47 Dirty,
48}
49
50#[derive(Debug, Clone)]
51pub struct StateObject {
52 pub balance: U256,
53 pub nonce: U256,
54 pub storage_root: H256,
55 pub code_hash: H256,
56 pub code: Vec<u8>,
57 pub code_size: usize,
58 pub code_state: CodeState,
59 pub storage_changes: HashMap<H256, H256>,
60}
61
62impl From<Account> for StateObject {
63 fn from(account: Account) -> Self {
64 StateObject {
65 balance: account.balance,
66 nonce: account.nonce,
67 storage_root: account.storage_root,
68 code_hash: account.code_hash,
69 code: vec![],
70 code_size: 0,
71 code_state: CodeState::Clean,
72 storage_changes: HashMap::new(),
73 }
74 }
75}
76
77const CODE_PREFIX: &str = "C:";
78
79impl StateObject {
80 pub fn new(balance: U256, nonce: U256) -> StateObject {
84 StateObject {
85 balance,
86 nonce,
87 storage_root: hashlib::RLP_NULL,
88 code_hash: hashlib::NIL_DATA,
89 code: vec![],
90 code_size: 0,
91 code_state: CodeState::Clean,
92 storage_changes: HashMap::new(),
93 }
94 }
95
96 pub fn from_rlp(data: &[u8]) -> Result<StateObject, Error> {
99 let account: Account = rlp::decode(data)?;
100 Ok(account.into())
101 }
102
103 pub fn account(&self) -> Account {
105 Account {
106 balance: self.balance,
107 nonce: self.nonce,
108 storage_root: self.storage_root,
109 code_hash: self.code_hash,
110 }
111 }
112
113 pub fn rlp(&self) -> Vec<u8> {
115 rlp::encode(&self.account())
116 }
117
118 pub fn is_empty(&self) -> bool {
121 self.balance.is_zero() && self.nonce.is_zero() && self.code_hash == hashlib::NIL_DATA
122 }
123
124 pub fn init_code(&mut self, code: Vec<u8>) {
126 self.code = code;
127 self.code_hash = From::from(&hashlib::summary(&self.code)[..]);
128 self.code_size = self.code.len();
129 self.code_state = CodeState::Dirty;
130 }
131
132 pub fn read_code<B: DB>(&mut self, db: Arc<B>) -> Result<(), Error> {
134 if self.code_hash == hashlib::NIL_DATA {
135 return Ok(());
136 }
137 let mut k = CODE_PREFIX.as_bytes().to_vec();
138 k.extend(self.code_hash.to_vec());
139 let c = db
140 .get(&k)
141 .or_else(|e| Err(Error::DB(format!("{}", e))))?
142 .unwrap_or_else(|| vec![]);
143 self.code = c;
144 self.code_size = self.code.len();
145 self.code_state = CodeState::Clean;
146 Ok(())
147 }
148
149 pub fn inc_nonce(&mut self) {
151 self.nonce += U256::from(1u8);
152 }
153
154 pub fn add_balance(&mut self, x: U256) {
157 let (a, b) = self.balance.overflowing_add(x);
158 assert_eq!(b, false);
160 self.balance = a;
161 }
162
163 pub fn sub_balance(&mut self, x: U256) {
166 let (a, b) = self.balance.overflowing_sub(x);
167 assert_eq!(b, false);
168 self.balance = a;
169 }
170
171 pub fn set_storage(&mut self, key: H256, value: H256) {
173 self.storage_changes.insert(key, value);
174 }
175
176 pub fn get_storage_at_backend<B: DB>(&self, db: Arc<B>, key: &H256) -> Result<Option<H256>, Error> {
178 if self.storage_root == hashlib::RLP_NULL {
179 return Ok(None);
180 }
181 let trie = PatriciaTrie::<_, cita_trie::Keccak256Hash>::from(db, &self.storage_root.0)?;
182 if let Some(b) = trie.get(&hashlib::encodek(key))? {
183 let u256_k: U256 = From::from(&hashlib::decodev(&b)?[..]);
184 let h256_k: H256 = u256_k.into();
185 return Ok(Some(h256_k));
186 }
187 Ok(None)
188 }
189
190 pub fn get_storage_at_changes(&self, key: &H256) -> Option<H256> {
192 self.storage_changes.get(key).and_then(|e| Some(*e))
193 }
194
195 pub fn get_storage<B: DB>(&self, db: Arc<B>, key: &H256) -> Result<Option<H256>, Error> {
197 if let Some(value) = self.get_storage_at_changes(key) {
198 return Ok(Some(value));
199 }
200 if let Some(value) = self.get_storage_at_backend(db, key)? {
201 return Ok(Some(value));
202 }
203 Ok(None)
204 }
205
206 pub fn get_storage_proof<B: DB>(&self, db: Arc<B>, key: &H256) -> Result<Vec<Vec<u8>>, Error> {
208 let trie = PatriciaTrie::<_, cita_trie::Keccak256Hash>::from(db, &self.storage_root.0)
209 .or_else(|e| Err(Error::DB(format!("StateObject::get_storage_proof: {}", e))))?;
210 let proof = trie.get_proof(&key.0)?;
211 Ok(proof)
212 }
213
214 pub fn commit_storage<B: DB>(&mut self, db: Arc<B>) -> Result<(), Error> {
216 let mut trie = if self.storage_root == hashlib::RLP_NULL {
217 PatriciaTrie::<_, cita_trie::Keccak256Hash>::new(db)
218 } else {
219 PatriciaTrie::<_, cita_trie::Keccak256Hash>::from(db, &self.storage_root.0)?
220 };
221 for (k, v) in self.storage_changes.drain() {
222 if v.is_zero() {
223 trie.remove(&hashlib::encodek(&k))?;
224 } else {
225 trie.insert(hashlib::encodek(&k), hashlib::encodev(&U256::from(v)))?;
226 }
227 }
228 self.storage_root = H256::from(&(trie.root()?)[..]);
229 Ok(())
230 }
231
232 pub fn commit_code<B: DB>(&mut self, db: Arc<B>) -> Result<(), Error> {
234 match (self.code_state == CodeState::Dirty, self.code.is_empty()) {
235 (true, true) => {
236 self.code_size = 0;
237 self.code_state = CodeState::Clean;
238 }
239 (true, false) => {
240 let mut k = CODE_PREFIX.as_bytes().to_vec();
241 k.extend(self.code_hash.to_vec());
242 db.insert(k, self.code.clone())
243 .or_else(|e| Err(Error::DB(format!("{}", e))))?;
244 self.code_size = self.code.len();
245 self.code_state = CodeState::Clean;
246 }
247 (false, _) => {}
248 }
249 Ok(())
250 }
251
252 pub fn clone_clean(&self) -> StateObject {
254 StateObject {
255 balance: self.balance,
256 nonce: self.nonce,
257 storage_root: self.storage_root,
258 code: self.code.clone(),
259 code_hash: self.code_hash,
260 code_size: self.code_size,
261 code_state: self.code_state,
262 storage_changes: HashMap::new(),
263 }
264 }
265
266 pub fn clone_dirty(&self) -> StateObject {
268 let mut state_object = self.clone_clean();
269 state_object.storage_changes = self.storage_changes.clone();
270 state_object
271 }
272
273 pub fn merge(&mut self, other: StateObject) {
275 self.balance = other.balance;
276 self.nonce = other.nonce;
277 self.storage_root = other.storage_root;
278 self.code_hash = other.code_hash;
279 self.code_state = other.code_state;
280 self.code = other.code;
281 self.code_size = other.code_size;
282 self.storage_changes = other.storage_changes;
283 }
284}
285
286#[cfg(test)]
287mod tests {
288 use super::*;
289
290 #[test]
291 fn state_object_new() {
292 let o = StateObject::new(69u8.into(), 0u8.into());
293 assert_eq!(o.balance, 69u8.into());
294 assert_eq!(o.nonce, 0u8.into());
295 assert_eq!(o.code_hash, hashlib::NIL_DATA);
296 assert_eq!(o.storage_root, hashlib::RLP_NULL);
297 assert_eq!(hex::encode(rlp::encode(&o.account())), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
298 }
299
300 #[test]
301 fn state_object_rlp() {
302 let a = StateObject::new(69u8.into(), 0u8.into());
303 let b = StateObject::from_rlp(&rlp::encode(&a.account())[..]).unwrap();
304 assert_eq!(a.balance, b.balance);
305 assert_eq!(a.nonce, b.nonce);
306 assert_eq!(a.code_hash, b.code_hash);
307 assert_eq!(a.storage_root, b.storage_root);
308 }
309
310 #[test]
311 fn state_object_code() {
312 let mut a = StateObject::new(69u8.into(), 0.into());
313 let db = Arc::new(cita_trie::MemoryDB::new(false));
314 a.init_code(vec![0x55, 0x44, 0xffu8]);
315 assert_eq!(a.code_state, CodeState::Dirty);
316 assert_eq!(a.code_size, 3);
317 a.commit_code(Arc::clone(&db)).unwrap();
318 assert_eq!(a.code_state, CodeState::Clean);
319 assert_eq!(
320 a.code_hash,
321 "af231e631776a517ca23125370d542873eca1fb4d613ed9b5d5335a46ae5b7eb".into()
322 );
323
324 let mut k = CODE_PREFIX.as_bytes().to_vec();
325 k.extend(a.code_hash.to_vec());
326 assert_eq!(db.get(&k).unwrap().unwrap(), vec![0x55, 0x44, 0xffu8]);
327 a.init_code(vec![0x55]);
328 assert_eq!(a.code_state, CodeState::Dirty);
329 assert_eq!(a.code_size, 1);
330 a.commit_code(Arc::clone(&db)).unwrap();
331 assert_eq!(
332 a.code_hash,
333 "37bf2238b11b68cdc8382cece82651b59d3c3988873b6e0f33d79694aa45f1be".into()
334 );
335
336 let mut k = CODE_PREFIX.as_bytes().to_vec();
337 k.extend(a.code_hash.to_vec());
338 assert_eq!(db.get(&k).unwrap().unwrap(), vec![0x55]);
339 }
340
341 #[test]
342 fn state_object_storage_1() {
343 let mut a = StateObject::new(69u8.into(), 0.into());
344 let db = Arc::new(cita_trie::MemoryDB::new(false));
345 a.set_storage(0.into(), 0x1234.into());
346 a.commit_storage(Arc::clone(&db)).unwrap();
347 assert_eq!(
348 a.storage_root,
349 "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into()
350 );
351 }
352
353 #[test]
354 fn state_object_storage_2() {
355 let mut a = StateObject::new(69u8.into(), 0.into());
356 let db = Arc::new(cita_trie::MemoryDB::new(false));
357 a.set_storage(0.into(), 0x1234.into());
358 a.commit_storage(Arc::clone(&db)).unwrap();
359 assert_eq!(
360 a.storage_root,
361 "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into()
362 );
363 a.set_storage(1.into(), 0x1234.into());
364 a.commit_storage(Arc::clone(&db)).unwrap();
365 assert_eq!(
366 a.storage_root,
367 "4e49574efd650366d071855e0a3975123ea9d64cc945e8f5de8c8c517e1b4ca5".into()
368 );
369 a.set_storage(1.into(), 0.into());
370 a.commit_storage(Arc::clone(&db)).unwrap();
371 assert_eq!(
372 a.storage_root,
373 "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into()
374 );
375 }
376
377 #[test]
378 fn state_object_storage_3() {
379 let mut a = StateObject::new(69u8.into(), 0.into());
380 let db = Arc::new(cita_trie::MemoryDB::new(false));
381 let a_rlp = {
382 a.set_storage(0x00u64.into(), 0x1234u64.into());
383 a.commit_storage(Arc::clone(&db)).unwrap();
384 a.init_code(vec![]);
385 a.commit_code(Arc::clone(&db)).unwrap();
386 rlp::encode(&a.account())
387 };
388 a = StateObject::from_rlp(&a_rlp[..]).unwrap();
389 assert_eq!(
390 a.storage_root,
391 "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2".into()
392 );
393 assert_eq!(
394 a.get_storage(Arc::clone(&db), &0x00u64.into()).unwrap().unwrap(),
395 0x1234u64.into()
396 );
397 assert_eq!(a.get_storage(Arc::clone(&db), &0x01u64.into()).unwrap(), None);
398 }
399
400 #[test]
401 fn state_object_note_code() {
402 let mut a = StateObject::new(69u8.into(), 0.into());
403 let db = Arc::new(cita_trie::MemoryDB::new(false));
404 let a_rlp = {
405 a.init_code(vec![0x55, 0x44, 0xffu8]);
406 a.commit_code(Arc::clone(&db)).unwrap();
407 a.rlp()
408 };
409 a = StateObject::from_rlp(&a_rlp[..]).unwrap();
410 a.read_code(Arc::clone(&db)).unwrap();
411 assert_eq!(a.code, vec![0x55, 0x44, 0xffu8]);
412 }
413}