github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/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/wanchain/go-wanchain/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  
    59  	storageByteArrayChange struct {
    60  		account  *common.Address
    61  		key      common.Hash
    62  		prevalue []byte
    63  	}
    64  
    65  	codeChange struct {
    66  		account            *common.Address
    67  		prevcode, prevhash []byte
    68  	}
    69  
    70  	// Changes to other state values.
    71  	refundChange struct {
    72  		prev *big.Int
    73  	}
    74  	addLogChange struct {
    75  		txhash common.Hash
    76  	}
    77  	addPreimageChange struct {
    78  		hash common.Hash
    79  	}
    80  	touchChange struct {
    81  		account   *common.Address
    82  		prev      bool
    83  		prevDirty bool
    84  	}
    85  )
    86  
    87  func (ch createObjectChange) undo(s *StateDB) {
    88  	delete(s.stateObjects, *ch.account)
    89  	delete(s.stateObjectsDirty, *ch.account)
    90  }
    91  
    92  func (ch resetObjectChange) undo(s *StateDB) {
    93  	s.setStateObject(ch.prev)
    94  }
    95  
    96  func (ch suicideChange) undo(s *StateDB) {
    97  	obj := s.getStateObject(*ch.account)
    98  	if obj != nil {
    99  		obj.suicided = ch.prev
   100  		obj.setBalance(ch.prevbalance)
   101  	}
   102  }
   103  
   104  var ripemd = common.HexToAddress("0000000000000000000000000000000000000003")
   105  
   106  func (ch touchChange) undo(s *StateDB) {
   107  	if !ch.prev && *ch.account != ripemd {
   108  		s.getStateObject(*ch.account).touched = ch.prev
   109  		if !ch.prevDirty {
   110  			delete(s.stateObjectsDirty, *ch.account)
   111  		}
   112  	}
   113  }
   114  
   115  func (ch balanceChange) undo(s *StateDB) {
   116  	s.getStateObject(*ch.account).setBalance(ch.prev)
   117  }
   118  
   119  func (ch nonceChange) undo(s *StateDB) {
   120  	s.getStateObject(*ch.account).setNonce(ch.prev)
   121  }
   122  
   123  func (ch codeChange) undo(s *StateDB) {
   124  	s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode)
   125  }
   126  
   127  func (ch storageChange) undo(s *StateDB) {
   128  	s.getStateObject(*ch.account).setState(ch.key, ch.prevalue)
   129  }
   130  
   131  func (ch storageByteArrayChange) undo(s *StateDB) {
   132  	s.getStateObject(*ch.account).setStateByteArray(ch.key, ch.prevalue)
   133  }
   134  
   135  func (ch refundChange) undo(s *StateDB) {
   136  	s.refund = ch.prev
   137  }
   138  
   139  func (ch addLogChange) undo(s *StateDB) {
   140  	logs := s.logs[ch.txhash]
   141  	if len(logs) == 1 {
   142  		delete(s.logs, ch.txhash)
   143  	} else {
   144  		s.logs[ch.txhash] = logs[:len(logs)-1]
   145  	}
   146  	s.logSize--
   147  }
   148  
   149  func (ch addPreimageChange) undo(s *StateDB) {
   150  	delete(s.preimages, ch.hash)
   151  }