github.com/haliliceylan/bsc@v1.1.10-0.20220501224556-eb78d644ebcb/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 "sync" 25 "time" 26 27 "github.com/ethereum/go-ethereum/common" 28 "github.com/ethereum/go-ethereum/crypto" 29 "github.com/ethereum/go-ethereum/metrics" 30 "github.com/ethereum/go-ethereum/rlp" 31 ) 32 33 var emptyCodeHash = crypto.Keccak256(nil) 34 35 type Code []byte 36 37 func (c Code) String() string { 38 return string(c) //strings.Join(Disassemble(c), " ") 39 } 40 41 type Storage map[common.Hash]common.Hash 42 43 func (s Storage) String() (str string) { 44 for key, value := range s { 45 str += fmt.Sprintf("%X : %X\n", key, value) 46 } 47 48 return 49 } 50 51 func (s Storage) Copy() Storage { 52 cpy := make(Storage) 53 for key, value := range s { 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 68 addrHash common.Hash // hash of ethereum address of the account 69 data Account 70 db *StateDB 71 rootCorrected bool // To indicate whether the root has been corrected in pipecommit mode 72 73 // DB error. 74 // State objects are used by the consensus core and VM which are 75 // unable to deal with database-level errors. Any error that occurs 76 // during a database read is memoized here and will eventually be returned 77 // by StateDB.Commit. 78 dbErr error 79 80 // Write caches. 81 trie Trie // storage trie, which becomes non-nil on first access 82 code Code // contract bytecode, which gets set when code is loaded 83 84 sharedOriginStorage *sync.Map // Point to the entry of the stateObject in sharedPool 85 originStorage Storage // Storage cache of original entries to dedup rewrites, reset for every transaction 86 87 pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block 88 dirtyStorage Storage // Storage entries that have been modified in the current transaction execution 89 fakeStorage Storage // Fake storage which constructed by caller for debugging purpose. 90 91 // Cache flags. 92 // When an object is marked suicided it will be delete from the trie 93 // during the "update" phase of the state transition. 94 dirtyCode bool // true if the code was updated 95 suicided bool 96 deleted bool 97 98 //encode 99 encodeData []byte 100 } 101 102 // empty returns whether the account is considered empty. 103 func (s *StateObject) empty() bool { 104 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) 105 } 106 107 // Account is the Ethereum consensus representation of accounts. 108 // These objects are stored in the main account trie. 109 type Account struct { 110 Nonce uint64 111 Balance *big.Int 112 Root common.Hash // merkle root of the storage trie 113 CodeHash []byte 114 } 115 116 // newObject creates a state object. 117 func newObject(db *StateDB, address common.Address, data Account) *StateObject { 118 if data.Balance == nil { 119 data.Balance = new(big.Int) 120 } 121 if data.CodeHash == nil { 122 data.CodeHash = emptyCodeHash 123 } 124 if data.Root == (common.Hash{}) { 125 data.Root = emptyRoot 126 } 127 var storageMap *sync.Map 128 // Check whether the storage exist in pool, new originStorage if not exist 129 if db != nil && db.storagePool != nil { 130 storageMap = db.GetStorage(address) 131 } 132 133 return &StateObject{ 134 db: db, 135 address: address, 136 addrHash: crypto.Keccak256Hash(address[:]), 137 data: data, 138 sharedOriginStorage: storageMap, 139 originStorage: make(Storage), 140 pendingStorage: make(Storage), 141 dirtyStorage: make(Storage), 142 } 143 } 144 145 // EncodeRLP implements rlp.Encoder. 146 func (s *StateObject) EncodeRLP(w io.Writer) error { 147 return rlp.Encode(w, s.data) 148 } 149 150 // setError remembers the first non-nil error it is called with. 151 func (s *StateObject) setError(err error) { 152 if s.dbErr == nil { 153 s.dbErr = err 154 } 155 } 156 157 func (s *StateObject) markSuicided() { 158 s.suicided = true 159 } 160 161 func (s *StateObject) touch() { 162 s.db.journal.append(touchChange{ 163 account: &s.address, 164 }) 165 if s.address == ripemd { 166 // Explicitly put it in the dirty-cache, which is otherwise generated from 167 // flattened journals. 168 s.db.journal.dirty(s.address) 169 } 170 } 171 172 func (s *StateObject) getTrie(db Database) Trie { 173 if s.trie == nil { 174 // Try fetching from prefetcher first 175 // We don't prefetch empty tries 176 if s.data.Root != emptyRoot && s.db.prefetcher != nil { 177 // When the miner is creating the pending state, there is no 178 // prefetcher 179 s.trie = s.db.prefetcher.trie(s.data.Root) 180 } 181 if s.trie == nil { 182 var err error 183 s.trie, err = db.OpenStorageTrie(s.addrHash, s.data.Root) 184 if err != nil { 185 s.trie, _ = db.OpenStorageTrie(s.addrHash, common.Hash{}) 186 s.setError(fmt.Errorf("can't create storage trie: %v", err)) 187 } 188 } 189 } 190 return s.trie 191 } 192 193 // GetState retrieves a value from the account storage trie. 194 func (s *StateObject) GetState(db Database, key common.Hash) common.Hash { 195 // If the fake storage is set, only lookup the state here(in the debugging mode) 196 if s.fakeStorage != nil { 197 return s.fakeStorage[key] 198 } 199 // If we have a dirty value for this state entry, return it 200 value, dirty := s.dirtyStorage[key] 201 if dirty { 202 return value 203 } 204 // Otherwise return the entry's original value 205 return s.GetCommittedState(db, key) 206 } 207 208 func (s *StateObject) getOriginStorage(key common.Hash) (common.Hash, bool) { 209 if value, cached := s.originStorage[key]; cached { 210 return value, true 211 } 212 // if L1 cache miss, try to get it from shared pool 213 if s.sharedOriginStorage != nil { 214 val, ok := s.sharedOriginStorage.Load(key) 215 if !ok { 216 return common.Hash{}, false 217 } 218 s.originStorage[key] = val.(common.Hash) 219 return val.(common.Hash), true 220 } 221 return common.Hash{}, false 222 } 223 224 func (s *StateObject) setOriginStorage(key common.Hash, value common.Hash) { 225 if s.db.writeOnSharedStorage && s.sharedOriginStorage != nil { 226 s.sharedOriginStorage.Store(key, value) 227 } 228 s.originStorage[key] = value 229 } 230 231 // GetCommittedState retrieves a value from the committed account storage trie. 232 func (s *StateObject) GetCommittedState(db Database, key common.Hash) common.Hash { 233 // If the fake storage is set, only lookup the state here(in the debugging mode) 234 if s.fakeStorage != nil { 235 return s.fakeStorage[key] 236 } 237 // If we have a pending write or clean cached, return that 238 if value, pending := s.pendingStorage[key]; pending { 239 return value 240 } 241 242 if value, cached := s.getOriginStorage(key); cached { 243 return value 244 } 245 // If no live objects are available, attempt to use snapshots 246 var ( 247 enc []byte 248 err error 249 meter *time.Duration 250 ) 251 readStart := time.Now() 252 if metrics.EnabledExpensive { 253 // If the snap is 'under construction', the first lookup may fail. If that 254 // happens, we don't want to double-count the time elapsed. Thus this 255 // dance with the metering. 256 defer func() { 257 if meter != nil { 258 *meter += time.Since(readStart) 259 } 260 }() 261 } 262 if s.db.snap != nil { 263 if metrics.EnabledExpensive { 264 meter = &s.db.SnapshotStorageReads 265 } 266 // If the object was destructed in *this* block (and potentially resurrected), 267 // the storage has been cleared out, and we should *not* consult the previous 268 // snapshot about any storage values. The only possible alternatives are: 269 // 1) resurrect happened, and new slot values were set -- those should 270 // have been handles via pendingStorage above. 271 // 2) we don't have new values, and can deliver empty response back 272 if _, destructed := s.db.snapDestructs[s.address]; destructed { 273 return common.Hash{} 274 } 275 enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes())) 276 } 277 // If snapshot unavailable or reading from it failed, load from the database 278 if s.db.snap == nil || err != nil { 279 if meter != nil { 280 // If we already spent time checking the snapshot, account for it 281 // and reset the readStart 282 *meter += time.Since(readStart) 283 readStart = time.Now() 284 } 285 if metrics.EnabledExpensive { 286 meter = &s.db.StorageReads 287 } 288 if enc, err = s.getTrie(db).TryGet(key.Bytes()); err != nil { 289 s.setError(err) 290 return common.Hash{} 291 } 292 } 293 var value common.Hash 294 if len(enc) > 0 { 295 _, content, _, err := rlp.Split(enc) 296 if err != nil { 297 s.setError(err) 298 } 299 value.SetBytes(content) 300 } 301 s.setOriginStorage(key, value) 302 return value 303 } 304 305 // SetState updates a value in account storage. 306 func (s *StateObject) SetState(db Database, key, value common.Hash) { 307 // If the fake storage is set, put the temporary state update here. 308 if s.fakeStorage != nil { 309 s.fakeStorage[key] = value 310 return 311 } 312 // If the new value is the same as old, don't set 313 prev := s.GetState(db, key) 314 if prev == value { 315 return 316 } 317 // New value is different, update and journal the change 318 s.db.journal.append(storageChange{ 319 account: &s.address, 320 key: key, 321 prevalue: prev, 322 }) 323 s.setState(key, value) 324 } 325 326 // SetStorage replaces the entire state storage with the given one. 327 // 328 // After this function is called, all original state will be ignored and state 329 // lookup only happens in the fake state storage. 330 // 331 // Note this function should only be used for debugging purpose. 332 func (s *StateObject) SetStorage(storage map[common.Hash]common.Hash) { 333 // Allocate fake storage if it's nil. 334 if s.fakeStorage == nil { 335 s.fakeStorage = make(Storage) 336 } 337 for key, value := range storage { 338 s.fakeStorage[key] = value 339 } 340 // Don't bother journal since this function should only be used for 341 // debugging and the `fake` storage won't be committed to database. 342 } 343 344 func (s *StateObject) setState(key, value common.Hash) { 345 s.dirtyStorage[key] = value 346 } 347 348 // finalise moves all dirty storage slots into the pending area to be hashed or 349 // committed later. It is invoked at the end of every transaction. 350 func (s *StateObject) finalise(prefetch bool) { 351 slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage)) 352 for key, value := range s.dirtyStorage { 353 s.pendingStorage[key] = value 354 if value != s.originStorage[key] { 355 slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure 356 } 357 } 358 359 // The account root need to be updated before prefetch, otherwise the account root is empty 360 if s.db.pipeCommit && s.data.Root == dummyRoot && !s.rootCorrected && s.db.snap.AccountsCorrected() { 361 if acc, err := s.db.snap.Account(crypto.HashData(s.db.hasher, s.address.Bytes())); err == nil { 362 if acc != nil && len(acc.Root) != 0 { 363 s.data.Root = common.BytesToHash(acc.Root) 364 s.rootCorrected = true 365 } 366 } 367 } 368 369 if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != emptyRoot && s.data.Root != dummyRoot { 370 s.db.prefetcher.prefetch(s.data.Root, slotsToPrefetch, s.addrHash) 371 } 372 if len(s.dirtyStorage) > 0 { 373 s.dirtyStorage = make(Storage) 374 } 375 } 376 377 // updateTrie writes cached storage modifications into the object's storage trie. 378 // It will return nil if the trie has not been loaded and no changes have been made 379 func (s *StateObject) updateTrie(db Database) Trie { 380 // Make sure all dirty slots are finalized into the pending storage area 381 s.finalise(false) // Don't prefetch any more, pull directly if need be 382 if len(s.pendingStorage) == 0 { 383 return s.trie 384 } 385 // Track the amount of time wasted on updating the storage trie 386 if metrics.EnabledExpensive { 387 defer func(start time.Time) { 388 s.db.MetricsMux.Lock() 389 s.db.StorageUpdates += time.Since(start) 390 s.db.MetricsMux.Unlock() 391 }(time.Now()) 392 } 393 // The snapshot storage map for the object 394 var storage map[string][]byte 395 // Insert all the pending updates into the trie 396 tr := s.getTrie(db) 397 398 usedStorage := make([][]byte, 0, len(s.pendingStorage)) 399 for key, value := range s.pendingStorage { 400 // Skip noop changes, persist actual changes 401 if value == s.originStorage[key] { 402 continue 403 } 404 s.originStorage[key] = value 405 var v []byte 406 if (value == common.Hash{}) { 407 s.setError(tr.TryDelete(key[:])) 408 } else { 409 // Encoding []byte cannot fail, ok to ignore the error. 410 v, _ = rlp.EncodeToBytes(common.TrimLeftZeroes(value[:])) 411 s.setError(tr.TryUpdate(key[:], v)) 412 } 413 // If state snapshotting is active, cache the data til commit 414 if s.db.snap != nil { 415 s.db.snapMux.Lock() 416 if storage == nil { 417 // Retrieve the old storage map, if available, create a new one otherwise 418 if storage = s.db.snapStorage[s.address]; storage == nil { 419 storage = make(map[string][]byte) 420 s.db.snapStorage[s.address] = storage 421 } 422 } 423 storage[string(key[:])] = v // v will be nil if value is 0x00 424 s.db.snapMux.Unlock() 425 } 426 usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure 427 } 428 if s.db.prefetcher != nil { 429 s.db.prefetcher.used(s.data.Root, usedStorage) 430 } 431 if len(s.pendingStorage) > 0 { 432 s.pendingStorage = make(Storage) 433 } 434 return tr 435 } 436 437 // UpdateRoot sets the trie root to the current root hash of 438 func (s *StateObject) updateRoot(db Database) { 439 // If nothing changed, don't bother with hashing anything 440 if s.updateTrie(db) == nil { 441 return 442 } 443 // Track the amount of time wasted on hashing the storage trie 444 if metrics.EnabledExpensive { 445 defer func(start time.Time) { 446 s.db.MetricsMux.Lock() 447 s.db.StorageHashes += time.Since(start) 448 s.db.MetricsMux.Unlock() 449 }(time.Now()) 450 } 451 s.data.Root = s.trie.Hash() 452 } 453 454 // CommitTrie the storage trie of the object to db. 455 // This updates the trie root. 456 func (s *StateObject) CommitTrie(db Database) error { 457 // If nothing changed, don't bother with hashing anything 458 if s.updateTrie(db) == nil { 459 if s.trie != nil && s.data.Root != emptyRoot { 460 db.CacheStorage(s.addrHash, s.data.Root, s.trie) 461 } 462 return nil 463 } 464 if s.dbErr != nil { 465 return s.dbErr 466 } 467 // Track the amount of time wasted on committing the storage trie 468 if metrics.EnabledExpensive { 469 defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now()) 470 } 471 root, err := s.trie.Commit(nil) 472 if err == nil { 473 s.data.Root = root 474 } 475 if s.data.Root != emptyRoot { 476 db.CacheStorage(s.addrHash, s.data.Root, s.trie) 477 } 478 return err 479 } 480 481 // AddBalance adds amount to s's balance. 482 // It is used to add funds to the destination account of a transfer. 483 func (s *StateObject) AddBalance(amount *big.Int) { 484 // EIP161: We must check emptiness for the objects such that the account 485 // clearing (0,0,0 objects) can take effect. 486 if amount.Sign() == 0 { 487 if s.empty() { 488 s.touch() 489 } 490 return 491 } 492 s.SetBalance(new(big.Int).Add(s.Balance(), amount)) 493 } 494 495 // SubBalance removes amount from s's balance. 496 // It is used to remove funds from the origin account of a transfer. 497 func (s *StateObject) SubBalance(amount *big.Int) { 498 if amount.Sign() == 0 { 499 return 500 } 501 s.SetBalance(new(big.Int).Sub(s.Balance(), amount)) 502 } 503 504 func (s *StateObject) SetBalance(amount *big.Int) { 505 s.db.journal.append(balanceChange{ 506 account: &s.address, 507 prev: new(big.Int).Set(s.data.Balance), 508 }) 509 s.setBalance(amount) 510 } 511 512 func (s *StateObject) setBalance(amount *big.Int) { 513 s.data.Balance = amount 514 } 515 516 // Return the gas back to the origin. Used by the Virtual machine or Closures 517 func (s *StateObject) ReturnGas(gas *big.Int) {} 518 519 func (s *StateObject) deepCopy(db *StateDB) *StateObject { 520 stateObject := newObject(db, s.address, s.data) 521 if s.trie != nil { 522 stateObject.trie = db.db.CopyTrie(s.trie) 523 } 524 stateObject.code = s.code 525 stateObject.dirtyStorage = s.dirtyStorage.Copy() 526 stateObject.originStorage = s.originStorage.Copy() 527 stateObject.pendingStorage = s.pendingStorage.Copy() 528 stateObject.suicided = s.suicided 529 stateObject.dirtyCode = s.dirtyCode 530 stateObject.deleted = s.deleted 531 return stateObject 532 } 533 534 // 535 // Attribute accessors 536 // 537 538 // Returns the address of the contract/account 539 func (s *StateObject) Address() common.Address { 540 return s.address 541 } 542 543 // Code returns the contract code associated with this object, if any. 544 func (s *StateObject) Code(db Database) []byte { 545 if s.code != nil { 546 return s.code 547 } 548 if bytes.Equal(s.CodeHash(), emptyCodeHash) { 549 return nil 550 } 551 code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) 552 if err != nil { 553 s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) 554 } 555 s.code = code 556 return code 557 } 558 559 // CodeSize returns the size of the contract code associated with this object, 560 // or zero if none. This method is an almost mirror of Code, but uses a cache 561 // inside the database to avoid loading codes seen recently. 562 func (s *StateObject) CodeSize(db Database) int { 563 if s.code != nil { 564 return len(s.code) 565 } 566 if bytes.Equal(s.CodeHash(), emptyCodeHash) { 567 return 0 568 } 569 size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash())) 570 if err != nil { 571 s.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) 572 } 573 return size 574 } 575 576 func (s *StateObject) SetCode(codeHash common.Hash, code []byte) { 577 prevcode := s.Code(s.db.db) 578 s.db.journal.append(codeChange{ 579 account: &s.address, 580 prevhash: s.CodeHash(), 581 prevcode: prevcode, 582 }) 583 s.setCode(codeHash, code) 584 } 585 586 func (s *StateObject) setCode(codeHash common.Hash, code []byte) { 587 s.code = code 588 s.data.CodeHash = codeHash[:] 589 s.dirtyCode = true 590 } 591 592 func (s *StateObject) SetNonce(nonce uint64) { 593 s.db.journal.append(nonceChange{ 594 account: &s.address, 595 prev: s.data.Nonce, 596 }) 597 s.setNonce(nonce) 598 } 599 600 func (s *StateObject) setNonce(nonce uint64) { 601 s.data.Nonce = nonce 602 } 603 604 func (s *StateObject) CodeHash() []byte { 605 return s.data.CodeHash 606 } 607 608 func (s *StateObject) Balance() *big.Int { 609 return s.data.Balance 610 } 611 612 func (s *StateObject) Nonce() uint64 { 613 return s.data.Nonce 614 } 615 616 // Never called, but must be present to allow StateObject to be used 617 // as a vm.Account interface that also satisfies the vm.ContractRef 618 // interface. Interfaces are awesome. 619 func (s *StateObject) Value() *big.Int { 620 panic("Value on StateObject should never be called") 621 }