github.com/ylsGit/go-ethereum@v1.6.5/core/state/journal.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package state 18 19 import ( 20 "math/big" 21 22 "github.com/ethereum/go-ethereum/common" 23 ) 24 25 type journalEntry interface { 26 undo(*StateDB) 27 } 28 29 type journal []journalEntry 30 31 type ( 32 // Changes to the account trie. 33 createObjectChange struct { 34 account *common.Address 35 } 36 resetObjectChange struct { 37 prev *stateObject 38 } 39 suicideChange struct { 40 account *common.Address 41 prev bool // whether account had already suicided 42 prevbalance *big.Int 43 } 44 45 // Changes to individual accounts. 46 balanceChange struct { 47 account *common.Address 48 prev *big.Int 49 } 50 nonceChange struct { 51 account *common.Address 52 prev uint64 53 } 54 storageChange struct { 55 account *common.Address 56 key, prevalue common.Hash 57 } 58 codeChange struct { 59 account *common.Address 60 prevcode, prevhash []byte 61 } 62 63 // Changes to other state values. 64 refundChange struct { 65 prev *big.Int 66 } 67 addLogChange struct { 68 txhash common.Hash 69 } 70 addPreimageChange struct { 71 hash common.Hash 72 } 73 touchChange struct { 74 account *common.Address 75 prev bool 76 prevDirty bool 77 } 78 ) 79 80 func (ch createObjectChange) undo(s *StateDB) { 81 delete(s.stateObjects, *ch.account) 82 delete(s.stateObjectsDirty, *ch.account) 83 } 84 85 func (ch resetObjectChange) undo(s *StateDB) { 86 s.setStateObject(ch.prev) 87 } 88 89 func (ch suicideChange) undo(s *StateDB) { 90 obj := s.getStateObject(*ch.account) 91 if obj != nil { 92 obj.suicided = ch.prev 93 obj.setBalance(ch.prevbalance) 94 // if the object wasn't suicided before, remove 95 // it from the list of destructed objects as well. 96 if !obj.suicided { 97 delete(s.stateObjectsDestructed, *ch.account) 98 } 99 } 100 } 101 102 var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") 103 104 func (ch touchChange) undo(s *StateDB) { 105 if !ch.prev && *ch.account != ripemd { 106 s.getStateObject(*ch.account).touched = ch.prev 107 if !ch.prevDirty { 108 delete(s.stateObjectsDirty, *ch.account) 109 } 110 } 111 } 112 113 func (ch balanceChange) undo(s *StateDB) { 114 s.getStateObject(*ch.account).setBalance(ch.prev) 115 } 116 117 func (ch nonceChange) undo(s *StateDB) { 118 s.getStateObject(*ch.account).setNonce(ch.prev) 119 } 120 121 func (ch codeChange) undo(s *StateDB) { 122 s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) 123 } 124 125 func (ch storageChange) undo(s *StateDB) { 126 s.getStateObject(*ch.account).setState(ch.key, ch.prevalue) 127 } 128 129 func (ch refundChange) undo(s *StateDB) { 130 s.refund = ch.prev 131 } 132 133 func (ch addLogChange) undo(s *StateDB) { 134 logs := s.logs[ch.txhash] 135 if len(logs) == 1 { 136 delete(s.logs, ch.txhash) 137 } else { 138 s.logs[ch.txhash] = logs[:len(logs)-1] 139 } 140 } 141 142 func (ch addPreimageChange) undo(s *StateDB) { 143 delete(s.preimages, ch.hash) 144 }