github.com/igggame/nebulas-go@v2.1.0+incompatible/core/state/world_state.go (about)

     1  // Copyright (C) 2017 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU 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-nebulas 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 General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  package state
    20  
    21  import (
    22  	"encoding/json"
    23  
    24  	"github.com/nebulasio/go-nebulas/consensus/pb"
    25  	"github.com/nebulasio/go-nebulas/core/pb"
    26  	"github.com/nebulasio/go-nebulas/util"
    27  
    28  	"github.com/nebulasio/go-nebulas/common/mvccdb"
    29  	"github.com/nebulasio/go-nebulas/common/trie"
    30  	"github.com/nebulasio/go-nebulas/storage"
    31  	"github.com/nebulasio/go-nebulas/util/byteutils"
    32  )
    33  
    34  func newChangeLog() (*mvccdb.MVCCDB, error) {
    35  	mem, err := storage.NewMemoryStorage()
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	db, err := mvccdb.NewMVCCDB(mem, false)
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  
    44  	db.SetStrictGlobalVersionCheck(true)
    45  	return db, nil
    46  }
    47  
    48  func newStateDB(storage storage.Storage) (*mvccdb.MVCCDB, error) {
    49  	return mvccdb.NewMVCCDB(storage, true)
    50  }
    51  
    52  type states struct {
    53  	accState       AccountState
    54  	txsState       *trie.Trie
    55  	eventsState    *trie.Trie
    56  	consensusState ConsensusState
    57  
    58  	consensus Consensus
    59  	changelog *mvccdb.MVCCDB
    60  	stateDB   *mvccdb.MVCCDB
    61  	innerDB   storage.Storage
    62  	txid      interface{}
    63  
    64  	gasConsumed map[string]*util.Uint128
    65  	events      map[string][]*Event
    66  }
    67  
    68  func newStates(consensus Consensus, stor storage.Storage) (*states, error) {
    69  	changelog, err := newChangeLog()
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	stateDB, err := newStateDB(stor)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	accState, err := NewAccountState(nil, stateDB)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  	txsState, err := trie.NewTrie(nil, stateDB, false)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	eventsState, err := trie.NewTrie(nil, stateDB, false)
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  	consensusState, err := consensus.NewState(&consensuspb.ConsensusRoot{}, stateDB, false)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	return &states{
    96  		accState:       accState,
    97  		txsState:       txsState,
    98  		eventsState:    eventsState,
    99  		consensusState: consensusState,
   100  
   101  		consensus: consensus,
   102  		changelog: changelog,
   103  		stateDB:   stateDB,
   104  		innerDB:   stor,
   105  		txid:      nil,
   106  
   107  		gasConsumed: make(map[string]*util.Uint128),
   108  		events:      make(map[string][]*Event),
   109  	}, nil
   110  }
   111  
   112  func (s *states) Replay(done *states) error {
   113  	err := s.accState.Replay(done.accState)
   114  	if err != nil {
   115  		return err
   116  	}
   117  	_, err = s.txsState.Replay(done.txsState)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	err = s.ReplayEvent(done)
   122  	if err != nil {
   123  		return err
   124  	}
   125  	err = s.consensusState.Replay(done.consensusState)
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	// replay gasconsumed
   131  	for from, gas := range done.gasConsumed {
   132  		consumed, ok := s.gasConsumed[from]
   133  		if !ok {
   134  			consumed = util.NewUint128()
   135  		}
   136  		consumed, err := consumed.Add(gas)
   137  		if err != nil {
   138  			return err
   139  		}
   140  		s.gasConsumed[from] = consumed
   141  	}
   142  	return nil
   143  }
   144  
   145  func (s *states) ReplayEvent(done *states) error {
   146  
   147  	tx := done.txid.(string)
   148  	events, ok := done.events[tx]
   149  	if !ok {
   150  		return nil
   151  	}
   152  
   153  	//replay event
   154  	txHash, err := byteutils.FromHex(tx)
   155  	if err != nil {
   156  		return err
   157  	}
   158  	for idx, event := range events {
   159  		cnt := int64(idx + 1)
   160  
   161  		key := append(txHash, byteutils.FromInt64(cnt)...)
   162  		bytes, err := json.Marshal(event)
   163  		if err != nil {
   164  			return err
   165  		}
   166  
   167  		_, err = s.eventsState.Put(key, bytes)
   168  		if err != nil {
   169  			return err
   170  		}
   171  	}
   172  	done.events = make(map[string][]*Event)
   173  	return nil
   174  }
   175  
   176  func (s *states) Clone() (*states, error) {
   177  	changelog, err := newChangeLog()
   178  	if err != nil {
   179  		return nil, err
   180  	}
   181  	stateDB, err := newStateDB(s.innerDB)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  
   186  	accState, err := NewAccountState(s.accState.RootHash(), stateDB)
   187  	if err != nil {
   188  		return nil, err
   189  	}
   190  	txsState, err := trie.NewTrie(s.txsState.RootHash(), stateDB, false)
   191  	if err != nil {
   192  		return nil, err
   193  	}
   194  	eventsState, err := trie.NewTrie(s.eventsState.RootHash(), stateDB, false)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  	consensusState, err := s.consensus.NewState(s.consensusState.RootHash(), stateDB, false)
   199  	if err != nil {
   200  		return nil, err
   201  	}
   202  
   203  	return &states{
   204  		accState:       accState,
   205  		txsState:       txsState,
   206  		eventsState:    eventsState,
   207  		consensusState: consensusState,
   208  
   209  		consensus: s.consensus,
   210  		changelog: changelog,
   211  		stateDB:   stateDB,
   212  		innerDB:   s.innerDB,
   213  		txid:      s.txid,
   214  
   215  		gasConsumed: make(map[string]*util.Uint128),
   216  		events:      make(map[string][]*Event),
   217  	}, nil
   218  }
   219  
   220  func (s *states) Begin() error {
   221  	if err := s.changelog.Begin(); err != nil {
   222  		return err
   223  	}
   224  	if err := s.stateDB.Begin(); err != nil {
   225  		return err
   226  	}
   227  	return nil
   228  }
   229  
   230  func (s *states) Commit() error {
   231  	if err := s.Flush(); err != nil {
   232  		return err
   233  	}
   234  	// changelog is used to check conflict temporarily
   235  	// we should rollback it when the transaction is over
   236  	if err := s.changelog.RollBack(); err != nil {
   237  		return err
   238  	}
   239  	if err := s.stateDB.Commit(); err != nil {
   240  		return err
   241  	}
   242  
   243  	s.events = make(map[string][]*Event)
   244  	s.gasConsumed = make(map[string]*util.Uint128)
   245  	return nil
   246  }
   247  
   248  func (s *states) RollBack() error {
   249  	if err := s.Abort(); err != nil {
   250  		return err
   251  	}
   252  	if err := s.changelog.RollBack(); err != nil {
   253  		return err
   254  	}
   255  	if err := s.stateDB.RollBack(); err != nil {
   256  		return err
   257  	}
   258  
   259  	s.events = make(map[string][]*Event)
   260  	s.gasConsumed = make(map[string]*util.Uint128)
   261  	return nil
   262  }
   263  
   264  func (s *states) Prepare(txid interface{}) (*states, error) {
   265  	changelog, err := s.changelog.Prepare(txid)
   266  	if err != nil {
   267  		return nil, err
   268  	}
   269  	stateDB, err := s.stateDB.Prepare(txid)
   270  	if err != nil {
   271  		return nil, err
   272  	}
   273  
   274  	// Flush all changes in world state into merkle trie
   275  	// make a snapshot of world state
   276  	if err := s.Flush(); err != nil {
   277  		return nil, err
   278  	}
   279  
   280  	accState, err := NewAccountState(s.AccountsRoot(), stateDB)
   281  	if err != nil {
   282  		return nil, err
   283  	}
   284  	txsState, err := trie.NewTrie(s.TxsRoot(), stateDB, true)
   285  	if err != nil {
   286  		return nil, err
   287  	}
   288  	eventsState, err := trie.NewTrie(s.EventsRoot(), stateDB, true)
   289  	if err != nil {
   290  		return nil, err
   291  	}
   292  	consensusState, err := s.consensus.NewState(s.ConsensusRoot(), stateDB, true)
   293  	if err != nil {
   294  		return nil, err
   295  	}
   296  
   297  	return &states{
   298  		accState:       accState,
   299  		txsState:       txsState,
   300  		eventsState:    eventsState,
   301  		consensusState: consensusState,
   302  
   303  		consensus: s.consensus,
   304  		changelog: changelog,
   305  		stateDB:   stateDB,
   306  		innerDB:   s.innerDB,
   307  		txid:      txid,
   308  
   309  		gasConsumed: make(map[string]*util.Uint128),
   310  		events:      make(map[string][]*Event),
   311  	}, nil
   312  }
   313  
   314  func (s *states) CheckAndUpdateTo(parent *states) ([]interface{}, error) {
   315  	dependency, err := s.changelog.CheckAndUpdate()
   316  	if err != nil {
   317  		return nil, err
   318  	}
   319  	_, err = s.stateDB.CheckAndUpdate()
   320  	if err != nil {
   321  		return nil, err
   322  	}
   323  	if err := parent.Replay(s); err != nil {
   324  		return nil, err
   325  	}
   326  	return dependency, nil
   327  }
   328  
   329  func (s *states) Reset(addr byteutils.Hash, isResetChangeLog bool) error {
   330  
   331  	if err := s.stateDB.Reset(); err != nil {
   332  		return err
   333  	}
   334  	if err := s.Abort(); err != nil {
   335  		return err
   336  	}
   337  
   338  	if isResetChangeLog {
   339  		if err := s.changelog.Reset(); err != nil {
   340  			return err
   341  		}
   342  		if addr != nil {
   343  			// record dependency
   344  			if err := s.changelog.Put(addr, addr); err != nil {
   345  				return err
   346  			}
   347  		}
   348  	}
   349  	return nil
   350  }
   351  
   352  func (s *states) Close() error {
   353  	if err := s.changelog.Close(); err != nil {
   354  		return err
   355  	}
   356  	if err := s.stateDB.Close(); err != nil {
   357  		return err
   358  	}
   359  	if err := s.Abort(); err != nil {
   360  		return err
   361  	}
   362  	return nil
   363  }
   364  
   365  func (s *states) AccountsRoot() byteutils.Hash {
   366  	return s.accState.RootHash()
   367  }
   368  
   369  func (s *states) TxsRoot() byteutils.Hash {
   370  	return s.txsState.RootHash()
   371  }
   372  
   373  func (s *states) EventsRoot() byteutils.Hash {
   374  	return s.eventsState.RootHash()
   375  }
   376  
   377  func (s *states) ConsensusRoot() *consensuspb.ConsensusRoot {
   378  	return s.consensusState.RootHash()
   379  }
   380  
   381  func (s *states) Flush() error {
   382  	return s.accState.Flush()
   383  }
   384  
   385  func (s *states) Abort() error {
   386  	// TODO: Abort txsState, eventsState, consensusState
   387  	// we don't need to abort the three states now
   388  	// because we only use abort in reset, close and rollback
   389  	// in close & rollback, we won't use states any more
   390  	// in reset, we won't change the three states before we reset them
   391  	return s.accState.Abort()
   392  }
   393  
   394  func (s *states) recordAccount(acc Account) (Account, error) {
   395  	if err := s.changelog.Put(acc.Address(), acc.Address()); err != nil {
   396  		return nil, err
   397  	}
   398  	return acc, nil
   399  }
   400  
   401  func (s *states) GetOrCreateUserAccount(addr byteutils.Hash) (Account, error) {
   402  	acc, err := s.accState.GetOrCreateUserAccount(addr)
   403  	if err != nil {
   404  		return nil, err
   405  	}
   406  	return s.recordAccount(acc)
   407  }
   408  
   409  func (s *states) GetContractAccount(addr byteutils.Hash) (Account, error) {
   410  	acc, err := s.accState.GetContractAccount(addr)
   411  	if err != nil {
   412  		return nil, err
   413  	}
   414  	if len(acc.BirthPlace()) == 0 {
   415  		return nil, ErrContractCheckFailed
   416  	}
   417  	return s.recordAccount(acc)
   418  }
   419  
   420  func (s *states) CreateContractAccount(owner byteutils.Hash, birthPlace byteutils.Hash, contractMeta *corepb.ContractMeta) (Account, error) {
   421  	acc, err := s.accState.CreateContractAccount(owner, birthPlace, contractMeta)
   422  	if err != nil {
   423  		return nil, err
   424  	}
   425  	return s.recordAccount(acc)
   426  }
   427  
   428  func (s *states) GetTx(txHash byteutils.Hash) ([]byte, error) {
   429  	bytes, err := s.txsState.Get(txHash)
   430  	if err != nil {
   431  		return nil, err
   432  	}
   433  	return bytes, nil
   434  }
   435  
   436  func (s *states) PutTx(txHash byteutils.Hash, txBytes []byte) error {
   437  	_, err := s.txsState.Put(txHash, txBytes)
   438  	if err != nil {
   439  		return err
   440  	}
   441  	return nil
   442  }
   443  
   444  func (s *states) RecordEvent(txHash byteutils.Hash, event *Event) {
   445  	events, ok := s.events[txHash.String()]
   446  	if !ok {
   447  		events = make([]*Event, 0)
   448  	}
   449  	s.events[txHash.String()] = append(events, event)
   450  }
   451  
   452  func (s *states) FetchEvents(txHash byteutils.Hash) ([]*Event, error) {
   453  	events := []*Event{}
   454  	iter, err := s.eventsState.Iterator(txHash)
   455  	if err != nil && err != storage.ErrKeyNotFound {
   456  		return nil, err
   457  	}
   458  	if err == nil {
   459  		exist, err := iter.Next()
   460  		if err != nil {
   461  			return nil, err
   462  		}
   463  		for exist {
   464  			event := new(Event)
   465  			err = json.Unmarshal(iter.Value(), event)
   466  			if err != nil {
   467  				return nil, err
   468  			}
   469  			events = append(events, event)
   470  			exist, err = iter.Next()
   471  			if err != nil {
   472  				return nil, err
   473  			}
   474  		}
   475  	}
   476  	return events, nil
   477  }
   478  
   479  func (s *states) Dynasty() ([]byteutils.Hash, error) {
   480  	return s.consensusState.Dynasty()
   481  }
   482  
   483  func (s *states) DynastyRoot() byteutils.Hash {
   484  	return s.consensusState.DynastyRoot()
   485  }
   486  
   487  func (s *states) Accounts() ([]Account, error) { // TODO delete
   488  	return s.accState.Accounts()
   489  }
   490  
   491  func (s *states) LoadAccountsRoot(root byteutils.Hash) error {
   492  	accState, err := NewAccountState(root, s.stateDB)
   493  	if err != nil {
   494  		return err
   495  	}
   496  	s.accState = accState
   497  	return nil
   498  }
   499  
   500  func (s *states) LoadTxsRoot(root byteutils.Hash) error {
   501  	txsState, err := trie.NewTrie(root, s.stateDB, false)
   502  	if err != nil {
   503  		return err
   504  	}
   505  	s.txsState = txsState
   506  	return nil
   507  }
   508  
   509  func (s *states) LoadEventsRoot(root byteutils.Hash) error {
   510  	eventsState, err := trie.NewTrie(root, s.stateDB, false)
   511  	if err != nil {
   512  		return err
   513  	}
   514  	s.eventsState = eventsState
   515  	return nil
   516  }
   517  
   518  func (s *states) LoadConsensusRoot(root *consensuspb.ConsensusRoot) error {
   519  	consensusState, err := s.consensus.NewState(root, s.stateDB, false)
   520  	if err != nil {
   521  		return err
   522  	}
   523  	s.consensusState = consensusState
   524  	return nil
   525  }
   526  
   527  func (s *states) RecordGas(from string, gas *util.Uint128) error {
   528  	consumed, ok := s.gasConsumed[from]
   529  	if !ok {
   530  		consumed = util.NewUint128()
   531  	}
   532  	consumed, err := consumed.Add(gas)
   533  	if err != nil {
   534  		return err
   535  	}
   536  	s.gasConsumed[from] = consumed
   537  	return nil
   538  }
   539  
   540  func (s *states) GetGas() map[string]*util.Uint128 {
   541  	gasConsumed := make(map[string]*util.Uint128)
   542  	for from, gas := range s.gasConsumed {
   543  		gasConsumed[from] = gas
   544  	}
   545  	s.gasConsumed = make(map[string]*util.Uint128)
   546  	return gasConsumed
   547  }
   548  
   549  func (s *states) GetBlockHashByHeight(height uint64) ([]byte, error) {
   550  	bytes, err := s.innerDB.Get(byteutils.FromUint64(height))
   551  	if err != nil {
   552  		return nil, err
   553  	}
   554  	return bytes, nil
   555  }
   556  
   557  func (s *states) GetBlock(hash byteutils.Hash) ([]byte, error) {
   558  	bytes, err := s.innerDB.Get(hash)
   559  	if err != nil {
   560  		return nil, err
   561  	}
   562  	return bytes, nil
   563  }
   564  
   565  // WorldState manange all current states in Blockchain
   566  type worldState struct {
   567  	*states
   568  	snapshot *states
   569  }
   570  
   571  // NewWorldState create a new empty WorldState
   572  func NewWorldState(consensus Consensus, storage storage.Storage) (WorldState, error) {
   573  	states, err := newStates(consensus, storage)
   574  	if err != nil {
   575  		return nil, err
   576  	}
   577  	return &worldState{
   578  		states:   states,
   579  		snapshot: nil,
   580  	}, nil
   581  }
   582  
   583  // Clone a new WorldState
   584  func (ws *worldState) Clone() (WorldState, error) {
   585  	s, err := ws.states.Clone()
   586  	if err != nil {
   587  		return nil, err
   588  	}
   589  	return &worldState{
   590  		states:   s,
   591  		snapshot: nil,
   592  	}, nil
   593  }
   594  
   595  func (ws *worldState) Begin() error {
   596  	snapshot, err := ws.states.Clone()
   597  	if err != nil {
   598  		return err
   599  	}
   600  	if err := ws.states.Begin(); err != nil {
   601  		return err
   602  	}
   603  	ws.snapshot = snapshot
   604  	return nil
   605  }
   606  
   607  func (ws *worldState) Commit() error {
   608  	if err := ws.states.Commit(); err != nil {
   609  		return err
   610  	}
   611  	ws.snapshot = nil
   612  	return nil
   613  }
   614  
   615  func (ws *worldState) RollBack() error {
   616  	if err := ws.states.RollBack(); err != nil {
   617  		return err
   618  	}
   619  	ws.states = ws.snapshot
   620  	ws.snapshot = nil
   621  	return nil
   622  }
   623  
   624  func (ws *worldState) Prepare(txid interface{}) (TxWorldState, error) {
   625  	s, err := ws.states.Prepare(txid)
   626  	if err != nil {
   627  		return nil, err
   628  	}
   629  	txState := &txWorldState{
   630  		states: s,
   631  		txid:   txid,
   632  		parent: ws,
   633  	}
   634  	return txState, nil
   635  }
   636  
   637  func (ws *worldState) NextConsensusState(elapsedSecond int64) (ConsensusState, error) {
   638  	return ws.states.consensusState.NextConsensusState(elapsedSecond, ws)
   639  }
   640  
   641  func (ws *worldState) SetConsensusState(consensusState ConsensusState) {
   642  	ws.states.consensusState = consensusState
   643  }
   644  
   645  type txWorldState struct {
   646  	*states
   647  	txid   interface{}
   648  	parent *worldState
   649  }
   650  
   651  func (tws *txWorldState) CheckAndUpdate() ([]interface{}, error) {
   652  	dependencies, err := tws.states.CheckAndUpdateTo(tws.parent.states)
   653  	if err != nil {
   654  		return nil, err
   655  	}
   656  	tws.parent = nil
   657  	return dependencies, nil
   658  }
   659  
   660  func (tws *txWorldState) Reset(addr byteutils.Hash, isResetChangeLog bool) error {
   661  	if err := tws.states.Reset(addr, isResetChangeLog); err != nil {
   662  		return err
   663  	}
   664  	return nil
   665  }
   666  
   667  func (tws *txWorldState) Close() error {
   668  	if err := tws.states.Close(); err != nil {
   669  		return err
   670  	}
   671  	tws.parent = nil
   672  	return nil
   673  }
   674  
   675  func (tws *txWorldState) TxID() interface{} {
   676  	return tws.txid
   677  }