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