github.com/annchain/OG@v0.0.9/arefactor_core/core/state/state_object.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package state 15 16 import ( 17 "bytes" 18 "encoding/hex" 19 "encoding/json" 20 "fmt" 21 "github.com/annchain/commongo/marshaller" 22 "math/big" 23 24 ogTypes "github.com/annchain/OG/arefactor/og_interface" 25 //"github.com/annchain/OG/common/crypto" 26 crypto "github.com/annchain/OG/arefactor/ogcrypto" 27 "github.com/annchain/OG/common/math" 28 log "github.com/sirupsen/logrus" 29 ) 30 31 //go:generate msgp 32 33 //msgp:tuple AccountData 34 type AccountData struct { 35 Address ogTypes.Address 36 Balances BalanceSet 37 Nonce uint64 38 Root ogTypes.Hash 39 CodeHash []byte 40 } 41 42 func NewAccountData() AccountData { 43 return AccountData{ 44 Address: &ogTypes.Address20{}, 45 Balances: NewBalanceSet(), 46 Nonce: 0, 47 Root: &ogTypes.Hash32{}, 48 CodeHash: []byte{}, 49 } 50 } 51 52 type StateObject struct { 53 address ogTypes.Address 54 addressHash ogTypes.Hash 55 data AccountData 56 57 dbErr error 58 59 code []byte 60 dirtycode bool 61 suicided bool // TODO suicided is useless now. 62 63 committedStorage map[ogTypes.HashKey]ogTypes.Hash 64 dirtyStorage map[ogTypes.HashKey]ogTypes.Hash 65 66 trie Trie 67 db StateDBInterface 68 } 69 70 func NewStateObject(addr ogTypes.Address, db StateDBInterface) *StateObject { 71 a := AccountData{} 72 a.Address = addr 73 a.Balances = NewBalanceSet() 74 a.Nonce = 0 75 a.CodeHash = emptyCodeHash.Bytes() 76 a.Root = emptyStateRoot 77 78 s := &StateObject{} 79 s.address = addr 80 s.addressHash = ogTypes.BytesToHash32(crypto.Keccak256Hash(addr.Bytes())) 81 s.committedStorage = make(map[ogTypes.HashKey]ogTypes.Hash) 82 s.dirtyStorage = make(map[ogTypes.HashKey]ogTypes.Hash) 83 s.data = a 84 s.db = db 85 return s 86 } 87 88 func (s *StateObject) Copy(src *StateObject) { 89 s.address = src.address 90 s.addressHash = src.addressHash 91 s.data = src.data 92 } 93 94 func (s *StateObject) GetBalance(tokenID int32) *math.BigInt { 95 b := s.data.Balances[tokenID] 96 if b == nil { 97 return math.NewBigInt(0) 98 } 99 return b 100 } 101 102 func (s *StateObject) GetAllBalance() BalanceSet { 103 return s.data.Balances 104 } 105 106 func (s *StateObject) AddBalance(tokenID int32, increment *math.BigInt) { 107 // check if increment is zero 108 if increment.Sign() == 0 { 109 return 110 } 111 if s.data.Balances[tokenID] != nil { 112 s.SetBalance(tokenID, s.data.Balances[tokenID].Add(increment)) 113 } 114 } 115 116 func (s *StateObject) SubBalance(tokenID int32, decrement *math.BigInt) { 117 // check if decrement is zero 118 if decrement.Sign() == 0 { 119 return 120 } 121 if s.data.Balances[tokenID] != nil { 122 s.SetBalance(tokenID, s.data.Balances[tokenID].Sub(decrement)) 123 } 124 } 125 126 func (s *StateObject) SetBalance(tokenID int32, balance *math.BigInt) { 127 s.db.AppendJournal(&balanceChange{ 128 account: s.address, 129 tokenID: tokenID, 130 prev: s.data.Balances[tokenID], 131 }) 132 s.setBalance(tokenID, balance) 133 } 134 135 func (s *StateObject) setBalance(tokenID int32, balance *math.BigInt) { 136 s.data.Balances[tokenID] = balance 137 } 138 139 func (s *StateObject) GetNonce() uint64 { 140 return s.data.Nonce 141 } 142 143 func (s *StateObject) SetNonce(nonce uint64) { 144 s.db.AppendJournal(&nonceChange{ 145 account: s.address, 146 prev: s.data.Nonce, 147 }) 148 s.setNonce(nonce) 149 } 150 151 func (s *StateObject) setNonce(nonce uint64) { 152 s.data.Nonce = nonce 153 } 154 155 func (s *StateObject) GetState(db Database, key ogTypes.Hash) ogTypes.Hash { 156 value, ok := s.dirtyStorage[key.HashKey()] 157 if ok { 158 return value 159 } 160 return s.GetCommittedState(db, key) 161 } 162 163 func (s *StateObject) GetCommittedState(db Database, key ogTypes.Hash) ogTypes.Hash { 164 value, ok := s.committedStorage[key.HashKey()] 165 if ok { 166 return value 167 } 168 // load state from trie db. 169 b, err := s.openTrie(db).TryGet(key.Bytes()) 170 if err != nil { 171 log.Errorf("get from trie db error: %v, key: %x", err, key.Bytes()) 172 s.setError(err) 173 } 174 175 value = ogTypes.BytesToHash32(b) 176 s.committedStorage[key.HashKey()] = value 177 178 return value 179 } 180 181 func (s *StateObject) SetState(db Database, key, value ogTypes.Hash) { 182 s.db.AppendJournal(&storageChange{ 183 account: s.address, 184 key: key, 185 prevalue: s.GetState(db, key), 186 }) 187 s.setState(key, value) 188 } 189 190 func (s *StateObject) setState(key, value ogTypes.Hash) { 191 s.dirtyStorage[key.HashKey()] = value 192 } 193 194 func (s *StateObject) GetCode(db Database) []byte { 195 if s.code != nil { 196 return s.code 197 } 198 if bytes.Equal(s.GetCodeHash().Bytes(), emptyCodeHash.Bytes()) { 199 return nil 200 } 201 code, err := db.ContractCode(s.addressHash, s.GetCodeHash()) 202 if err != nil { 203 s.setError(fmt.Errorf("load code from db error: %v", err)) 204 } 205 s.code = code 206 return s.code 207 } 208 209 func (s *StateObject) SetCode(codehash ogTypes.Hash, code []byte) { 210 s.db.AppendJournal(&codeChange{ 211 account: s.address, 212 prevcode: s.code, 213 prevhash: s.data.CodeHash, 214 }) 215 s.setCode(codehash, code) 216 } 217 218 func (s *StateObject) setCode(codehash ogTypes.Hash, code []byte) { 219 s.code = code 220 s.data.CodeHash = codehash.Bytes() 221 s.dirtycode = true 222 } 223 224 func (s *StateObject) GetCodeHash() ogTypes.Hash { 225 return ogTypes.BytesToHash32(s.data.CodeHash) 226 } 227 228 func (s *StateObject) GetCodeSize(db Database) (int, error) { 229 if s.code != nil { 230 return len(s.code), nil 231 } 232 return db.ContractCodeSize(s.addressHash, ogTypes.BytesToHash32(s.data.CodeHash)) 233 } 234 235 func (s *StateObject) openTrie(db Database) Trie { 236 if s.trie != nil { 237 return s.trie 238 } 239 t, err := db.OpenStorageTrie(s.addressHash, s.data.Root) 240 if err != nil { 241 t, _ = db.OpenStorageTrie(s.addressHash, ogTypes.BytesToHash32([]byte{})) 242 } 243 s.trie = t 244 return s.trie 245 } 246 247 func (s *StateObject) updateTrie(db Database) { 248 var err error 249 t := s.openTrie(db) 250 for key, value := range s.dirtyStorage { 251 if len(value.Bytes()) == 0 { 252 err = t.TryDelete(key.Bytes()) 253 if err != nil { 254 s.setError(err) 255 continue 256 } 257 delete(s.committedStorage, key) 258 continue 259 } 260 //log.Tracef("Panic debug, StateObject updateTrie, key: %x, value: %x", key.ToBytes(), value.ToBytes()) 261 err = t.TryUpdate(key.Bytes(), value.Bytes()) 262 if err != nil { 263 s.setError(err) 264 } 265 s.committedStorage[key] = value 266 delete(s.dirtyStorage, key) 267 } 268 } 269 270 func (s *StateObject) CommitStorage(db Database, preCommit bool) error { 271 s.updateTrie(db) 272 if s.dbErr != nil { 273 return s.dbErr 274 } 275 root, err := s.trie.Commit(nil, preCommit) 276 if err != nil { 277 return err 278 } 279 s.data.Root = root 280 return nil 281 } 282 283 // Uncache clears dirtyStorage and committedStorage. This is aimed 284 // to check if state is committed into db. 285 // 286 // Note that this function is for test debug only, should not 287 // be called by other functions. 288 func (s *StateObject) Uncache() { 289 s.committedStorage = make(map[ogTypes.HashKey]ogTypes.Hash) 290 s.dirtyStorage = make(map[ogTypes.HashKey]ogTypes.Hash) 291 } 292 293 /* 294 Encode part 295 */ 296 297 func (s *StateObject) Map() map[string]interface{} { 298 stobjMap := map[string]interface{}{} 299 300 stobjMap["code"] = hex.EncodeToString(s.code) 301 stobjMap["committed"] = s.committedStorage 302 stobjMap["dirty"] = s.dirtyStorage 303 stobjMap["data"] = s.data 304 305 return stobjMap 306 } 307 308 func (s *StateObject) String() string { 309 stobjMap := s.Map() 310 b, _ := json.Marshal(stobjMap) 311 return string(b) 312 } 313 314 /** 315 marshalling part 316 */ 317 318 func (s *StateObject) Encode() ([]byte, error) { 319 return s.data.MarshalMsg() 320 } 321 322 func (s *StateObject) Decode(b []byte, db *StateDB) error { 323 a := NewAccountData() 324 _, err := a.UnmarshalMsg(b) 325 326 s.data = a 327 s.address = a.Address 328 s.addressHash = ogTypes.BytesToHash32(crypto.Keccak256Hash(a.Address.Bytes())) 329 s.committedStorage = make(map[ogTypes.HashKey]ogTypes.Hash) 330 s.dirtyStorage = make(map[ogTypes.HashKey]ogTypes.Hash) 331 s.db = db 332 return err 333 } 334 335 func (a *AccountData) MarshalMsg() (b []byte, err error) { 336 b = make([]byte, marshaller.HeaderSize) 337 338 // (Address) Address 339 addrB, err := a.Address.MarshalMsg() 340 if err != nil { 341 return b, err 342 } 343 b = append(b, addrB...) 344 345 // (BalanceSet) Balances 346 blcB, err := a.Balances.MarshalMsg() 347 if err != nil { 348 return b, err 349 } 350 b = append(b, blcB...) 351 352 // (uint64) Nonce 353 b = marshaller.AppendUint64(b, a.Nonce) 354 355 // (Hash) Root 356 hashB, err := a.Root.MarshalMsg() 357 if err != nil { 358 return b, err 359 } 360 b = append(b, hashB...) 361 362 // ([]byte) CodeHash 363 b = marshaller.AppendBytes(b, a.CodeHash) 364 365 // Fill header 366 b = marshaller.FillHeaderData(b) 367 368 return b, nil 369 } 370 371 func (a *AccountData) UnmarshalMsg(b []byte) ([]byte, error) { 372 b, _, err := marshaller.DecodeHeader(b) 373 if err != nil { 374 return b, err 375 } 376 377 // Address 378 a.Address, b, err = ogTypes.UnmarshalAddress(b) 379 if err != nil { 380 return b, err 381 } 382 383 // BalanceSet 384 bs := &BalanceSet{} 385 b, err = bs.UnmarshalMsg(b) 386 if err != nil { 387 return b, err 388 } 389 a.Balances = *bs 390 391 // Nonce 392 a.Nonce, b, err = marshaller.ReadUint64(b) 393 if err != nil { 394 return b, err 395 } 396 397 // Hash Root 398 a.Root, b, err = ogTypes.UnmarshalHash(b) 399 if err != nil { 400 return b, err 401 } 402 403 // ([]byte) CodeHash 404 a.CodeHash, b, err = marshaller.ReadBytes(b) 405 if err != nil { 406 return b, err 407 } 408 409 return b, nil 410 } 411 412 func (a *AccountData) MsgSize() int { 413 // Address + Balances + Root + CodeHash 414 size := marshaller.CalIMarshallerSize(a.Address.MsgSize()) + 415 marshaller.CalIMarshallerSize(a.Balances.MsgSize()) + 416 marshaller.CalIMarshallerSize(a.Root.MsgSize()) + 417 marshaller.CalIMarshallerSize(len(a.CodeHash)) 418 // Nonce 419 size += marshaller.Uint64Size 420 421 return size 422 } 423 424 /** 425 BalanceSet 426 */ 427 428 type BalanceSet map[int32]*math.BigInt 429 430 func NewBalanceSet() BalanceSet { 431 return make(map[int32]*math.BigInt) 432 } 433 434 func (bs *BalanceSet) PreAdd(tokenID int32, increment *math.BigInt) *math.BigInt { 435 bi := (*bs)[tokenID] 436 if bi == nil { 437 bi = math.NewBigInt(0) 438 } 439 return bi.Add(increment) 440 } 441 442 func (bs *BalanceSet) PreSub(tokenID int32, decrement *math.BigInt) *math.BigInt { 443 bi := (*bs)[tokenID] 444 if bi == nil { 445 return math.NewBigInt(0) 446 } 447 return bi.Sub(decrement) 448 } 449 450 func (bs *BalanceSet) Copy() BalanceSet { 451 b := NewBalanceSet() 452 for k, v := range *bs { 453 b[k] = v 454 } 455 return b 456 } 457 458 func (bs *BalanceSet) IsEmpty() bool { 459 for _, v := range *bs { 460 if v.GetInt64() != int64(0) { 461 return false 462 } 463 } 464 return true 465 } 466 467 /** 468 marshaller part 469 */ 470 471 func (bs *BalanceSet) MarshalMsg() (b []byte, err error) { 472 b = make([]byte, marshaller.HeaderSize) 473 474 for k, v := range *bs { 475 // marshal key 476 b = marshaller.AppendInt32(b, k) 477 // marshal value 478 b = marshaller.AppendBigInt(b, v.Value) 479 } 480 481 b = marshaller.FillHeaderDataNum(b, len(*bs)) 482 483 return b, nil 484 } 485 486 func (bs *BalanceSet) UnmarshalMsg(bts []byte) (b []byte, err error) { 487 488 b, mapSize, err := marshaller.DecodeHeader(bts) 489 if err != nil { 490 return nil, err 491 } 492 493 bsRaw := BalanceSet(make(map[int32]*math.BigInt)) 494 var k int32 495 var v *big.Int 496 for i := 0; i < mapSize; i++ { 497 k, b, err = marshaller.ReadInt32(b) 498 if err != nil { 499 return nil, err 500 } 501 v, b, err = marshaller.ReadBigInt(b) 502 if err != nil { 503 return nil, err 504 } 505 506 bsRaw[k] = math.NewBigIntFromBigInt(v) 507 } 508 509 bs = &bsRaw 510 511 return b, nil 512 } 513 514 func (bs *BalanceSet) MsgSize() int { 515 sz := 0 516 for _, v := range *bs { 517 sz += marshaller.Int32Size + marshaller.CalBigIntSize(v.Value) 518 } 519 520 return sz 521 } 522 523 /* 524 components 525 */ 526 527 func (s *StateObject) setError(err error) { 528 if s.dbErr == nil { 529 s.dbErr = err 530 } 531 }