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 }