github.com/jiajun1992/watercarver@v0.0.0-20191031150618-dfc2b17c0c4a/go-ethereum/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 crypto2 "github.com/ethereum/go-ethereum/ctcrypto/crypto" 23 "io" 24 "math/big" 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 72 // DB error. 73 // State objects are used by the consensus core and VM which are 74 // unable to deal with database-level errors. Any error that occurs 75 // during a database read is memoized here and will eventually be returned 76 // by StateDB.Commit. 77 dbErr error 78 79 // Write caches. 80 trie Trie // storage trie, which becomes non-nil on first access 81 code Code // contract bytecode, which gets set when code is loaded 82 83 originStorage Storage // Storage cache of original entries to dedup rewrites, reset for every transaction 84 pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block 85 dirtyStorage Storage // Storage entries that have been modified in the current transaction execution 86 fakeStorage Storage // Fake storage which constructed by caller for debugging purpose. 87 88 // Cache flags. 89 // When an object is marked suicided it will be delete from the trie 90 // during the "update" phase of the state transition. 91 dirtyCode bool // true if the code was updated 92 suicided bool 93 deleted bool 94 } 95 96 // empty returns whether the account is considered empty. 97 func (s *stateObject) empty() bool { 98 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) 99 } 100 101 // Account is the Ethereum consensus representation of accounts. 102 // These objects are stored in the main account trie. 103 type Account struct { 104 Nonce uint64 105 Balance *big.Int 106 CTBalance crypto2.Key 107 Root common.Hash // merkle root of the storage trie 108 CodeHash []byte 109 } 110 111 // newObject creates a state object. 112 func newObject(db *StateDB, address common.Address, data Account) *stateObject { 113 if data.Balance == nil { 114 data.Balance = new(big.Int) 115 } 116 if data.CodeHash == nil { 117 data.CodeHash = emptyCodeHash 118 } 119 if data.Root == (common.Hash{}) { 120 data.Root = emptyRoot 121 } 122 return &stateObject{ 123 db: db, 124 address: address, 125 addrHash: crypto.Keccak256Hash(address[:]), 126 data: data, 127 originStorage: make(Storage), 128 pendingStorage: make(Storage), 129 dirtyStorage: make(Storage), 130 } 131 } 132 133 // EncodeRLP implements rlp.Encoder. 134 func (s *stateObject) EncodeRLP(w io.Writer) error { 135 return rlp.Encode(w, s.data) 136 } 137 138 // setError remembers the first non-nil error it is called with. 139 func (s *stateObject) setError(err error) { 140 if s.dbErr == nil { 141 s.dbErr = err 142 } 143 } 144 145 func (s *stateObject) markSuicided() { 146 s.suicided = true 147 } 148 149 func (s *stateObject) touch() { 150 s.db.journal.append(touchChange{ 151 account: &s.address, 152 }) 153 if s.address == ripemd { 154 // Explicitly put it in the dirty-cache, which is otherwise generated from 155 // flattened journals. 156 s.db.journal.dirty(s.address) 157 } 158 } 159 160 func (s *stateObject) getTrie(db Database) Trie { 161 if s.trie == nil { 162 var err error 163 s.trie, err = db.OpenStorageTrie(s.addrHash, s.data.Root) 164 if err != nil { 165 s.trie, _ = db.OpenStorageTrie(s.addrHash, common.Hash{}) 166 s.setError(fmt.Errorf("can't create storage trie: %v", err)) 167 } 168 } 169 return s.trie 170 } 171 172 // GetState retrieves a value from the account storage trie. 173 func (s *stateObject) GetState(db Database, key common.Hash) common.Hash { 174 // If the fake storage is set, only lookup the state here(in the debugging mode) 175 if s.fakeStorage != nil { 176 return s.fakeStorage[key] 177 } 178 // If we have a dirty value for this state entry, return it 179 value, dirty := s.dirtyStorage[key] 180 if dirty { 181 return value 182 } 183 // Otherwise return the entry's original value 184 return s.GetCommittedState(db, key) 185 } 186 187 // GetCommittedState retrieves a value from the committed account storage trie. 188 func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash { 189 // If the fake storage is set, only lookup the state here(in the debugging mode) 190 if s.fakeStorage != nil { 191 return s.fakeStorage[key] 192 } 193 // If we have a pending write or clean cached, return that 194 if value, pending := s.pendingStorage[key]; pending { 195 return value 196 } 197 if value, cached := s.originStorage[key]; cached { 198 return value 199 } 200 // Track the amount of time wasted on reading the storage trie 201 if metrics.EnabledExpensive { 202 defer func(start time.Time) { s.db.StorageReads += time.Since(start) }(time.Now()) 203 } 204 // Otherwise load the value from the database 205 enc, err := s.getTrie(db).TryGet(key[:]) 206 if err != nil { 207 s.setError(err) 208 return common.Hash{} 209 } 210 var value common.Hash 211 if len(enc) > 0 { 212 _, content, _, err := rlp.Split(enc) 213 if err != nil { 214 s.setError(err) 215 } 216 value.SetBytes(content) 217 } 218 s.originStorage[key] = value 219 return value 220 } 221 222 // SetState updates a value in account storage. 223 func (s *stateObject) SetState(db Database, key, value common.Hash) { 224 // If the fake storage is set, put the temporary state update here. 225 if s.fakeStorage != nil { 226 s.fakeStorage[key] = value 227 return 228 } 229 // If the new value is the same as old, don't set 230 prev := s.GetState(db, key) 231 if prev == value { 232 return 233 } 234 // New value is different, update and journal the change 235 s.db.journal.append(storageChange{ 236 account: &s.address, 237 key: key, 238 prevalue: prev, 239 }) 240 s.setState(key, value) 241 } 242 243 // SetStorage replaces the entire state storage with the given one. 244 // 245 // After this function is called, all original state will be ignored and state 246 // lookup only happens in the fake state storage. 247 // 248 // Note this function should only be used for debugging purpose. 249 func (s *stateObject) SetStorage(storage map[common.Hash]common.Hash) { 250 // Allocate fake storage if it's nil. 251 if s.fakeStorage == nil { 252 s.fakeStorage = make(Storage) 253 } 254 for key, value := range storage { 255 s.fakeStorage[key] = value 256 } 257 // Don't bother journal since this function should only be used for 258 // debugging and the `fake` storage won't be committed to database. 259 } 260 261 func (s *stateObject) setState(key, value common.Hash) { 262 s.dirtyStorage[key] = value 263 } 264 265 // finalise moves all dirty storage slots into the pending area to be hashed or 266 // committed later. It is invoked at the end of every transaction. 267 func (s *stateObject) finalise() { 268 for key, value := range s.dirtyStorage { 269 s.pendingStorage[key] = value 270 } 271 if len(s.dirtyStorage) > 0 { 272 s.dirtyStorage = make(Storage) 273 } 274 } 275 276 // updateTrie writes cached storage modifications into the object's storage trie. 277 func (s *stateObject) updateTrie(db Database) Trie { 278 // Make sure all dirty slots are finalized into the pending storage area 279 s.finalise() 280 281 // Track the amount of time wasted on updating the storge trie 282 if metrics.EnabledExpensive { 283 defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now()) 284 } 285 // Insert all the pending updates into the trie 286 tr := s.getTrie(db) 287 for key, value := range s.pendingStorage { 288 // Skip noop changes, persist actual changes 289 if value == s.originStorage[key] { 290 continue 291 } 292 s.originStorage[key] = value 293 294 if (value == common.Hash{}) { 295 s.setError(tr.TryDelete(key[:])) 296 continue 297 } 298 // Encoding []byte cannot fail, ok to ignore the error. 299 v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(value[:])) 300 s.setError(tr.TryUpdate(key[:], v)) 301 } 302 if len(s.pendingStorage) > 0 { 303 s.pendingStorage = make(Storage) 304 } 305 return tr 306 } 307 308 // UpdateRoot sets the trie root to the current root hash of 309 func (s *stateObject) updateRoot(db Database) { 310 s.updateTrie(db) 311 312 // Track the amount of time wasted on hashing the storge trie 313 if metrics.EnabledExpensive { 314 defer func(start time.Time) { s.db.StorageHashes += time.Since(start) }(time.Now()) 315 } 316 s.data.Root = s.trie.Hash() 317 } 318 319 // CommitTrie the storage trie of the object to db. 320 // This updates the trie root. 321 func (s *stateObject) CommitTrie(db Database) error { 322 s.updateTrie(db) 323 if s.dbErr != nil { 324 return s.dbErr 325 } 326 // Track the amount of time wasted on committing the storge trie 327 if metrics.EnabledExpensive { 328 defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now()) 329 } 330 root, err := s.trie.Commit(nil) 331 if err == nil { 332 s.data.Root = root 333 } 334 return err 335 } 336 337 // AddBalance removes amount from c's balance. 338 // It is used to add funds to the destination account of a transfer. 339 func (s *stateObject) AddBalance(amount *big.Int) { 340 // EIP158: We must check emptiness for the objects such that the account 341 // clearing (0,0,0 objects) can take effect. 342 if amount.Sign() == 0 { 343 if s.empty() { 344 s.touch() 345 } 346 347 return 348 } 349 s.SetBalance(new(big.Int).Add(s.Balance(), amount)) 350 } 351 352 // SubBalance removes amount from c's balance. 353 // It is used to remove funds from the origin account of a transfer. 354 func (s *stateObject) SubBalance(amount *big.Int) { 355 if amount.Sign() == 0 { 356 return 357 } 358 s.SetBalance(new(big.Int).Sub(s.Balance(), amount)) 359 } 360 361 func (s *stateObject) SetBalance(amount *big.Int) { 362 s.db.journal.append(balanceChange{ 363 account: &s.address, 364 prev: new(big.Int).Set(s.data.Balance), 365 }) 366 s.setBalance(amount) 367 } 368 369 func (s *stateObject) setBalance(amount *big.Int) { 370 s.data.Balance = amount 371 } 372 373 func (s *stateObject) SetCTBalance(commitment crypto2.Key) { 374 s.db.journal.append(ctBalanceChange{ 375 account: &s.address, 376 prev: s.data.CTBalance, 377 }) 378 s.setCTBalance(commitment) 379 } 380 381 func (s *stateObject) setCTBalance(commitment crypto2.Key) { 382 s.data.CTBalance = commitment 383 } 384 385 // Return the gas back to the origin. Used by the Virtual machine or Closures 386 func (s *stateObject) ReturnGas(gas *big.Int) {} 387 388 func (s *stateObject) deepCopy(db *StateDB) *stateObject { 389 stateObject := newObject(db, s.address, s.data) 390 if s.trie != nil { 391 stateObject.trie = db.db.CopyTrie(s.trie) 392 } 393 stateObject.code = s.code 394 stateObject.dirtyStorage = s.dirtyStorage.Copy() 395 stateObject.originStorage = s.originStorage.Copy() 396 stateObject.pendingStorage = s.pendingStorage.Copy() 397 stateObject.suicided = s.suicided 398 stateObject.dirtyCode = s.dirtyCode 399 stateObject.deleted = s.deleted 400 return stateObject 401 } 402 403 // 404 // Attribute accessors 405 // 406 407 // Returns the address of the contract/account 408 func (s *stateObject) Address() common.Address { 409 return s.address 410 } 411 412 // Code returns the contract code associated with this object, if any. 413 func (s *stateObject) Code(db Database) []byte { 414 if s.code != nil { 415 return s.code 416 } 417 if bytes.Equal(s.CodeHash(), emptyCodeHash) { 418 return nil 419 } 420 code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) 421 if err != nil { 422 s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) 423 } 424 s.code = code 425 return code 426 } 427 428 func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { 429 prevcode := s.Code(s.db.db) 430 s.db.journal.append(codeChange{ 431 account: &s.address, 432 prevhash: s.CodeHash(), 433 prevcode: prevcode, 434 }) 435 s.setCode(codeHash, code) 436 } 437 438 func (s *stateObject) setCode(codeHash common.Hash, code []byte) { 439 s.code = code 440 s.data.CodeHash = codeHash[:] 441 s.dirtyCode = true 442 } 443 444 func (s *stateObject) SetNonce(nonce uint64) { 445 s.db.journal.append(nonceChange{ 446 account: &s.address, 447 prev: s.data.Nonce, 448 }) 449 s.setNonce(nonce) 450 } 451 452 func (s *stateObject) setNonce(nonce uint64) { 453 s.data.Nonce = nonce 454 } 455 456 func (s *stateObject) CodeHash() []byte { 457 return s.data.CodeHash 458 } 459 460 func (s *stateObject) Balance() *big.Int { 461 return s.data.Balance 462 } 463 464 func (s *stateObject) CTBalance() crypto2.Key { 465 return s.data.CTBalance 466 } 467 468 func (s *stateObject) Nonce() uint64 { 469 return s.data.Nonce 470 } 471 472 // Never called, but must be present to allow stateObject to be used 473 // as a vm.Account interface that also satisfies the vm.ContractRef 474 // interface. Interfaces are awesome. 475 func (s *stateObject) Value() *big.Int { 476 panic("Value on stateObject should never be called") 477 }