github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/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 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 18 package state 19 20 import ( 21 "bytes" 22 "encoding/hex" 23 "fmt" 24 "github.com/PlatONnetwork/PlatON-Go/core/vm" 25 "github.com/PlatONnetwork/PlatON-Go/log" 26 "io" 27 "math/big" 28 //"runtime/debug" 29 30 "github.com/PlatONnetwork/PlatON-Go/common" 31 "github.com/PlatONnetwork/PlatON-Go/crypto" 32 "github.com/PlatONnetwork/PlatON-Go/rlp" 33 ) 34 35 var emptyCodeHash = crypto.Keccak256(nil) 36 37 type Code []byte 38 type Abi []byte 39 40 func (self Code) String() string { 41 return string(self) //strings.Join(Disassemble(self), " ") 42 } 43 44 type Storage map[string]common.Hash 45 type ValueStorage map[common.Hash][]byte 46 47 // Storage -> hash : hash , common.Hash ([32]byte) 48 //type Storage map[common.Hash]common.Hash 49 50 func (self Storage) String() (str string) { 51 for key, value := range self { 52 // %X -> Provide hexadecimal 53 str += fmt.Sprintf("%X : %X\n", key, value) 54 } 55 56 return 57 } 58 59 // Copy a copy of Storage 60 func (self Storage) Copy() Storage { 61 cpy := make(Storage) 62 for key, value := range self { 63 cpy[key] = value 64 } 65 66 return cpy 67 } 68 69 func (self ValueStorage) Copy() ValueStorage { 70 cpy := make(ValueStorage) 71 for key, value := range self { 72 cpy[key] = value 73 } 74 75 return cpy 76 } 77 78 // stateObject represents an Ethereum account which is being modified. 79 // 80 // The usage pattern is as follows: 81 // First you need to obtain a state object. 82 // Account values can be accessed and modified through the object. 83 // Finally, call CommitTrie to write the modified storage trie into a database. 84 type stateObject struct { 85 address common.Address 86 addrHash common.Hash // hash of ethereum address of the account 87 data Account 88 db *StateDB 89 90 // DB error. 91 // State objects are used by the consensus core and VM which are 92 // unable to deal with database-level errors. Any error that occurs 93 // during a database read is memoized here and will eventually be returned 94 // by StateDB.Commit. 95 dbErr error 96 97 // Write caches. 98 trie Trie 99 // storage trie, which becomes non-nil on first access 100 code Code // contract bytecode, which gets set when code is loaded 101 102 abi Abi 103 104 originStorage Storage // Storage cache of original entries to dedup rewrites 105 originValueStorage ValueStorage // Storage cache of original entries to dedup rewrites 106 107 dirtyStorage Storage // Storage entries that need to be flushed to disk 108 dirtyValueStorage ValueStorage // Storage entries that need to be flushed to disk 109 110 // Cache flags. 111 // When an object is marked suicided it will be delete from the trie 112 // during the "update" phase of the state transition. 113 dirtyCode bool // true if the code was updated 114 suicided bool 115 deleted bool 116 } 117 118 // empty returns whether the account is considered empty. 119 func (s *stateObject) empty() bool { 120 if _, ok := vm.PrecompiledContractsPpos[s.address]; ok { 121 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) && s.data.Root == (common.Hash{}) 122 } else { 123 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) 124 } 125 } 126 127 // Account is the Ethereum consensus representation of accounts. 128 // These objects are stored in the main account trie. 129 type Account struct { 130 Nonce uint64 131 Balance *big.Int 132 Root common.Hash // merkle root of the storage trie 133 CodeHash []byte 134 AbiHash []byte 135 } 136 137 // newObject creates a state object. 138 func newObject(db *StateDB, address common.Address, data Account) *stateObject { 139 log.Debug("newObject", "state db addr", fmt.Sprintf("%p", db), "state root", db.Root().Hex()) 140 if data.Balance == nil { 141 data.Balance = new(big.Int) 142 } 143 if data.CodeHash == nil { 144 data.CodeHash = emptyCodeHash 145 } 146 return &stateObject{ 147 db: db, 148 address: address, 149 addrHash: crypto.Keccak256Hash(address[:]), 150 data: data, 151 152 originStorage: make(Storage), 153 originValueStorage: make(map[common.Hash][]byte), 154 155 dirtyStorage: make(Storage), 156 dirtyValueStorage: make(map[common.Hash][]byte), 157 } 158 } 159 160 // EncodeRLP implements rlp.Encoder. 161 func (c *stateObject) EncodeRLP(w io.Writer) error { 162 return rlp.Encode(w, c.data) 163 } 164 165 // setError remembers the first non-nil error it is called with. 166 func (self *stateObject) setError(err error) { 167 if self.dbErr == nil { 168 self.dbErr = err 169 } 170 } 171 172 func (self *stateObject) markSuicided() { 173 self.suicided = true 174 } 175 176 func (c *stateObject) touch() { 177 c.db.journal.append(touchChange{ 178 account: &c.address, 179 }) 180 if c.address == ripemd { 181 // Explicitly put it in the dirty-cache, which is otherwise generated from 182 // flattened journals. 183 c.db.journal.dirty(c.address) 184 } 185 } 186 187 func (c *stateObject) getTrie(db Database) Trie { 188 if c.trie == nil { 189 var err error 190 c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root) 191 if err != nil { 192 c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{}) 193 c.setError(fmt.Errorf("can't create storage trie: %v", err)) 194 } 195 } 196 return c.trie 197 } 198 199 // GetState retrieves a value from the account storage trie. 200 //func (self *stateObject) GetState(db Database, key common.Hash) common.Hash { 201 // // If we have a dirty value for this state entry, return it 202 // value, dirty := self.dirtyStorage[key] 203 // if dirty { 204 // return value 205 // } 206 // // Otherwise return the entry's original value 207 // return self.GetCommittedState(db, key) 208 //} 209 210 // GetState retrieves a value from the account storage trie. 211 func (self *stateObject) GetState(db Database, keyTree string) []byte { 212 // If we have a dirty value for this state entry, return it 213 valueKey, dirty := self.dirtyStorage[keyTree] 214 if dirty { 215 value, ok := self.dirtyValueStorage[valueKey] 216 if ok { 217 return value 218 } 219 } 220 // Otherwise return the entry's original value 221 return self.GetCommittedState(db, keyTree) 222 } 223 224 // GetCommittedState retrieves a value from the committed account storage trie. 225 //func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash { 226 // // If we have the original value cached, return that 227 // value, cached := self.originStorage[key] 228 // if cached { 229 // return value 230 // } 231 // // Otherwise load the value from the database 232 // enc, err := self.getTrie(db).TryGet(key[:]) 233 // if err != nil { 234 // self.setError(err) 235 // return common.Hash{} 236 // } 237 // if len(enc) > 0 { 238 // _, content, _, err := rlp.Split(enc) 239 // if err != nil { 240 // self.setError(err) 241 // } 242 // value.SetBytes(content) 243 // } 244 // self.originStorage[key] = value 245 // return value 246 //} 247 248 // GetCommittedState retrieves a value from the committed account storage trie. 249 func (self *stateObject) GetCommittedState(db Database, key string) []byte { 250 var value []byte 251 // If we have the original value cached, return that 252 valueKey, cached := self.originStorage[key] 253 if cached { 254 value, cached2 := self.originValueStorage[valueKey] 255 if cached2 { 256 return value 257 } 258 } 259 log.Debug("GetCommittedState", "stateObject addr", fmt.Sprintf("%p", self), "statedb addr", fmt.Sprintf("%p", self.db), "root", self.data.Root, "key", hex.EncodeToString([]byte(key))) 260 //if self.data.Root == (common.Hash{}) { 261 // log.Info("GetCommittedState", "stack", string(debug.Stack())) 262 //} 263 // Otherwise load the valueKey from trie 264 enc, err := self.getTrie(db).TryGet([]byte(key)) 265 if err != nil { 266 self.setError(err) 267 return []byte{} 268 } 269 if len(enc) > 0 { 270 _, content, _, err := rlp.Split(enc) 271 if err != nil { 272 self.setError(err) 273 } 274 valueKey.SetBytes(content) 275 276 //load value from db 277 value = self.db.trie.GetKey(valueKey.Bytes()) 278 if err != nil { 279 self.setError(err) 280 } 281 } 282 283 if valueKey != emptyStorage && len(value) == 0 { 284 log.Error("invalid storage valuekey", "key", hex.EncodeToString([]byte(key)), "valueKey", valueKey.String()) 285 return []byte{} 286 } 287 if len(value) == 0 && valueKey == emptyStorage { 288 log.Debug("empty storage valuekey", "key", hex.EncodeToString([]byte(key)), "valueKey", valueKey.String()) 289 } 290 log.Info("GetCommittedState", "stateObject addr", fmt.Sprintf("%p", self), "statedb addr", fmt.Sprintf("%p", self.db), "root", self.data.Root, "key", hex.EncodeToString([]byte(key)), "valueKey", valueKey.String(), "value", len(value)) 291 self.originStorage[key] = valueKey 292 self.originValueStorage[valueKey] = value 293 return value 294 } 295 296 // SetState updates a value in account storage. 297 // set [keyTrie,valueKey] to storage 298 // set [valueKey,value] to db 299 func (self *stateObject) SetState(db Database, keyTrie string, valueKey common.Hash, value []byte) { 300 log.Debug("SetState ", "keyTrie", hex.EncodeToString([]byte(keyTrie)), "valueKey", valueKey, "value", hex.EncodeToString(value)) 301 //if the new value is the same as old,don't set 302 preValue := self.GetState(db, keyTrie) // get value key 303 if bytes.Equal(preValue, value) { 304 return 305 } 306 307 //New value is different, update and journal the change 308 self.db.journal.append(storageChange{ 309 account: &self.address, 310 key: keyTrie, 311 valueKey: self.originStorage[keyTrie], 312 preValue: preValue, 313 }) 314 315 self.setState(keyTrie, valueKey, value) 316 } 317 318 func (self *stateObject) setState(key string, valueKey common.Hash, value []byte) { 319 cpy := make([]byte, len(value)) 320 copy(cpy, value) 321 self.dirtyStorage[key] = valueKey 322 self.dirtyValueStorage[valueKey] = cpy 323 } 324 325 // updateTrie writes cached storage modifications into the object's storage trie. 326 func (self *stateObject) updateTrie(db Database) Trie { 327 tr := self.getTrie(db) 328 for key, valueKey := range self.dirtyStorage { 329 delete(self.dirtyStorage, key) 330 331 if valueKey == self.originStorage[key] { 332 continue 333 } 334 335 self.originStorage[key] = valueKey 336 337 if valueKey == emptyStorage { 338 self.setError(tr.TryDelete([]byte(key))) 339 continue 340 } 341 342 v, _ := rlp.EncodeToBytes(bytes.TrimLeft(valueKey[:], "\x00")) 343 self.setError(tr.TryUpdate([]byte(key), v)) 344 345 //flush dirty value 346 if value, ok := self.dirtyValueStorage[valueKey]; ok { 347 delete(self.dirtyValueStorage, valueKey) 348 self.originValueStorage[valueKey] = value 349 self.setError(tr.TryUpdateValue(valueKey.Bytes(), value)) 350 } 351 } 352 353 return tr 354 } 355 356 // UpdateRoot sets the trie root to the current root hash of 357 func (self *stateObject) updateRoot(db Database) { 358 self.updateTrie(db) 359 self.data.Root = self.trie.Hash() 360 } 361 362 // CommitTrie the storage trie of the object to db. 363 // This updates the trie root. 364 func (self *stateObject) CommitTrie(db Database) error { 365 self.updateTrie(db) 366 if self.dbErr != nil { 367 return self.dbErr 368 } 369 370 for h, v := range self.originValueStorage { 371 if h != emptyStorage && !bytes.Equal(v, []byte{}) { 372 self.trie.TryUpdateValue(h.Bytes(), v) 373 } 374 } 375 root, err := self.trie.Commit(nil) 376 if err == nil { 377 self.data.Root = root 378 } 379 return err 380 } 381 382 // AddBalance removes amount from c's balance. 383 // It is used to add funds to the destination account of a transfer. 384 func (c *stateObject) AddBalance(amount *big.Int) { 385 // EIP158: We must check emptiness for the objects such that the account 386 // clearing (0,0,0 objects) can take effect. 387 if amount.Sign() == 0 { 388 if c.empty() { 389 c.touch() 390 } 391 392 return 393 } 394 c.SetBalance(new(big.Int).Add(c.Balance(), amount)) 395 } 396 397 // SubBalance removes amount from c's balance. 398 // It is used to remove funds from the origin account of a transfer. 399 func (c *stateObject) SubBalance(amount *big.Int) { 400 if amount.Sign() == 0 { 401 return 402 } 403 c.SetBalance(new(big.Int).Sub(c.Balance(), amount)) 404 } 405 406 func (self *stateObject) SetBalance(amount *big.Int) { 407 self.db.journal.append(balanceChange{ 408 account: &self.address, 409 prev: new(big.Int).Set(self.data.Balance), 410 }) 411 self.setBalance(amount) 412 } 413 414 func (self *stateObject) setBalance(amount *big.Int) { 415 self.data.Balance = amount 416 } 417 418 // Return the gas back to the origin. Used by the Virtual machine or Closures 419 func (c *stateObject) ReturnGas(gas *big.Int) {} 420 421 func (self *stateObject) deepCopy(db *StateDB) *stateObject { 422 stateObject := newObject(db, self.address, self.data) 423 if self.trie != nil { 424 stateObject.trie = db.db.CopyTrie(self.trie) 425 } 426 stateObject.code = self.code 427 stateObject.dirtyStorage = self.dirtyStorage.Copy() 428 stateObject.dirtyValueStorage = self.dirtyValueStorage.Copy() 429 stateObject.originStorage = self.originStorage.Copy() 430 stateObject.originValueStorage = self.originValueStorage.Copy() 431 stateObject.suicided = self.suicided 432 stateObject.dirtyCode = self.dirtyCode 433 stateObject.deleted = self.deleted 434 return stateObject 435 } 436 437 // 438 // Attribute accessors 439 // 440 441 // Returns the address of the contract/account 442 func (c *stateObject) Address() common.Address { 443 return c.address 444 } 445 446 // Code returns the contract code associated with this object, if any. 447 func (self *stateObject) Code(db Database) []byte { 448 if self.code != nil { 449 return self.code 450 } 451 if bytes.Equal(self.CodeHash(), emptyCodeHash) { 452 return nil 453 } 454 code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash())) 455 if err != nil { 456 self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err)) 457 } 458 self.code = code 459 return code 460 } 461 462 func (self *stateObject) SetCode(codeHash common.Hash, code []byte) { 463 prevcode := self.Code(self.db.db) 464 self.db.journal.append(codeChange{ 465 account: &self.address, 466 prevhash: self.CodeHash(), 467 prevcode: prevcode, 468 }) 469 self.setCode(codeHash, code) 470 } 471 472 func (self *stateObject) setCode(codeHash common.Hash, code []byte) { 473 self.code = code 474 self.data.CodeHash = codeHash[:] 475 self.dirtyCode = true 476 } 477 478 func (self *stateObject) SetNonce(nonce uint64) { 479 self.db.journal.append(nonceChange{ 480 account: &self.address, 481 prev: self.data.Nonce, 482 }) 483 self.setNonce(nonce) 484 } 485 486 func (self *stateObject) setNonce(nonce uint64) { 487 self.data.Nonce = nonce 488 } 489 490 func (self *stateObject) CodeHash() []byte { 491 return self.data.CodeHash 492 } 493 494 func (self *stateObject) Balance() *big.Int { 495 return self.data.Balance 496 } 497 498 func (self *stateObject) Nonce() uint64 { 499 return self.data.Nonce 500 } 501 502 // Never called, but must be present to allow stateObject to be used 503 // as a vm.Account interface that also satisfies the vm.ContractRef 504 // interface. Interfaces are awesome. 505 func (self *stateObject) Value() *big.Int { 506 panic("Value on stateObject should never be called") 507 } 508 509 // todo: New method 510 // ======================================= New method =============================== 511 512 // todo: new method -> AbiHash 513 func (self *stateObject) AbiHash() []byte { 514 return self.data.AbiHash 515 } 516 517 // ABI returns the contract abi associated with this object, if any. 518 func (self *stateObject) Abi(db Database) []byte { 519 //if self.Abi != nil { 520 // return self.abi 521 //} 522 if bytes.Equal(self.AbiHash(), emptyCodeHash) { 523 return nil 524 } 525 // Extract the code from the tree, enter the parameters: address and hash, here you need to find the acquisition rules in depth 526 abi, err := db.ContractAbi(self.addrHash, common.BytesToHash(self.AbiHash())) 527 if err != nil { 528 self.setError(fmt.Errorf("can't load abi hash %x: %v", self.AbiHash(), err)) 529 } 530 self.abi = abi 531 return abi 532 } 533 534 // todo: new method -> SetAbi. 535 func (self *stateObject) SetAbi(abiHash common.Hash, abi []byte) { 536 prevabi := self.Abi(self.db.db) 537 self.db.journal.append(abiChange{ 538 account: &self.address, 539 prevhash: self.AbiHash(), 540 prevabi: prevabi, 541 }) 542 self.setAbi(abiHash, abi) 543 } 544 545 // todo: new method -> setAbi 546 func (self *stateObject) setAbi(abiHash common.Hash, abi []byte) { 547 self.abi = abi 548 self.data.AbiHash = abiHash[:] 549 }