github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/state/statedb.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2014 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 //包状态在以太坊状态trie上提供一个缓存层。 26 package state 27 28 import ( 29 "fmt" 30 "math/big" 31 "sort" 32 "sync" 33 34 "github.com/ethereum/go-ethereum/common" 35 "github.com/ethereum/go-ethereum/core/types" 36 "github.com/ethereum/go-ethereum/crypto" 37 "github.com/ethereum/go-ethereum/log" 38 "github.com/ethereum/go-ethereum/rlp" 39 "github.com/ethereum/go-ethereum/trie" 40 ) 41 42 type revision struct { 43 id int 44 journalIndex int 45 } 46 47 var ( 48 //EmptyState是空状态trie项的已知哈希。 49 emptyState = crypto.Keccak256Hash(nil) 50 51 //emptycode是空EVM字节码的已知哈希。 52 emptyCode = crypto.Keccak256Hash(nil) 53 ) 54 55 //以太坊协议中的statedbs用于存储任何内容 56 //在梅克尔特里亚。statedbs负责缓存和存储 57 //嵌套状态。它是要检索的常规查询接口: 58 //*合同 59 //*帐户 60 type StateDB struct { 61 db Database 62 trie Trie 63 64 //此映射包含“活动”对象,在处理状态转换时将对其进行修改。 65 stateObjects map[common.Address]*stateObject 66 stateObjectsDirty map[common.Address]struct{} 67 68 //数据库错误。 69 //状态对象由共识核心和虚拟机使用,它们是 70 //无法处理数据库级错误。发生的任何错误 71 //在数据库读取过程中,将在此处记忆并最终返回 72 //按statedb.commit。 73 dbErr error 74 75 //退款柜台,也用于州过渡。 76 refund uint64 77 78 thash, bhash common.Hash 79 txIndex int 80 logs map[common.Hash][]*types.Log 81 logSize uint 82 83 preimages map[common.Hash][]byte 84 85 //国家修改杂志。这是 86 //快照并还原为快照。 87 journal *journal 88 validRevisions []revision 89 nextRevisionId int 90 91 lock sync.Mutex 92 } 93 94 //从给定的trie创建新状态。 95 func New(root common.Hash, db Database) (*StateDB, error) { 96 tr, err := db.OpenTrie(root) 97 if err != nil { 98 return nil, err 99 } 100 return &StateDB{ 101 db: db, 102 trie: tr, 103 stateObjects: make(map[common.Address]*stateObject), 104 stateObjectsDirty: make(map[common.Address]struct{}), 105 logs: make(map[common.Hash][]*types.Log), 106 preimages: make(map[common.Hash][]byte), 107 journal: newJournal(), 108 }, nil 109 } 110 111 //setError记住调用它时使用的第一个非零错误。 112 func (self *StateDB) setError(err error) { 113 if self.dbErr == nil { 114 self.dbErr = err 115 } 116 } 117 118 func (self *StateDB) Error() error { 119 return self.dbErr 120 } 121 122 //重置从状态数据库中清除所有短暂状态对象,但保留 123 //基础状态将尝试避免为下一个操作重新加载数据。 124 func (self *StateDB) Reset(root common.Hash) error { 125 tr, err := self.db.OpenTrie(root) 126 if err != nil { 127 return err 128 } 129 self.trie = tr 130 self.stateObjects = make(map[common.Address]*stateObject) 131 self.stateObjectsDirty = make(map[common.Address]struct{}) 132 self.thash = common.Hash{} 133 self.bhash = common.Hash{} 134 self.txIndex = 0 135 self.logs = make(map[common.Hash][]*types.Log) 136 self.logSize = 0 137 self.preimages = make(map[common.Hash][]byte) 138 self.clearJournalAndRefund() 139 return nil 140 } 141 142 func (self *StateDB) AddLog(log *types.Log) { 143 self.journal.append(addLogChange{txhash: self.thash}) 144 145 log.TxHash = self.thash 146 log.BlockHash = self.bhash 147 log.TxIndex = uint(self.txIndex) 148 log.Index = self.logSize 149 self.logs[self.thash] = append(self.logs[self.thash], log) 150 self.logSize++ 151 } 152 153 func (self *StateDB) GetLogs(hash common.Hash) []*types.Log { 154 return self.logs[hash] 155 } 156 157 func (self *StateDB) Logs() []*types.Log { 158 var logs []*types.Log 159 for _, lgs := range self.logs { 160 logs = append(logs, lgs...) 161 } 162 return logs 163 } 164 165 //AdvPrimI图记录由VM看到的Sa3预图像。 166 func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) { 167 if _, ok := self.preimages[hash]; !ok { 168 self.journal.append(addPreimageChange{hash: hash}) 169 pi := make([]byte, len(preimage)) 170 copy(pi, preimage) 171 self.preimages[hash] = pi 172 } 173 } 174 175 //preimages返回已提交的sha3 preimages列表。 176 func (self *StateDB) Preimages() map[common.Hash][]byte { 177 return self.preimages 178 } 179 180 func (self *StateDB) AddRefund(gas uint64) { 181 self.journal.append(refundChange{prev: self.refund}) 182 self.refund += gas 183 } 184 185 //exist报告给定帐户地址是否存在于状态中。 186 //值得注意的是,对于自杀账户,这也会返回真值。 187 func (self *StateDB) Exist(addr common.Address) bool { 188 return self.getStateObject(addr) != nil 189 } 190 191 //空返回状态对象是否不存在 192 //或根据EIP161规范为空(余额=nonce=代码=0) 193 func (self *StateDB) Empty(addr common.Address) bool { 194 so := self.getStateObject(addr) 195 return so == nil || so.empty() 196 } 197 198 //从给定地址检索余额,如果找不到对象,则检索0 199 func (self *StateDB) GetBalance(addr common.Address) *big.Int { 200 stateObject := self.getStateObject(addr) 201 if stateObject != nil { 202 return stateObject.Balance() 203 } 204 return common.Big0 205 } 206 207 func (self *StateDB) GetNonce(addr common.Address) uint64 { 208 stateObject := self.getStateObject(addr) 209 if stateObject != nil { 210 return stateObject.Nonce() 211 } 212 213 return 0 214 } 215 216 func (self *StateDB) GetCode(addr common.Address) []byte { 217 stateObject := self.getStateObject(addr) 218 if stateObject != nil { 219 return stateObject.Code(self.db) 220 } 221 return nil 222 } 223 224 func (self *StateDB) GetCodeSize(addr common.Address) int { 225 stateObject := self.getStateObject(addr) 226 if stateObject == nil { 227 return 0 228 } 229 if stateObject.code != nil { 230 return len(stateObject.code) 231 } 232 size, err := self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash())) 233 if err != nil { 234 self.setError(err) 235 } 236 return size 237 } 238 239 func (self *StateDB) GetCodeHash(addr common.Address) common.Hash { 240 stateObject := self.getStateObject(addr) 241 if stateObject == nil { 242 return common.Hash{} 243 } 244 return common.BytesToHash(stateObject.CodeHash()) 245 } 246 247 func (self *StateDB) GetState(addr common.Address, bhash common.Hash) common.Hash { 248 stateObject := self.getStateObject(addr) 249 if stateObject != nil { 250 return stateObject.GetState(self.db, bhash) 251 } 252 return common.Hash{} 253 } 254 255 //数据库检索支持低级trie操作的低级数据库。 256 func (self *StateDB) Database() Database { 257 return self.db 258 } 259 260 //storage trie返回帐户的存储trie。 261 //返回值是副本,对于不存在的帐户为零。 262 func (self *StateDB) StorageTrie(addr common.Address) Trie { 263 stateObject := self.getStateObject(addr) 264 if stateObject == nil { 265 return nil 266 } 267 cpy := stateObject.deepCopy(self) 268 return cpy.updateTrie(self.db) 269 } 270 271 func (self *StateDB) HasSuicided(addr common.Address) bool { 272 stateObject := self.getStateObject(addr) 273 if stateObject != nil { 274 return stateObject.suicided 275 } 276 return false 277 } 278 279 /* 280 *设定器 281 **/ 282 283 284 //addbalance将金额添加到与addr关联的帐户。 285 func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) { 286 stateObject := self.GetOrNewStateObject(addr) 287 if stateObject != nil { 288 stateObject.AddBalance(amount) 289 } 290 } 291 292 //子余额从与addr关联的帐户中减去金额。 293 func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) { 294 stateObject := self.GetOrNewStateObject(addr) 295 if stateObject != nil { 296 stateObject.SubBalance(amount) 297 } 298 } 299 300 func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) { 301 stateObject := self.GetOrNewStateObject(addr) 302 if stateObject != nil { 303 stateObject.SetBalance(amount) 304 } 305 } 306 307 func (self *StateDB) SetNonce(addr common.Address, nonce uint64) { 308 stateObject := self.GetOrNewStateObject(addr) 309 if stateObject != nil { 310 stateObject.SetNonce(nonce) 311 } 312 } 313 314 func (self *StateDB) SetCode(addr common.Address, code []byte) { 315 stateObject := self.GetOrNewStateObject(addr) 316 if stateObject != nil { 317 stateObject.SetCode(crypto.Keccak256Hash(code), code) 318 } 319 } 320 321 func (self *StateDB) SetState(addr common.Address, key, value common.Hash) { 322 stateObject := self.GetOrNewStateObject(addr) 323 if stateObject != nil { 324 stateObject.SetState(self.db, key, value) 325 } 326 } 327 328 //自杀将指定帐户标记为自杀。 329 //这将清除帐户余额。 330 // 331 //在提交状态之前,帐户的状态对象仍然可用, 332 //GetStateObject将在自杀后返回非零帐户。 333 func (self *StateDB) Suicide(addr common.Address) bool { 334 stateObject := self.getStateObject(addr) 335 if stateObject == nil { 336 return false 337 } 338 self.journal.append(suicideChange{ 339 account: &addr, 340 prev: stateObject.suicided, 341 prevbalance: new(big.Int).Set(stateObject.Balance()), 342 }) 343 stateObject.markSuicided() 344 stateObject.data.Balance = new(big.Int) 345 346 return true 347 } 348 349 // 350 //设置、更新和删除状态对象方法。 351 // 352 353 //updateStateObject将给定对象写入trie。 354 func (self *StateDB) updateStateObject(stateObject *stateObject) { 355 addr := stateObject.Address() 356 data, err := rlp.EncodeToBytes(stateObject) 357 if err != nil { 358 panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err)) 359 } 360 self.setError(self.trie.TryUpdate(addr[:], data)) 361 } 362 363 //DeleteStateObject从状态trie中删除给定的对象。 364 func (self *StateDB) deleteStateObject(stateObject *stateObject) { 365 stateObject.deleted = true 366 addr := stateObject.Address() 367 self.setError(self.trie.TryDelete(addr[:])) 368 } 369 370 //检索由地址给定的状态对象。如果未找到,则返回nil。 371 func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) { 372 //喜欢“活”的对象。 373 if obj := self.stateObjects[addr]; obj != nil { 374 if obj.deleted { 375 return nil 376 } 377 return obj 378 } 379 380 //从数据库加载对象。 381 enc, err := self.trie.TryGet(addr[:]) 382 if len(enc) == 0 { 383 self.setError(err) 384 return nil 385 } 386 var data Account 387 if err := rlp.DecodeBytes(enc, &data); err != nil { 388 log.Error("Failed to decode state object", "addr", addr, "err", err) 389 return nil 390 } 391 //插入到实况集。 392 obj := newObject(self, addr, data) 393 self.setStateObject(obj) 394 return obj 395 } 396 397 func (self *StateDB) setStateObject(object *stateObject) { 398 self.stateObjects[object.Address()] = object 399 } 400 401 //检索状态对象或创建新的状态对象(如果为零)。 402 func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject { 403 stateObject := self.getStateObject(addr) 404 if stateObject == nil || stateObject.deleted { 405 stateObject, _ = self.createObject(addr) 406 } 407 return stateObject 408 } 409 410 //CreateObject创建新的状态对象。如果有现有帐户 411 //给定的地址,将被覆盖并作为第二个返回值返回。 412 func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) { 413 prev = self.getStateObject(addr) 414 newobj = newObject(self, addr, Account{}) 415 newobj.setNonce(0) //将对象设置为脏 416 if prev == nil { 417 self.journal.append(createObjectChange{account: &addr}) 418 } else { 419 self.journal.append(resetObjectChange{prev: prev}) 420 } 421 self.setStateObject(newobj) 422 return newobj, prev 423 } 424 425 //CreateCount显式创建状态对象。如果有地址的状态对象 426 //已存在余额转入新账户。 427 // 428 //在EVM创建操作期间调用CreateCount。可能出现的情况是 429 //合同执行以下操作: 430 // 431 //1。将资金发送到sha(account++(nonce+1))。 432 //2。tx_create(sha(account++nonce))(注意,这会得到1的地址) 433 // 434 //保持平衡可确保乙醚不会消失。 435 func (self *StateDB) CreateAccount(addr common.Address) { 436 new, prev := self.createObject(addr) 437 if prev != nil { 438 new.setBalance(prev.data.Balance) 439 } 440 } 441 442 func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) { 443 so := db.getStateObject(addr) 444 if so == nil { 445 return 446 } 447 448 //在对存储进行迭代时,首先检查缓存 449 for h, value := range so.cachedStorage { 450 cb(h, value) 451 } 452 453 it := trie.NewIterator(so.getTrie(db.db).NodeIterator(nil)) 454 for it.Next() { 455 //忽略缓存值 456 key := common.BytesToHash(db.trie.GetKey(it.Key)) 457 if _, ok := so.cachedStorage[key]; !ok { 458 cb(key, common.BytesToHash(it.Value)) 459 } 460 } 461 } 462 463 //复制创建状态的深度独立副本。 464 //复制状态的快照无法应用于该副本。 465 func (self *StateDB) Copy() *StateDB { 466 self.lock.Lock() 467 defer self.lock.Unlock() 468 469 //复制所有基本字段,初始化内存字段 470 state := &StateDB{ 471 db: self.db, 472 trie: self.db.CopyTrie(self.trie), 473 stateObjects: make(map[common.Address]*stateObject, len(self.journal.dirties)), 474 stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)), 475 refund: self.refund, 476 logs: make(map[common.Hash][]*types.Log, len(self.logs)), 477 logSize: self.logSize, 478 preimages: make(map[common.Hash][]byte), 479 journal: newJournal(), 480 } 481 //复制脏状态、日志和预映像 482 for addr := range self.journal.dirties { 483 //如文件所述[此处](https://github.com/ethereum/go-ethereum/pull/16485 issuecomment-380438527) 484 //在定稿方法中,有一种情况是对象在日志中,而不是 485 //在StateObjects中:oog在拜占庭之前接触到ripemd。因此,我们需要检查 486 //零 487 if object, exist := self.stateObjects[addr]; exist { 488 state.stateObjects[addr] = object.deepCopy(state) 489 state.stateObjectsDirty[addr] = struct{}{} 490 } 491 } 492 //上面,我们不复制实际的日记。这意味着,如果复制副本, 493 //上面的循环将是无操作,因为副本的日志是空的。 494 //因此,这里我们迭代StateObjects,以启用副本的副本 495 for addr := range self.stateObjectsDirty { 496 if _, exist := state.stateObjects[addr]; !exist { 497 state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state) 498 state.stateObjectsDirty[addr] = struct{}{} 499 } 500 } 501 502 for hash, logs := range self.logs { 503 state.logs[hash] = make([]*types.Log, len(logs)) 504 copy(state.logs[hash], logs) 505 } 506 for hash, preimage := range self.preimages { 507 state.preimages[hash] = preimage 508 } 509 return state 510 } 511 512 //快照返回状态的当前修订版的标识符。 513 func (self *StateDB) Snapshot() int { 514 id := self.nextRevisionId 515 self.nextRevisionId++ 516 self.validRevisions = append(self.validRevisions, revision{id, self.journal.length()}) 517 return id 518 } 519 520 //RevertToSnapshot恢复自给定修订之后所做的所有状态更改。 521 func (self *StateDB) RevertToSnapshot(revid int) { 522 //在有效快照的堆栈中查找快照。 523 idx := sort.Search(len(self.validRevisions), func(i int) bool { 524 return self.validRevisions[i].id >= revid 525 }) 526 if idx == len(self.validRevisions) || self.validRevisions[idx].id != revid { 527 panic(fmt.Errorf("revision id %v cannot be reverted", revid)) 528 } 529 snapshot := self.validRevisions[idx].journalIndex 530 531 //重播日志以撤消更改并删除失效的快照 532 self.journal.revert(self, snapshot) 533 self.validRevisions = self.validRevisions[:idx] 534 } 535 536 //GetRefund返回退款计数器的当前值。 537 func (self *StateDB) GetRefund() uint64 { 538 return self.refund 539 } 540 541 //通过移除自毁对象最终确定状态 542 //清除日记账和退款。 543 func (s *StateDB) Finalise(deleteEmptyObjects bool) { 544 for addr := range s.journal.dirties { 545 stateObject, exist := s.stateObjects[addr] 546 if !exist { 547 //ripemd在德克萨斯州的1714175号区块“接触”,邮编:0x1237F737031E40BCDE4A8B7E717B2D15E3ECADFE49BB1BC71EE9DEB09C6FCF2 548 //Tx耗尽了气体,尽管“触摸”的概念在那里并不存在,但是 549 //触摸事件仍将记录在日志中。因为瑞普米德是一片特殊的雪花, 550 //即使日志被还原,它仍将在日志中保留。在这种特殊情况下, 551 //它可能存在于's.journal.dirties'中,但不存在于's.stateobjects'中。 552 //因此,我们可以在这里安全地忽略它 553 continue 554 } 555 556 if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) { 557 s.deleteStateObject(stateObject) 558 } else { 559 stateObject.updateRoot(s.db) 560 s.updateStateObject(stateObject) 561 } 562 s.stateObjectsDirty[addr] = struct{}{} 563 } 564 //使日记帐无效,因为不允许跨交易记录还原。 565 s.clearJournalAndRefund() 566 } 567 568 //IntermediateRoot计算状态trie的当前根哈希。 569 //它在事务之间调用,以获取 570 //进入交易记录收据。 571 func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { 572 s.Finalise(deleteEmptyObjects) 573 return s.trie.Hash() 574 } 575 576 //准备设置当前事务哈希、索引和块哈希,即 577 //在EVM发出新状态日志时使用。 578 func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) { 579 self.thash = thash 580 self.bhash = bhash 581 self.txIndex = ti 582 } 583 584 func (s *StateDB) clearJournalAndRefund() { 585 s.journal = newJournal() 586 s.validRevisions = s.validRevisions[:0] 587 s.refund = 0 588 } 589 590 //commit将状态写入内存中的基础trie数据库。 591 func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) { 592 defer s.clearJournalAndRefund() 593 594 for addr := range s.journal.dirties { 595 s.stateObjectsDirty[addr] = struct{}{} 596 } 597 //将对象提交到trie。 598 for addr, stateObject := range s.stateObjects { 599 _, isDirty := s.stateObjectsDirty[addr] 600 switch { 601 case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()): 602 //如果对象已被删除,请不要麻烦同步它。 603 //只需在trie中标记为删除即可。 604 s.deleteStateObject(stateObject) 605 case isDirty: 606 //编写与状态对象关联的任何合同代码 607 if stateObject.code != nil && stateObject.dirtyCode { 608 s.db.TrieDB().InsertBlob(common.BytesToHash(stateObject.CodeHash()), stateObject.code) 609 stateObject.dirtyCode = false 610 } 611 //将状态对象中的任何存储更改写入其存储trie。 612 if err := stateObject.CommitTrie(s.db); err != nil { 613 return common.Hash{}, err 614 } 615 //更新主帐户trie中的对象。 616 s.updateStateObject(stateObject) 617 } 618 delete(s.stateObjectsDirty, addr) 619 } 620 //写入trie更改。 621 root, err = s.trie.Commit(func(leaf []byte, parent common.Hash) error { 622 var account Account 623 if err := rlp.DecodeBytes(leaf, &account); err != nil { 624 return nil 625 } 626 if account.Root != emptyState { 627 s.db.TrieDB().Reference(account.Root, parent) 628 } 629 code := common.BytesToHash(account.CodeHash) 630 if code != emptyCode { 631 s.db.TrieDB().Reference(code, parent) 632 } 633 return nil 634 }) 635 log.Debug("Trie cache stats after commit", "misses", trie.CacheMisses(), "unloads", trie.CacheUnloads()) 636 return root, err 637 }