github.com/daeglee/go-ethereum@v0.0.0-20190504220456-cad3e8d18e9b/core/state/statedb.go (about)

     1  // Copyright 2014 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 provides a caching layer atop the Ethereum state trie.
    18  package state
    19  
    20  import (
    21  	"errors"
    22  	"fmt"
    23  	"math/big"
    24  	"sort"
    25  	"time"
    26  
    27  	"github.com/ethereum/go-ethereum/common"
    28  	"github.com/ethereum/go-ethereum/core/types"
    29  	"github.com/ethereum/go-ethereum/crypto"
    30  	"github.com/ethereum/go-ethereum/log"
    31  	"github.com/ethereum/go-ethereum/metrics"
    32  	"github.com/ethereum/go-ethereum/rlp"
    33  	"github.com/ethereum/go-ethereum/trie"
    34  	"encoding/binary"
    35  )
    36  
    37  type revision struct {
    38  	id           int
    39  	journalIndex int
    40  }
    41  
    42  var (
    43  	// emptyRoot is the known root hash of an empty trie.
    44  	emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
    45  
    46  	// emptyCode is the known hash of the empty EVM bytecode.
    47  	emptyCode = crypto.Keccak256Hash(nil)
    48  )
    49  
    50  type proofList [][]byte
    51  
    52  func (n *proofList) Put(key []byte, value []byte) error {
    53  	*n = append(*n, value)
    54  	return nil
    55  }
    56  
    57  func (n *proofList) Delete(key []byte) error {
    58  	panic("not supported")
    59  }
    60  
    61  // StateDBs within the ethereum protocol are used to store anything
    62  // within the merkle trie. StateDBs take care of caching and storing
    63  // nested states. It's the general query interface to retrieve:
    64  // * Contracts
    65  // * Accounts
    66  type StateDB struct {
    67  	db   Database
    68  	trie Trie
    69  
    70  	// This map holds 'live' objects, which will get modified while processing a state transition.
    71  	stateObjects      map[common.Address]*stateObject
    72  	stateObjectsDirty map[common.Address]struct{}
    73  
    74  	// DB error.
    75  	// State objects are used by the consensus core and VM which are
    76  	// unable to deal with database-level errors. Any error that occurs
    77  	// during a database read is memoized here and will eventually be returned
    78  	// by StateDB.Commit.
    79  	dbErr error
    80  
    81  	// The refund counter, also used by state transitioning.
    82  	refund uint64
    83  
    84  	thash, bhash common.Hash
    85  	txIndex      int
    86  	logs         map[common.Hash][]*types.Log
    87  	logSize      uint
    88  
    89  	preimages map[common.Hash][]byte
    90  
    91  	// Journal of state modifications. This is the backbone of
    92  	// Snapshot and RevertToSnapshot.
    93  	journal        *journal
    94  	validRevisions []revision
    95  	nextRevisionId int
    96  
    97  	// Measurements gathered during execution for debugging purposes
    98  	AccountReads   time.Duration
    99  	AccountHashes  time.Duration
   100  	AccountUpdates time.Duration
   101  	AccountCommits time.Duration
   102  	StorageReads   time.Duration
   103  	StorageHashes  time.Duration
   104  	StorageUpdates time.Duration
   105  	StorageCommits time.Duration
   106  }
   107  
   108  // Create a new state from a given trie.
   109  func New(root common.Hash, db Database) (*StateDB, error) {
   110  	tr, err := db.OpenTrie(root)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  	return &StateDB{
   115  		db:                db,
   116  		trie:              tr,
   117  		stateObjects:      make(map[common.Address]*stateObject),
   118  		stateObjectsDirty: make(map[common.Address]struct{}),
   119  		logs:              make(map[common.Hash][]*types.Log),
   120  		preimages:         make(map[common.Hash][]byte),
   121  		journal:           newJournal(),
   122  	}, nil
   123  }
   124  
   125  // setError remembers the first non-nil error it is called with.
   126  func (self *StateDB) setError(err error) {
   127  	if self.dbErr == nil {
   128  		self.dbErr = err
   129  	}
   130  }
   131  
   132  func (self *StateDB) Error() error {
   133  	return self.dbErr
   134  }
   135  
   136  // Reset clears out all ephemeral state objects from the state db, but keeps
   137  // the underlying state trie to avoid reloading data for the next operations.
   138  func (self *StateDB) Reset(root common.Hash) error {
   139  	tr, err := self.db.OpenTrie(root)
   140  	if err != nil {
   141  		return err
   142  	}
   143  	self.trie = tr
   144  	self.stateObjects = make(map[common.Address]*stateObject)
   145  	self.stateObjectsDirty = make(map[common.Address]struct{})
   146  	self.thash = common.Hash{}
   147  	self.bhash = common.Hash{}
   148  	self.txIndex = 0
   149  	self.logs = make(map[common.Hash][]*types.Log)
   150  	self.logSize = 0
   151  	self.preimages = make(map[common.Hash][]byte)
   152  	self.clearJournalAndRefund()
   153  	return nil
   154  }
   155  
   156  func (self *StateDB) AddLog(log *types.Log) {
   157  	self.journal.append(addLogChange{txhash: self.thash})
   158  
   159  	log.TxHash = self.thash
   160  	log.BlockHash = self.bhash
   161  	log.TxIndex = uint(self.txIndex)
   162  	log.Index = self.logSize
   163  	self.logs[self.thash] = append(self.logs[self.thash], log)
   164  	self.logSize++
   165  }
   166  
   167  func (self *StateDB) GetLogs(hash common.Hash) []*types.Log {
   168  	return self.logs[hash]
   169  }
   170  
   171  func (self *StateDB) Logs() []*types.Log {
   172  	var logs []*types.Log
   173  	for _, lgs := range self.logs {
   174  		logs = append(logs, lgs...)
   175  	}
   176  	return logs
   177  }
   178  
   179  // AddPreimage records a SHA3 preimage seen by the VM.
   180  func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) {
   181  	if _, ok := self.preimages[hash]; !ok {
   182  		self.journal.append(addPreimageChange{hash: hash})
   183  		pi := make([]byte, len(preimage))
   184  		copy(pi, preimage)
   185  		self.preimages[hash] = pi
   186  	}
   187  }
   188  
   189  // Preimages returns a list of SHA3 preimages that have been submitted.
   190  func (self *StateDB) Preimages() map[common.Hash][]byte {
   191  	return self.preimages
   192  }
   193  
   194  // AddRefund adds gas to the refund counter
   195  func (self *StateDB) AddRefund(gas uint64) {
   196  	self.journal.append(refundChange{prev: self.refund})
   197  	self.refund += gas
   198  }
   199  
   200  // SubRefund removes gas from the refund counter.
   201  // This method will panic if the refund counter goes below zero
   202  func (self *StateDB) SubRefund(gas uint64) {
   203  	self.journal.append(refundChange{prev: self.refund})
   204  	if gas > self.refund {
   205  		panic("Refund counter below zero")
   206  	}
   207  	self.refund -= gas
   208  }
   209  
   210  // Exist reports whether the given account address exists in the state.
   211  // Notably this also returns true for suicided accounts.
   212  func (self *StateDB) Exist(addr common.Address) bool {
   213  	return self.getStateObject(addr) != nil
   214  }
   215  
   216  // Empty returns whether the state object is either non-existent
   217  // or empty according to the EIP161 specification (balance = nonce = code = 0)
   218  func (self *StateDB) Empty(addr common.Address) bool {
   219  	so := self.getStateObject(addr)
   220  	return so == nil || so.empty()
   221  }
   222  
   223  // Retrieve the balance from the given address or 0 if object not found
   224  func (self *StateDB) GetBalance(addr common.Address) *big.Int {
   225  	stateObject := self.getStateObject(addr)
   226  	if stateObject != nil {
   227  		return stateObject.Balance()
   228  	}
   229  	return common.Big0
   230  }
   231  
   232  func (self *StateDB) GetNonce(addr common.Address) uint64 {
   233  	stateObject := self.getStateObject(addr)
   234  	if stateObject != nil {
   235  		return stateObject.Nonce()
   236  	}
   237  
   238  	return 0
   239  }
   240  
   241  // TxIndex returns the current transaction index set by Prepare.
   242  func (self *StateDB) TxIndex() int {
   243  	return self.txIndex
   244  }
   245  
   246  // BlockHash returns the current block hash set by Prepare.
   247  func (self *StateDB) BlockHash() common.Hash {
   248  	return self.bhash
   249  }
   250  
   251  func (self *StateDB) GetCode(addr common.Address) []byte {
   252  	stateObject := self.getStateObject(addr)
   253  	if stateObject != nil {
   254  		return stateObject.Code(self.db)
   255  	}
   256  	return nil
   257  }
   258  
   259  func (self *StateDB) GetCodeSize(addr common.Address) int {
   260  	stateObject := self.getStateObject(addr)
   261  	if stateObject == nil {
   262  		return 0
   263  	}
   264  	if stateObject.code != nil {
   265  		return len(stateObject.code)
   266  	}
   267  	size, err := self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash()))
   268  	if err != nil {
   269  		self.setError(err)
   270  	}
   271  	return size
   272  }
   273  
   274  func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
   275  	stateObject := self.getStateObject(addr)
   276  	if stateObject == nil {
   277  		return common.Hash{}
   278  	}
   279  	return common.BytesToHash(stateObject.CodeHash())
   280  }
   281  
   282  // GetState retrieves a value from the given account's storage trie.
   283  func (self *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
   284  	stateObject := self.getStateObject(addr)
   285  	if stateObject != nil {
   286  		return stateObject.GetState(self.db, hash)
   287  	}
   288  	return common.Hash{}
   289  }
   290  
   291  // GetProof returns the MerkleProof for a given Account
   292  func (self *StateDB) GetProof(a common.Address) ([][]byte, error) {
   293  	var proof proofList
   294  	err := self.trie.Prove(crypto.Keccak256(a.Bytes()), 0, &proof)
   295  	return [][]byte(proof), err
   296  }
   297  
   298  // GetProof returns the StorageProof for given key
   299  func (self *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) {
   300  	var proof proofList
   301  	trie := self.StorageTrie(a)
   302  	if trie == nil {
   303  		return proof, errors.New("storage trie for requested address does not exist")
   304  	}
   305  	err := trie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof)
   306  	return [][]byte(proof), err
   307  }
   308  
   309  // GetCommittedState retrieves a value from the given account's committed storage trie.
   310  func (self *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
   311  	stateObject := self.getStateObject(addr)
   312  	if stateObject != nil {
   313  		return stateObject.GetCommittedState(self.db, hash)
   314  	}
   315  	return common.Hash{}
   316  }
   317  
   318  // Database retrieves the low level database supporting the lower level trie ops.
   319  func (self *StateDB) Database() Database {
   320  	return self.db
   321  }
   322  
   323  // StorageTrie returns the storage trie of an account.
   324  // The return value is a copy and is nil for non-existent accounts.
   325  func (self *StateDB) StorageTrie(addr common.Address) Trie {
   326  	stateObject := self.getStateObject(addr)
   327  	if stateObject == nil {
   328  		return nil
   329  	}
   330  	cpy := stateObject.deepCopy(self)
   331  	return cpy.updateTrie(self.db)
   332  }
   333  
   334  func (self *StateDB) HasSuicided(addr common.Address) bool {
   335  	stateObject := self.getStateObject(addr)
   336  	if stateObject != nil {
   337  		return stateObject.suicided
   338  	}
   339  	return false
   340  }
   341  
   342  /*
   343   * SETTERS
   344   */
   345  
   346  // AddBalance adds amount to the account associated with addr.
   347  func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
   348  	stateObject := self.GetOrNewStateObject(addr)
   349  	if stateObject != nil {
   350  		stateObject.AddBalance(amount)
   351  	}
   352  }
   353  
   354  func (self *StateDB) AddFutureTx(contract common.Address, addr common.Address, input []byte) {
   355  	//self.db // state db가 아닌 ethdb.db에 저장해야함
   356  	// 블록생성할때 transactionlist에 추가해야함
   357  	// 새로운 블록을 받아올때 포함되면 삭제
   358  	//last8 := 	input[len(input)-8:]
   359  	// from => addr, input => data, to => receipient, contract, contract address, time=>account Nonce => make  새로운 transaction형태만드는 함수
   360  	// disk 저장 =>
   361  	// contract 주소와 해당 컨트랙트에서 예약한 번호 (contract 주소, 번호)
   362  	//ebn := binary.BigEndian.Uint64(last8) // account nonce값까지 생성함
   363  	//batch := temp_db.NewBatch()
   364  	//newmem := rawdb.NewMemoryDatabase()
   365  	// 배치는 가져왔으니 이제 해보자..
   366  
   367  	// future transction을 저장하는 방법 생성
   368  	//log.Info("hawa","haha",batch.ValueSize(),newmem.Close())
   369  
   370  
   371  
   372  	last8 := 	input[len(input)-8:]
   373  	nonce := binary.BigEndian.Uint64(last8) //accountNonce
   374  	gas := new(uint64)
   375  	*gas = 1000000
   376  	gasPirce := big.NewInt(10*1e9)
   377  
   378  
   379  	future_tx := types.NewFutureTransaction(nonce,contract,*gas,gasPirce,input, addr)
   380  
   381  	StoreTx(*future_tx, nonce)
   382  
   383  	// future transaction 생성을위한 default값 생성하기
   384  
   385  
   386  	// 우선 트랜잭션 생성 => 생성한 트랜잭션을 넣기
   387  }
   388  /*
   389  func future_accountNonce(n uint64) uint64 {
   390  	n |= (1 << 63)
   391  	return n
   392  }
   393  */
   394  
   395  // SubBalance subtracts amount from the account associated with addr.
   396  func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) {
   397  	stateObject := self.GetOrNewStateObject(addr)
   398  	if stateObject != nil {
   399  		stateObject.SubBalance(amount)
   400  	}
   401  }
   402  
   403  func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) {
   404  	stateObject := self.GetOrNewStateObject(addr)
   405  	if stateObject != nil {
   406  		stateObject.SetBalance(amount)
   407  	}
   408  }
   409  
   410  func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
   411  	stateObject := self.GetOrNewStateObject(addr)
   412  	if stateObject != nil {
   413  		stateObject.SetNonce(nonce)
   414  	}
   415  }
   416  
   417  func (self *StateDB) SetCode(addr common.Address, code []byte) {
   418  	stateObject := self.GetOrNewStateObject(addr)
   419  	if stateObject != nil {
   420  		stateObject.SetCode(crypto.Keccak256Hash(code), code)
   421  	}
   422  }
   423  
   424  func (self *StateDB) SetState(addr common.Address, key, value common.Hash) {
   425  	stateObject := self.GetOrNewStateObject(addr)
   426  	if stateObject != nil {
   427  		stateObject.SetState(self.db, key, value)
   428  	}
   429  }
   430  
   431  // Suicide marks the given account as suicided.
   432  // This clears the account balance.
   433  //
   434  // The account's state object is still available until the state is committed,
   435  // getStateObject will return a non-nil account after Suicide.
   436  func (self *StateDB) Suicide(addr common.Address) bool {
   437  	stateObject := self.getStateObject(addr)
   438  	if stateObject == nil {
   439  		return false
   440  	}
   441  	self.journal.append(suicideChange{
   442  		account:     &addr,
   443  		prev:        stateObject.suicided,
   444  		prevbalance: new(big.Int).Set(stateObject.Balance()),
   445  	})
   446  	stateObject.markSuicided()
   447  	stateObject.data.Balance = new(big.Int)
   448  
   449  	return true
   450  }
   451  
   452  //
   453  // Setting, updating & deleting state object methods.
   454  //
   455  
   456  // updateStateObject writes the given object to the trie.
   457  func (s *StateDB) updateStateObject(stateObject *stateObject) {
   458  	// Track the amount of time wasted on updating the account from the trie
   459  	if metrics.EnabledExpensive {
   460  		defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
   461  	}
   462  	// Encode the account and update the account trie
   463  	addr := stateObject.Address()
   464  
   465  	data, err := rlp.EncodeToBytes(stateObject)
   466  	if err != nil {
   467  		panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
   468  	}
   469  	s.setError(s.trie.TryUpdate(addr[:], data))
   470  }
   471  
   472  // deleteStateObject removes the given object from the state trie.
   473  func (s *StateDB) deleteStateObject(stateObject *stateObject) {
   474  	// Track the amount of time wasted on deleting the account from the trie
   475  	if metrics.EnabledExpensive {
   476  		defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now())
   477  	}
   478  	// Delete the account from the trie
   479  	stateObject.deleted = true
   480  
   481  	addr := stateObject.Address()
   482  	s.setError(s.trie.TryDelete(addr[:]))
   483  }
   484  
   485  // Retrieve a state object given by the address. Returns nil if not found.
   486  func (s *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
   487  	// Prefer live objects
   488  	if obj := s.stateObjects[addr]; obj != nil {
   489  		if obj.deleted {
   490  			return nil
   491  		}
   492  		return obj
   493  	}
   494  	// Track the amount of time wasted on loading the object from the database
   495  	if metrics.EnabledExpensive {
   496  		defer func(start time.Time) { s.AccountReads += time.Since(start) }(time.Now())
   497  	}
   498  	// Load the object from the database
   499  	enc, err := s.trie.TryGet(addr[:])
   500  	if len(enc) == 0 {
   501  		s.setError(err)
   502  		return nil
   503  	}
   504  	var data Account
   505  	if err := rlp.DecodeBytes(enc, &data); err != nil {
   506  		log.Error("Failed to decode state object", "addr", addr, "err", err)
   507  		return nil
   508  	}
   509  	// Insert into the live set
   510  	obj := newObject(s, addr, data)
   511  	s.setStateObject(obj)
   512  	return obj
   513  }
   514  
   515  func (self *StateDB) setStateObject(object *stateObject) {
   516  	self.stateObjects[object.Address()] = object
   517  }
   518  
   519  // Retrieve a state object or create a new state object if nil.
   520  func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
   521  	stateObject := self.getStateObject(addr)
   522  	if stateObject == nil || stateObject.deleted {
   523  		stateObject, _ = self.createObject(addr)
   524  	}
   525  	return stateObject
   526  }
   527  
   528  // createObject creates a new state object. If there is an existing account with
   529  // the given address, it is overwritten and returned as the second return value.
   530  func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
   531  	prev = self.getStateObject(addr)
   532  	newobj = newObject(self, addr, Account{})
   533  	newobj.setNonce(0) // sets the object to dirty
   534  	if prev == nil {
   535  		self.journal.append(createObjectChange{account: &addr})
   536  	} else {
   537  		self.journal.append(resetObjectChange{prev: prev})
   538  	}
   539  	self.setStateObject(newobj)
   540  	return newobj, prev
   541  }
   542  
   543  // CreateAccount explicitly creates a state object. If a state object with the address
   544  // already exists the balance is carried over to the new account.
   545  //
   546  // CreateAccount is called during the EVM CREATE operation. The situation might arise that
   547  // a contract does the following:
   548  //
   549  //   1. sends funds to sha(account ++ (nonce + 1))
   550  //   2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
   551  //
   552  // Carrying over the balance ensures that Ether doesn't disappear.
   553  func (self *StateDB) CreateAccount(addr common.Address) {
   554  	newObj, prev := self.createObject(addr)
   555  	if prev != nil {
   556  		newObj.setBalance(prev.data.Balance)
   557  	}
   558  }
   559  
   560  func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) {
   561  	so := db.getStateObject(addr)
   562  	if so == nil {
   563  		return
   564  	}
   565  	it := trie.NewIterator(so.getTrie(db.db).NodeIterator(nil))
   566  	for it.Next() {
   567  		key := common.BytesToHash(db.trie.GetKey(it.Key))
   568  		if value, dirty := so.dirtyStorage[key]; dirty {
   569  			cb(key, value)
   570  			continue
   571  		}
   572  		cb(key, common.BytesToHash(it.Value))
   573  	}
   574  }
   575  
   576  // Copy creates a deep, independent copy of the state.
   577  // Snapshots of the copied state cannot be applied to the copy.
   578  func (self *StateDB) Copy() *StateDB {
   579  	// Copy all the basic fields, initialize the memory ones
   580  	state := &StateDB{
   581  		db:                self.db,
   582  		trie:              self.db.CopyTrie(self.trie),
   583  		stateObjects:      make(map[common.Address]*stateObject, len(self.journal.dirties)),
   584  		stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)),
   585  		refund:            self.refund,
   586  		logs:              make(map[common.Hash][]*types.Log, len(self.logs)),
   587  		logSize:           self.logSize,
   588  		preimages:         make(map[common.Hash][]byte, len(self.preimages)),
   589  		journal:           newJournal(),
   590  	}
   591  	// Copy the dirty states, logs, and preimages
   592  	for addr := range self.journal.dirties {
   593  		// As documented [here](https://github.com/ethereum/go-ethereum/pull/16485#issuecomment-380438527),
   594  		// and in the Finalise-method, there is a case where an object is in the journal but not
   595  		// in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for
   596  		// nil
   597  		if object, exist := self.stateObjects[addr]; exist {
   598  			state.stateObjects[addr] = object.deepCopy(state)
   599  			state.stateObjectsDirty[addr] = struct{}{}
   600  		}
   601  	}
   602  	// Above, we don't copy the actual journal. This means that if the copy is copied, the
   603  	// loop above will be a no-op, since the copy's journal is empty.
   604  	// Thus, here we iterate over stateObjects, to enable copies of copies
   605  	for addr := range self.stateObjectsDirty {
   606  		if _, exist := state.stateObjects[addr]; !exist {
   607  			state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
   608  			state.stateObjectsDirty[addr] = struct{}{}
   609  		}
   610  	}
   611  	for hash, logs := range self.logs {
   612  		cpy := make([]*types.Log, len(logs))
   613  		for i, l := range logs {
   614  			cpy[i] = new(types.Log)
   615  			*cpy[i] = *l
   616  		}
   617  		state.logs[hash] = cpy
   618  	}
   619  	for hash, preimage := range self.preimages {
   620  		state.preimages[hash] = preimage
   621  	}
   622  	return state
   623  }
   624  
   625  // Snapshot returns an identifier for the current revision of the state.
   626  func (self *StateDB) Snapshot() int {
   627  	id := self.nextRevisionId
   628  	self.nextRevisionId++
   629  	self.validRevisions = append(self.validRevisions, revision{id, self.journal.length()})
   630  	return id
   631  }
   632  
   633  // RevertToSnapshot reverts all state changes made since the given revision.
   634  func (self *StateDB) RevertToSnapshot(revid int) {
   635  	// Find the snapshot in the stack of valid snapshots.
   636  	idx := sort.Search(len(self.validRevisions), func(i int) bool {
   637  		return self.validRevisions[i].id >= revid
   638  	})
   639  	if idx == len(self.validRevisions) || self.validRevisions[idx].id != revid {
   640  		panic(fmt.Errorf("revision id %v cannot be reverted", revid))
   641  	}
   642  	snapshot := self.validRevisions[idx].journalIndex
   643  
   644  	// Replay the journal to undo changes and remove invalidated snapshots
   645  	self.journal.revert(self, snapshot)
   646  	self.validRevisions = self.validRevisions[:idx]
   647  }
   648  
   649  // GetRefund returns the current value of the refund counter.
   650  func (self *StateDB) GetRefund() uint64 {
   651  	return self.refund
   652  }
   653  
   654  // Finalise finalises the state by removing the self destructed objects
   655  // and clears the journal as well as the refunds.
   656  func (s *StateDB) Finalise(deleteEmptyObjects bool) {
   657  	for addr := range s.journal.dirties {
   658  		stateObject, exist := s.stateObjects[addr]
   659  		if !exist {
   660  			// ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2
   661  			// That tx goes out of gas, and although the notion of 'touched' does not exist there, the
   662  			// touch-event will still be recorded in the journal. Since ripeMD is a special snowflake,
   663  			// it will persist in the journal even though the journal is reverted. In this special circumstance,
   664  			// it may exist in `s.journal.dirties` but not in `s.stateObjects`.
   665  			// Thus, we can safely ignore it here
   666  			continue
   667  		}
   668  
   669  		if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) {
   670  			s.deleteStateObject(stateObject)
   671  		} else {
   672  			stateObject.updateRoot(s.db)
   673  			s.updateStateObject(stateObject)
   674  		}
   675  		s.stateObjectsDirty[addr] = struct{}{}
   676  	}
   677  	// Invalidate journal because reverting across transactions is not allowed.
   678  	s.clearJournalAndRefund()
   679  }
   680  
   681  // IntermediateRoot computes the current root hash of the state trie.
   682  // It is called in between transactions to get the root hash that
   683  // goes into transaction receipts.
   684  func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
   685  	s.Finalise(deleteEmptyObjects)
   686  
   687  	// Track the amount of time wasted on hashing the account trie
   688  	if metrics.EnabledExpensive {
   689  		defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now())
   690  	}
   691  	return s.trie.Hash()
   692  }
   693  
   694  // Prepare sets the current transaction hash and index and block hash which is
   695  // used when the EVM emits new state logs.
   696  func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) {
   697  	self.thash = thash
   698  	self.bhash = bhash
   699  	self.txIndex = ti
   700  }
   701  
   702  func (s *StateDB) clearJournalAndRefund() {
   703  	s.journal = newJournal()
   704  	s.validRevisions = s.validRevisions[:0]
   705  	s.refund = 0
   706  }
   707  
   708  // Commit writes the state to the underlying in-memory trie database.
   709  func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) {
   710  	defer s.clearJournalAndRefund()
   711  
   712  	for addr := range s.journal.dirties {
   713  		s.stateObjectsDirty[addr] = struct{}{}
   714  	}
   715  	// Commit objects to the trie, measuring the elapsed time
   716  	for addr, stateObject := range s.stateObjects {
   717  		_, isDirty := s.stateObjectsDirty[addr]
   718  		switch {
   719  		case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()):
   720  			// If the object has been removed, don't bother syncing it
   721  			// and just mark it for deletion in the trie.
   722  			s.deleteStateObject(stateObject)
   723  		case isDirty:
   724  			// Write any contract code associated with the state object
   725  			if stateObject.code != nil && stateObject.dirtyCode {
   726  				s.db.TrieDB().InsertBlob(common.BytesToHash(stateObject.CodeHash()), stateObject.code)
   727  				stateObject.dirtyCode = false
   728  			}
   729  			// Write any storage changes in the state object to its storage trie.
   730  			if err := stateObject.CommitTrie(s.db); err != nil {
   731  				return common.Hash{}, err
   732  			}
   733  			// Update the object in the main account trie.
   734  			s.updateStateObject(stateObject)
   735  		}
   736  		delete(s.stateObjectsDirty, addr)
   737  	}
   738  	// Write the account trie changes, measuing the amount of wasted time
   739  	if metrics.EnabledExpensive {
   740  		defer func(start time.Time) { s.AccountCommits += time.Since(start) }(time.Now())
   741  	}
   742  	root, err = s.trie.Commit(func(leaf []byte, parent common.Hash) error {
   743  		var account Account
   744  		if err := rlp.DecodeBytes(leaf, &account); err != nil {
   745  			return nil
   746  		}
   747  		if account.Root != emptyRoot {
   748  			s.db.TrieDB().Reference(account.Root, parent)
   749  		}
   750  		code := common.BytesToHash(account.CodeHash)
   751  		if code != emptyCode {
   752  			s.db.TrieDB().Reference(code, parent)
   753  		}
   754  		return nil
   755  	})
   756  	return root, err
   757  }