1use std::collections::BTreeMap;
2use std::sync::Arc;
3
4use cita_trie::{PatriciaTrie, Trie, DB};
5use ethereum_types::{BigEndianHash, H256, U256};
6use hashbrown::HashMap;
7
8use crate::common;
9use crate::common::hash;
10use crate::state::err::Error;
11
12#[derive(Debug)]
16pub struct Account {
17 pub balance: U256,
18 pub nonce: U256,
19 pub storage_root: H256,
20 pub code_hash: H256,
21 pub abi_hash: H256,
22}
23
24impl rlp::Encodable for Account {
26 fn rlp_append(&self, s: &mut rlp::RlpStream) {
27 s.begin_list(5)
28 .append(&self.nonce)
29 .append(&self.balance)
30 .append(&self.storage_root)
31 .append(&self.code_hash)
32 .append(&self.abi_hash);
33 }
34}
35
36impl rlp::Decodable for Account {
38 fn decode(data: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
39 Ok(Account {
40 nonce: data.val_at(0)?,
41 balance: data.val_at(1)?,
42 storage_root: data.val_at(2)?,
43 code_hash: data.val_at(3)?,
44 abi_hash: data.val_at(4)?,
45 })
46 }
47}
48
49#[derive(PartialEq, Eq, Clone, Copy, Debug)]
50pub enum CodeState {
51 Clean,
52 Dirty,
53}
54
55#[derive(Debug, Clone)]
56pub struct StateObject {
57 pub balance: U256,
58 pub nonce: U256,
59 pub storage_root: H256,
60 pub code_hash: H256,
61 pub code: Vec<u8>,
62 pub code_size: usize,
63 pub code_state: CodeState,
64 pub abi_hash: H256,
65 pub abi: Vec<u8>,
66 pub abi_size: usize,
67 pub abi_state: CodeState,
68 pub storage_changes: HashMap<H256, H256>,
69}
70
71impl From<Account> for StateObject {
72 fn from(account: Account) -> Self {
73 StateObject {
74 balance: account.balance,
75 nonce: account.nonce,
76 storage_root: account.storage_root,
77 code_hash: account.code_hash,
78 code: vec![],
79 code_size: 0,
80 code_state: CodeState::Clean,
81 abi_hash: account.abi_hash,
82 abi: vec![],
83 abi_size: 0,
84 abi_state: CodeState::Clean,
85 storage_changes: HashMap::new(),
86 }
87 }
88}
89
90impl StateObject {
94 pub fn new(balance: U256, nonce: U256) -> StateObject {
98 StateObject {
99 balance,
100 nonce,
101 storage_root: common::hash::RLP_NULL,
102 code_hash: common::hash::NIL_DATA,
103 code: vec![],
104 code_size: 0,
105 code_state: CodeState::Clean,
106 abi_hash: common::hash::NIL_DATA,
107 abi: vec![],
108 abi_size: 0,
109 abi_state: CodeState::Clean,
110 storage_changes: HashMap::new(),
111 }
112 }
113
114 pub fn from_rlp(data: &[u8]) -> Result<StateObject, Error> {
117 let account: Account = rlp::decode(data)?;
118 Ok(account.into())
119 }
120
121 pub fn account(&self) -> Account {
123 Account {
124 balance: self.balance,
125 nonce: self.nonce,
126 storage_root: self.storage_root,
127 code_hash: self.code_hash,
128 abi_hash: self.abi_hash,
129 }
130 }
131
132 pub fn rlp(&self) -> Vec<u8> {
134 rlp::encode(&self.account()).to_vec()
135 }
136
137 pub fn is_empty(&self) -> bool {
140 self.balance.is_zero()
141 && self.nonce.is_zero()
142 && self.code_hash == common::hash::NIL_DATA
143 && self.storage_root == common::hash::RLP_NULL
144 }
145
146 pub fn init_code(&mut self, code: Vec<u8>) {
148 self.code = code;
149 self.code_size = self.code.len();
150 self.code_hash = {
151 if self.code_size > 0 {
152 H256::from_slice(common::hash::summary(&self.code).as_slice())
153 } else {
154 common::hash::NIL_DATA
155 }
156 };
157 self.code_state = CodeState::Dirty;
158 }
159
160 pub fn init_abi(&mut self, abi: Vec<u8>) {
162 self.abi = abi;
163 self.abi_size = self.abi.len();
164 self.abi_hash = {
165 if self.abi_size > 0 {
166 H256::from_slice(common::hash::summary(&self.abi).as_slice())
167 } else {
168 common::hash::NIL_DATA
169 }
170 };
171 self.abi_state = CodeState::Dirty;
172 }
173
174 pub fn read_code<B: DB>(&mut self, db: Arc<B>) -> Result<(), Error> {
176 if self.code_hash == common::hash::NIL_DATA {
177 return Ok(());
178 }
179 let c = db
180 .get(self.code_hash.as_bytes())
181 .map_err(|e| Error::DB(format!("{}", e)))?
182 .unwrap_or_default();
183 self.code = c;
184 self.code_size = self.code.len();
185 self.code_state = CodeState::Clean;
186 Ok(())
187 }
188
189 pub fn read_abi<B: DB>(&mut self, db: Arc<B>) -> Result<(), Error> {
191 if self.abi_hash == common::hash::NIL_DATA {
192 return Ok(());
193 }
194 let c = db
195 .get(self.abi_hash.as_bytes())
196 .map_err(|e| Error::DB(format!("{}", e)))?
197 .unwrap_or_default();
198 self.abi = c;
199 self.abi_size = self.abi.len();
200 self.abi_state = CodeState::Clean;
201 Ok(())
202 }
203
204 pub fn inc_nonce(&mut self) {
206 self.nonce += U256::from(1u8);
207 }
208
209 pub fn add_balance(&mut self, x: U256) {
212 let (a, b) = self.balance.overflowing_add(x);
213 assert!(!b);
215 self.balance = a;
216 }
217
218 pub fn sub_balance(&mut self, x: U256) {
221 self.balance = self.balance.saturating_sub(x);
222 }
223
224 pub fn set_storage(&mut self, key: H256, value: H256) {
226 self.storage_changes.insert(key, value);
227 }
228
229 pub fn get_storage_at_backend<B: DB>(&self, db: Arc<B>, key: &H256) -> Result<Option<H256>, Error> {
231 if self.storage_root == common::hash::RLP_NULL {
232 return Ok(None);
233 }
234 let trie = PatriciaTrie::from(db, Arc::new(hash::get_hasher()), &self.storage_root.0)?;
235 if let Some(b) = trie.get(key.as_bytes())? {
236 let u256_k: U256 = rlp::decode(&b)?;
237 let h256_k = H256::from_uint(&u256_k);
238 return Ok(Some(h256_k));
239 }
240 Ok(None)
241 }
242
243 pub fn get_storage_at_changes(&self, key: &H256) -> Option<H256> {
245 self.storage_changes.get(key).copied()
246 }
247
248 pub fn get_storage_changes(&self) -> BTreeMap<String, String> {
250 let mut result = BTreeMap::new();
251 for (k, v) in self.storage_changes.iter() {
252 let key = String::from("0x") + &hex::encode(*k);
253 let value = String::from("0x") + &hex::encode(*v);
254 result.insert(key.clone(), value.clone());
255 }
256 result
257 }
258
259 pub fn get_storage<B: DB>(&self, db: Arc<B>, key: &H256) -> Result<Option<H256>, Error> {
261 if let Some(value) = self.get_storage_at_changes(key) {
262 return Ok(Some(value));
263 }
264 if let Some(value) = self.get_storage_at_backend(db, key)? {
265 return Ok(Some(value));
266 }
267 Ok(None)
268 }
269
270 pub fn get_storage_proof<B: DB>(&self, db: Arc<B>, key: &H256) -> Result<Vec<Vec<u8>>, Error> {
272 let trie = PatriciaTrie::from(db, Arc::new(hash::get_hasher()), &self.storage_root.0)
273 .map_err(|e| Error::DB(format!("StateObject::get_storage_proof: {}", e)))?;
274 let proof = trie.get_proof(&key.0)?;
275 Ok(proof)
276 }
277
278 pub fn commit_storage<B: DB>(&mut self, db: Arc<B>) -> Result<(), Error> {
280 let mut trie = if self.storage_root == common::hash::RLP_NULL {
281 PatriciaTrie::new(db, Arc::new(hash::get_hasher()))
282 } else {
283 PatriciaTrie::from(db, Arc::new(hash::get_hasher()), &self.storage_root.0)?
284 };
285
286 for (k, v) in self.storage_changes.drain() {
287 if v.is_zero() {
288 trie.remove(k.as_bytes())?;
289 } else {
290 trie.insert(k.0.to_vec(), rlp::encode(&U256::from_big_endian(v.as_bytes())).to_vec())?;
291 }
292 }
293
294 self.storage_root = H256::from_slice(trie.root()?.as_slice());
295 Ok(())
296 }
297
298 pub fn commit_code<B: DB>(&mut self, db: Arc<B>) -> Result<(), Error> {
300 match (self.code_state == CodeState::Dirty, self.code.is_empty()) {
301 (true, true) => {
302 self.code_size = 0;
303 self.code_state = CodeState::Clean;
304 }
305 (true, false) => {
306 db.insert(self.code_hash.0.to_vec(), self.code.clone())
307 .map_err(|e| Error::DB(format!("{}", e)))?;
308 self.code_size = self.code.len();
309 self.code_state = CodeState::Clean;
310 }
311 (false, _) => {}
312 }
313 Ok(())
314 }
315
316 pub fn commit_abi<B: DB>(&mut self, db: Arc<B>) -> Result<(), Error> {
318 match (self.abi_state == CodeState::Dirty, self.abi.is_empty()) {
319 (true, true) => {
320 self.abi_size = 0;
321 self.abi_state = CodeState::Clean;
322 }
323 (true, false) => {
324 db.insert(self.abi_hash.0.to_vec(), self.abi.clone())
325 .map_err(|e| Error::DB(format!("{}", e)))?;
326 self.abi_size = self.abi.len();
327 self.abi_state = CodeState::Clean;
328 }
329 (false, _) => {}
330 }
331 Ok(())
332 }
333
334 pub fn clone_clean(&self) -> StateObject {
336 StateObject {
337 balance: self.balance,
338 nonce: self.nonce,
339 storage_root: self.storage_root,
340 code: self.code.clone(),
341 code_hash: self.code_hash,
342 code_size: self.code_size,
343 code_state: self.code_state,
344 abi: self.abi.clone(),
345 abi_hash: self.abi_hash,
346 abi_size: self.abi_size,
347 abi_state: self.abi_state,
348 storage_changes: HashMap::new(),
349 }
350 }
351
352 pub fn clone_dirty(&self) -> StateObject {
354 let mut state_object = self.clone_clean();
355 state_object.storage_changes = self.storage_changes.clone();
356 state_object
357 }
358
359 pub fn merge(&mut self, other: StateObject) {
361 self.balance = other.balance;
362 self.nonce = other.nonce;
363 self.storage_root = other.storage_root;
364 self.code_hash = other.code_hash;
365 self.code_state = other.code_state;
366 self.code = other.code;
367 self.code_size = other.code_size;
368 self.abi_hash = other.abi_hash;
369 self.abi_state = other.abi_state;
370 self.abi = other.abi;
371 self.abi_size = other.abi_size;
372 self.storage_changes = other.storage_changes;
373 }
374}
375
376#[cfg(test)]
377mod tests {
378 use super::*;
379 use std::str::FromStr;
380
381 #[test]
382 fn state_object_new() {
383 let o = StateObject::new(69u8.into(), 0u8.into());
384 assert_eq!(o.balance, 69u8.into());
385 assert_eq!(o.nonce, 0u8.into());
386 assert_eq!(o.code_hash, common::hash::NIL_DATA);
387 assert_eq!(o.abi_hash, common::hash::NIL_DATA);
388 assert_eq!(o.storage_root, common::hash::RLP_NULL);
389 assert_eq!(hex::encode(rlp::encode(&o.account())), "f8658045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
390 }
391
392 #[test]
393 fn state_object_rlp() {
394 let a = StateObject::new(69u8.into(), 0u8.into());
395 let b = StateObject::from_rlp(&rlp::encode(&a.account())[..]).unwrap();
396 assert_eq!(a.balance, b.balance);
397 assert_eq!(a.nonce, b.nonce);
398 assert_eq!(a.code_hash, b.code_hash);
399 assert_eq!(a.storage_root, b.storage_root);
400 }
401
402 #[test]
403 fn state_object_code() {
404 let mut a = StateObject::new(69u8.into(), 0.into());
405 let db = Arc::new(cita_trie::MemoryDB::new(false));
406 a.init_code(vec![0x55, 0x44, 0xffu8]);
407 assert_eq!(a.code_state, CodeState::Dirty);
408 assert_eq!(a.code_size, 3);
409 a.commit_code(Arc::clone(&db)).unwrap();
410 assert_eq!(a.code_state, CodeState::Clean);
411 assert_eq!(
412 a.code_hash,
413 H256::from_str("af231e631776a517ca23125370d542873eca1fb4d613ed9b5d5335a46ae5b7eb").unwrap()
414 );
415
416 let k = a.code_hash.0.to_vec();
417 assert_eq!(db.get(&k).unwrap().unwrap(), vec![0x55, 0x44, 0xffu8]);
418 a.init_code(vec![0x55]);
419 assert_eq!(a.code_state, CodeState::Dirty);
420 assert_eq!(a.code_size, 1);
421 a.commit_code(Arc::clone(&db)).unwrap();
422 assert_eq!(
423 a.code_hash,
424 H256::from_str("37bf2238b11b68cdc8382cece82651b59d3c3988873b6e0f33d79694aa45f1be").unwrap()
425 );
426
427 let k = a.code_hash.0.to_vec();
428 assert_eq!(db.get(&k).unwrap().unwrap(), vec![0x55]);
429 }
430
431 #[test]
432 fn state_object_storage_1() {
433 let mut a = StateObject::new(69u8.into(), 0.into());
434 let db = Arc::new(cita_trie::MemoryDB::new(false));
435 a.set_storage(H256::zero(), H256::from_low_u64_be(0x1234));
436 a.commit_storage(Arc::clone(&db)).unwrap();
437 assert_eq!(
438 a.storage_root,
439 H256::from_str("71623f5ec821de33ad5aa81f8c82f0916c6f60de0a536f8c466d440c56715bd5").unwrap()
440 );
441 }
442
443 #[test]
444 fn state_object_storage_2() {
445 let mut a = StateObject::new(69u8.into(), 0.into());
446 let db = Arc::new(cita_trie::MemoryDB::new(false));
447 a.set_storage(H256::zero(), H256::from_low_u64_be(0x1234));
448 a.commit_storage(Arc::clone(&db)).unwrap();
449 assert_eq!(
450 a.storage_root,
451 H256::from_str("71623f5ec821de33ad5aa81f8c82f0916c6f60de0a536f8c466d440c56715bd5").unwrap()
453 );
454 a.set_storage(H256::from_low_u64_be(1), H256::from_low_u64_be(0x1234));
455 a.commit_storage(Arc::clone(&db)).unwrap();
456 assert_eq!(
457 a.storage_root,
458 H256::from_str("a3db671bd0653a641fb031dccb869982da390eade9e6f993802ed09c4f6b7b2a").unwrap()
460 );
461 a.set_storage(H256::from_low_u64_be(1), H256::zero());
462 a.commit_storage(Arc::clone(&db)).unwrap();
463 assert_eq!(
464 a.storage_root,
465 H256::from_str("71623f5ec821de33ad5aa81f8c82f0916c6f60de0a536f8c466d440c56715bd5").unwrap()
467 );
468 }
469
470 #[test]
471 fn state_object_storage_3() {
472 let mut a = StateObject::new(69u8.into(), 0.into());
473 let db = Arc::new(cita_trie::MemoryDB::new(false));
474 let a_rlp = {
475 a.set_storage(H256::zero(), H256::from_low_u64_be(0x1234));
476 a.commit_storage(Arc::clone(&db)).unwrap();
477 a.init_code(vec![]);
478 a.commit_code(Arc::clone(&db)).unwrap();
479 rlp::encode(&a.account())
480 };
481 a = StateObject::from_rlp(&a_rlp[..]).unwrap();
482 assert_eq!(
483 a.storage_root,
484 H256::from_str("71623f5ec821de33ad5aa81f8c82f0916c6f60de0a536f8c466d440c56715bd5").unwrap()
486 );
487 assert_eq!(
488 a.get_storage(Arc::clone(&db), &H256::zero()).unwrap().unwrap(),
489 H256::from_low_u64_be(0x1234)
490 );
491 assert_eq!(a.get_storage(Arc::clone(&db), &H256::from_low_u64_be(1)).unwrap(), None);
492 }
493
494 #[test]
495 fn state_object_note_code() {
496 let mut a = StateObject::new(69u8.into(), 0.into());
497 let db = Arc::new(cita_trie::MemoryDB::new(false));
498 let a_rlp = {
499 a.init_code(vec![0x55, 0x44, 0xffu8]);
500 a.commit_code(Arc::clone(&db)).unwrap();
501 a.rlp()
502 };
503 a = StateObject::from_rlp(&a_rlp[..]).unwrap();
504 a.read_code(Arc::clone(&db)).unwrap();
505 assert_eq!(a.code, vec![0x55, 0x44, 0xffu8]);
506 }
507}