github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/core/state/statedb.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 provides a caching layer atop the Ethereum state trie.
    18  package state
    19  
    20  import (
    21  	"bytes"
    22  	"compress/gzip"
    23  	"encoding/binary"
    24  	"fmt"
    25  	"io"
    26  	"math/big"
    27  	"sort"
    28  	"sync"
    29  
    30  	"github.com/FusionFoundation/efsn/common"
    31  	"github.com/FusionFoundation/efsn/core/types"
    32  	"github.com/FusionFoundation/efsn/crypto"
    33  	"github.com/FusionFoundation/efsn/log"
    34  	"github.com/FusionFoundation/efsn/rlp"
    35  	"github.com/FusionFoundation/efsn/trie"
    36  )
    37  
    38  type revision struct {
    39  	id           int
    40  	journalIndex int
    41  }
    42  
    43  var (
    44  	// emptyState is the known hash of an empty state trie entry.
    45  	emptyState = crypto.Keccak256Hash(nil)
    46  
    47  	// emptyCode is the known hash of the empty EVM bytecode.
    48  	emptyCode = crypto.Keccak256Hash(nil)
    49  )
    50  
    51  // StateDBs within the ethereum protocol are used to store anything
    52  // within the merkle trie. StateDBs take care of caching and storing
    53  // nested states. It's the general query interface to retrieve:
    54  // * Contracts
    55  // * Accounts
    56  type StateDB struct {
    57  	db   Database
    58  	trie Trie
    59  
    60  	// This map holds 'live' objects, which will get modified while processing a state transition.
    61  	stateObjects      map[common.Address]*stateObject
    62  	stateObjectsDirty map[common.Address]struct{}
    63  
    64  	// DB error.
    65  	// State objects are used by the consensus core and VM which are
    66  	// unable to deal with database-level errors. Any error that occurs
    67  	// during a database read is memoized here and will eventually be returned
    68  	// by StateDB.Commit.
    69  	dbErr error
    70  
    71  	// The refund counter, also used by state transitioning.
    72  	refund uint64
    73  
    74  	thash, bhash common.Hash
    75  	txIndex      int
    76  	logs         map[common.Hash][]*types.Log
    77  	logSize      uint
    78  
    79  	preimages map[common.Hash][]byte
    80  
    81  	// Journal of state modifications. This is the backbone of
    82  	// Snapshot and RevertToSnapshot.
    83  	journal        *journal
    84  	validRevisions []revision
    85  	nextRevisionId int
    86  
    87  	ticketsHash common.Hash
    88  	tickets     common.TicketsDataSlice
    89  
    90  	lock   sync.Mutex
    91  	rwlock sync.RWMutex
    92  }
    93  
    94  type CachedTickets struct {
    95  	hash    common.Hash
    96  	tickets common.TicketsDataSlice
    97  }
    98  
    99  const maxCachedTicketsCount = 101
   100  
   101  type CachedTicketSlice struct {
   102  	tickets [maxCachedTicketsCount]CachedTickets
   103  	start   int64
   104  	end     int64
   105  	rwlock  sync.RWMutex
   106  }
   107  
   108  var cachedTicketSlice = CachedTicketSlice{
   109  	tickets: [maxCachedTicketsCount]CachedTickets{},
   110  	start:   0,
   111  	end:     0,
   112  }
   113  
   114  func (cts *CachedTicketSlice) Add(hash common.Hash, tickets common.TicketsDataSlice) {
   115  	if cts.Get(hash) != nil {
   116  		return
   117  	}
   118  
   119  	elem := CachedTickets{
   120  		hash:    hash,
   121  		tickets: tickets.DeepCopy(),
   122  	}
   123  
   124  	cts.rwlock.Lock()
   125  	defer cts.rwlock.Unlock()
   126  
   127  	cts.tickets[cts.end] = elem
   128  	cts.end = (cts.end + 1) % maxCachedTicketsCount
   129  	if cts.end == cts.start {
   130  		cts.start = (cts.start + 1) % maxCachedTicketsCount
   131  	}
   132  }
   133  
   134  func (cts *CachedTicketSlice) Get(hash common.Hash) common.TicketsDataSlice {
   135  	if hash == (common.Hash{}) {
   136  		return common.TicketsDataSlice{}
   137  	}
   138  
   139  	cts.rwlock.RLock()
   140  	defer cts.rwlock.RUnlock()
   141  
   142  	for i := cts.start; i != cts.end; i = (i + 1) % maxCachedTicketsCount {
   143  		v := cts.tickets[i]
   144  		if v.hash == hash {
   145  			return v.tickets
   146  		}
   147  	}
   148  	return nil
   149  }
   150  
   151  func GetCachedTickets(hash common.Hash) common.TicketsDataSlice {
   152  	return cachedTicketSlice.Get(hash)
   153  }
   154  
   155  func calcTicketsStorageData(tickets common.TicketsDataSlice) ([]byte, error) {
   156  	blob, err := rlp.EncodeToBytes(&tickets)
   157  	if err != nil {
   158  		return nil, fmt.Errorf("Unable to encode tickets. err: %v", err)
   159  	}
   160  
   161  	var buf bytes.Buffer
   162  	zw := gzip.NewWriter(&buf)
   163  	if _, err := zw.Write(blob); err != nil {
   164  		return nil, fmt.Errorf("Unable to zip tickets data")
   165  	}
   166  	if err := zw.Close(); err != nil {
   167  		return nil, fmt.Errorf("Unable to zip tickets")
   168  	}
   169  	data := buf.Bytes()
   170  	return data, nil
   171  }
   172  
   173  func AddCachedTickets(hash common.Hash, tickets common.TicketsDataSlice) error {
   174  	data, err := calcTicketsStorageData(tickets)
   175  	if err != nil {
   176  		return fmt.Errorf("AddCachedTickets: %v", err)
   177  	}
   178  	if hash != crypto.Keccak256Hash(data) {
   179  		return fmt.Errorf("AddCachedTickets: hash mismatch")
   180  	}
   181  	cachedTicketSlice.Add(hash, tickets)
   182  	return nil
   183  }
   184  
   185  // Create a new state from a given trie.
   186  func New(root common.Hash, mixDigest common.Hash, db Database) (*StateDB, error) {
   187  	tr, err := db.OpenTrie(root)
   188  	if err != nil {
   189  		return nil, err
   190  	}
   191  	statedb := &StateDB{
   192  		db:                db,
   193  		trie:              tr,
   194  		stateObjects:      make(map[common.Address]*stateObject),
   195  		stateObjectsDirty: make(map[common.Address]struct{}),
   196  		logs:              make(map[common.Hash][]*types.Log),
   197  		preimages:         make(map[common.Hash][]byte),
   198  		journal:           newJournal(),
   199  		ticketsHash:       mixDigest,
   200  		tickets:           nil,
   201  	}
   202  	return statedb, nil
   203  }
   204  
   205  // setError remembers the first non-nil error it is called with.
   206  func (self *StateDB) setError(err error) {
   207  	if self.dbErr == nil {
   208  		self.dbErr = err
   209  	}
   210  }
   211  
   212  func (self *StateDB) Error() error {
   213  	return self.dbErr
   214  }
   215  
   216  // Reset clears out all ephemeral state objects from the state db, but keeps
   217  // the underlying state trie to avoid reloading data for the next operations.
   218  func (self *StateDB) Reset(root common.Hash) error {
   219  	tr, err := self.db.OpenTrie(root)
   220  	if err != nil {
   221  		return err
   222  	}
   223  	self.trie = tr
   224  	self.stateObjects = make(map[common.Address]*stateObject)
   225  	self.stateObjectsDirty = make(map[common.Address]struct{})
   226  	self.thash = common.Hash{}
   227  	self.bhash = common.Hash{}
   228  	self.txIndex = 0
   229  	self.logs = make(map[common.Hash][]*types.Log)
   230  	self.logSize = 0
   231  	self.preimages = make(map[common.Hash][]byte)
   232  	self.clearJournalAndRefund()
   233  	self.tickets = nil
   234  	return nil
   235  }
   236  
   237  func (self *StateDB) AddLog(log *types.Log) {
   238  	self.journal.append(addLogChange{txhash: self.thash})
   239  
   240  	log.TxHash = self.thash
   241  	log.BlockHash = self.bhash
   242  	log.TxIndex = uint(self.txIndex)
   243  	log.Index = self.logSize
   244  	self.logs[self.thash] = append(self.logs[self.thash], log)
   245  	self.logSize++
   246  }
   247  
   248  func (self *StateDB) GetLogs(hash common.Hash) []*types.Log {
   249  	return self.logs[hash]
   250  }
   251  
   252  func (self *StateDB) Logs() []*types.Log {
   253  	var logs []*types.Log
   254  	for _, lgs := range self.logs {
   255  		logs = append(logs, lgs...)
   256  	}
   257  	return logs
   258  }
   259  
   260  // AddPreimage records a SHA3 preimage seen by the VM.
   261  func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) {
   262  	if _, ok := self.preimages[hash]; !ok {
   263  		self.journal.append(addPreimageChange{hash: hash})
   264  		pi := make([]byte, len(preimage))
   265  		copy(pi, preimage)
   266  		self.preimages[hash] = pi
   267  	}
   268  }
   269  
   270  // Preimages returns a list of SHA3 preimages that have been submitted.
   271  func (self *StateDB) Preimages() map[common.Hash][]byte {
   272  	return self.preimages
   273  }
   274  
   275  // AddRefund adds gas to the refund counter
   276  func (self *StateDB) AddRefund(gas uint64) {
   277  	self.journal.append(refundChange{prev: self.refund})
   278  	self.refund += gas
   279  }
   280  
   281  // SubRefund removes gas from the refund counter.
   282  // This method will panic if the refund counter goes below zero
   283  func (self *StateDB) SubRefund(gas uint64) {
   284  	self.journal.append(refundChange{prev: self.refund})
   285  	if gas > self.refund {
   286  		panic("Refund counter below zero")
   287  	}
   288  	self.refund -= gas
   289  }
   290  
   291  // Exist reports whether the given account address exists in the state.
   292  // Notably this also returns true for suicided accounts.
   293  func (self *StateDB) Exist(addr common.Address) bool {
   294  	return self.getStateObject(addr) != nil
   295  }
   296  
   297  // Empty returns whether the state object is either non-existent
   298  // or empty according to the EIP161 specification (balance = nonce = code = 0)
   299  func (self *StateDB) Empty(addr common.Address) bool {
   300  	so := self.getStateObject(addr)
   301  	return so == nil || so.empty()
   302  }
   303  
   304  func (self *StateDB) GetAllBalances(addr common.Address) map[common.Hash]string {
   305  	stateObject := self.getStateObject(addr)
   306  	if stateObject != nil {
   307  		return stateObject.CopyBalances()
   308  	}
   309  	return make(map[common.Hash]string)
   310  }
   311  
   312  func (self *StateDB) GetBalance(assetID common.Hash, addr common.Address) *big.Int {
   313  	stateObject := self.getStateObject(addr)
   314  	if stateObject != nil {
   315  		return stateObject.Balance(assetID)
   316  	}
   317  	return big.NewInt(0)
   318  }
   319  
   320  func (self *StateDB) GetAllTimeLockBalances(addr common.Address) map[common.Hash]*common.TimeLock {
   321  	stateObject := self.getStateObject(addr)
   322  	if stateObject != nil {
   323  		return stateObject.CopyTimeLockBalances()
   324  	}
   325  	return make(map[common.Hash]*common.TimeLock)
   326  }
   327  
   328  func (self *StateDB) GetTimeLockBalance(assetID common.Hash, addr common.Address) *common.TimeLock {
   329  	stateObject := self.getStateObject(addr)
   330  	if stateObject != nil {
   331  		return stateObject.TimeLockBalance(assetID)
   332  	}
   333  	return new(common.TimeLock)
   334  }
   335  
   336  func (self *StateDB) GetNonce(addr common.Address) uint64 {
   337  	stateObject := self.getStateObject(addr)
   338  	if stateObject != nil {
   339  		return stateObject.Nonce()
   340  	}
   341  
   342  	return 0
   343  }
   344  
   345  func (self *StateDB) GetCode(addr common.Address) []byte {
   346  	stateObject := self.getStateObject(addr)
   347  	if stateObject != nil {
   348  		return stateObject.Code(self.db)
   349  	}
   350  	return nil
   351  }
   352  
   353  func (self *StateDB) GetCodeSize(addr common.Address) int {
   354  	stateObject := self.getStateObject(addr)
   355  	if stateObject == nil {
   356  		return 0
   357  	}
   358  	if stateObject.code != nil {
   359  		return len(stateObject.code)
   360  	}
   361  	size, err := self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash()))
   362  	if err != nil {
   363  		self.setError(err)
   364  	}
   365  	return size
   366  }
   367  
   368  func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
   369  	stateObject := self.getStateObject(addr)
   370  	if stateObject == nil {
   371  		return common.Hash{}
   372  	}
   373  	return common.BytesToHash(stateObject.CodeHash())
   374  }
   375  
   376  // GetState retrieves a value from the given account's storage trie.
   377  func (self *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
   378  	stateObject := self.getStateObject(addr)
   379  	if stateObject != nil {
   380  		return stateObject.GetState(self.db, hash)
   381  	}
   382  	return common.Hash{}
   383  }
   384  
   385  // GetCommittedState retrieves a value from the given account's committed storage trie.
   386  func (self *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
   387  	stateObject := self.getStateObject(addr)
   388  	if stateObject != nil {
   389  		return stateObject.GetCommittedState(self.db, hash)
   390  	}
   391  	return common.Hash{}
   392  }
   393  
   394  func (self *StateDB) GetData(addr common.Address) []byte {
   395  	stateObject := self.getStateObject(addr)
   396  	if stateObject != nil {
   397  		return stateObject.Code(self.db)
   398  	}
   399  	return nil
   400  }
   401  
   402  func (self *StateDB) GetDataHash(addr common.Address) common.Hash {
   403  	stateObject := self.getStateObject(addr)
   404  	if stateObject != nil {
   405  		return common.BytesToHash(stateObject.CodeHash())
   406  	}
   407  	return common.Hash{}
   408  }
   409  
   410  // Database retrieves the low level database supporting the lower level trie ops.
   411  func (self *StateDB) Database() Database {
   412  	return self.db
   413  }
   414  
   415  // StorageTrie returns the storage trie of an account.
   416  // The return value is a copy and is nil for non-existent accounts.
   417  func (self *StateDB) StorageTrie(addr common.Address) Trie {
   418  	stateObject := self.getStateObject(addr)
   419  	if stateObject == nil {
   420  		return nil
   421  	}
   422  	cpy := stateObject.deepCopy(self)
   423  	return cpy.updateTrie(self.db)
   424  }
   425  
   426  func (self *StateDB) HasSuicided(addr common.Address) bool {
   427  	stateObject := self.getStateObject(addr)
   428  	if stateObject != nil {
   429  		return stateObject.suicided
   430  	}
   431  	return false
   432  }
   433  
   434  /*
   435   * SETTERS
   436   */
   437  
   438  // AddBalance adds amount to the account associated with addr.
   439  func (self *StateDB) AddBalance(addr common.Address, assetID common.Hash, amount *big.Int) {
   440  	stateObject := self.GetOrNewStateObject(addr)
   441  	if stateObject != nil {
   442  		stateObject.AddBalance(assetID, amount)
   443  	}
   444  }
   445  
   446  // SubBalance subtracts amount from the account associated with addr.
   447  func (self *StateDB) SubBalance(addr common.Address, assetID common.Hash, amount *big.Int) {
   448  	stateObject := self.GetOrNewStateObject(addr)
   449  	if stateObject != nil {
   450  		stateObject.SubBalance(assetID, amount)
   451  	}
   452  }
   453  
   454  func (self *StateDB) SetBalance(addr common.Address, assetID common.Hash, amount *big.Int) {
   455  	stateObject := self.GetOrNewStateObject(addr)
   456  	if stateObject != nil {
   457  		stateObject.SetBalance(assetID, amount)
   458  	}
   459  }
   460  
   461  func (self *StateDB) AddTimeLockBalance(addr common.Address, assetID common.Hash, amount *common.TimeLock, blockNumber *big.Int, timestamp uint64) {
   462  	stateObject := self.GetOrNewStateObject(addr)
   463  	if stateObject != nil {
   464  		stateObject.AddTimeLockBalance(assetID, amount, blockNumber, timestamp)
   465  	}
   466  }
   467  
   468  func (self *StateDB) SubTimeLockBalance(addr common.Address, assetID common.Hash, amount *common.TimeLock, blockNumber *big.Int, timestamp uint64) {
   469  	stateObject := self.GetOrNewStateObject(addr)
   470  	if stateObject != nil {
   471  		stateObject.SubTimeLockBalance(assetID, amount, blockNumber, timestamp)
   472  	}
   473  }
   474  
   475  func (self *StateDB) SetTimeLockBalance(addr common.Address, assetID common.Hash, amount *common.TimeLock) {
   476  	stateObject := self.GetOrNewStateObject(addr)
   477  	if stateObject != nil {
   478  		stateObject.SetTimeLockBalance(assetID, amount)
   479  	}
   480  }
   481  
   482  func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
   483  	stateObject := self.GetOrNewStateObject(addr)
   484  	if stateObject != nil {
   485  		stateObject.SetNonce(nonce)
   486  	}
   487  }
   488  
   489  func (self *StateDB) SetCode(addr common.Address, code []byte) {
   490  	stateObject := self.GetOrNewStateObject(addr)
   491  	if stateObject != nil {
   492  		stateObject.SetCode(crypto.Keccak256Hash(code), code)
   493  	}
   494  }
   495  
   496  func (self *StateDB) SetState(addr common.Address, key, value common.Hash) {
   497  	stateObject := self.GetOrNewStateObject(addr)
   498  	if stateObject != nil {
   499  		stateObject.SetState(self.db, key, value)
   500  	}
   501  }
   502  
   503  func (self *StateDB) SetData(addr common.Address, value []byte) common.Hash {
   504  	stateObject := self.GetOrNewStateObject(addr)
   505  	if stateObject != nil {
   506  		hash := crypto.Keccak256Hash(value)
   507  		stateObject.SetCode(hash, value)
   508  		return hash
   509  	}
   510  	return common.Hash{}
   511  }
   512  
   513  // Suicide marks the given account as suicided.
   514  // This clears the account balance.
   515  //
   516  // The account's state object is still available until the state is committed,
   517  // getStateObject will return a non-nil account after Suicide.
   518  func (self *StateDB) Suicide(addr common.Address) bool {
   519  	stateObject := self.getStateObject(addr)
   520  	if stateObject == nil {
   521  		return false
   522  	}
   523  	for i, v := range stateObject.data.BalancesVal {
   524  		k := stateObject.data.BalancesHash[i]
   525  		self.journal.append(suicideChange{
   526  			isTimeLock:  false,
   527  			account:     &addr,
   528  			prev:        stateObject.suicided,
   529  			assetID:     k,
   530  			prevbalance: new(big.Int).Set(v),
   531  		})
   532  		stateObject.suicided = true
   533  		stateObject.setBalance(k, new(big.Int))
   534  	}
   535  
   536  	for i, v := range stateObject.data.TimeLockBalancesVal {
   537  		k := stateObject.data.TimeLockBalancesHash[i]
   538  		self.journal.append(suicideChange{
   539  			account:             &addr,
   540  			prev:                stateObject.suicided,
   541  			assetID:             k,
   542  			prevTimeLockBalance: new(common.TimeLock).Set(v),
   543  		})
   544  		stateObject.suicided = true
   545  		stateObject.SetTimeLockBalance(k, new(common.TimeLock))
   546  	}
   547  
   548  	stateObject.markSuicided()
   549  	return true
   550  }
   551  
   552  func (self *StateDB) TransferAll(from, to common.Address, blockNumber *big.Int, timestamp uint64) {
   553  	fromObject := self.getStateObject(from)
   554  	if fromObject == nil {
   555  		return
   556  	}
   557  
   558  	// remove tickets
   559  	self.ClearTickets(from, to, blockNumber, timestamp)
   560  
   561  	// burn notation
   562  	self.BurnNotation(from)
   563  
   564  	// transfer all balances
   565  	for i, v := range fromObject.data.BalancesVal {
   566  		k := fromObject.data.BalancesHash[i]
   567  		fromObject.SetBalance(k, new(big.Int))
   568  		self.AddBalance(to, k, v)
   569  	}
   570  
   571  	// transfer all timelock balances
   572  	for i, v := range fromObject.data.TimeLockBalancesVal {
   573  		k := fromObject.data.TimeLockBalancesHash[i]
   574  		fromObject.SetTimeLockBalance(k, new(common.TimeLock))
   575  		self.AddTimeLockBalance(to, k, v, blockNumber, timestamp)
   576  	}
   577  }
   578  
   579  //
   580  // Setting, updating & deleting state object methods.
   581  //
   582  
   583  // updateStateObject writes the given object to the trie.
   584  func (self *StateDB) updateStateObject(stateObject *stateObject) {
   585  	addr := stateObject.Address()
   586  	data, err := rlp.EncodeToBytes(stateObject)
   587  	if err != nil {
   588  		panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
   589  	}
   590  	self.setError(self.trie.TryUpdate(addr[:], data))
   591  }
   592  
   593  // deleteStateObject removes the given object from the state trie.
   594  func (self *StateDB) deleteStateObject(stateObject *stateObject) {
   595  	stateObject.deleted = true
   596  	addr := stateObject.Address()
   597  	self.setError(self.trie.TryDelete(addr[:]))
   598  }
   599  
   600  // Retrieve a state object given by the address. Returns nil if not found.
   601  func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
   602  	// Prefer 'live' objects.
   603  	if obj := self.stateObjects[addr]; obj != nil {
   604  		if obj.deleted {
   605  			return nil
   606  		}
   607  		return obj
   608  	}
   609  
   610  	// Load the object from the database.
   611  	enc, err := self.trie.TryGet(addr[:])
   612  	if len(enc) == 0 {
   613  		self.setError(err)
   614  		return nil
   615  	}
   616  	var data Account
   617  	if err := rlp.DecodeBytes(enc, &data); err != nil {
   618  		log.Error("Failed to decode state object", "addr", addr, "err", err)
   619  		return nil
   620  	}
   621  	// Insert into the live set.
   622  	obj := newObject(self, addr, data)
   623  	self.setStateObject(obj)
   624  	return obj
   625  }
   626  
   627  func (self *StateDB) setStateObject(object *stateObject) {
   628  	self.stateObjects[object.Address()] = object
   629  }
   630  
   631  // Retrieve a state object or create a new state object if nil.
   632  func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
   633  	stateObject := self.getStateObject(addr)
   634  	if stateObject == nil || stateObject.deleted {
   635  		stateObject, _ = self.createObject(addr)
   636  	}
   637  	return stateObject
   638  }
   639  
   640  // createObject creates a new state object. If there is an existing account with
   641  // the given address, it is overwritten and returned as the second return value.
   642  func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
   643  	prev = self.getStateObject(addr)
   644  	newobj = newObject(self, addr, Account{})
   645  	newobj.setNonce(0) // sets the object to dirty
   646  	if prev == nil {
   647  		self.journal.append(createObjectChange{account: &addr})
   648  	} else {
   649  		self.journal.append(resetObjectChange{prev: prev})
   650  	}
   651  	self.setStateObject(newobj)
   652  	return newobj, prev
   653  }
   654  
   655  // CreateAccount explicitly creates a state object. If a state object with the address
   656  // already exists the balance is carried over to the new account.
   657  //
   658  // CreateAccount is called during the EVM CREATE operation. The situation might arise that
   659  // a contract does the following:
   660  //
   661  //   1. sends funds to sha(account ++ (nonce + 1))
   662  //   2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
   663  //
   664  // Carrying over the balance ensures that Ether doesn't disappear.
   665  func (self *StateDB) CreateAccount(addr common.Address) {
   666  	new, prev := self.createObject(addr)
   667  	if prev != nil {
   668  		for i, v := range prev.data.BalancesVal {
   669  			new.setBalance(prev.data.BalancesHash[i], v)
   670  		}
   671  		for i, v := range prev.data.TimeLockBalancesVal {
   672  			new.setTimeLockBalance(prev.data.TimeLockBalancesHash[i], v)
   673  		}
   674  	}
   675  }
   676  
   677  func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) {
   678  	so := db.getStateObject(addr)
   679  	if so == nil {
   680  		return
   681  	}
   682  	it := trie.NewIterator(so.getTrie(db.db).NodeIterator(nil))
   683  	for it.Next() {
   684  		key := common.BytesToHash(db.trie.GetKey(it.Key))
   685  		if value, dirty := so.dirtyStorage[key]; dirty {
   686  			cb(key, value)
   687  			continue
   688  		}
   689  		cb(key, common.BytesToHash(it.Value))
   690  	}
   691  }
   692  
   693  // Copy creates a deep, independent copy of the state.
   694  // Snapshots of the copied state cannot be applied to the copy.
   695  func (self *StateDB) Copy() *StateDB {
   696  	self.lock.Lock()
   697  	defer self.lock.Unlock()
   698  
   699  	// Copy all the basic fields, initialize the memory ones
   700  	state := &StateDB{
   701  		db:                self.db,
   702  		trie:              self.db.CopyTrie(self.trie),
   703  		stateObjects:      make(map[common.Address]*stateObject, len(self.journal.dirties)),
   704  		stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)),
   705  		refund:            self.refund,
   706  		logs:              make(map[common.Hash][]*types.Log, len(self.logs)),
   707  		logSize:           self.logSize,
   708  		preimages:         make(map[common.Hash][]byte),
   709  		journal:           newJournal(),
   710  		ticketsHash:       self.ticketsHash,
   711  		tickets:           self.tickets.DeepCopy(),
   712  	}
   713  	// Copy the dirty states, logs, and preimages
   714  	for addr := range self.journal.dirties {
   715  		// As documented [here](https://github.com/FusionFoundation/efsn/pull/16485#issuecomment-380438527),
   716  		// and in the Finalise-method, there is a case where an object is in the journal but not
   717  		// in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for
   718  		// nil
   719  		if object, exist := self.stateObjects[addr]; exist {
   720  			state.stateObjects[addr] = object.deepCopy(state)
   721  			state.stateObjectsDirty[addr] = struct{}{}
   722  		}
   723  	}
   724  	// Above, we don't copy the actual journal. This means that if the copy is copied, the
   725  	// loop above will be a no-op, since the copy's journal is empty.
   726  	// Thus, here we iterate over stateObjects, to enable copies of copies
   727  	for addr := range self.stateObjectsDirty {
   728  		if _, exist := state.stateObjects[addr]; !exist {
   729  			state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
   730  			state.stateObjectsDirty[addr] = struct{}{}
   731  		}
   732  	}
   733  	for hash, logs := range self.logs {
   734  		cpy := make([]*types.Log, len(logs))
   735  		for i, l := range logs {
   736  			cpy[i] = new(types.Log)
   737  			*cpy[i] = *l
   738  		}
   739  		state.logs[hash] = cpy
   740  	}
   741  	for hash, preimage := range self.preimages {
   742  		state.preimages[hash] = preimage
   743  	}
   744  	return state
   745  }
   746  
   747  // Snapshot returns an identifier for the current revision of the state.
   748  func (self *StateDB) Snapshot() int {
   749  	id := self.nextRevisionId
   750  	self.nextRevisionId++
   751  	self.validRevisions = append(self.validRevisions, revision{id, self.journal.length()})
   752  	return id
   753  }
   754  
   755  // RevertToSnapshot reverts all state changes made since the given revision.
   756  func (self *StateDB) RevertToSnapshot(revid int) {
   757  	// Find the snapshot in the stack of valid snapshots.
   758  	idx := sort.Search(len(self.validRevisions), func(i int) bool {
   759  		return self.validRevisions[i].id >= revid
   760  	})
   761  	if idx == len(self.validRevisions) || self.validRevisions[idx].id != revid {
   762  		panic(fmt.Errorf("revision id %v cannot be reverted", revid))
   763  	}
   764  	snapshot := self.validRevisions[idx].journalIndex
   765  
   766  	// Replay the journal to undo changes and remove invalidated snapshots
   767  	self.journal.revert(self, snapshot)
   768  	self.validRevisions = self.validRevisions[:idx]
   769  }
   770  
   771  // GetRefund returns the current value of the refund counter.
   772  func (self *StateDB) GetRefund() uint64 {
   773  	return self.refund
   774  }
   775  
   776  // Finalise finalises the state by removing the self destructed objects
   777  // and clears the journal as well as the refunds.
   778  func (s *StateDB) Finalise(deleteEmptyObjects bool) {
   779  	for addr := range s.journal.dirties {
   780  		stateObject, exist := s.stateObjects[addr]
   781  		if !exist {
   782  			// ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2
   783  			// That tx goes out of gas, and although the notion of 'touched' does not exist there, the
   784  			// touch-event will still be recorded in the journal. Since ripeMD is a special snowflake,
   785  			// it will persist in the journal even though the journal is reverted. In this special circumstance,
   786  			// it may exist in `s.journal.dirties` but not in `s.stateObjects`.
   787  			// Thus, we can safely ignore it here
   788  			continue
   789  		}
   790  
   791  		if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) {
   792  			s.deleteStateObject(stateObject)
   793  		} else {
   794  			stateObject.updateRoot(s.db)
   795  			s.updateStateObject(stateObject)
   796  		}
   797  		s.stateObjectsDirty[addr] = struct{}{}
   798  	}
   799  	// Invalidate journal because reverting across transactions is not allowed.
   800  	s.clearJournalAndRefund()
   801  }
   802  
   803  // IntermediateRoot computes the current root hash of the state trie.
   804  // It is called in between transactions to get the root hash that
   805  // goes into transaction receipts.
   806  func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
   807  	s.Finalise(deleteEmptyObjects)
   808  	return s.trie.Hash()
   809  }
   810  
   811  // Prepare sets the current transaction hash and index and block hash which is
   812  // used when the EVM emits new state logs.
   813  func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) {
   814  	self.thash = thash
   815  	self.bhash = bhash
   816  	self.txIndex = ti
   817  }
   818  
   819  func (s *StateDB) clearJournalAndRefund() {
   820  	s.journal = newJournal()
   821  	s.validRevisions = s.validRevisions[:0]
   822  	s.refund = 0
   823  }
   824  
   825  // Commit writes the state to the underlying in-memory trie database.
   826  func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) {
   827  	defer s.clearJournalAndRefund()
   828  
   829  	for addr := range s.journal.dirties {
   830  		s.stateObjectsDirty[addr] = struct{}{}
   831  	}
   832  	// Commit objects to the trie.
   833  	for addr, stateObject := range s.stateObjects {
   834  
   835  		_, isDirty := s.stateObjectsDirty[addr]
   836  		switch {
   837  		case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()):
   838  			// If the object has been removed, don't bother syncing it
   839  			// and just mark it for deletion in the trie.
   840  			s.deleteStateObject(stateObject)
   841  		case isDirty:
   842  			// Write any contract code associated with the state object
   843  			if stateObject.code != nil && stateObject.dirtyCode {
   844  				// log.Info( "SAVING code object " , "addr", addr)
   845  				s.db.TrieDB().InsertBlob(common.BytesToHash(stateObject.CodeHash()), stateObject.code)
   846  				stateObject.dirtyCode = false
   847  			}
   848  			// Write any storage changes in the state object to its storage trie.
   849  			if err := stateObject.CommitTrie(s.db); err != nil {
   850  				return common.Hash{}, err
   851  			}
   852  			// Update the object in the main account trie.
   853  			s.updateStateObject(stateObject)
   854  		}
   855  		delete(s.stateObjectsDirty, addr)
   856  	}
   857  	// Write trie changes.
   858  	root, err = s.trie.Commit(func(leaf []byte, parent common.Hash) error {
   859  		var account Account
   860  		if err := rlp.DecodeBytes(leaf, &account); err != nil {
   861  			return nil
   862  		}
   863  		if account.Root != emptyState {
   864  			s.db.TrieDB().Reference(account.Root, parent)
   865  		}
   866  		code := common.BytesToHash(account.CodeHash)
   867  		if code != emptyCode {
   868  			s.db.TrieDB().Reference(code, parent)
   869  		}
   870  		return nil
   871  	})
   872  	log.Debug("Trie cache stats after commit", "misses", trie.CacheMisses(), "unloads", trie.CacheUnloads())
   873  	return root, err
   874  }
   875  
   876  // GetNotation wacom
   877  func (db *StateDB) GetNotation(addr common.Address) uint64 {
   878  	stateObject := db.getStateObject(addr)
   879  	if stateObject != nil {
   880  		return stateObject.Notation()
   881  	}
   882  	return 0
   883  }
   884  
   885  // AllNotation wacom
   886  func (db *StateDB) AllNotation() ([]common.Address, error) {
   887  	return nil, fmt.Errorf("AllNotations has been depreciated please use api.fusionnetwork.io")
   888  }
   889  
   890  // GenNotation wacom
   891  func (db *StateDB) GenNotation(addr common.Address) error {
   892  	stateObject := db.GetOrNewStateObject(addr)
   893  	if stateObject != nil {
   894  		if n := db.GetNotation(addr); n != 0 {
   895  			return fmt.Errorf("Account %s has a notation:%d", addr.String(), n)
   896  		}
   897  		// get last notation value
   898  		nextNotation, err := db.GetNotationCount()
   899  		nextNotation++
   900  		if err != nil {
   901  			log.Error("GenNotation: Unable to get next notation value")
   902  			return err
   903  		}
   904  		newNotation := db.CalcNotationDisplay(nextNotation)
   905  		db.setNotationCount(nextNotation)
   906  		db.setNotationToAddressLookup(newNotation, addr)
   907  		stateObject.SetNotation(newNotation)
   908  		return nil
   909  	}
   910  	return nil
   911  }
   912  
   913  func (db *StateDB) BurnNotation(addr common.Address) {
   914  	stateObject := db.getStateObject(addr)
   915  	if stateObject != nil {
   916  		notation := stateObject.Notation()
   917  		if notation != 0 {
   918  			db.setNotationToAddressLookup(notation, common.Address{})
   919  			stateObject.SetNotation(0)
   920  		}
   921  	}
   922  }
   923  
   924  type notationPersist struct {
   925  	Deleted bool
   926  	Count   uint64
   927  	Address common.Address
   928  }
   929  
   930  func (db *StateDB) GetNotationCount() (uint64, error) {
   931  	data := db.GetStructData(common.NotationKeyAddress, common.NotationKeyAddress.Bytes())
   932  	if len(data) == 0 || data == nil {
   933  		return 0, nil // not created yet
   934  	}
   935  	var np notationPersist
   936  	rlp.DecodeBytes(data, &np)
   937  	return np.Count, nil
   938  }
   939  
   940  func (db *StateDB) setNotationCount(newCount uint64) error {
   941  	np := notationPersist{
   942  		Count: newCount,
   943  	}
   944  	data, err := rlp.EncodeToBytes(&np)
   945  	if err != nil {
   946  		return err
   947  	}
   948  	db.SetStructData(common.NotationKeyAddress, common.NotationKeyAddress.Bytes(), data)
   949  	return nil
   950  }
   951  
   952  func (db *StateDB) setNotationToAddressLookup(notation uint64, address common.Address) error {
   953  	np := notationPersist{
   954  		Count:   notation,
   955  		Address: address,
   956  	}
   957  	data, err := rlp.EncodeToBytes(&np)
   958  	if err != nil {
   959  		return err
   960  	}
   961  	buf := make([]byte, binary.MaxVarintLen64)
   962  	binary.PutUvarint(buf, notation)
   963  	db.SetStructData(common.NotationKeyAddress, buf, data)
   964  	return nil
   965  }
   966  
   967  // GetAddressByNotation wacom
   968  func (db *StateDB) GetAddressByNotation(notation uint64) (common.Address, error) {
   969  	buf := make([]byte, binary.MaxVarintLen64)
   970  	binary.PutUvarint(buf, notation)
   971  	data := db.GetStructData(common.NotationKeyAddress, buf)
   972  	if len(data) == 0 || data == nil {
   973  		return common.Address{}, fmt.Errorf("notation %v does not exist", notation)
   974  	}
   975  	var np notationPersist
   976  	err := rlp.DecodeBytes(data, &np)
   977  	if err != nil {
   978  		return common.Address{}, err
   979  	}
   980  	if np.Deleted || np.Address == (common.Address{}) {
   981  		return common.Address{}, fmt.Errorf("notation was deleted")
   982  	}
   983  	return np.Address, nil
   984  }
   985  
   986  // TransferNotation wacom
   987  func (db *StateDB) TransferNotation(notation uint64, from common.Address, to common.Address) error {
   988  	stateObjectFrom := db.GetOrNewStateObject(from)
   989  	if stateObjectFrom == nil {
   990  		return fmt.Errorf("Unable to get from address")
   991  	}
   992  	stateObjectTo := db.GetOrNewStateObject(to)
   993  	if stateObjectTo == nil {
   994  		return fmt.Errorf("Unable to get to address")
   995  	}
   996  	address, err := db.GetAddressByNotation(notation)
   997  	if err != nil {
   998  		return err
   999  	}
  1000  	if address != from {
  1001  		return fmt.Errorf("This notation is not the from address")
  1002  	}
  1003  	// reset the notation
  1004  	oldNotationTo := stateObjectTo.Notation()
  1005  	if oldNotationTo != 0 {
  1006  		// need to clear notation to address
  1007  		// user should transfer an old notation or can burn it like this
  1008  		db.setNotationToAddressLookup(oldNotationTo, common.Address{})
  1009  	}
  1010  	db.setNotationToAddressLookup(notation, to)
  1011  	stateObjectTo.SetNotation(notation)
  1012  	stateObjectFrom.SetNotation(0)
  1013  	return nil
  1014  }
  1015  
  1016  // CalcNotationDisplay wacom
  1017  func (db *StateDB) CalcNotationDisplay(notation uint64) uint64 {
  1018  	if notation == 0 {
  1019  		return notation
  1020  	}
  1021  	check := (notation ^ 8192 ^ 13 + 73/76798669*708583737978) % 100
  1022  	return (notation*100 + check)
  1023  }
  1024  
  1025  // AllAssets wacom
  1026  func (db *StateDB) AllAssets() (map[common.Hash]common.Asset, error) {
  1027  	return nil, fmt.Errorf("All assets has been depreciated, use api.fusionnetwork.io")
  1028  }
  1029  
  1030  type assetPersist struct {
  1031  	Deleted bool // if true swap was recalled and should not be returned
  1032  	Asset   common.Asset
  1033  }
  1034  
  1035  // GetAsset wacom
  1036  func (db *StateDB) GetAsset(assetID common.Hash) (common.Asset, error) {
  1037  	data := db.GetStructData(common.AssetKeyAddress, assetID.Bytes())
  1038  	var asset assetPersist
  1039  	if len(data) == 0 || data == nil {
  1040  		return common.Asset{}, fmt.Errorf("asset not found")
  1041  	}
  1042  	rlp.DecodeBytes(data, &asset)
  1043  	if asset.Deleted {
  1044  		return common.Asset{}, fmt.Errorf("asset deleted")
  1045  	}
  1046  	return asset.Asset, nil
  1047  }
  1048  
  1049  // GenAsset wacom
  1050  func (db *StateDB) GenAsset(asset common.Asset) error {
  1051  	_, err := db.GetAsset(asset.ID)
  1052  	if err == nil {
  1053  		return fmt.Errorf("%s asset exists", asset.ID.String())
  1054  	}
  1055  	assetToSave := assetPersist{
  1056  		Deleted: false,
  1057  		Asset:   asset,
  1058  	}
  1059  	data, err := rlp.EncodeToBytes(&assetToSave)
  1060  	if err != nil {
  1061  		return err
  1062  	}
  1063  	db.SetStructData(common.AssetKeyAddress, asset.ID.Bytes(), data)
  1064  	return nil
  1065  }
  1066  
  1067  // UpdateAsset wacom
  1068  func (db *StateDB) UpdateAsset(asset common.Asset) error {
  1069  	/** to update a asset we just overwrite it
  1070  	 */
  1071  	assetToSave := assetPersist{
  1072  		Deleted: false,
  1073  		Asset:   asset,
  1074  	}
  1075  	data, err := rlp.EncodeToBytes(&assetToSave)
  1076  	if err != nil {
  1077  		return err
  1078  	}
  1079  	db.SetStructData(common.AssetKeyAddress, asset.ID.Bytes(), data)
  1080  	return nil
  1081  }
  1082  
  1083  // IsTicketExist wacom
  1084  func (db *StateDB) IsTicketExist(id common.Hash) bool {
  1085  	tickets, err := db.AllTickets()
  1086  	if err != nil {
  1087  		log.Error("IsTicketExist unable to retrieve all tickets")
  1088  		return false
  1089  	}
  1090  
  1091  	_, err = tickets.Get(id)
  1092  	return err == nil
  1093  }
  1094  
  1095  // GetTicket wacom
  1096  func (db *StateDB) GetTicket(id common.Hash) (*common.Ticket, error) {
  1097  	tickets, err := db.AllTickets()
  1098  	if err != nil {
  1099  		log.Error("GetTicket unable to retrieve all tickets")
  1100  		return nil, fmt.Errorf("GetTicket error: %v", err)
  1101  	}
  1102  	return tickets.Get(id)
  1103  }
  1104  
  1105  // AllTickets wacom
  1106  func (db *StateDB) AllTickets() (common.TicketsDataSlice, error) {
  1107  	if len(db.tickets) != 0 {
  1108  		return db.tickets, nil
  1109  	}
  1110  
  1111  	key := db.ticketsHash
  1112  	ts := cachedTicketSlice.Get(key)
  1113  	if ts != nil {
  1114  		db.tickets = ts.DeepCopy()
  1115  		return db.tickets, nil
  1116  	}
  1117  
  1118  	db.rwlock.RLock()
  1119  	defer db.rwlock.RUnlock()
  1120  
  1121  	blob := db.GetData(common.TicketKeyAddress)
  1122  	if len(blob) == 0 {
  1123  		return common.TicketsDataSlice{}, db.Error()
  1124  	}
  1125  
  1126  	gz, err := gzip.NewReader(bytes.NewBuffer(blob))
  1127  	if err != nil {
  1128  		return nil, fmt.Errorf("Read tickets zip data: %v", err)
  1129  	}
  1130  	var buf bytes.Buffer
  1131  	if _, err = io.Copy(&buf, gz); err != nil {
  1132  		return nil, fmt.Errorf("Copy tickets zip data: %v", err)
  1133  	}
  1134  	if err := gz.Close(); err != nil {
  1135  		return nil, fmt.Errorf("Close read zip tickets: %v", err)
  1136  	}
  1137  	data := buf.Bytes()
  1138  
  1139  	var tickets common.TicketsDataSlice
  1140  	if err := rlp.DecodeBytes(data, &tickets); err != nil {
  1141  		log.Error("Unable to decode tickets")
  1142  		return nil, fmt.Errorf("Unable to decode tickets, err: %v", err)
  1143  	}
  1144  	db.tickets = tickets
  1145  	cachedTicketSlice.Add(key, db.tickets)
  1146  	return db.tickets, nil
  1147  }
  1148  
  1149  // AddTicket wacom
  1150  func (db *StateDB) AddTicket(ticket common.Ticket) error {
  1151  	tickets, err := db.AllTickets()
  1152  	if err != nil {
  1153  		return fmt.Errorf("AddTicket error: %v", err)
  1154  	}
  1155  	tickets, err = tickets.AddTicket(&ticket)
  1156  	if err != nil {
  1157  		return fmt.Errorf("AddTicket error: %v", err)
  1158  	}
  1159  	db.tickets = tickets
  1160  	return nil
  1161  }
  1162  
  1163  // RemoveTicket wacom
  1164  func (db *StateDB) RemoveTicket(id common.Hash) error {
  1165  	tickets, err := db.AllTickets()
  1166  	if err != nil {
  1167  		return fmt.Errorf("RemoveTicket error: %v", err)
  1168  	}
  1169  	tickets, err = tickets.RemoveTicket(id)
  1170  	if err != nil {
  1171  		return fmt.Errorf("RemoveTicket error: %v", err)
  1172  	}
  1173  	db.tickets = tickets
  1174  	return nil
  1175  }
  1176  
  1177  func (db *StateDB) TotalNumberOfTickets() uint64 {
  1178  	db.rwlock.RLock()
  1179  	defer db.rwlock.RUnlock()
  1180  
  1181  	return db.tickets.NumberOfTickets()
  1182  }
  1183  
  1184  func (db *StateDB) UpdateTickets(blockNumber *big.Int, timestamp uint64) (common.Hash, error) {
  1185  	db.rwlock.Lock()
  1186  	defer db.rwlock.Unlock()
  1187  
  1188  	tickets := db.tickets
  1189  	tickets, err := tickets.ClearExpiredTickets(timestamp)
  1190  	if err != nil {
  1191  		return common.Hash{}, fmt.Errorf("UpdateTickets: %v", err)
  1192  	}
  1193  	db.tickets = tickets
  1194  
  1195  	data, err := calcTicketsStorageData(db.tickets)
  1196  	if err != nil {
  1197  		return common.Hash{}, fmt.Errorf("UpdateTickets: %v", err)
  1198  	}
  1199  
  1200  	hash := db.SetData(common.TicketKeyAddress, data)
  1201  	cachedTicketSlice.Add(hash, db.tickets)
  1202  	return hash, nil
  1203  }
  1204  
  1205  func (db *StateDB) ClearTickets(from, to common.Address, blockNumber *big.Int, timestamp uint64) {
  1206  	tickets, err := db.AllTickets()
  1207  	if err != nil {
  1208  		return
  1209  	}
  1210  	for i, v := range tickets {
  1211  		if v.Owner != from {
  1212  			continue
  1213  		}
  1214  		for _, ticket := range v.Tickets {
  1215  			if ticket.ExpireTime <= timestamp {
  1216  				continue
  1217  			}
  1218  			value := common.NewTimeLock(&common.TimeLockItem{
  1219  				StartTime: ticket.StartTime,
  1220  				EndTime:   ticket.ExpireTime,
  1221  				Value:     ticket.Value(),
  1222  			})
  1223  			db.AddTimeLockBalance(to, common.SystemAssetID, value, blockNumber, timestamp)
  1224  		}
  1225  		tickets = append(tickets[:i], tickets[i+1:]...)
  1226  		db.tickets = tickets
  1227  		break
  1228  	}
  1229  }
  1230  
  1231  // AllSwaps wacom
  1232  func (db *StateDB) AllSwaps() (map[common.Hash]common.Swap, error) {
  1233  	return nil, fmt.Errorf("AllSwaps has been depreciated please use api.fusionnetwork.io")
  1234  }
  1235  
  1236  /** swaps
  1237  *
  1238   */
  1239  type swapPersist struct {
  1240  	Deleted bool // if true swap was recalled and should not be returned
  1241  	Swap    common.Swap
  1242  }
  1243  
  1244  // GetSwap wacom
  1245  func (db *StateDB) GetSwap(swapID common.Hash) (common.Swap, error) {
  1246  	data := db.GetStructData(common.SwapKeyAddress, swapID.Bytes())
  1247  	var swap swapPersist
  1248  	if len(data) == 0 || data == nil {
  1249  		return common.Swap{}, fmt.Errorf("swap not found")
  1250  	}
  1251  	rlp.DecodeBytes(data, &swap)
  1252  	if swap.Deleted {
  1253  		return common.Swap{}, fmt.Errorf("swap deleted")
  1254  	}
  1255  	return swap.Swap, nil
  1256  }
  1257  
  1258  // AddSwap wacom
  1259  func (db *StateDB) AddSwap(swap common.Swap) error {
  1260  	_, err := db.GetSwap(swap.ID)
  1261  	if err == nil {
  1262  		return fmt.Errorf("%s Swap exists", swap.ID.String())
  1263  	}
  1264  	swapToSave := swapPersist{
  1265  		Deleted: false,
  1266  		Swap:    swap,
  1267  	}
  1268  	data, err := rlp.EncodeToBytes(&swapToSave)
  1269  	if err != nil {
  1270  		return err
  1271  	}
  1272  	db.SetStructData(common.SwapKeyAddress, swap.ID.Bytes(), data)
  1273  	return nil
  1274  }
  1275  
  1276  // UpdateSwap wacom
  1277  func (db *StateDB) UpdateSwap(swap common.Swap) error {
  1278  	/** to update a swap we just overwrite it
  1279  	 */
  1280  	swapToSave := swapPersist{
  1281  		Deleted: false,
  1282  		Swap:    swap,
  1283  	}
  1284  	data, err := rlp.EncodeToBytes(&swapToSave)
  1285  	if err != nil {
  1286  		return err
  1287  	}
  1288  	db.SetStructData(common.SwapKeyAddress, swap.ID.Bytes(), data)
  1289  	return nil
  1290  }
  1291  
  1292  // RemoveSwap wacom
  1293  func (db *StateDB) RemoveSwap(id common.Hash) error {
  1294  	swapFound, err := db.GetSwap(id)
  1295  	if err != nil {
  1296  		return fmt.Errorf("%s Swap not found ", id.String())
  1297  	}
  1298  
  1299  	swapToSave := swapPersist{
  1300  		Deleted: true,
  1301  		Swap:    swapFound,
  1302  	}
  1303  	data, err := rlp.EncodeToBytes(&swapToSave)
  1304  	if err != nil {
  1305  		return err
  1306  	}
  1307  	db.SetStructData(common.SwapKeyAddress, id.Bytes(), data)
  1308  	return nil
  1309  }
  1310  
  1311  /** swaps
  1312  *
  1313   */
  1314  type multiSwapPersist struct {
  1315  	Deleted bool // if true swap was recalled and should not be returned
  1316  	Swap    common.MultiSwap
  1317  }
  1318  
  1319  // GetMultiSwap wacom
  1320  func (db *StateDB) GetMultiSwap(swapID common.Hash) (common.MultiSwap, error) {
  1321  	data := db.GetStructData(common.MultiSwapKeyAddress, swapID.Bytes())
  1322  	var swap multiSwapPersist
  1323  	if len(data) == 0 || data == nil {
  1324  		return common.MultiSwap{}, fmt.Errorf("multi swap not found")
  1325  	}
  1326  	rlp.DecodeBytes(data, &swap)
  1327  	if swap.Deleted {
  1328  		return common.MultiSwap{}, fmt.Errorf("multi swap deleted")
  1329  	}
  1330  	return swap.Swap, nil
  1331  }
  1332  
  1333  // AddMultiSwap wacom
  1334  func (db *StateDB) AddMultiSwap(swap common.MultiSwap) error {
  1335  	_, err := db.GetMultiSwap(swap.ID)
  1336  	if err == nil {
  1337  		return fmt.Errorf("%s Multi Swap exists", swap.ID.String())
  1338  	}
  1339  	swapToSave := multiSwapPersist{
  1340  		Deleted: false,
  1341  		Swap:    swap,
  1342  	}
  1343  	data, err := rlp.EncodeToBytes(&swapToSave)
  1344  	if err != nil {
  1345  		return err
  1346  	}
  1347  	db.SetStructData(common.MultiSwapKeyAddress, swap.ID.Bytes(), data)
  1348  	return nil
  1349  }
  1350  
  1351  // UpdateMultiSwap wacom
  1352  func (db *StateDB) UpdateMultiSwap(swap common.MultiSwap) error {
  1353  	/** to update a swap we just overwrite it
  1354  	 */
  1355  	swapToSave := multiSwapPersist{
  1356  		Deleted: false,
  1357  		Swap:    swap,
  1358  	}
  1359  	data, err := rlp.EncodeToBytes(&swapToSave)
  1360  	if err != nil {
  1361  		return err
  1362  	}
  1363  	db.SetStructData(common.MultiSwapKeyAddress, swap.ID.Bytes(), data)
  1364  	return nil
  1365  }
  1366  
  1367  // RemoveSwap wacom
  1368  func (db *StateDB) RemoveMultiSwap(id common.Hash) error {
  1369  	swapFound, err := db.GetMultiSwap(id)
  1370  	if err != nil {
  1371  		return fmt.Errorf("%s Multi Swap not found ", id.String())
  1372  	}
  1373  
  1374  	swapToSave := multiSwapPersist{
  1375  		Deleted: true,
  1376  		Swap:    swapFound,
  1377  	}
  1378  	data, err := rlp.EncodeToBytes(&swapToSave)
  1379  	if err != nil {
  1380  		return err
  1381  	}
  1382  	db.SetStructData(common.MultiSwapKeyAddress, id.Bytes(), data)
  1383  	return nil
  1384  }
  1385  
  1386  /** ReportIllegal
  1387   */
  1388  
  1389  // GetReport wacom
  1390  func (db *StateDB) IsReportExist(report []byte) bool {
  1391  	hash := crypto.Keccak256Hash(report)
  1392  	data := db.GetStructData(common.ReportKeyAddress, hash.Bytes())
  1393  	return len(data) > 0
  1394  }
  1395  
  1396  // AddReport wacom
  1397  func (db *StateDB) AddReport(report []byte) error {
  1398  	if db.IsReportExist(report) {
  1399  		return fmt.Errorf("AddReport error: report exists")
  1400  	}
  1401  	hash := crypto.Keccak256Hash(report)
  1402  	db.SetStructData(common.ReportKeyAddress, hash.Bytes(), report)
  1403  	return nil
  1404  }
  1405  
  1406  // GetStructData wacom
  1407  func (db *StateDB) GetStructData(addr common.Address, key []byte) []byte {
  1408  	if key == nil {
  1409  		return nil
  1410  	}
  1411  	stateObject := db.GetOrNewStateObject(addr)
  1412  	if stateObject != nil {
  1413  		keyHash := crypto.Keccak256Hash(key)
  1414  		keyIndex := new(big.Int)
  1415  		keyIndex.SetBytes(keyHash[:])
  1416  		info := stateObject.GetState(db.db, keyHash)
  1417  		size := common.BytesToInt(info[0:4])
  1418  		length := common.BytesToInt(info[common.HashLength/2 : common.HashLength/2+4])
  1419  		data := make([]byte, size)
  1420  		for i := 0; i < length; i++ {
  1421  			tempIndex := big.NewInt(int64(i))
  1422  			tempKey := crypto.Keccak256Hash(tempIndex.Bytes(), keyIndex.Bytes())
  1423  			tempData := stateObject.GetState(db.db, tempKey)
  1424  			start := i * common.HashLength
  1425  			end := start + common.HashLength
  1426  			if end > size {
  1427  				end = size
  1428  			}
  1429  			copy(data[start:end], tempData[common.HashLength-end+start:])
  1430  		}
  1431  		return data
  1432  	}
  1433  
  1434  	return nil
  1435  }
  1436  
  1437  // SetStructData wacom
  1438  func (db *StateDB) SetStructData(addr common.Address, key, value []byte) {
  1439  	if key == nil || value == nil {
  1440  		return
  1441  	}
  1442  	stateObject := db.GetOrNewStateObject(addr)
  1443  	if stateObject != nil {
  1444  		size := len(value)
  1445  		length := size / common.HashLength
  1446  		if size%common.HashLength != 0 {
  1447  			length++
  1448  		}
  1449  		info := common.Hash{}
  1450  		copy(info[0:], common.IntToBytes(size))
  1451  		copy(info[common.HashLength/2:], common.IntToBytes(length))
  1452  		keyHash := crypto.Keccak256Hash(key)
  1453  		keyIndex := new(big.Int)
  1454  		keyIndex.SetBytes(keyHash[:])
  1455  		stateObject.SetState(db.db, keyHash, info)
  1456  		for i := 0; i < length; i++ {
  1457  			tempIndex := big.NewInt(int64(i))
  1458  			tempKey := crypto.Keccak256Hash(tempIndex.Bytes(), keyIndex.Bytes())
  1459  			tempData := common.Hash{}
  1460  			start := i * common.HashLength
  1461  			end := start + common.HashLength
  1462  			if end > size {
  1463  				end = size
  1464  			}
  1465  			tempData.SetBytes(value[start:end])
  1466  			stateObject.SetState(db.db, tempKey, tempData)
  1467  		}
  1468  		stateObject.SetNonce(stateObject.Nonce() + 1)
  1469  	}
  1470  }