github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/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  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package state
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/hex"
    23  	"fmt"
    24  	"github.com/PlatONnetwork/PlatON-Go/core/vm"
    25  	"github.com/PlatONnetwork/PlatON-Go/log"
    26  	"io"
    27  	"math/big"
    28  	//"runtime/debug"
    29  
    30  	"github.com/PlatONnetwork/PlatON-Go/common"
    31  	"github.com/PlatONnetwork/PlatON-Go/crypto"
    32  	"github.com/PlatONnetwork/PlatON-Go/rlp"
    33  )
    34  
    35  var emptyCodeHash = crypto.Keccak256(nil)
    36  
    37  type Code []byte
    38  type Abi []byte
    39  
    40  func (self Code) String() string {
    41  	return string(self) //strings.Join(Disassemble(self), " ")
    42  }
    43  
    44  type Storage map[string]common.Hash
    45  type ValueStorage map[common.Hash][]byte
    46  
    47  // Storage -> hash : hash , common.Hash ([32]byte)
    48  //type Storage map[common.Hash]common.Hash
    49  
    50  func (self Storage) String() (str string) {
    51  	for key, value := range self {
    52  		// %X -> Provide hexadecimal
    53  		str += fmt.Sprintf("%X : %X\n", key, value)
    54  	}
    55  
    56  	return
    57  }
    58  
    59  // Copy a copy of Storage
    60  func (self Storage) Copy() Storage {
    61  	cpy := make(Storage)
    62  	for key, value := range self {
    63  		cpy[key] = value
    64  	}
    65  
    66  	return cpy
    67  }
    68  
    69  func (self ValueStorage) Copy() ValueStorage {
    70  	cpy := make(ValueStorage)
    71  	for key, value := range self {
    72  		cpy[key] = value
    73  	}
    74  
    75  	return cpy
    76  }
    77  
    78  // stateObject represents an Ethereum account which is being modified.
    79  //
    80  // The usage pattern is as follows:
    81  // First you need to obtain a state object.
    82  // Account values can be accessed and modified through the object.
    83  // Finally, call CommitTrie to write the modified storage trie into a database.
    84  type stateObject struct {
    85  	address  common.Address
    86  	addrHash common.Hash // hash of ethereum address of the account
    87  	data     Account
    88  	db       *StateDB
    89  
    90  	// DB error.
    91  	// State objects are used by the consensus core and VM which are
    92  	// unable to deal with database-level errors. Any error that occurs
    93  	// during a database read is memoized here and will eventually be returned
    94  	// by StateDB.Commit.
    95  	dbErr error
    96  
    97  	// Write caches.
    98  	trie Trie
    99  	// storage trie, which becomes non-nil on first access
   100  	code Code // contract bytecode, which gets set when code is loaded
   101  
   102  	abi Abi
   103  
   104  	originStorage      Storage      // Storage cache of original entries to dedup rewrites
   105  	originValueStorage ValueStorage // Storage cache of original entries to dedup rewrites
   106  
   107  	dirtyStorage      Storage      // Storage entries that need to be flushed to disk
   108  	dirtyValueStorage ValueStorage // Storage entries that need to be flushed to disk
   109  
   110  	// Cache flags.
   111  	// When an object is marked suicided it will be delete from the trie
   112  	// during the "update" phase of the state transition.
   113  	dirtyCode bool // true if the code was updated
   114  	suicided  bool
   115  	deleted   bool
   116  }
   117  
   118  // empty returns whether the account is considered empty.
   119  func (s *stateObject) empty() bool {
   120  	if _, ok := vm.PrecompiledContractsPpos[s.address]; ok {
   121  		return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) && s.data.Root == (common.Hash{})
   122  	} else {
   123  		return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
   124  	}
   125  }
   126  
   127  // Account is the Ethereum consensus representation of accounts.
   128  // These objects are stored in the main account trie.
   129  type Account struct {
   130  	Nonce    uint64
   131  	Balance  *big.Int
   132  	Root     common.Hash // merkle root of the storage trie
   133  	CodeHash []byte
   134  	AbiHash []byte
   135  }
   136  
   137  // newObject creates a state object.
   138  func newObject(db *StateDB, address common.Address, data Account) *stateObject {
   139  	log.Debug("newObject", "state db addr", fmt.Sprintf("%p", db), "state root", db.Root().Hex())
   140  	if data.Balance == nil {
   141  		data.Balance = new(big.Int)
   142  	}
   143  	if data.CodeHash == nil {
   144  		data.CodeHash = emptyCodeHash
   145  	}
   146  	return &stateObject{
   147  		db:       db,
   148  		address:  address,
   149  		addrHash: crypto.Keccak256Hash(address[:]),
   150  		data:     data,
   151  
   152  		originStorage:      make(Storage),
   153  		originValueStorage: make(map[common.Hash][]byte),
   154  
   155  		dirtyStorage:      make(Storage),
   156  		dirtyValueStorage: make(map[common.Hash][]byte),
   157  	}
   158  }
   159  
   160  // EncodeRLP implements rlp.Encoder.
   161  func (c *stateObject) EncodeRLP(w io.Writer) error {
   162  	return rlp.Encode(w, c.data)
   163  }
   164  
   165  // setError remembers the first non-nil error it is called with.
   166  func (self *stateObject) setError(err error) {
   167  	if self.dbErr == nil {
   168  		self.dbErr = err
   169  	}
   170  }
   171  
   172  func (self *stateObject) markSuicided() {
   173  	self.suicided = true
   174  }
   175  
   176  func (c *stateObject) touch() {
   177  	c.db.journal.append(touchChange{
   178  		account: &c.address,
   179  	})
   180  	if c.address == ripemd {
   181  		// Explicitly put it in the dirty-cache, which is otherwise generated from
   182  		// flattened journals.
   183  		c.db.journal.dirty(c.address)
   184  	}
   185  }
   186  
   187  func (c *stateObject) getTrie(db Database) Trie {
   188  	if c.trie == nil {
   189  		var err error
   190  		c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root)
   191  		if err != nil {
   192  			c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{})
   193  			c.setError(fmt.Errorf("can't create storage trie: %v", err))
   194  		}
   195  	}
   196  	return c.trie
   197  }
   198  
   199  // GetState retrieves a value from the account storage trie.
   200  //func (self *stateObject) GetState(db Database, key common.Hash) common.Hash {
   201  //	// If we have a dirty value for this state entry, return it
   202  //	value, dirty := self.dirtyStorage[key]
   203  //	if dirty {
   204  //		return value
   205  //	}
   206  //	// Otherwise return the entry's original value
   207  //	return self.GetCommittedState(db, key)
   208  //}
   209  
   210  // GetState retrieves a value from the account storage trie.
   211  func (self *stateObject) GetState(db Database, keyTree string) []byte {
   212  	// If we have a dirty value for this state entry, return it
   213  	valueKey, dirty := self.dirtyStorage[keyTree]
   214  	if dirty {
   215  		value, ok := self.dirtyValueStorage[valueKey]
   216  		if ok {
   217  			return value
   218  		}
   219  	}
   220  	// Otherwise return the entry's original value
   221  	return self.GetCommittedState(db, keyTree)
   222  }
   223  
   224  // GetCommittedState retrieves a value from the committed account storage trie.
   225  //func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash {
   226  //	// If we have the original value cached, return that
   227  //	value, cached := self.originStorage[key]
   228  //	if cached {
   229  //		return value
   230  //	}
   231  //	// Otherwise load the value from the database
   232  //	enc, err := self.getTrie(db).TryGet(key[:])
   233  //	if err != nil {
   234  //		self.setError(err)
   235  //		return common.Hash{}
   236  //	}
   237  //	if len(enc) > 0 {
   238  //		_, content, _, err := rlp.Split(enc)
   239  //		if err != nil {
   240  //			self.setError(err)
   241  //		}
   242  //		value.SetBytes(content)
   243  //	}
   244  //	self.originStorage[key] = value
   245  //	return value
   246  //}
   247  
   248  // GetCommittedState retrieves a value from the committed account storage trie.
   249  func (self *stateObject) GetCommittedState(db Database, key string) []byte {
   250  	var value []byte
   251  	// If we have the original value cached, return that
   252  	valueKey, cached := self.originStorage[key]
   253  	if cached {
   254  		value, cached2 := self.originValueStorage[valueKey]
   255  		if cached2 {
   256  			return value
   257  		}
   258  	}
   259  	log.Debug("GetCommittedState", "stateObject addr", fmt.Sprintf("%p", self), "statedb addr", fmt.Sprintf("%p", self.db), "root", self.data.Root, "key", hex.EncodeToString([]byte(key)))
   260  	//if self.data.Root == (common.Hash{}) {
   261  	//	log.Info("GetCommittedState", "stack", string(debug.Stack()))
   262  	//}
   263  	// Otherwise load the valueKey from trie
   264  	enc, err := self.getTrie(db).TryGet([]byte(key))
   265  	if err != nil {
   266  		self.setError(err)
   267  		return []byte{}
   268  	}
   269  	if len(enc) > 0 {
   270  		_, content, _, err := rlp.Split(enc)
   271  		if err != nil {
   272  			self.setError(err)
   273  		}
   274  		valueKey.SetBytes(content)
   275  
   276  		//load value from db
   277  		value = self.db.trie.GetKey(valueKey.Bytes())
   278  		if err != nil {
   279  			self.setError(err)
   280  		}
   281  	}
   282  
   283  	if valueKey != emptyStorage && len(value) == 0 {
   284  		log.Error("invalid storage valuekey", "key", hex.EncodeToString([]byte(key)), "valueKey", valueKey.String())
   285  		return []byte{}
   286  	}
   287  	if len(value) == 0 && valueKey == emptyStorage {
   288  		log.Debug("empty storage valuekey", "key", hex.EncodeToString([]byte(key)), "valueKey", valueKey.String())
   289  	}
   290  	log.Info("GetCommittedState", "stateObject addr", fmt.Sprintf("%p", self), "statedb addr", fmt.Sprintf("%p", self.db), "root", self.data.Root, "key", hex.EncodeToString([]byte(key)), "valueKey", valueKey.String(), "value", len(value))
   291  	self.originStorage[key] = valueKey
   292  	self.originValueStorage[valueKey] = value
   293  	return value
   294  }
   295  
   296  // SetState updates a value in account storage.
   297  // set [keyTrie,valueKey] to storage
   298  // set [valueKey,value] to db
   299  func (self *stateObject) SetState(db Database, keyTrie string, valueKey common.Hash, value []byte) {
   300  	log.Debug("SetState ", "keyTrie", hex.EncodeToString([]byte(keyTrie)), "valueKey", valueKey, "value", hex.EncodeToString(value))
   301  	//if the new value is the same as old,don't set
   302  	preValue := self.GetState(db, keyTrie) // get value key
   303  	if bytes.Equal(preValue, value) {
   304  		return
   305  	}
   306  
   307  	//New value is different, update and journal the change
   308  	self.db.journal.append(storageChange{
   309  		account:  &self.address,
   310  		key:      keyTrie,
   311  		valueKey: self.originStorage[keyTrie],
   312  		preValue: preValue,
   313  	})
   314  
   315  	self.setState(keyTrie, valueKey, value)
   316  }
   317  
   318  func (self *stateObject) setState(key string, valueKey common.Hash, value []byte) {
   319  	cpy := make([]byte, len(value))
   320  	copy(cpy, value)
   321  	self.dirtyStorage[key] = valueKey
   322  	self.dirtyValueStorage[valueKey] = cpy
   323  }
   324  
   325  // updateTrie writes cached storage modifications into the object's storage trie.
   326  func (self *stateObject) updateTrie(db Database) Trie {
   327  	tr := self.getTrie(db)
   328  	for key, valueKey := range self.dirtyStorage {
   329  		delete(self.dirtyStorage, key)
   330  
   331  		if valueKey == self.originStorage[key] {
   332  			continue
   333  		}
   334  
   335  		self.originStorage[key] = valueKey
   336  
   337  		if valueKey == emptyStorage {
   338  			self.setError(tr.TryDelete([]byte(key)))
   339  			continue
   340  		}
   341  
   342  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(valueKey[:], "\x00"))
   343  		self.setError(tr.TryUpdate([]byte(key), v))
   344  
   345  		//flush dirty value
   346  		if value, ok := self.dirtyValueStorage[valueKey]; ok {
   347  			delete(self.dirtyValueStorage, valueKey)
   348  			self.originValueStorage[valueKey] = value
   349  			self.setError(tr.TryUpdateValue(valueKey.Bytes(), value))
   350  		}
   351  	}
   352  
   353  	return tr
   354  }
   355  
   356  // UpdateRoot sets the trie root to the current root hash of
   357  func (self *stateObject) updateRoot(db Database) {
   358  	self.updateTrie(db)
   359  	self.data.Root = self.trie.Hash()
   360  }
   361  
   362  // CommitTrie the storage trie of the object to db.
   363  // This updates the trie root.
   364  func (self *stateObject) CommitTrie(db Database) error {
   365  	self.updateTrie(db)
   366  	if self.dbErr != nil {
   367  		return self.dbErr
   368  	}
   369  
   370  	for h, v := range self.originValueStorage {
   371  		if h != emptyStorage && !bytes.Equal(v, []byte{}) {
   372  			self.trie.TryUpdateValue(h.Bytes(), v)
   373  		}
   374  	}
   375  	root, err := self.trie.Commit(nil)
   376  	if err == nil {
   377  		self.data.Root = root
   378  	}
   379  	return err
   380  }
   381  
   382  // AddBalance removes amount from c's balance.
   383  // It is used to add funds to the destination account of a transfer.
   384  func (c *stateObject) AddBalance(amount *big.Int) {
   385  	// EIP158: We must check emptiness for the objects such that the account
   386  	// clearing (0,0,0 objects) can take effect.
   387  	if amount.Sign() == 0 {
   388  		if c.empty() {
   389  			c.touch()
   390  		}
   391  
   392  		return
   393  	}
   394  	c.SetBalance(new(big.Int).Add(c.Balance(), amount))
   395  }
   396  
   397  // SubBalance removes amount from c's balance.
   398  // It is used to remove funds from the origin account of a transfer.
   399  func (c *stateObject) SubBalance(amount *big.Int) {
   400  	if amount.Sign() == 0 {
   401  		return
   402  	}
   403  	c.SetBalance(new(big.Int).Sub(c.Balance(), amount))
   404  }
   405  
   406  func (self *stateObject) SetBalance(amount *big.Int) {
   407  	self.db.journal.append(balanceChange{
   408  		account: &self.address,
   409  		prev:    new(big.Int).Set(self.data.Balance),
   410  	})
   411  	self.setBalance(amount)
   412  }
   413  
   414  func (self *stateObject) setBalance(amount *big.Int) {
   415  	self.data.Balance = amount
   416  }
   417  
   418  // Return the gas back to the origin. Used by the Virtual machine or Closures
   419  func (c *stateObject) ReturnGas(gas *big.Int) {}
   420  
   421  func (self *stateObject) deepCopy(db *StateDB) *stateObject {
   422  	stateObject := newObject(db, self.address, self.data)
   423  	if self.trie != nil {
   424  		stateObject.trie = db.db.CopyTrie(self.trie)
   425  	}
   426  	stateObject.code = self.code
   427  	stateObject.dirtyStorage = self.dirtyStorage.Copy()
   428  	stateObject.dirtyValueStorage = self.dirtyValueStorage.Copy()
   429  	stateObject.originStorage = self.originStorage.Copy()
   430  	stateObject.originValueStorage = self.originValueStorage.Copy()
   431  	stateObject.suicided = self.suicided
   432  	stateObject.dirtyCode = self.dirtyCode
   433  	stateObject.deleted = self.deleted
   434  	return stateObject
   435  }
   436  
   437  //
   438  // Attribute accessors
   439  //
   440  
   441  // Returns the address of the contract/account
   442  func (c *stateObject) Address() common.Address {
   443  	return c.address
   444  }
   445  
   446  // Code returns the contract code associated with this object, if any.
   447  func (self *stateObject) Code(db Database) []byte {
   448  	if self.code != nil {
   449  		return self.code
   450  	}
   451  	if bytes.Equal(self.CodeHash(), emptyCodeHash) {
   452  		return nil
   453  	}
   454  	code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash()))
   455  	if err != nil {
   456  		self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err))
   457  	}
   458  	self.code = code
   459  	return code
   460  }
   461  
   462  func (self *stateObject) SetCode(codeHash common.Hash, code []byte) {
   463  	prevcode := self.Code(self.db.db)
   464  	self.db.journal.append(codeChange{
   465  		account:  &self.address,
   466  		prevhash: self.CodeHash(),
   467  		prevcode: prevcode,
   468  	})
   469  	self.setCode(codeHash, code)
   470  }
   471  
   472  func (self *stateObject) setCode(codeHash common.Hash, code []byte) {
   473  	self.code = code
   474  	self.data.CodeHash = codeHash[:]
   475  	self.dirtyCode = true
   476  }
   477  
   478  func (self *stateObject) SetNonce(nonce uint64) {
   479  	self.db.journal.append(nonceChange{
   480  		account: &self.address,
   481  		prev:    self.data.Nonce,
   482  	})
   483  	self.setNonce(nonce)
   484  }
   485  
   486  func (self *stateObject) setNonce(nonce uint64) {
   487  	self.data.Nonce = nonce
   488  }
   489  
   490  func (self *stateObject) CodeHash() []byte {
   491  	return self.data.CodeHash
   492  }
   493  
   494  func (self *stateObject) Balance() *big.Int {
   495  	return self.data.Balance
   496  }
   497  
   498  func (self *stateObject) Nonce() uint64 {
   499  	return self.data.Nonce
   500  }
   501  
   502  // Never called, but must be present to allow stateObject to be used
   503  // as a vm.Account interface that also satisfies the vm.ContractRef
   504  // interface. Interfaces are awesome.
   505  func (self *stateObject) Value() *big.Int {
   506  	panic("Value on stateObject should never be called")
   507  }
   508  
   509  // todo: New method
   510  // ======================================= New method ===============================
   511  
   512  // todo: new method -> AbiHash
   513  func (self *stateObject) AbiHash() []byte {
   514  	return self.data.AbiHash
   515  }
   516  
   517  // ABI returns the contract abi associated with this object, if any.
   518  func (self *stateObject) Abi(db Database) []byte {
   519  	//if self.Abi != nil {
   520  	//	return self.abi
   521  	//}
   522  	if bytes.Equal(self.AbiHash(), emptyCodeHash) {
   523  		return nil
   524  	}
   525  	// Extract the code from the tree, enter the parameters: address and hash, here you need to find the acquisition rules in depth
   526  	abi, err := db.ContractAbi(self.addrHash, common.BytesToHash(self.AbiHash()))
   527  	if err != nil {
   528  		self.setError(fmt.Errorf("can't load abi hash %x: %v", self.AbiHash(), err))
   529  	}
   530  	self.abi = abi
   531  	return abi
   532  }
   533  
   534  // todo: new method -> SetAbi.
   535  func (self *stateObject) SetAbi(abiHash common.Hash, abi []byte) {
   536  	prevabi := self.Abi(self.db.db)
   537  	self.db.journal.append(abiChange{
   538  		account:  &self.address,
   539  		prevhash: self.AbiHash(),
   540  		prevabi:  prevabi,
   541  	})
   542  	self.setAbi(abiHash, abi)
   543  }
   544  
   545  // todo: new method -> setAbi
   546  func (self *stateObject) setAbi(abiHash common.Hash, abi []byte) {
   547  	self.abi = abi
   548  	self.data.AbiHash = abiHash[:]
   549  }