github.com/immesys/bw2bc@v1.1.0/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  
   267  	return stateObject
   268  }
   269  
   270  func (self *StateObject) Set(stateObject *StateObject) {
   271  	*self = *stateObject
   272  }
   273  
   274  //
   275  // Attribute accessors
   276  //
   277  
   278  func (self *StateObject) Balance() *big.Int {
   279  	return self.balance
   280  }
   281  
   282  func (c *StateObject) N() *big.Int {
   283  	return big.NewInt(int64(c.nonce))
   284  }
   285  
   286  // Returns the address of the contract/account
   287  func (c *StateObject) Address() common.Address {
   288  	return c.address
   289  }
   290  
   291  // Returns the initialization Code
   292  func (c *StateObject) Init() Code {
   293  	return c.initCode
   294  }
   295  
   296  func (self *StateObject) Trie() *trie.SecureTrie {
   297  	return self.trie
   298  }
   299  
   300  func (self *StateObject) Root() []byte {
   301  	return self.trie.Root()
   302  }
   303  
   304  func (self *StateObject) Code() []byte {
   305  	return self.code
   306  }
   307  
   308  func (self *StateObject) SetCode(code []byte) {
   309  	self.code = code
   310  	self.dirty = true
   311  }
   312  
   313  func (self *StateObject) SetInitCode(code []byte) {
   314  	self.initCode = code
   315  	self.dirty = true
   316  }
   317  
   318  func (self *StateObject) SetNonce(nonce uint64) {
   319  	self.nonce = nonce
   320  	self.dirty = true
   321  }
   322  
   323  func (self *StateObject) Nonce() uint64 {
   324  	return self.nonce
   325  }
   326  
   327  func (self *StateObject) EachStorage(cb func(key, value []byte)) {
   328  	// When iterating over the storage check the cache first
   329  	for h, v := range self.storage {
   330  		cb([]byte(h), v.Bytes())
   331  	}
   332  
   333  	it := self.trie.Iterator()
   334  	for it.Next() {
   335  		// ignore cached values
   336  		key := self.trie.GetKey(it.Key)
   337  		if _, ok := self.storage[string(key)]; !ok {
   338  			cb(key, it.Value)
   339  		}
   340  	}
   341  }
   342  
   343  //
   344  // Encoding
   345  //
   346  
   347  // State object encoding methods
   348  func (c *StateObject) RlpEncode() []byte {
   349  	return common.Encode([]interface{}{c.nonce, c.balance, c.Root(), c.CodeHash()})
   350  }
   351  
   352  func (c *StateObject) CodeHash() common.Bytes {
   353  	return crypto.Sha3(c.code)
   354  }
   355  
   356  func (c *StateObject) RlpDecode(data []byte) {
   357  	decoder := common.NewValueFromBytes(data)
   358  	c.nonce = decoder.Get(0).Uint()
   359  	c.balance = decoder.Get(1).BigInt()
   360  	c.trie = trie.NewSecure(decoder.Get(2).Bytes(), c.db)
   361  	c.storage = make(map[string]common.Hash)
   362  	c.gasPool = new(big.Int)
   363  
   364  	c.codeHash = decoder.Get(3).Bytes()
   365  
   366  	c.code, _ = c.db.Get(c.codeHash)
   367  }
   368  
   369  // Storage change object. Used by the manifest for notifying changes to
   370  // the sub channels.
   371  type StorageState struct {
   372  	StateAddress []byte
   373  	Address      []byte
   374  	Value        *big.Int
   375  }