-
Notifications
You must be signed in to change notification settings - Fork 197
/
journalEntries.go
140 lines (115 loc) · 3.71 KB
/
journalEntries.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
package state
import (
"github.com/ElrondNetwork/elrond-go/core/check"
)
type journalEntryCode struct {
codeHash []byte
updater Updater
}
// NewJournalEntryCode creates a new instance of JournalEntryCode
func NewJournalEntryCode(codeHash []byte, updater Updater) (*journalEntryCode, error) {
if check.IfNil(updater) {
return nil, ErrNilUpdater
}
if len(codeHash) == 0 {
return nil, ErrInvalidHash
}
return &journalEntryCode{
codeHash: codeHash,
updater: updater,
}, nil
}
// Revert applies undo operation
func (jea *journalEntryCode) Revert() (AccountHandler, error) {
return nil, jea.updater.Update(jea.codeHash, nil)
}
// IsInterfaceNil returns true if there is no value under the interface
func (jea *journalEntryCode) IsInterfaceNil() bool {
return jea == nil
}
// JournalEntryAccount represents a journal entry for account fields change
type journalEntryAccount struct {
account AccountHandler
}
// NewJournalEntryAccount creates a new instance of JournalEntryAccount
func NewJournalEntryAccount(account AccountHandler) (*journalEntryAccount, error) {
if check.IfNil(account) {
return nil, ErrNilAccountHandler
}
return &journalEntryAccount{
account: account,
}, nil
}
// Revert applies undo operation
func (jea *journalEntryAccount) Revert() (AccountHandler, error) {
return jea.account, nil
}
// IsInterfaceNil returns true if there is no value under the interface
func (jea *journalEntryAccount) IsInterfaceNil() bool {
return jea == nil
}
// JournalEntryAccountCreation represents a journal entry for account creation
type journalEntryAccountCreation struct {
address []byte
updater Updater
}
// NewJournalEntryAccountCreation creates a new instance of JournalEntryAccountCreation
func NewJournalEntryAccountCreation(address []byte, updater Updater) (*journalEntryAccountCreation, error) {
if check.IfNil(updater) {
return nil, ErrNilUpdater
}
if len(address) == 0 {
return nil, ErrInvalidAddressLength
}
return &journalEntryAccountCreation{
address: address,
updater: updater,
}, nil
}
// Revert applies undo operation
func (jea *journalEntryAccountCreation) Revert() (AccountHandler, error) {
return nil, jea.updater.Update(jea.address, nil)
}
// IsInterfaceNil returns true if there is no value under the interface
func (jea *journalEntryAccountCreation) IsInterfaceNil() bool {
return jea == nil
}
// JournalEntryDataTrieUpdates stores all the updates done to the account's data trie,
// so it can be reverted in case of rollback
type journalEntryDataTrieUpdates struct {
trieUpdates map[string][]byte
account baseAccountHandler
}
// NewJournalEntryDataTrieUpdates outputs a new JournalEntryDataTrieUpdates implementation used to revert an account's data trie
func NewJournalEntryDataTrieUpdates(trieUpdates map[string][]byte, account baseAccountHandler) (*journalEntryDataTrieUpdates, error) {
if check.IfNil(account) {
return nil, ErrNilAccountHandler
}
if len(trieUpdates) == 0 {
return nil, ErrNilOrEmptyDataTrieUpdates
}
return &journalEntryDataTrieUpdates{
trieUpdates: trieUpdates,
account: account,
}, nil
}
// Revert applies undo operation
func (jedtu *journalEntryDataTrieUpdates) Revert() (AccountHandler, error) {
for key := range jedtu.trieUpdates {
err := jedtu.account.DataTrie().Update([]byte(key), jedtu.trieUpdates[key])
if err != nil {
return nil, err
}
log.Trace("revert data trie update", "key", []byte(key), "val", jedtu.trieUpdates[key])
}
rootHash, err := jedtu.account.DataTrie().Root()
if err != nil {
return nil, err
}
jedtu.account.SetRootHash(rootHash)
return jedtu.account, nil
}
// IsInterfaceNil returns true if there is no value under the interface
func (jedtu *journalEntryDataTrieUpdates) IsInterfaceNil() bool {
return jedtu == nil
}