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  }