forked from broxus/ton-labs-block
-
Notifications
You must be signed in to change notification settings - Fork 0
/
shard_accounts.rs
126 lines (109 loc) · 4.34 KB
/
shard_accounts.rs
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
* Copyright 2018-2020 TON DEV SOLUTIONS LTD.
*
* Licensed under the SOFTWARE EVALUATION License (the "License"); you may not use
* this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific TON DEV software governing permissions and
* limitations under the License.
*/
use crate::{
define_HashmapAugE,
accounts::{Account, ShardAccount},
hashmapaug::{Augmentable, HashmapAugType},
types::{CurrencyCollection, Number5},
Serializable, Deserializable, Augmentation,
};
use std::fmt;
use ton_types::{
error, fail, Result,
AccountId, UInt256,
BuilderData, Cell, IBitstring,
HashmapType, SliceData, hm_label, HashmapSubtree,
};
/////////////////////////////////////////////////////////////////////////////////////////
// 4.1.9. The combined state of all accounts in a shard. The split part
// of the shardchain state (cf. 1.2.1 and 1.2.2) is given by (upd from Lite Client v11):
// _ (HashmapAugE 256 ShardAccount DepthBalanceInfo) = ShardAccounts;
define_HashmapAugE!(ShardAccounts, 256, UInt256, ShardAccount, DepthBalanceInfo);
impl HashmapSubtree for ShardAccounts {}
impl ShardAccounts {
pub fn insert(&mut self, split_depth: u8, account: &Account, last_trans_hash: UInt256, last_trans_lt: u64) -> Result<Option<AccountId>> {
match account.get_id() {
Some(acc_id) => {
let depth_balance_info = DepthBalanceInfo::new(split_depth, account.get_balance().unwrap())?;
let sh_account = ShardAccount::with_params(account, last_trans_hash, last_trans_lt)?;
self.set_builder_serialized(acc_id.clone(), &sh_account.write_to_new_cell()?, &depth_balance_info).unwrap();
Ok(Some(acc_id))
}
_ => Ok(None)
}
}
pub fn account(&self, account_id: &AccountId) -> Result<Option<ShardAccount>> {
self.get_serialized(account_id.clone())
}
pub fn balance(&self, account_id: &AccountId) -> Result<Option<DepthBalanceInfo>> {
match self.get_serialized_raw(account_id.clone())? {
Some(mut slice) => Ok(Some(DepthBalanceInfo::construct_from(&mut slice)?)),
None => Ok(None)
}
}
pub fn full_balance(&self) -> &CurrencyCollection {
&self.root_extra().balance
}
pub fn split_for(&mut self, split_key: &SliceData) -> Result<&DepthBalanceInfo> {
self.into_subtree_with_prefix(split_key, &mut 0)?;
self.update_root_extra()
}
}
impl Augmentation<DepthBalanceInfo> for ShardAccount {
fn aug(&self) -> Result<DepthBalanceInfo> {
let account = self.read_account()?;
let balance = account.balance().cloned().unwrap_or_default();
let split_depth = account.split_depth().unwrap_or_default();
Ok(DepthBalanceInfo {
split_depth,
balance,
})
}
}
/// depth_balance$_ split_depth:(#<= 30) balance:CurrencyCollection = DepthBalanceInfo;
#[derive(Default, Clone, Debug, Eq, PartialEq)]
pub struct DepthBalanceInfo {
split_depth: Number5,
balance: CurrencyCollection,
}
impl DepthBalanceInfo {
pub fn new(split_depth: u8, balance: &CurrencyCollection) -> Result<Self> {
Ok(Self {
split_depth: Number5::new_checked(split_depth as u32, 30)?,
balance: balance.clone(),
})
}
pub fn set_split_depth(&mut self, split_depth: Number5) { self.split_depth = split_depth }
pub fn set_balance(&mut self, balance: CurrencyCollection) { self.balance = balance }
pub fn balance(&self) -> &CurrencyCollection { &self.balance }
}
impl Augmentable for DepthBalanceInfo {
fn calc(&mut self, other: &Self) -> Result<bool> {
self.balance.calc(&other.balance)
// TODO: do something with split_depth
}
}
impl Deserializable for DepthBalanceInfo {
fn read_from(&mut self, cell: &mut SliceData) -> Result<()> {
self.split_depth.read_from(cell)?;
self.balance.read_from(cell)?;
Ok(())
}
}
impl Serializable for DepthBalanceInfo {
fn write_to(&self, cell: &mut BuilderData) -> Result<()> {
self.split_depth.write_to(cell)?;
self.balance.write_to(cell)?;
Ok(())
}
}