github.com/theQRL/go-zond@v0.1.1/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 "time" 25 26 "github.com/theQRL/go-zond/common" 27 "github.com/theQRL/go-zond/core/types" 28 "github.com/theQRL/go-zond/crypto" 29 "github.com/theQRL/go-zond/metrics" 30 "github.com/theQRL/go-zond/rlp" 31 "github.com/theQRL/go-zond/trie/trienode" 32 ) 33 34 type Code []byte 35 36 func (c Code) String() string { 37 return string(c) //strings.Join(Disassemble(c), " ") 38 } 39 40 type Storage map[common.Hash]common.Hash 41 42 func (s Storage) String() (str string) { 43 for key, value := range s { 44 str += fmt.Sprintf("%X : %X\n", key, value) 45 } 46 return 47 } 48 49 func (s Storage) Copy() Storage { 50 cpy := make(Storage, len(s)) 51 for key, value := range s { 52 cpy[key] = value 53 } 54 return cpy 55 } 56 57 // stateObject represents an Ethereum account which is being modified. 58 // 59 // The usage pattern is as follows: 60 // - First you need to obtain a state object. 61 // - Account values as well as storages can be accessed and modified through the object. 62 // - Finally, call commit to return the changes of storage trie and update account data. 63 type stateObject struct { 64 db *StateDB 65 address common.Address // address of ethereum account 66 addrHash common.Hash // hash of ethereum address of the account 67 origin *types.StateAccount // Account original data without any change applied, nil means it was not existent 68 data types.StateAccount // Account data with all mutations applied in the scope of block 69 70 // Write caches. 71 trie Trie // storage trie, which becomes non-nil on first access 72 code Code // contract bytecode, which gets set when code is loaded 73 74 originStorage Storage // Storage cache of original entries to dedup rewrites 75 pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block 76 dirtyStorage Storage // Storage entries that have been modified in the current transaction execution, reset for every transaction 77 78 // Cache flags. 79 dirtyCode bool // true if the code was updated 80 81 // Flag whether the account was marked as self-destructed. The self-destructed account 82 // is still accessible in the scope of same transaction. 83 selfDestructed bool 84 85 // Flag whether the account was marked as deleted. A self-destructed account 86 // or an account that is considered as empty will be marked as deleted at 87 // the end of transaction and no longer accessible anymore. 88 deleted bool 89 90 // Flag whether the object was created in the current transaction 91 created bool 92 } 93 94 // empty returns whether the account is considered empty. 95 func (s *stateObject) empty() bool { 96 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes()) 97 } 98 99 // newObject creates a state object. 100 func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *stateObject { 101 origin := acct 102 if acct == nil { 103 acct = types.NewEmptyStateAccount() 104 } 105 return &stateObject{ 106 db: db, 107 address: address, 108 addrHash: crypto.Keccak256Hash(address[:]), 109 origin: origin, 110 data: *acct, 111 originStorage: make(Storage), 112 pendingStorage: make(Storage), 113 dirtyStorage: make(Storage), 114 } 115 } 116 117 // EncodeRLP implements rlp.Encoder. 118 func (s *stateObject) EncodeRLP(w io.Writer) error { 119 return rlp.Encode(w, &s.data) 120 } 121 122 func (s *stateObject) markSelfdestructed() { 123 s.selfDestructed = true 124 } 125 126 func (s *stateObject) touch() { 127 s.db.journal.append(touchChange{ 128 account: &s.address, 129 }) 130 if s.address == ripemd { 131 // Explicitly put it in the dirty-cache, which is otherwise generated from 132 // flattened journals. 133 s.db.journal.dirty(s.address) 134 } 135 } 136 137 // getTrie returns the associated storage trie. The trie will be opened 138 // if it's not loaded previously. An error will be returned if trie can't 139 // be loaded. 140 func (s *stateObject) getTrie() (Trie, error) { 141 if s.trie == nil { 142 // Try fetching from prefetcher first 143 if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil { 144 // When the miner is creating the pending state, there is no prefetcher 145 s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root) 146 } 147 if s.trie == nil { 148 tr, err := s.db.db.OpenStorageTrie(s.db.originalRoot, s.address, s.data.Root) 149 if err != nil { 150 return nil, err 151 } 152 s.trie = tr 153 } 154 } 155 return s.trie, nil 156 } 157 158 // GetState retrieves a value from the account storage trie. 159 func (s *stateObject) GetState(key common.Hash) common.Hash { 160 // If we have a dirty value for this state entry, return it 161 value, dirty := s.dirtyStorage[key] 162 if dirty { 163 return value 164 } 165 // Otherwise return the entry's original value 166 return s.GetCommittedState(key) 167 } 168 169 // GetCommittedState retrieves a value from the committed account storage trie. 170 func (s *stateObject) GetCommittedState(key common.Hash) common.Hash { 171 // If we have a pending write or clean cached, return that 172 if value, pending := s.pendingStorage[key]; pending { 173 return value 174 } 175 if value, cached := s.originStorage[key]; cached { 176 return value 177 } 178 // If the object was destructed in *this* block (and potentially resurrected), 179 // the storage has been cleared out, and we should *not* consult the previous 180 // database about any storage values. The only possible alternatives are: 181 // 1) resurrect happened, and new slot values were set -- those should 182 // have been handles via pendingStorage above. 183 // 2) we don't have new values, and can deliver empty response back 184 if _, destructed := s.db.stateObjectsDestruct[s.address]; destructed { 185 return common.Hash{} 186 } 187 // If no live objects are available, attempt to use snapshots 188 var ( 189 enc []byte 190 err error 191 value common.Hash 192 ) 193 if s.db.snap != nil { 194 start := time.Now() 195 enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes())) 196 if metrics.EnabledExpensive { 197 s.db.SnapshotStorageReads += time.Since(start) 198 } 199 if len(enc) > 0 { 200 _, content, _, err := rlp.Split(enc) 201 if err != nil { 202 s.db.setError(err) 203 } 204 value.SetBytes(content) 205 } 206 } 207 // If the snapshot is unavailable or reading from it fails, load from the database. 208 if s.db.snap == nil || err != nil { 209 start := time.Now() 210 tr, err := s.getTrie() 211 if err != nil { 212 s.db.setError(err) 213 return common.Hash{} 214 } 215 val, err := tr.GetStorage(s.address, key.Bytes()) 216 if metrics.EnabledExpensive { 217 s.db.StorageReads += time.Since(start) 218 } 219 if err != nil { 220 s.db.setError(err) 221 return common.Hash{} 222 } 223 value.SetBytes(val) 224 } 225 s.originStorage[key] = value 226 return value 227 } 228 229 // SetState updates a value in account storage. 230 func (s *stateObject) SetState(key, value common.Hash) { 231 // If the new value is the same as old, don't set 232 prev := s.GetState(key) 233 if prev == value { 234 return 235 } 236 // New value is different, update and journal the change 237 s.db.journal.append(storageChange{ 238 account: &s.address, 239 key: key, 240 prevalue: prev, 241 }) 242 s.setState(key, value) 243 } 244 245 func (s *stateObject) setState(key, value common.Hash) { 246 s.dirtyStorage[key] = value 247 } 248 249 // finalise moves all dirty storage slots into the pending area to be hashed or 250 // committed later. It is invoked at the end of every transaction. 251 func (s *stateObject) finalise(prefetch bool) { 252 slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage)) 253 for key, value := range s.dirtyStorage { 254 s.pendingStorage[key] = value 255 if value != s.originStorage[key] { 256 slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure 257 } 258 } 259 if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash { 260 s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, slotsToPrefetch) 261 } 262 if len(s.dirtyStorage) > 0 { 263 s.dirtyStorage = make(Storage) 264 } 265 } 266 267 // updateTrie is responsible for persisting cached storage changes into the 268 // object's storage trie. In case the storage trie is not yet loaded, this 269 // function will load the trie automatically. If any issues arise during the 270 // loading or updating of the trie, an error will be returned. Furthermore, 271 // this function will return the mutated storage trie, or nil if there is no 272 // storage change at all. 273 func (s *stateObject) updateTrie() (Trie, error) { 274 // Make sure all dirty slots are finalized into the pending storage area 275 s.finalise(false) 276 277 // Short circuit if nothing changed, don't bother with hashing anything 278 if len(s.pendingStorage) == 0 { 279 return s.trie, nil 280 } 281 // Track the amount of time wasted on updating the storage trie 282 if metrics.EnabledExpensive { 283 defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now()) 284 } 285 // The snapshot storage map for the object 286 var ( 287 storage map[common.Hash][]byte 288 origin map[common.Hash][]byte 289 ) 290 tr, err := s.getTrie() 291 if err != nil { 292 s.db.setError(err) 293 return nil, err 294 } 295 // Insert all the pending storage updates into the trie 296 usedStorage := make([][]byte, 0, len(s.pendingStorage)) 297 for key, value := range s.pendingStorage { 298 // Skip noop changes, persist actual changes 299 if value == s.originStorage[key] { 300 continue 301 } 302 prev := s.originStorage[key] 303 s.originStorage[key] = value 304 305 var encoded []byte // rlp-encoded value to be used by the snapshot 306 if (value == common.Hash{}) { 307 if err := tr.DeleteStorage(s.address, key[:]); err != nil { 308 s.db.setError(err) 309 return nil, err 310 } 311 s.db.StorageDeleted += 1 312 } else { 313 // Encoding []byte cannot fail, ok to ignore the error. 314 trimmed := common.TrimLeftZeroes(value[:]) 315 encoded, _ = rlp.EncodeToBytes(trimmed) 316 if err := tr.UpdateStorage(s.address, key[:], trimmed); err != nil { 317 s.db.setError(err) 318 return nil, err 319 } 320 s.db.StorageUpdated += 1 321 } 322 // Cache the mutated storage slots until commit 323 if storage == nil { 324 if storage = s.db.storages[s.addrHash]; storage == nil { 325 storage = make(map[common.Hash][]byte) 326 s.db.storages[s.addrHash] = storage 327 } 328 } 329 khash := crypto.HashData(s.db.hasher, key[:]) 330 storage[khash] = encoded // encoded will be nil if it's deleted 331 332 // Cache the original value of mutated storage slots 333 if origin == nil { 334 if origin = s.db.storagesOrigin[s.address]; origin == nil { 335 origin = make(map[common.Hash][]byte) 336 s.db.storagesOrigin[s.address] = origin 337 } 338 } 339 // Track the original value of slot only if it's mutated first time 340 if _, ok := origin[khash]; !ok { 341 if prev == (common.Hash{}) { 342 origin[khash] = nil // nil if it was not present previously 343 } else { 344 // Encoding []byte cannot fail, ok to ignore the error. 345 b, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(prev[:])) 346 origin[khash] = b 347 } 348 } 349 // Cache the items for preloading 350 usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure 351 } 352 if s.db.prefetcher != nil { 353 s.db.prefetcher.used(s.addrHash, s.data.Root, usedStorage) 354 } 355 s.pendingStorage = make(Storage) // reset pending map 356 return tr, nil 357 } 358 359 // updateRoot flushes all cached storage mutations to trie, recalculating the 360 // new storage trie root. 361 func (s *stateObject) updateRoot() { 362 // Flush cached storage mutations into trie, short circuit if any error 363 // is occurred or there is not change in the trie. 364 tr, err := s.updateTrie() 365 if err != nil || tr == nil { 366 return 367 } 368 // Track the amount of time wasted on hashing the storage trie 369 if metrics.EnabledExpensive { 370 defer func(start time.Time) { s.db.StorageHashes += time.Since(start) }(time.Now()) 371 } 372 s.data.Root = tr.Hash() 373 } 374 375 // commit obtains a set of dirty storage trie nodes and updates the account data. 376 // The returned set can be nil if nothing to commit. This function assumes all 377 // storage mutations have already been flushed into trie by updateRoot. 378 func (s *stateObject) commit() (*trienode.NodeSet, error) { 379 // Short circuit if trie is not even loaded, don't bother with committing anything 380 if s.trie == nil { 381 s.origin = s.data.Copy() 382 return nil, nil 383 } 384 // Track the amount of time wasted on committing the storage trie 385 if metrics.EnabledExpensive { 386 defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now()) 387 } 388 // The trie is currently in an open state and could potentially contain 389 // cached mutations. Call commit to acquire a set of nodes that have been 390 // modified, the set can be nil if nothing to commit. 391 root, nodes, err := s.trie.Commit(false) 392 if err != nil { 393 return nil, err 394 } 395 s.data.Root = root 396 397 // Update original account data after commit 398 s.origin = s.data.Copy() 399 return nodes, nil 400 } 401 402 // AddBalance adds amount to s's balance. 403 // It is used to add funds to the destination account of a transfer. 404 func (s *stateObject) AddBalance(amount *big.Int) { 405 // EIP161: We must check emptiness for the objects such that the account 406 // clearing (0,0,0 objects) can take effect. 407 if amount.Sign() == 0 { 408 if s.empty() { 409 s.touch() 410 } 411 return 412 } 413 s.SetBalance(new(big.Int).Add(s.Balance(), amount)) 414 } 415 416 // SubBalance removes amount from s's balance. 417 // It is used to remove funds from the origin account of a transfer. 418 func (s *stateObject) SubBalance(amount *big.Int) { 419 if amount.Sign() == 0 { 420 return 421 } 422 s.SetBalance(new(big.Int).Sub(s.Balance(), amount)) 423 } 424 425 func (s *stateObject) SetBalance(amount *big.Int) { 426 s.db.journal.append(balanceChange{ 427 account: &s.address, 428 prev: new(big.Int).Set(s.data.Balance), 429 }) 430 s.setBalance(amount) 431 } 432 433 func (s *stateObject) setBalance(amount *big.Int) { 434 s.data.Balance = amount 435 } 436 437 func (s *stateObject) deepCopy(db *StateDB) *stateObject { 438 obj := &stateObject{ 439 db: db, 440 address: s.address, 441 addrHash: s.addrHash, 442 origin: s.origin, 443 data: s.data, 444 } 445 if s.trie != nil { 446 obj.trie = db.db.CopyTrie(s.trie) 447 } 448 obj.code = s.code 449 obj.dirtyStorage = s.dirtyStorage.Copy() 450 obj.originStorage = s.originStorage.Copy() 451 obj.pendingStorage = s.pendingStorage.Copy() 452 obj.selfDestructed = s.selfDestructed 453 obj.dirtyCode = s.dirtyCode 454 obj.deleted = s.deleted 455 return obj 456 } 457 458 // 459 // Attribute accessors 460 // 461 462 // Address returns the address of the contract/account 463 func (s *stateObject) Address() common.Address { 464 return s.address 465 } 466 467 // Code returns the contract code associated with this object, if any. 468 func (s *stateObject) Code() []byte { 469 if s.code != nil { 470 return s.code 471 } 472 if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { 473 return nil 474 } 475 code, err := s.db.db.ContractCode(s.address, common.BytesToHash(s.CodeHash())) 476 if err != nil { 477 s.db.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) 478 } 479 s.code = code 480 return code 481 } 482 483 // CodeSize returns the size of the contract code associated with this object, 484 // or zero if none. This method is an almost mirror of Code, but uses a cache 485 // inside the database to avoid loading codes seen recently. 486 func (s *stateObject) CodeSize() int { 487 if s.code != nil { 488 return len(s.code) 489 } 490 if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { 491 return 0 492 } 493 size, err := s.db.db.ContractCodeSize(s.address, common.BytesToHash(s.CodeHash())) 494 if err != nil { 495 s.db.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) 496 } 497 return size 498 } 499 500 func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { 501 prevcode := s.Code() 502 s.db.journal.append(codeChange{ 503 account: &s.address, 504 prevhash: s.CodeHash(), 505 prevcode: prevcode, 506 }) 507 s.setCode(codeHash, code) 508 } 509 510 func (s *stateObject) setCode(codeHash common.Hash, code []byte) { 511 s.code = code 512 s.data.CodeHash = codeHash[:] 513 s.dirtyCode = true 514 } 515 516 func (s *stateObject) SetNonce(nonce uint64) { 517 s.db.journal.append(nonceChange{ 518 account: &s.address, 519 prev: s.data.Nonce, 520 }) 521 s.setNonce(nonce) 522 } 523 524 func (s *stateObject) setNonce(nonce uint64) { 525 s.data.Nonce = nonce 526 } 527 528 func (s *stateObject) CodeHash() []byte { 529 return s.data.CodeHash 530 } 531 532 func (s *stateObject) Balance() *big.Int { 533 return s.data.Balance 534 } 535 536 func (s *stateObject) Nonce() uint64 { 537 return s.data.Nonce 538 } 539 540 func (s *stateObject) Root() common.Hash { 541 return s.data.Root 542 }