github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/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  	"math/big"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/crypto"
    26  	"github.com/ethereum/go-ethereum/logger"
    27  	"github.com/ethereum/go-ethereum/logger/glog"
    28  	"github.com/ethereum/go-ethereum/rlp"
    29  	"github.com/ethereum/go-ethereum/trie"
    30  )
    31  
    32  type Code []byte
    33  
    34  func (self Code) String() string {
    35  	return string(self) //strings.Join(Disassemble(self), " ")
    36  }
    37  
    38  type Storage map[string]common.Hash
    39  
    40  func (self Storage) String() (str string) {
    41  	for key, value := range self {
    42  		str += fmt.Sprintf("%X : %X\n", key, value)
    43  	}
    44  
    45  	return
    46  }
    47  
    48  func (self Storage) Copy() Storage {
    49  	cpy := make(Storage)
    50  	for key, value := range self {
    51  		cpy[key] = value
    52  	}
    53  
    54  	return cpy
    55  }
    56  
    57  type StateObject struct {
    58  	// State database for storing state changes
    59  	db   common.Database
    60  	trie *trie.SecureTrie
    61  
    62  	// Address belonging to this account
    63  	address common.Address
    64  	// The balance of the account
    65  	balance *big.Int
    66  	// The nonce of the account
    67  	nonce uint64
    68  	// The code hash if code is present (i.e. a contract)
    69  	codeHash []byte
    70  	// The code for this account
    71  	code Code
    72  	// Temporarily initialisation code
    73  	initCode Code
    74  	// Cached storage (flushed when updated)
    75  	storage Storage
    76  
    77  	// Total gas pool is the total amount of gas currently
    78  	// left if this object is the coinbase. Gas is directly
    79  	// purchased of the coinbase.
    80  	gasPool *big.Int
    81  
    82  	// Mark for deletion
    83  	// When an object is marked for deletion it will be delete from the trie
    84  	// during the "update" phase of the state transition
    85  	remove  bool
    86  	deleted bool
    87  	dirty   bool
    88  }
    89  
    90  func (self *StateObject) Reset() {
    91  	self.storage = make(Storage)
    92  }
    93  
    94  func NewStateObject(address common.Address, db common.Database) *StateObject {
    95  	object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int), dirty: true}
    96  	object.trie = trie.NewSecure((common.Hash{}).Bytes(), db)
    97  	object.storage = make(Storage)
    98  	object.gasPool = new(big.Int)
    99  
   100  	return object
   101  }
   102  
   103  func NewStateObjectFromBytes(address common.Address, data []byte, db common.Database) *StateObject {
   104  	// TODO clean me up
   105  	var extobject struct {
   106  		Nonce    uint64
   107  		Balance  *big.Int
   108  		Root     common.Hash
   109  		CodeHash []byte
   110  	}
   111  	err := rlp.Decode(bytes.NewReader(data), &extobject)
   112  	if err != nil {
   113  		fmt.Println(err)
   114  		return nil
   115  	}
   116  
   117  	object := &StateObject{address: address, db: db}
   118  	object.nonce = extobject.Nonce
   119  	object.balance = extobject.Balance
   120  	object.codeHash = extobject.CodeHash
   121  	object.trie = trie.NewSecure(extobject.Root[:], db)
   122  	object.storage = make(map[string]common.Hash)
   123  	object.gasPool = new(big.Int)
   124  	object.code, _ = db.Get(extobject.CodeHash)
   125  
   126  	return object
   127  }
   128  
   129  func (self *StateObject) MarkForDeletion() {
   130  	self.remove = true
   131  	self.dirty = true
   132  
   133  	if glog.V(logger.Core) {
   134  		glog.Infof("%x: #%d %v X\n", self.Address(), self.nonce, self.balance)
   135  	}
   136  }
   137  
   138  func (c *StateObject) getAddr(addr common.Hash) common.Hash {
   139  	var ret []byte
   140  	rlp.DecodeBytes(c.trie.Get(addr[:]), &ret)
   141  	return common.BytesToHash(ret)
   142  }
   143  
   144  func (c *StateObject) setAddr(addr []byte, value common.Hash) {
   145  	v, err := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00"))
   146  	if err != nil {
   147  		// if RLPing failed we better panic and not fail silently. This would be considered a consensus issue
   148  		panic(err)
   149  	}
   150  	c.trie.Update(addr, v)
   151  }
   152  
   153  func (self *StateObject) Storage() Storage {
   154  	return self.storage
   155  }
   156  
   157  func (self *StateObject) GetState(key common.Hash) common.Hash {
   158  	strkey := key.Str()
   159  	value, exists := self.storage[strkey]
   160  	if !exists {
   161  		value = self.getAddr(key)
   162  		if (value != common.Hash{}) {
   163  			self.storage[strkey] = value
   164  		}
   165  	}
   166  
   167  	return value
   168  }
   169  
   170  func (self *StateObject) SetState(k, value common.Hash) {
   171  	self.storage[k.Str()] = value
   172  	self.dirty = true
   173  }
   174  
   175  // Update updates the current cached storage to the trie
   176  func (self *StateObject) Update() {
   177  	for key, value := range self.storage {
   178  		if (value == common.Hash{}) {
   179  			self.trie.Delete([]byte(key))
   180  			continue
   181  		}
   182  
   183  		self.setAddr([]byte(key), value)
   184  	}
   185  }
   186  
   187  func (c *StateObject) GetInstr(pc *big.Int) *common.Value {
   188  	if int64(len(c.code)-1) < pc.Int64() {
   189  		return common.NewValue(0)
   190  	}
   191  
   192  	return common.NewValueFromBytes([]byte{c.code[pc.Int64()]})
   193  }
   194  
   195  func (c *StateObject) AddBalance(amount *big.Int) {
   196  	c.SetBalance(new(big.Int).Add(c.balance, amount))
   197  
   198  	if glog.V(logger.Core) {
   199  		glog.Infof("%x: #%d %v (+ %v)\n", c.Address(), c.nonce, c.balance, amount)
   200  	}
   201  }
   202  
   203  func (c *StateObject) SubBalance(amount *big.Int) {
   204  	c.SetBalance(new(big.Int).Sub(c.balance, amount))
   205  
   206  	if glog.V(logger.Core) {
   207  		glog.Infof("%x: #%d %v (- %v)\n", c.Address(), c.nonce, c.balance, amount)
   208  	}
   209  }
   210  
   211  func (c *StateObject) SetBalance(amount *big.Int) {
   212  	c.balance = amount
   213  	c.dirty = true
   214  }
   215  
   216  func (c *StateObject) St() Storage {
   217  	return c.storage
   218  }
   219  
   220  //
   221  // Gas setters and getters
   222  //
   223  
   224  // Return the gas back to the origin. Used by the Virtual machine or Closures
   225  func (c *StateObject) ReturnGas(gas, price *big.Int) {}
   226  
   227  func (self *StateObject) SetGasLimit(gasLimit *big.Int) {
   228  	self.gasPool = new(big.Int).Set(gasLimit)
   229  
   230  	if glog.V(logger.Core) {
   231  		glog.Infof("%x: gas (+ %v)", self.Address(), self.gasPool)
   232  	}
   233  }
   234  
   235  func (self *StateObject) SubGas(gas, price *big.Int) error {
   236  	if self.gasPool.Cmp(gas) < 0 {
   237  		return GasLimitError(self.gasPool, gas)
   238  	}
   239  
   240  	self.gasPool.Sub(self.gasPool, gas)
   241  
   242  	rGas := new(big.Int).Set(gas)
   243  	rGas.Mul(rGas, price)
   244  
   245  	self.dirty = true
   246  
   247  	return nil
   248  }
   249  
   250  func (self *StateObject) AddGas(gas, price *big.Int) {
   251  	self.gasPool.Add(self.gasPool, gas)
   252  }
   253  
   254  func (self *StateObject) Copy() *StateObject {
   255  	stateObject := NewStateObject(self.Address(), self.db)
   256  	stateObject.balance.Set(self.balance)
   257  	stateObject.codeHash = common.CopyBytes(self.codeHash)
   258  	stateObject.nonce = self.nonce
   259  	stateObject.trie = self.trie
   260  	stateObject.code = common.CopyBytes(self.code)
   261  	stateObject.initCode = common.CopyBytes(self.initCode)
   262  	stateObject.storage = self.storage.Copy()
   263  	stateObject.gasPool.Set(self.gasPool)
   264  	stateObject.remove = self.remove
   265  	stateObject.dirty = self.dirty
   266  	stateObject.deleted = self.deleted
   267  
   268  	return stateObject
   269  }
   270  
   271  func (self *StateObject) Set(stateObject *StateObject) {
   272  	*self = *stateObject
   273  }
   274  
   275  //
   276  // Attribute accessors
   277  //
   278  
   279  func (self *StateObject) Balance() *big.Int {
   280  	return self.balance
   281  }
   282  
   283  func (c *StateObject) N() *big.Int {
   284  	return big.NewInt(int64(c.nonce))
   285  }
   286  
   287  // Returns the address of the contract/account
   288  func (c *StateObject) Address() common.Address {
   289  	return c.address
   290  }
   291  
   292  // Returns the initialization Code
   293  func (c *StateObject) Init() Code {
   294  	return c.initCode
   295  }
   296  
   297  func (self *StateObject) Trie() *trie.SecureTrie {
   298  	return self.trie
   299  }
   300  
   301  func (self *StateObject) Root() []byte {
   302  	return self.trie.Root()
   303  }
   304  
   305  func (self *StateObject) Code() []byte {
   306  	return self.code
   307  }
   308  
   309  func (self *StateObject) SetCode(code []byte) {
   310  	self.code = code
   311  	self.dirty = true
   312  }
   313  
   314  func (self *StateObject) SetInitCode(code []byte) {
   315  	self.initCode = code
   316  	self.dirty = true
   317  }
   318  
   319  func (self *StateObject) SetNonce(nonce uint64) {
   320  	self.nonce = nonce
   321  	self.dirty = true
   322  }
   323  
   324  func (self *StateObject) Nonce() uint64 {
   325  	return self.nonce
   326  }
   327  
   328  func (self *StateObject) EachStorage(cb func(key, value []byte)) {
   329  	// When iterating over the storage check the cache first
   330  	for h, v := range self.storage {
   331  		cb([]byte(h), v.Bytes())
   332  	}
   333  
   334  	it := self.trie.Iterator()
   335  	for it.Next() {
   336  		// ignore cached values
   337  		key := self.trie.GetKey(it.Key)
   338  		if _, ok := self.storage[string(key)]; !ok {
   339  			cb(key, it.Value)
   340  		}
   341  	}
   342  }
   343  
   344  //
   345  // Encoding
   346  //
   347  
   348  // State object encoding methods
   349  func (c *StateObject) RlpEncode() []byte {
   350  	return common.Encode([]interface{}{c.nonce, c.balance, c.Root(), c.CodeHash()})
   351  }
   352  
   353  func (c *StateObject) CodeHash() common.Bytes {
   354  	return crypto.Sha3(c.code)
   355  }
   356  
   357  func (c *StateObject) RlpDecode(data []byte) {
   358  	decoder := common.NewValueFromBytes(data)
   359  	c.nonce = decoder.Get(0).Uint()
   360  	c.balance = decoder.Get(1).BigInt()
   361  	c.trie = trie.NewSecure(decoder.Get(2).Bytes(), c.db)
   362  	c.storage = make(map[string]common.Hash)
   363  	c.gasPool = new(big.Int)
   364  
   365  	c.codeHash = decoder.Get(3).Bytes()
   366  
   367  	c.code, _ = c.db.Get(c.codeHash)
   368  }
   369  
   370  // Storage change object. Used by the manifest for notifying changes to
   371  // the sub channels.
   372  type StorageState struct {
   373  	StateAddress []byte
   374  	Address      []byte
   375  	Value        *big.Int
   376  }