github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/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  
    25  	"github.com/atheioschain/go-atheios/common"
    26  	"github.com/atheioschain/go-atheios/crypto"
    27  	"github.com/atheioschain/go-atheios/logger"
    28  	"github.com/atheioschain/go-atheios/logger/glog"
    29  	"github.com/atheioschain/go-atheios/rlp"
    30  	"github.com/atheioschain/go-atheios/trie"
    31  )
    32  
    33  var emptyCodeHash = crypto.Keccak256(nil)
    34  
    35  type Code []byte
    36  
    37  func (self Code) String() string {
    38  	return string(self) //strings.Join(Disassemble(self), " ")
    39  }
    40  
    41  type Storage map[common.Hash]common.Hash
    42  
    43  func (self Storage) String() (str string) {
    44  	for key, value := range self {
    45  		str += fmt.Sprintf("%X : %X\n", key, value)
    46  	}
    47  
    48  	return
    49  }
    50  
    51  func (self Storage) Copy() Storage {
    52  	cpy := make(Storage)
    53  	for key, value := range self {
    54  		cpy[key] = value
    55  	}
    56  
    57  	return cpy
    58  }
    59  
    60  // StateObject represents an Ethereum account which is being modified.
    61  //
    62  // The usage pattern is as follows:
    63  // First you need to obtain a state object.
    64  // Account values can be accessed and modified through the object.
    65  // Finally, call CommitTrie to write the modified storage trie into a database.
    66  type StateObject struct {
    67  	address common.Address // Ethereum address of this account
    68  	data    Account
    69  	db      *StateDB
    70  
    71  	// DB error.
    72  	// State objects are used by the consensus core and VM which are
    73  	// unable to deal with database-level errors. Any error that occurs
    74  	// during a database read is memoized here and will eventually be returned
    75  	// by StateDB.Commit.
    76  	dbErr error
    77  
    78  	// Write caches.
    79  	trie *trie.SecureTrie // storage trie, which becomes non-nil on first access
    80  	code Code             // contract bytecode, which gets set when code is loaded
    81  
    82  	cachedStorage Storage // Storage entry cache to avoid duplicate reads
    83  	dirtyStorage  Storage // Storage entries that need to be flushed to disk
    84  
    85  	// Cache flags.
    86  	// When an object is marked suicided it will be delete from the trie
    87  	// during the "update" phase of the state transition.
    88  	dirtyCode bool // true if the code was updated
    89  	suicided  bool
    90  	touched   bool
    91  	deleted   bool
    92  	onDirty   func(addr common.Address) // Callback method to mark a state object newly dirty
    93  }
    94  
    95  // empty returns whether the account is considered empty.
    96  func (s *StateObject) empty() bool {
    97  	return s.data.Nonce == 0 && s.data.Balance.BitLen() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
    98  }
    99  
   100  // Account is the Ethereum consensus representation of accounts.
   101  // These objects are stored in the main account trie.
   102  type Account struct {
   103  	Nonce    uint64
   104  	Balance  *big.Int
   105  	Root     common.Hash // merkle root of the storage trie
   106  	CodeHash []byte
   107  }
   108  
   109  // newObject creates a state object.
   110  func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *StateObject {
   111  	if data.Balance == nil {
   112  		data.Balance = new(big.Int)
   113  	}
   114  	if data.CodeHash == nil {
   115  		data.CodeHash = emptyCodeHash
   116  	}
   117  	return &StateObject{db: db, address: address, data: data, cachedStorage: make(Storage), dirtyStorage: make(Storage), onDirty: onDirty}
   118  }
   119  
   120  // EncodeRLP implements rlp.Encoder.
   121  func (c *StateObject) EncodeRLP(w io.Writer) error {
   122  	return rlp.Encode(w, c.data)
   123  }
   124  
   125  // setError remembers the first non-nil error it is called with.
   126  func (self *StateObject) setError(err error) {
   127  	if self.dbErr == nil {
   128  		self.dbErr = err
   129  	}
   130  }
   131  
   132  func (self *StateObject) markSuicided() {
   133  	self.suicided = true
   134  	if self.onDirty != nil {
   135  		self.onDirty(self.Address())
   136  		self.onDirty = nil
   137  	}
   138  	if glog.V(logger.Core) {
   139  		glog.Infof("%x: #%d %v X\n", self.Address(), self.Nonce(), self.Balance())
   140  	}
   141  }
   142  
   143  func (c *StateObject) touch() {
   144  	c.db.journal = append(c.db.journal, touchChange{
   145  		account: &c.address,
   146  		prev:    c.touched,
   147  	})
   148  	if c.onDirty != nil {
   149  		c.onDirty(c.Address())
   150  		c.onDirty = nil
   151  	}
   152  	c.touched = true
   153  }
   154  
   155  func (c *StateObject) getTrie(db trie.Database) *trie.SecureTrie {
   156  	if c.trie == nil {
   157  		var err error
   158  		c.trie, err = trie.NewSecure(c.data.Root, db, 0)
   159  		if err != nil {
   160  			c.trie, _ = trie.NewSecure(common.Hash{}, db, 0)
   161  			c.setError(fmt.Errorf("can't create storage trie: %v", err))
   162  		}
   163  	}
   164  	return c.trie
   165  }
   166  
   167  // GetState returns a value in account storage.
   168  func (self *StateObject) GetState(db trie.Database, key common.Hash) common.Hash {
   169  	value, exists := self.cachedStorage[key]
   170  	if exists {
   171  		return value
   172  	}
   173  	// Load from DB in case it is missing.
   174  	if enc := self.getTrie(db).Get(key[:]); len(enc) > 0 {
   175  		_, content, _, err := rlp.Split(enc)
   176  		if err != nil {
   177  			self.setError(err)
   178  		}
   179  		value.SetBytes(content)
   180  	}
   181  	if (value != common.Hash{}) {
   182  		self.cachedStorage[key] = value
   183  	}
   184  	return value
   185  }
   186  
   187  // SetState updates a value in account storage.
   188  func (self *StateObject) SetState(db trie.Database, key, value common.Hash) {
   189  	self.db.journal = append(self.db.journal, storageChange{
   190  		account:  &self.address,
   191  		key:      key,
   192  		prevalue: self.GetState(db, key),
   193  	})
   194  	self.setState(key, value)
   195  }
   196  
   197  func (self *StateObject) setState(key, value common.Hash) {
   198  	self.cachedStorage[key] = value
   199  	self.dirtyStorage[key] = value
   200  
   201  	if self.onDirty != nil {
   202  		self.onDirty(self.Address())
   203  		self.onDirty = nil
   204  	}
   205  }
   206  
   207  // updateTrie writes cached storage modifications into the object's storage trie.
   208  func (self *StateObject) updateTrie(db trie.Database) {
   209  	tr := self.getTrie(db)
   210  	for key, value := range self.dirtyStorage {
   211  		delete(self.dirtyStorage, key)
   212  		if (value == common.Hash{}) {
   213  			tr.Delete(key[:])
   214  			continue
   215  		}
   216  		// Encoding []byte cannot fail, ok to ignore the error.
   217  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00"))
   218  		tr.Update(key[:], v)
   219  	}
   220  }
   221  
   222  // UpdateRoot sets the trie root to the current root hash of
   223  func (self *StateObject) updateRoot(db trie.Database) {
   224  	self.updateTrie(db)
   225  	self.data.Root = self.trie.Hash()
   226  }
   227  
   228  // CommitTrie the storage trie of the object to dwb.
   229  // This updates the trie root.
   230  func (self *StateObject) CommitTrie(db trie.Database, dbw trie.DatabaseWriter) error {
   231  	self.updateTrie(db)
   232  	if self.dbErr != nil {
   233  		return self.dbErr
   234  	}
   235  	root, err := self.trie.CommitTo(dbw)
   236  	if err == nil {
   237  		self.data.Root = root
   238  	}
   239  	return err
   240  }
   241  
   242  // AddBalance removes amount from c's balance.
   243  // It is used to add funds to the destination account of a transfer.
   244  func (c *StateObject) AddBalance(amount *big.Int) {
   245  	// EIP158: We must check emptiness for the objects such that the account
   246  	// clearing (0,0,0 objects) can take effect.
   247  	if amount.Cmp(common.Big0) == 0 {
   248  		if c.empty() {
   249  			c.touch()
   250  		}
   251  
   252  		return
   253  	}
   254  	c.SetBalance(new(big.Int).Add(c.Balance(), amount))
   255  
   256  	if glog.V(logger.Core) {
   257  		glog.Infof("%x: #%d %v (+ %v)\n", c.Address(), c.Nonce(), c.Balance(), amount)
   258  	}
   259  }
   260  
   261  // SubBalance removes amount from c's balance.
   262  // It is used to remove funds from the origin account of a transfer.
   263  func (c *StateObject) SubBalance(amount *big.Int) {
   264  	if amount.Cmp(common.Big0) == 0 {
   265  		return
   266  	}
   267  	c.SetBalance(new(big.Int).Sub(c.Balance(), amount))
   268  
   269  	if glog.V(logger.Core) {
   270  		glog.Infof("%x: #%d %v (- %v)\n", c.Address(), c.Nonce(), c.Balance(), amount)
   271  	}
   272  }
   273  
   274  func (self *StateObject) SetBalance(amount *big.Int) {
   275  	self.db.journal = append(self.db.journal, balanceChange{
   276  		account: &self.address,
   277  		prev:    new(big.Int).Set(self.data.Balance),
   278  	})
   279  	self.setBalance(amount)
   280  }
   281  
   282  func (self *StateObject) setBalance(amount *big.Int) {
   283  	self.data.Balance = amount
   284  	if self.onDirty != nil {
   285  		self.onDirty(self.Address())
   286  		self.onDirty = nil
   287  	}
   288  }
   289  
   290  // Return the gas back to the origin. Used by the Virtual machine or Closures
   291  func (c *StateObject) ReturnGas(gas *big.Int) {}
   292  
   293  func (self *StateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *StateObject {
   294  	stateObject := newObject(db, self.address, self.data, onDirty)
   295  	stateObject.trie = self.trie
   296  	stateObject.code = self.code
   297  	stateObject.dirtyStorage = self.dirtyStorage.Copy()
   298  	stateObject.cachedStorage = self.dirtyStorage.Copy()
   299  	stateObject.suicided = self.suicided
   300  	stateObject.dirtyCode = self.dirtyCode
   301  	stateObject.deleted = self.deleted
   302  	return stateObject
   303  }
   304  
   305  //
   306  // Attribute accessors
   307  //
   308  
   309  // Returns the address of the contract/account
   310  func (c *StateObject) Address() common.Address {
   311  	return c.address
   312  }
   313  
   314  // Code returns the contract code associated with this object, if any.
   315  func (self *StateObject) Code(db trie.Database) []byte {
   316  	if self.code != nil {
   317  		return self.code
   318  	}
   319  	if bytes.Equal(self.CodeHash(), emptyCodeHash) {
   320  		return nil
   321  	}
   322  	code, err := db.Get(self.CodeHash())
   323  	if err != nil {
   324  		self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err))
   325  	}
   326  	self.code = code
   327  	return code
   328  }
   329  
   330  func (self *StateObject) SetCode(codeHash common.Hash, code []byte) {
   331  	prevcode := self.Code(self.db.db)
   332  	self.db.journal = append(self.db.journal, codeChange{
   333  		account:  &self.address,
   334  		prevhash: self.CodeHash(),
   335  		prevcode: prevcode,
   336  	})
   337  	self.setCode(codeHash, code)
   338  }
   339  
   340  func (self *StateObject) setCode(codeHash common.Hash, code []byte) {
   341  	self.code = code
   342  	self.data.CodeHash = codeHash[:]
   343  	self.dirtyCode = true
   344  	if self.onDirty != nil {
   345  		self.onDirty(self.Address())
   346  		self.onDirty = nil
   347  	}
   348  }
   349  
   350  func (self *StateObject) SetNonce(nonce uint64) {
   351  	self.db.journal = append(self.db.journal, nonceChange{
   352  		account: &self.address,
   353  		prev:    self.data.Nonce,
   354  	})
   355  	self.setNonce(nonce)
   356  }
   357  
   358  func (self *StateObject) setNonce(nonce uint64) {
   359  	self.data.Nonce = nonce
   360  	if self.onDirty != nil {
   361  		self.onDirty(self.Address())
   362  		self.onDirty = nil
   363  	}
   364  }
   365  
   366  func (self *StateObject) CodeHash() []byte {
   367  	return self.data.CodeHash
   368  }
   369  
   370  func (self *StateObject) Balance() *big.Int {
   371  	return self.data.Balance
   372  }
   373  
   374  func (self *StateObject) Nonce() uint64 {
   375  	return self.data.Nonce
   376  }
   377  
   378  // Never called, but must be present to allow StateObject to be used
   379  // as a vm.Account interface that also satisfies the vm.ContractRef
   380  // interface. Interfaces are awesome.
   381  func (self *StateObject) Value() *big.Int {
   382  	panic("Value on StateObject should never be called")
   383  }
   384  
   385  func (self *StateObject) ForEachStorage(cb func(key, value common.Hash) bool) {
   386  	// When iterating over the storage check the cache first
   387  	for h, value := range self.cachedStorage {
   388  		cb(h, value)
   389  	}
   390  
   391  	it := self.getTrie(self.db.db).Iterator()
   392  	for it.Next() {
   393  		// ignore cached values
   394  		key := common.BytesToHash(self.trie.GetKey(it.Key))
   395  		if _, ok := self.cachedStorage[key]; !ok {
   396  			cb(key, common.BytesToHash(it.Value))
   397  		}
   398  	}
   399  }