1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! Mock Account definition and builder related methods.

use eth_types::{geth_types::Account, Address, Bytes, Word};
use std::collections::HashMap;

#[derive(Debug, Clone, Default)]
/// Mock structure which represents an Account and can be used for tests.
/// It contains all the builder-pattern methods required to be able to specify
/// any of its details.
pub struct MockAccount {
    /// Address
    pub address: Address,
    /// nonce
    pub nonce: u64,
    /// Balance
    pub balance: Word,
    /// EVM Code
    pub code: Bytes,
    /// Storage
    pub storage: HashMap<Word, Word>,
}

impl From<MockAccount> for Account {
    fn from(mock: MockAccount) -> Self {
        Account {
            address: mock.address,
            nonce: mock.nonce.into(),
            balance: mock.balance,
            code: mock.code,
            storage: mock.storage,
        }
    }
}

impl MockAccount {
    /// Set address field for the MockAccount.
    pub fn address(&mut self, address: Address) -> &mut Self {
        self.address = address;
        self
    }

    /// Set nonce field for the MockAccount.
    pub fn nonce(&mut self, nonce: u64) -> &mut Self {
        self.nonce = nonce;
        self
    }

    /// Set balance field for the MockAccount.
    pub fn balance(&mut self, balance: Word) -> &mut Self {
        self.balance = balance;
        self
    }

    /// Set code field for the MockAccount.
    pub fn code<T: Into<Bytes>>(&mut self, code: T) -> &mut Self {
        self.code = code.into();
        self
    }

    /// Add storage field for the MockAccount by passing an iterator over the
    /// key-value tuples of type [(`Word`, `Word`)].
    pub fn storage<I: Iterator<Item = (Word, Word)>>(&mut self, storage: I) -> &mut Self {
        storage.for_each(|pair| {
            assert!(self.storage.insert(pair.0, pair.1).is_none());
        });
        self
    }

    /// Set all fields for the MockAccount based on their values in `account`.
    pub fn account(&mut self, account: &Account) -> &mut Self {
        self.address(account.address);
        self.nonce(account.nonce.as_u64());
        self.balance(account.balance);
        self.code(account.code.clone());
        self.storage(account.storage.iter().map(|(k, v)| (*k, *v)));
        self
    }

    /// Finalizes the current MockAccount under construction returning a new
    /// instance to it.
    pub fn build(&mut self) -> Self {
        self.to_owned()
    }
}