github.com/4000d/go-ethereum@v1.8.2-0.20180223170251-423c8bb1d821/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 uint64 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 } 95 } 96 97 var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") 98 99 func (ch touchChange) undo(s *StateDB) { 100 if !ch.prev && *ch.account != ripemd { 101 s.getStateObject(*ch.account).touched = ch.prev 102 if !ch.prevDirty { 103 delete(s.stateObjectsDirty, *ch.account) 104 } 105 } 106 } 107 108 func (ch balanceChange) undo(s *StateDB) { 109 s.getStateObject(*ch.account).setBalance(ch.prev) 110 } 111 112 func (ch nonceChange) undo(s *StateDB) { 113 s.getStateObject(*ch.account).setNonce(ch.prev) 114 } 115 116 func (ch codeChange) undo(s *StateDB) { 117 s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) 118 } 119 120 func (ch storageChange) undo(s *StateDB) { 121 s.getStateObject(*ch.account).setState(ch.key, ch.prevalue) 122 } 123 124 func (ch refundChange) undo(s *StateDB) { 125 s.refund = ch.prev 126 } 127 128 func (ch addLogChange) undo(s *StateDB) { 129 logs := s.logs[ch.txhash] 130 if len(logs) == 1 { 131 delete(s.logs, ch.txhash) 132 } else { 133 s.logs[ch.txhash] = logs[:len(logs)-1] 134 } 135 s.logSize-- 136 } 137 138 func (ch addPreimageChange) undo(s *StateDB) { 139 delete(s.preimages, ch.hash) 140 }