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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use exonum_merkledb::{IndexAccess, ObjectHash, ProofListIndex, ProofMapIndex};
use exonum::crypto::{Hash, PublicKey};
use crate::{wallet::Wallet, INITIAL_BALANCE};
#[derive(Debug)]
pub struct Schema<T> {
access: T,
}
impl<T> AsMut<T> for Schema<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.access
}
}
impl<T> Schema<T>
where
T: IndexAccess,
{
pub fn new(access: T) -> Self {
Schema { access }
}
pub fn wallets(&self) -> ProofMapIndex<T, PublicKey, Wallet> {
ProofMapIndex::new("cryptocurrency.wallets", self.access.clone())
}
pub fn wallet_history(&self, public_key: &PublicKey) -> ProofListIndex<T, Hash> {
ProofListIndex::new_in_family(
"cryptocurrency.wallet_history",
public_key,
self.access.clone(),
)
}
pub fn wallet(&self, pub_key: &PublicKey) -> Option<Wallet> {
self.wallets().get(pub_key)
}
pub fn state_hash(&self) -> Vec<Hash> {
vec![self.wallets().object_hash()]
}
pub fn increase_wallet_balance(&mut self, wallet: Wallet, amount: u64, transaction: &Hash) {
let wallet = {
let mut history = self.wallet_history(&wallet.pub_key);
history.push(*transaction);
let history_hash = history.object_hash();
let balance = wallet.balance;
wallet.set_balance(balance + amount, &history_hash)
};
self.wallets().put(&wallet.pub_key, wallet.clone());
}
pub fn decrease_wallet_balance(&mut self, wallet: Wallet, amount: u64, transaction: &Hash) {
let wallet = {
let mut history = self.wallet_history(&wallet.pub_key);
history.push(*transaction);
let history_hash = history.object_hash();
let balance = wallet.balance;
wallet.set_balance(balance - amount, &history_hash)
};
self.wallets().put(&wallet.pub_key, wallet.clone());
}
pub fn create_wallet(&mut self, key: &PublicKey, name: &str, transaction: &Hash) {
let wallet = {
let mut history = self.wallet_history(key);
history.push(*transaction);
let history_hash = history.object_hash();
Wallet::new(key, name, INITIAL_BALANCE, history.len(), &history_hash)
};
self.wallets().put(key, wallet);
}
}