-
Notifications
You must be signed in to change notification settings - Fork 198
/
metaAccount.go
215 lines (171 loc) · 5.66 KB
/
metaAccount.go
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package state
import (
"math/big"
"github.com/ElrondNetwork/elrond-go/data"
)
// MiniBlockData is the data to be saved in shard account for any shard
type MiniBlockData struct {
Hash []byte
ReceiverShardId uint32
SenderShardId uint32
TxCount uint32
}
// MetaAccount is the struct used in serialization/deserialization
type MetaAccount struct {
Round uint64
Nonce uint64
TxCount *big.Int
CodeHash []byte
RootHash []byte
MiniBlocks []*MiniBlockData
PubKeyLeader []byte
ShardRootHash []byte
addressContainer AddressContainer
code []byte
accountTracker AccountTracker
dataTrieTracker DataTrieTracker
}
// NewMetaAccount creates new simple meta account for an AccountContainer (that has just been initialized)
func NewMetaAccount(addressContainer AddressContainer, tracker AccountTracker) (*MetaAccount, error) {
if addressContainer == nil || addressContainer.IsInterfaceNil() {
return nil, ErrNilAddressContainer
}
if tracker == nil || tracker.IsInterfaceNil() {
return nil, ErrNilAccountTracker
}
return &MetaAccount{
TxCount: big.NewInt(0),
addressContainer: addressContainer,
accountTracker: tracker,
dataTrieTracker: NewTrackableDataTrie(nil),
}, nil
}
// IsInterfaceNil returns true if there is no value under the interface
func (a *MetaAccount) IsInterfaceNil() bool {
if a == nil {
return true
}
return false
}
// AddressContainer returns the address associated with the account
func (a *MetaAccount) AddressContainer() AddressContainer {
return a.addressContainer
}
// SetRoundWithJournal sets the account's round, saving the old round before changing
func (a *MetaAccount) SetRoundWithJournal(round uint64) error {
entry, err := NewMetaJournalEntryRound(a, a.Round)
if err != nil {
return err
}
a.accountTracker.Journalize(entry)
a.Round = round
return a.accountTracker.SaveAccount(a)
}
// SetTxCountWithJournal sets the total tx count for this shard, saving the old txCount before changing
func (a *MetaAccount) SetTxCountWithJournal(txCount *big.Int) error {
entry, err := NewMetaJournalEntryTxCount(a, a.TxCount)
if err != nil {
return err
}
a.accountTracker.Journalize(entry)
a.TxCount = txCount
return a.accountTracker.SaveAccount(a)
}
// SetMiniBlocksDataWithJournal sets the current final mini blocks header data,
// saving the old mini blocks header data before changing
func (a *MetaAccount) SetMiniBlocksDataWithJournal(miniBlocksData []*MiniBlockData) error {
entry, err := NewMetaJournalEntryMiniBlocksData(a, a.MiniBlocks)
if err != nil {
return err
}
a.accountTracker.Journalize(entry)
a.MiniBlocks = miniBlocksData
return a.accountTracker.SaveAccount(a)
}
// SetShardRootHashWithJournal sets the account's root hash, saving the old root hash before changing
func (a *MetaAccount) SetShardRootHashWithJournal(shardRootHash []byte) error {
entry, err := NewMetaJournalEntryShardRootHash(a, a.ShardRootHash)
if err != nil {
return err
}
a.accountTracker.Journalize(entry)
a.ShardRootHash = shardRootHash
return a.accountTracker.SaveAccount(a)
}
//------- code / code hash
// GetCodeHash returns the code hash associated with this account
func (a *MetaAccount) GetCodeHash() []byte {
return a.CodeHash
}
// SetCodeHash sets the code hash associated with the account
func (a *MetaAccount) SetCodeHash(roothash []byte) {
a.CodeHash = roothash
}
// SetCodeHashWithJournal sets the account's code hash, saving the old code hash before changing
func (a *MetaAccount) SetCodeHashWithJournal(codeHash []byte) error {
entry, err := NewBaseJournalEntryCodeHash(a, a.CodeHash)
if err != nil {
return err
}
a.accountTracker.Journalize(entry)
a.CodeHash = codeHash
return a.accountTracker.SaveAccount(a)
}
// GetCode gets the actual code that needs to be run in the VM
func (a *MetaAccount) GetCode() []byte {
return a.code
}
// SetCode sets the actual code that needs to be run in the VM
func (a *MetaAccount) SetCode(code []byte) {
a.code = code
}
//------- data trie / root hash
// GetRootHash returns the root hash associated with this account
func (a *MetaAccount) GetRootHash() []byte {
return a.RootHash
}
// SetRootHash sets the root hash associated with the account
func (a *MetaAccount) SetRootHash(roothash []byte) {
a.RootHash = roothash
}
// SetRootHashWithJournal sets the account's root hash, saving the old root hash before changing
func (a *MetaAccount) SetRootHashWithJournal(rootHash []byte) error {
entry, err := NewBaseJournalEntryRootHash(a, a.RootHash, a.DataTrie())
if err != nil {
return err
}
a.accountTracker.Journalize(entry)
a.RootHash = rootHash
return a.accountTracker.SaveAccount(a)
}
// SetNonceWithJournal sets the account's nonce, saving the old nonce before changing
func (a *MetaAccount) SetNonceWithJournal(nonce uint64) error {
entry, err := NewBaseJournalEntryNonce(a, a.Nonce)
if err != nil {
return err
}
a.accountTracker.Journalize(entry)
a.Nonce = nonce
return a.accountTracker.SaveAccount(a)
}
//SetNonce saves the nonce to the account
func (a *MetaAccount) SetNonce(nonce uint64) {
a.Nonce = nonce
}
// GetNonce gets the nonce of the account
func (a *MetaAccount) GetNonce() uint64 {
return a.Nonce
}
// DataTrie returns the trie that holds the current account's data
func (a *MetaAccount) DataTrie() data.Trie {
return a.dataTrieTracker.DataTrie()
}
// SetDataTrie sets the trie that holds the current account's data
func (a *MetaAccount) SetDataTrie(trie data.Trie) {
a.dataTrieTracker.SetDataTrie(trie)
}
// DataTrieTracker returns the trie wrapper used in managing the SC data
func (a *MetaAccount) DataTrieTracker() DataTrieTracker {
return a.dataTrieTracker
}
//TODO add Cap'N'Proto converter funcs