github.com/alexanderbez/go-ethereum@v1.8.17-0.20181024144731-0a57b29f0c8e/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 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/crypto" 27 "github.com/ethereum/go-ethereum/rlp" 28 ) 29 30 var ( 31 _ StateObject = (*stateObject)(nil) 32 33 emptyCodeHash = crypto.Keccak256(nil) 34 ) 35 36 type Code []byte 37 38 func (self Code) String() string { 39 return string(self) //strings.Join(Disassemble(self), " ") 40 } 41 42 type Storage map[common.Hash]common.Hash 43 44 func (self Storage) String() (str string) { 45 for key, value := range self { 46 str += fmt.Sprintf("%X : %X\n", key, value) 47 } 48 49 return 50 } 51 52 func (self Storage) Copy() Storage { 53 cpy := make(Storage) 54 for key, value := range self { 55 cpy[key] = value 56 } 57 58 return cpy 59 } 60 61 type ( 62 StateObject interface { 63 GetCommittedState(db Database, key common.Hash) common.Hash 64 GetState(db Database, key common.Hash) common.Hash 65 SetState(db Database, key, value common.Hash) 66 67 Code(db Database) []byte 68 SetCode(codeHash common.Hash, code []byte) 69 CodeHash() []byte 70 71 AddBalance(amount *big.Int) 72 SubBalance(amount *big.Int) 73 SetBalance(amount *big.Int) 74 75 Balance() *big.Int 76 ReturnGas(gas *big.Int) 77 Address() common.Address 78 79 SetNonce(nonce uint64) 80 Nonce() uint64 81 } 82 83 // stateObject represents an Ethereum account which is being modified. 84 // 85 // The usage pattern is as follows: 86 // First you need to obtain a state object. 87 // Account values can be accessed and modified through the object. 88 // Finally, call CommitTrie to write the modified storage trie into a database. 89 stateObject struct { 90 address common.Address 91 addrHash common.Hash // hash of ethereum address of the account 92 data Account 93 db *CommitStateDB 94 95 // DB error. 96 // State objects are used by the consensus core and VM which are 97 // unable to deal with database-level errors. Any error that occurs 98 // during a database read is memoized here and will eventually be returned 99 // by StateDB.Commit. 100 dbErr error 101 102 // Write caches. 103 trie Trie // storage trie, which becomes non-nil on first access 104 code Code // contract bytecode, which gets set when code is loaded 105 106 originStorage Storage // Storage cache of original entries to dedup rewrites 107 dirtyStorage Storage // Storage entries that need to be flushed to disk 108 109 // Cache flags. 110 // When an object is marked suicided it will be delete from the trie 111 // during the "update" phase of the state transition. 112 dirtyCode bool // true if the code was updated 113 suicided bool 114 deleted bool 115 } 116 117 // Account is the Ethereum consensus representation of accounts. 118 // These objects are stored in the main account trie. 119 Account struct { 120 Nonce uint64 121 Balance *big.Int 122 Root common.Hash // merkle root of the storage trie 123 CodeHash []byte 124 } 125 ) 126 127 // empty returns whether the account is considered empty. 128 func (s *stateObject) empty() bool { 129 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) 130 } 131 132 // newObject creates a state object. 133 func newObject(db *CommitStateDB, address common.Address, data Account) *stateObject { 134 if data.Balance == nil { 135 data.Balance = new(big.Int) 136 } 137 if data.CodeHash == nil { 138 data.CodeHash = emptyCodeHash 139 } 140 return &stateObject{ 141 db: db, 142 address: address, 143 addrHash: crypto.Keccak256Hash(address[:]), 144 data: data, 145 originStorage: make(Storage), 146 dirtyStorage: make(Storage), 147 } 148 } 149 150 // EncodeRLP implements rlp.Encoder. 151 func (c *stateObject) EncodeRLP(w io.Writer) error { 152 return rlp.Encode(w, c.data) 153 } 154 155 // setError remembers the first non-nil error it is called with. 156 func (self *stateObject) setError(err error) { 157 if self.dbErr == nil { 158 self.dbErr = err 159 } 160 } 161 162 func (self *stateObject) markSuicided() { 163 self.suicided = true 164 } 165 166 func (c *stateObject) touch() { 167 c.db.journal.append(touchChange{ 168 account: &c.address, 169 }) 170 if c.address == ripemd { 171 // Explicitly put it in the dirty-cache, which is otherwise generated from 172 // flattened journals. 173 c.db.journal.dirty(c.address) 174 } 175 } 176 177 func (c *stateObject) getTrie(db Database) Trie { 178 if c.trie == nil { 179 var err error 180 c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root) 181 if err != nil { 182 c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{}) 183 c.setError(fmt.Errorf("can't create storage trie: %v", err)) 184 } 185 } 186 return c.trie 187 } 188 189 // GetState retrieves a value from the account storage trie. 190 func (self *stateObject) GetState(db Database, key common.Hash) common.Hash { 191 // If we have a dirty value for this state entry, return it 192 value, dirty := self.dirtyStorage[key] 193 if dirty { 194 return value 195 } 196 // Otherwise return the entry's original value 197 return self.GetCommittedState(db, key) 198 } 199 200 // GetCommittedState retrieves a value from the committed account storage trie. 201 func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash { 202 // If we have the original value cached, return that 203 value, cached := self.originStorage[key] 204 if cached { 205 return value 206 } 207 // Otherwise load the value from the database 208 enc, err := self.getTrie(db).TryGet(key[:]) 209 if err != nil { 210 self.setError(err) 211 return common.Hash{} 212 } 213 if len(enc) > 0 { 214 _, content, _, err := rlp.Split(enc) 215 if err != nil { 216 self.setError(err) 217 } 218 value.SetBytes(content) 219 } 220 self.originStorage[key] = value 221 return value 222 } 223 224 // SetState updates a value in account storage. 225 func (self *stateObject) SetState(db Database, key, value common.Hash) { 226 // If the new value is the same as old, don't set 227 prev := self.GetState(db, key) 228 if prev == value { 229 return 230 } 231 // New value is different, update and journal the change 232 self.db.journal.append(storageChange{ 233 account: &self.address, 234 key: key, 235 prevalue: prev, 236 }) 237 self.setState(key, value) 238 } 239 240 func (self *stateObject) setState(key, value common.Hash) { 241 self.dirtyStorage[key] = value 242 } 243 244 // updateTrie writes cached storage modifications into the object's storage trie. 245 func (self *stateObject) updateTrie(db Database) Trie { 246 tr := self.getTrie(db) 247 for key, value := range self.dirtyStorage { 248 delete(self.dirtyStorage, key) 249 250 // Skip noop changes, persist actual changes 251 if value == self.originStorage[key] { 252 continue 253 } 254 self.originStorage[key] = value 255 256 if (value == common.Hash{}) { 257 self.setError(tr.TryDelete(key[:])) 258 continue 259 } 260 // Encoding []byte cannot fail, ok to ignore the error. 261 v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) 262 self.setError(tr.TryUpdate(key[:], v)) 263 } 264 return tr 265 } 266 267 // UpdateRoot sets the trie root to the current root hash of 268 func (self *stateObject) updateRoot(db Database) { 269 self.updateTrie(db) 270 self.data.Root = self.trie.Hash() 271 } 272 273 // CommitTrie the storage trie of the object to db. 274 // This updates the trie root. 275 func (self *stateObject) CommitTrie(db Database) error { 276 self.updateTrie(db) 277 if self.dbErr != nil { 278 return self.dbErr 279 } 280 root, err := self.trie.Commit(nil) 281 if err == nil { 282 self.data.Root = root 283 } 284 return err 285 } 286 287 // AddBalance removes amount from c's balance. 288 // It is used to add funds to the destination account of a transfer. 289 func (c *stateObject) AddBalance(amount *big.Int) { 290 // EIP158: We must check emptiness for the objects such that the account 291 // clearing (0,0,0 objects) can take effect. 292 if amount.Sign() == 0 { 293 if c.empty() { 294 c.touch() 295 } 296 297 return 298 } 299 c.SetBalance(new(big.Int).Add(c.Balance(), amount)) 300 } 301 302 // SubBalance removes amount from c's balance. 303 // It is used to remove funds from the origin account of a transfer. 304 func (c *stateObject) SubBalance(amount *big.Int) { 305 if amount.Sign() == 0 { 306 return 307 } 308 c.SetBalance(new(big.Int).Sub(c.Balance(), amount)) 309 } 310 311 func (self *stateObject) SetBalance(amount *big.Int) { 312 self.db.journal.append(balanceChange{ 313 account: &self.address, 314 prev: new(big.Int).Set(self.data.Balance), 315 }) 316 self.setBalance(amount) 317 } 318 319 func (self *stateObject) setBalance(amount *big.Int) { 320 self.data.Balance = amount 321 } 322 323 // Return the gas back to the origin. Used by the Virtual machine or Closures 324 func (c *stateObject) ReturnGas(gas *big.Int) {} 325 326 func (self *stateObject) deepCopy(db *CommitStateDB) *stateObject { 327 stateObject := newObject(db, self.address, self.data) 328 if self.trie != nil { 329 stateObject.trie = db.db.CopyTrie(self.trie) 330 } 331 stateObject.code = self.code 332 stateObject.dirtyStorage = self.dirtyStorage.Copy() 333 stateObject.originStorage = self.originStorage.Copy() 334 stateObject.suicided = self.suicided 335 stateObject.dirtyCode = self.dirtyCode 336 stateObject.deleted = self.deleted 337 return stateObject 338 } 339 340 // 341 // Attribute accessors 342 // 343 344 // Returns the address of the contract/account 345 func (c *stateObject) Address() common.Address { 346 return c.address 347 } 348 349 // Code returns the contract code associated with this object, if any. 350 func (self *stateObject) Code(db Database) []byte { 351 if self.code != nil { 352 return self.code 353 } 354 if bytes.Equal(self.CodeHash(), emptyCodeHash) { 355 return nil 356 } 357 code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash())) 358 if err != nil { 359 self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err)) 360 } 361 self.code = code 362 return code 363 } 364 365 func (self *stateObject) SetCode(codeHash common.Hash, code []byte) { 366 prevcode := self.Code(self.db.db) 367 self.db.journal.append(codeChange{ 368 account: &self.address, 369 prevhash: self.CodeHash(), 370 prevcode: prevcode, 371 }) 372 373 self.setCode(codeHash, code) 374 } 375 376 func (self *stateObject) setCode(codeHash common.Hash, code []byte) { 377 self.code = code 378 self.data.CodeHash = codeHash[:] 379 self.dirtyCode = true 380 } 381 382 func (self *stateObject) SetNonce(nonce uint64) { 383 self.db.journal.append(nonceChange{ 384 account: &self.address, 385 prev: self.data.Nonce, 386 }) 387 self.setNonce(nonce) 388 } 389 390 func (self *stateObject) setNonce(nonce uint64) { 391 self.data.Nonce = nonce 392 } 393 394 func (self *stateObject) CodeHash() []byte { 395 return self.data.CodeHash 396 } 397 398 func (self *stateObject) Balance() *big.Int { 399 return self.data.Balance 400 } 401 402 func (self *stateObject) Nonce() uint64 { 403 return self.data.Nonce 404 } 405 406 // Never called, but must be present to allow stateObject to be used 407 // as a vm.Account interface that also satisfies the vm.ContractRef 408 // interface. Interfaces are awesome. 409 func (self *stateObject) Value() *big.Int { 410 panic("Value on stateObject should never be called") 411 }