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 }