github.com/theQRL/go-zond@v0.1.1/core/state/state_object.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
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"math/big"
    24  	"time"
    25  
    26  	"github.com/theQRL/go-zond/common"
    27  	"github.com/theQRL/go-zond/core/types"
    28  	"github.com/theQRL/go-zond/crypto"
    29  	"github.com/theQRL/go-zond/metrics"
    30  	"github.com/theQRL/go-zond/rlp"
    31  	"github.com/theQRL/go-zond/trie/trienode"
    32  )
    33  
    34  type Code []byte
    35  
    36  func (c Code) String() string {
    37  	return string(c) //strings.Join(Disassemble(c), " ")
    38  }
    39  
    40  type Storage map[common.Hash]common.Hash
    41  
    42  func (s Storage) String() (str string) {
    43  	for key, value := range s {
    44  		str += fmt.Sprintf("%X : %X\n", key, value)
    45  	}
    46  	return
    47  }
    48  
    49  func (s Storage) Copy() Storage {
    50  	cpy := make(Storage, len(s))
    51  	for key, value := range s {
    52  		cpy[key] = value
    53  	}
    54  	return cpy
    55  }
    56  
    57  // stateObject represents an Ethereum account which is being modified.
    58  //
    59  // The usage pattern is as follows:
    60  // - First you need to obtain a state object.
    61  // - Account values as well as storages can be accessed and modified through the object.
    62  // - Finally, call commit to return the changes of storage trie and update account data.
    63  type stateObject struct {
    64  	db       *StateDB
    65  	address  common.Address      // address of ethereum account
    66  	addrHash common.Hash         // hash of ethereum address of the account
    67  	origin   *types.StateAccount // Account original data without any change applied, nil means it was not existent
    68  	data     types.StateAccount  // Account data with all mutations applied in the scope of block
    69  
    70  	// Write caches.
    71  	trie Trie // storage trie, which becomes non-nil on first access
    72  	code Code // contract bytecode, which gets set when code is loaded
    73  
    74  	originStorage  Storage // Storage cache of original entries to dedup rewrites
    75  	pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block
    76  	dirtyStorage   Storage // Storage entries that have been modified in the current transaction execution, reset for every transaction
    77  
    78  	// Cache flags.
    79  	dirtyCode bool // true if the code was updated
    80  
    81  	// Flag whether the account was marked as self-destructed. The self-destructed account
    82  	// is still accessible in the scope of same transaction.
    83  	selfDestructed bool
    84  
    85  	// Flag whether the account was marked as deleted. A self-destructed account
    86  	// or an account that is considered as empty will be marked as deleted at
    87  	// the end of transaction and no longer accessible anymore.
    88  	deleted bool
    89  
    90  	// Flag whether the object was created in the current transaction
    91  	created bool
    92  }
    93  
    94  // empty returns whether the account is considered empty.
    95  func (s *stateObject) empty() bool {
    96  	return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes())
    97  }
    98  
    99  // newObject creates a state object.
   100  func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *stateObject {
   101  	origin := acct
   102  	if acct == nil {
   103  		acct = types.NewEmptyStateAccount()
   104  	}
   105  	return &stateObject{
   106  		db:             db,
   107  		address:        address,
   108  		addrHash:       crypto.Keccak256Hash(address[:]),
   109  		origin:         origin,
   110  		data:           *acct,
   111  		originStorage:  make(Storage),
   112  		pendingStorage: make(Storage),
   113  		dirtyStorage:   make(Storage),
   114  	}
   115  }
   116  
   117  // EncodeRLP implements rlp.Encoder.
   118  func (s *stateObject) EncodeRLP(w io.Writer) error {
   119  	return rlp.Encode(w, &s.data)
   120  }
   121  
   122  func (s *stateObject) markSelfdestructed() {
   123  	s.selfDestructed = true
   124  }
   125  
   126  func (s *stateObject) touch() {
   127  	s.db.journal.append(touchChange{
   128  		account: &s.address,
   129  	})
   130  	if s.address == ripemd {
   131  		// Explicitly put it in the dirty-cache, which is otherwise generated from
   132  		// flattened journals.
   133  		s.db.journal.dirty(s.address)
   134  	}
   135  }
   136  
   137  // getTrie returns the associated storage trie. The trie will be opened
   138  // if it's not loaded previously. An error will be returned if trie can't
   139  // be loaded.
   140  func (s *stateObject) getTrie() (Trie, error) {
   141  	if s.trie == nil {
   142  		// Try fetching from prefetcher first
   143  		if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil {
   144  			// When the miner is creating the pending state, there is no prefetcher
   145  			s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root)
   146  		}
   147  		if s.trie == nil {
   148  			tr, err := s.db.db.OpenStorageTrie(s.db.originalRoot, s.address, s.data.Root)
   149  			if err != nil {
   150  				return nil, err
   151  			}
   152  			s.trie = tr
   153  		}
   154  	}
   155  	return s.trie, nil
   156  }
   157  
   158  // GetState retrieves a value from the account storage trie.
   159  func (s *stateObject) GetState(key common.Hash) common.Hash {
   160  	// If we have a dirty value for this state entry, return it
   161  	value, dirty := s.dirtyStorage[key]
   162  	if dirty {
   163  		return value
   164  	}
   165  	// Otherwise return the entry's original value
   166  	return s.GetCommittedState(key)
   167  }
   168  
   169  // GetCommittedState retrieves a value from the committed account storage trie.
   170  func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
   171  	// If we have a pending write or clean cached, return that
   172  	if value, pending := s.pendingStorage[key]; pending {
   173  		return value
   174  	}
   175  	if value, cached := s.originStorage[key]; cached {
   176  		return value
   177  	}
   178  	// If the object was destructed in *this* block (and potentially resurrected),
   179  	// the storage has been cleared out, and we should *not* consult the previous
   180  	// database about any storage values. The only possible alternatives are:
   181  	//   1) resurrect happened, and new slot values were set -- those should
   182  	//      have been handles via pendingStorage above.
   183  	//   2) we don't have new values, and can deliver empty response back
   184  	if _, destructed := s.db.stateObjectsDestruct[s.address]; destructed {
   185  		return common.Hash{}
   186  	}
   187  	// If no live objects are available, attempt to use snapshots
   188  	var (
   189  		enc   []byte
   190  		err   error
   191  		value common.Hash
   192  	)
   193  	if s.db.snap != nil {
   194  		start := time.Now()
   195  		enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes()))
   196  		if metrics.EnabledExpensive {
   197  			s.db.SnapshotStorageReads += time.Since(start)
   198  		}
   199  		if len(enc) > 0 {
   200  			_, content, _, err := rlp.Split(enc)
   201  			if err != nil {
   202  				s.db.setError(err)
   203  			}
   204  			value.SetBytes(content)
   205  		}
   206  	}
   207  	// If the snapshot is unavailable or reading from it fails, load from the database.
   208  	if s.db.snap == nil || err != nil {
   209  		start := time.Now()
   210  		tr, err := s.getTrie()
   211  		if err != nil {
   212  			s.db.setError(err)
   213  			return common.Hash{}
   214  		}
   215  		val, err := tr.GetStorage(s.address, key.Bytes())
   216  		if metrics.EnabledExpensive {
   217  			s.db.StorageReads += time.Since(start)
   218  		}
   219  		if err != nil {
   220  			s.db.setError(err)
   221  			return common.Hash{}
   222  		}
   223  		value.SetBytes(val)
   224  	}
   225  	s.originStorage[key] = value
   226  	return value
   227  }
   228  
   229  // SetState updates a value in account storage.
   230  func (s *stateObject) SetState(key, value common.Hash) {
   231  	// If the new value is the same as old, don't set
   232  	prev := s.GetState(key)
   233  	if prev == value {
   234  		return
   235  	}
   236  	// New value is different, update and journal the change
   237  	s.db.journal.append(storageChange{
   238  		account:  &s.address,
   239  		key:      key,
   240  		prevalue: prev,
   241  	})
   242  	s.setState(key, value)
   243  }
   244  
   245  func (s *stateObject) setState(key, value common.Hash) {
   246  	s.dirtyStorage[key] = value
   247  }
   248  
   249  // finalise moves all dirty storage slots into the pending area to be hashed or
   250  // committed later. It is invoked at the end of every transaction.
   251  func (s *stateObject) finalise(prefetch bool) {
   252  	slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage))
   253  	for key, value := range s.dirtyStorage {
   254  		s.pendingStorage[key] = value
   255  		if value != s.originStorage[key] {
   256  			slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure
   257  		}
   258  	}
   259  	if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash {
   260  		s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, slotsToPrefetch)
   261  	}
   262  	if len(s.dirtyStorage) > 0 {
   263  		s.dirtyStorage = make(Storage)
   264  	}
   265  }
   266  
   267  // updateTrie is responsible for persisting cached storage changes into the
   268  // object's storage trie. In case the storage trie is not yet loaded, this
   269  // function will load the trie automatically. If any issues arise during the
   270  // loading or updating of the trie, an error will be returned. Furthermore,
   271  // this function will return the mutated storage trie, or nil if there is no
   272  // storage change at all.
   273  func (s *stateObject) updateTrie() (Trie, error) {
   274  	// Make sure all dirty slots are finalized into the pending storage area
   275  	s.finalise(false)
   276  
   277  	// Short circuit if nothing changed, don't bother with hashing anything
   278  	if len(s.pendingStorage) == 0 {
   279  		return s.trie, nil
   280  	}
   281  	// Track the amount of time wasted on updating the storage trie
   282  	if metrics.EnabledExpensive {
   283  		defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now())
   284  	}
   285  	// The snapshot storage map for the object
   286  	var (
   287  		storage map[common.Hash][]byte
   288  		origin  map[common.Hash][]byte
   289  	)
   290  	tr, err := s.getTrie()
   291  	if err != nil {
   292  		s.db.setError(err)
   293  		return nil, err
   294  	}
   295  	// Insert all the pending storage updates into the trie
   296  	usedStorage := make([][]byte, 0, len(s.pendingStorage))
   297  	for key, value := range s.pendingStorage {
   298  		// Skip noop changes, persist actual changes
   299  		if value == s.originStorage[key] {
   300  			continue
   301  		}
   302  		prev := s.originStorage[key]
   303  		s.originStorage[key] = value
   304  
   305  		var encoded []byte // rlp-encoded value to be used by the snapshot
   306  		if (value == common.Hash{}) {
   307  			if err := tr.DeleteStorage(s.address, key[:]); err != nil {
   308  				s.db.setError(err)
   309  				return nil, err
   310  			}
   311  			s.db.StorageDeleted += 1
   312  		} else {
   313  			// Encoding []byte cannot fail, ok to ignore the error.
   314  			trimmed := common.TrimLeftZeroes(value[:])
   315  			encoded, _ = rlp.EncodeToBytes(trimmed)
   316  			if err := tr.UpdateStorage(s.address, key[:], trimmed); err != nil {
   317  				s.db.setError(err)
   318  				return nil, err
   319  			}
   320  			s.db.StorageUpdated += 1
   321  		}
   322  		// Cache the mutated storage slots until commit
   323  		if storage == nil {
   324  			if storage = s.db.storages[s.addrHash]; storage == nil {
   325  				storage = make(map[common.Hash][]byte)
   326  				s.db.storages[s.addrHash] = storage
   327  			}
   328  		}
   329  		khash := crypto.HashData(s.db.hasher, key[:])
   330  		storage[khash] = encoded // encoded will be nil if it's deleted
   331  
   332  		// Cache the original value of mutated storage slots
   333  		if origin == nil {
   334  			if origin = s.db.storagesOrigin[s.address]; origin == nil {
   335  				origin = make(map[common.Hash][]byte)
   336  				s.db.storagesOrigin[s.address] = origin
   337  			}
   338  		}
   339  		// Track the original value of slot only if it's mutated first time
   340  		if _, ok := origin[khash]; !ok {
   341  			if prev == (common.Hash{}) {
   342  				origin[khash] = nil // nil if it was not present previously
   343  			} else {
   344  				// Encoding []byte cannot fail, ok to ignore the error.
   345  				b, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(prev[:]))
   346  				origin[khash] = b
   347  			}
   348  		}
   349  		// Cache the items for preloading
   350  		usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure
   351  	}
   352  	if s.db.prefetcher != nil {
   353  		s.db.prefetcher.used(s.addrHash, s.data.Root, usedStorage)
   354  	}
   355  	s.pendingStorage = make(Storage) // reset pending map
   356  	return tr, nil
   357  }
   358  
   359  // updateRoot flushes all cached storage mutations to trie, recalculating the
   360  // new storage trie root.
   361  func (s *stateObject) updateRoot() {
   362  	// Flush cached storage mutations into trie, short circuit if any error
   363  	// is occurred or there is not change in the trie.
   364  	tr, err := s.updateTrie()
   365  	if err != nil || tr == nil {
   366  		return
   367  	}
   368  	// Track the amount of time wasted on hashing the storage trie
   369  	if metrics.EnabledExpensive {
   370  		defer func(start time.Time) { s.db.StorageHashes += time.Since(start) }(time.Now())
   371  	}
   372  	s.data.Root = tr.Hash()
   373  }
   374  
   375  // commit obtains a set of dirty storage trie nodes and updates the account data.
   376  // The returned set can be nil if nothing to commit. This function assumes all
   377  // storage mutations have already been flushed into trie by updateRoot.
   378  func (s *stateObject) commit() (*trienode.NodeSet, error) {
   379  	// Short circuit if trie is not even loaded, don't bother with committing anything
   380  	if s.trie == nil {
   381  		s.origin = s.data.Copy()
   382  		return nil, nil
   383  	}
   384  	// Track the amount of time wasted on committing the storage trie
   385  	if metrics.EnabledExpensive {
   386  		defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now())
   387  	}
   388  	// The trie is currently in an open state and could potentially contain
   389  	// cached mutations. Call commit to acquire a set of nodes that have been
   390  	// modified, the set can be nil if nothing to commit.
   391  	root, nodes, err := s.trie.Commit(false)
   392  	if err != nil {
   393  		return nil, err
   394  	}
   395  	s.data.Root = root
   396  
   397  	// Update original account data after commit
   398  	s.origin = s.data.Copy()
   399  	return nodes, nil
   400  }
   401  
   402  // AddBalance adds amount to s's balance.
   403  // It is used to add funds to the destination account of a transfer.
   404  func (s *stateObject) AddBalance(amount *big.Int) {
   405  	// EIP161: We must check emptiness for the objects such that the account
   406  	// clearing (0,0,0 objects) can take effect.
   407  	if amount.Sign() == 0 {
   408  		if s.empty() {
   409  			s.touch()
   410  		}
   411  		return
   412  	}
   413  	s.SetBalance(new(big.Int).Add(s.Balance(), amount))
   414  }
   415  
   416  // SubBalance removes amount from s's balance.
   417  // It is used to remove funds from the origin account of a transfer.
   418  func (s *stateObject) SubBalance(amount *big.Int) {
   419  	if amount.Sign() == 0 {
   420  		return
   421  	}
   422  	s.SetBalance(new(big.Int).Sub(s.Balance(), amount))
   423  }
   424  
   425  func (s *stateObject) SetBalance(amount *big.Int) {
   426  	s.db.journal.append(balanceChange{
   427  		account: &s.address,
   428  		prev:    new(big.Int).Set(s.data.Balance),
   429  	})
   430  	s.setBalance(amount)
   431  }
   432  
   433  func (s *stateObject) setBalance(amount *big.Int) {
   434  	s.data.Balance = amount
   435  }
   436  
   437  func (s *stateObject) deepCopy(db *StateDB) *stateObject {
   438  	obj := &stateObject{
   439  		db:       db,
   440  		address:  s.address,
   441  		addrHash: s.addrHash,
   442  		origin:   s.origin,
   443  		data:     s.data,
   444  	}
   445  	if s.trie != nil {
   446  		obj.trie = db.db.CopyTrie(s.trie)
   447  	}
   448  	obj.code = s.code
   449  	obj.dirtyStorage = s.dirtyStorage.Copy()
   450  	obj.originStorage = s.originStorage.Copy()
   451  	obj.pendingStorage = s.pendingStorage.Copy()
   452  	obj.selfDestructed = s.selfDestructed
   453  	obj.dirtyCode = s.dirtyCode
   454  	obj.deleted = s.deleted
   455  	return obj
   456  }
   457  
   458  //
   459  // Attribute accessors
   460  //
   461  
   462  // Address returns the address of the contract/account
   463  func (s *stateObject) Address() common.Address {
   464  	return s.address
   465  }
   466  
   467  // Code returns the contract code associated with this object, if any.
   468  func (s *stateObject) Code() []byte {
   469  	if s.code != nil {
   470  		return s.code
   471  	}
   472  	if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
   473  		return nil
   474  	}
   475  	code, err := s.db.db.ContractCode(s.address, common.BytesToHash(s.CodeHash()))
   476  	if err != nil {
   477  		s.db.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err))
   478  	}
   479  	s.code = code
   480  	return code
   481  }
   482  
   483  // CodeSize returns the size of the contract code associated with this object,
   484  // or zero if none. This method is an almost mirror of Code, but uses a cache
   485  // inside the database to avoid loading codes seen recently.
   486  func (s *stateObject) CodeSize() int {
   487  	if s.code != nil {
   488  		return len(s.code)
   489  	}
   490  	if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
   491  		return 0
   492  	}
   493  	size, err := s.db.db.ContractCodeSize(s.address, common.BytesToHash(s.CodeHash()))
   494  	if err != nil {
   495  		s.db.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err))
   496  	}
   497  	return size
   498  }
   499  
   500  func (s *stateObject) SetCode(codeHash common.Hash, code []byte) {
   501  	prevcode := s.Code()
   502  	s.db.journal.append(codeChange{
   503  		account:  &s.address,
   504  		prevhash: s.CodeHash(),
   505  		prevcode: prevcode,
   506  	})
   507  	s.setCode(codeHash, code)
   508  }
   509  
   510  func (s *stateObject) setCode(codeHash common.Hash, code []byte) {
   511  	s.code = code
   512  	s.data.CodeHash = codeHash[:]
   513  	s.dirtyCode = true
   514  }
   515  
   516  func (s *stateObject) SetNonce(nonce uint64) {
   517  	s.db.journal.append(nonceChange{
   518  		account: &s.address,
   519  		prev:    s.data.Nonce,
   520  	})
   521  	s.setNonce(nonce)
   522  }
   523  
   524  func (s *stateObject) setNonce(nonce uint64) {
   525  	s.data.Nonce = nonce
   526  }
   527  
   528  func (s *stateObject) CodeHash() []byte {
   529  	return s.data.CodeHash
   530  }
   531  
   532  func (s *stateObject) Balance() *big.Int {
   533  	return s.data.Balance
   534  }
   535  
   536  func (s *stateObject) Nonce() uint64 {
   537  	return s.data.Nonce
   538  }
   539  
   540  func (s *stateObject) Root() common.Hash {
   541  	return s.data.Root
   542  }