github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/state/journal.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:35</date> 10 //</624450080002281472> 11 12 13 package state 14 15 import ( 16 "math/big" 17 18 "github.com/ethereum/go-ethereum/common" 19 ) 20 21 //journalEntry is a modification entry in the state change journal that can be 22 //按需归还。 23 type journalEntry interface { 24 //REVERT撤消此日记条目引入的更改。 25 revert(*StateDB) 26 27 //dirtied returns the Ethereum address modified by this journal entry. 28 dirtied() *common.Address 29 } 30 31 //日志包含自上次状态以来应用的状态修改列表 32 //承诺。它们被跟踪,以便在执行时能够还原。 33 //exception or revertal request. 34 type journal struct { 35 entries []journalEntry //日记帐跟踪的当前更改 36 dirties map[common.Address]int //脏帐户和更改数 37 } 38 39 //NewJournal创建新的初始化日志。 40 func newJournal() *journal { 41 return &journal{ 42 dirties: make(map[common.Address]int), 43 } 44 } 45 46 //append在变更日志的末尾插入一个新的修改条目。 47 func (j *journal) append(entry journalEntry) { 48 j.entries = append(j.entries, entry) 49 if addr := entry.dirtied(); addr != nil { 50 j.dirties[*addr]++ 51 } 52 } 53 54 //REVERT撤消一批日志修改以及任何已还原的 55 //处理也很脏。 56 func (j *journal) revert(statedb *StateDB, snapshot int) { 57 for i := len(j.entries) - 1; i >= snapshot; i-- { 58 //撤消操作所做的更改 59 j.entries[i].revert(statedb) 60 61 //删除由更改引起的任何脏跟踪 62 if addr := j.entries[i].dirtied(); addr != nil { 63 if j.dirties[*addr]--; j.dirties[*addr] == 0 { 64 delete(j.dirties, *addr) 65 } 66 } 67 } 68 j.entries = j.entries[:snapshot] 69 } 70 71 //dirty explicitly sets an address to dirty, even if the change entries would 72 //否则建议清洁。这个方法是处理ripemd的丑陋的黑客 73 //precompile consensus exception. 74 func (j *journal) dirty(addr common.Address) { 75 j.dirties[addr]++ 76 } 77 78 //length返回日记帐中的当前条目数。 79 func (j *journal) length() int { 80 return len(j.entries) 81 } 82 83 type ( 84 //对帐户trie的更改。 85 createObjectChange struct { 86 account *common.Address 87 } 88 resetObjectChange struct { 89 prev *stateObject 90 } 91 suicideChange struct { 92 account *common.Address 93 prev bool //账户是否已经自杀 94 prevbalance *big.Int 95 } 96 97 //个人账户变更。 98 balanceChange struct { 99 account *common.Address 100 prev *big.Int 101 } 102 nonceChange struct { 103 account *common.Address 104 prev uint64 105 } 106 storageChange struct { 107 account *common.Address 108 key, prevalue common.Hash 109 } 110 codeChange struct { 111 account *common.Address 112 prevcode, prevhash []byte 113 } 114 115 //其他状态值的更改。 116 refundChange struct { 117 prev uint64 118 } 119 addLogChange struct { 120 txhash common.Hash 121 } 122 addPreimageChange struct { 123 hash common.Hash 124 } 125 touchChange struct { 126 account *common.Address 127 prev bool 128 prevDirty bool 129 } 130 ) 131 132 func (ch createObjectChange) revert(s *StateDB) { 133 delete(s.stateObjects, *ch.account) 134 delete(s.stateObjectsDirty, *ch.account) 135 } 136 137 func (ch createObjectChange) dirtied() *common.Address { 138 return ch.account 139 } 140 141 func (ch resetObjectChange) revert(s *StateDB) { 142 s.setStateObject(ch.prev) 143 } 144 145 func (ch resetObjectChange) dirtied() *common.Address { 146 return nil 147 } 148 149 func (ch suicideChange) revert(s *StateDB) { 150 obj := s.getStateObject(*ch.account) 151 if obj != nil { 152 obj.suicided = ch.prev 153 obj.setBalance(ch.prevbalance) 154 } 155 } 156 157 func (ch suicideChange) dirtied() *common.Address { 158 return ch.account 159 } 160 161 var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") 162 163 func (ch touchChange) revert(s *StateDB) { 164 } 165 166 func (ch touchChange) dirtied() *common.Address { 167 return ch.account 168 } 169 170 func (ch balanceChange) revert(s *StateDB) { 171 s.getStateObject(*ch.account).setBalance(ch.prev) 172 } 173 174 func (ch balanceChange) dirtied() *common.Address { 175 return ch.account 176 } 177 178 func (ch nonceChange) revert(s *StateDB) { 179 s.getStateObject(*ch.account).setNonce(ch.prev) 180 } 181 182 func (ch nonceChange) dirtied() *common.Address { 183 return ch.account 184 } 185 186 func (ch codeChange) revert(s *StateDB) { 187 s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) 188 } 189 190 func (ch codeChange) dirtied() *common.Address { 191 return ch.account 192 } 193 194 func (ch storageChange) revert(s *StateDB) { 195 s.getStateObject(*ch.account).setState(ch.key, ch.prevalue) 196 } 197 198 func (ch storageChange) dirtied() *common.Address { 199 return ch.account 200 } 201 202 func (ch refundChange) revert(s *StateDB) { 203 s.refund = ch.prev 204 } 205 206 func (ch refundChange) dirtied() *common.Address { 207 return nil 208 } 209 210 func (ch addLogChange) revert(s *StateDB) { 211 logs := s.logs[ch.txhash] 212 if len(logs) == 1 { 213 delete(s.logs, ch.txhash) 214 } else { 215 s.logs[ch.txhash] = logs[:len(logs)-1] 216 } 217 s.logSize-- 218 } 219 220 func (ch addLogChange) dirtied() *common.Address { 221 return nil 222 } 223 224 func (ch addPreimageChange) revert(s *StateDB) { 225 delete(s.preimages, ch.hash) 226 } 227 228 func (ch addPreimageChange) dirtied() *common.Address { 229 return nil 230 } 231