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