github.com/amazechain/amc@v0.1.3/modules/state/intra_block_state.go (about)

     1  // Copyright 2023 The AmazeChain Authors
     2  // This file is part of the AmazeChain library.
     3  //
     4  // The AmazeChain 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 AmazeChain 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 AmazeChain 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  	"fmt"
    22  	"github.com/amazechain/amc/common/account"
    23  	"github.com/amazechain/amc/common/block"
    24  	"github.com/amazechain/amc/common/crypto"
    25  	"github.com/amazechain/amc/common/hash"
    26  
    27  	"github.com/amazechain/amc/common/transaction"
    28  	"github.com/amazechain/amc/common/types"
    29  	"github.com/amazechain/amc/internal/avm/rlp"
    30  	"github.com/amazechain/amc/log"
    31  	"golang.org/x/crypto/sha3"
    32  	"sort"
    33  	"unsafe"
    34  
    35  	"github.com/holiman/uint256"
    36  
    37  	"github.com/amazechain/amc/params"
    38  )
    39  
    40  type revision struct {
    41  	id           int
    42  	journalIndex int
    43  }
    44  
    45  type StateTracer interface {
    46  	CaptureAccountRead(account types.Address) error
    47  	CaptureAccountWrite(account types.Address) error
    48  }
    49  
    50  // SystemAddress - sender address for internal state updates.
    51  var SystemAddress = types.HexToAddress("0xfffffffffffffffffffffffffffffffffffffffe")
    52  
    53  // BalanceIncrease represents the increase of balance of an account that did not require
    54  // reading the account first
    55  type BalanceIncrease struct {
    56  	increase    uint256.Int
    57  	transferred bool // Set to true when the corresponding stateObject is created and balance increase is transferred to the stateObject
    58  	count       int  // Number of increases - this needs tracking for proper reversion
    59  }
    60  
    61  // IntraBlockState is responsible for caching and managing state changes
    62  // that occur during block's execution.
    63  // NOT THREAD SAFE!
    64  type IntraBlockState struct {
    65  	stateReader StateReader
    66  
    67  	// This map holds 'live' objects, which will get modified while processing a state transition.
    68  	stateObjects      map[types.Address]*stateObject
    69  	stateObjectsDirty map[types.Address]struct{}
    70  
    71  	nilAccounts map[types.Address]struct{} // Remember non-existent account to avoid reading them again
    72  
    73  	// DB error.
    74  	// State objects are used by the consensus core and VM which are
    75  	// unable to deal with database-level errors. Any error that occurs
    76  	// during a database read is memoized here and will eventually be returned
    77  	// by IntraBlockState.Commit.
    78  	savedErr error
    79  
    80  	// The refund counter, also used by state transitioning.
    81  	refund uint64
    82  
    83  	thash, bhash types.Hash
    84  	txIndex      int
    85  	logs         map[types.Hash][]*block.Log
    86  	logSize      uint
    87  
    88  	// Journal of state modifications. This is the backbone of
    89  	// Snapshot and RevertToSnapshot.
    90  	journal        *journal
    91  	validRevisions []revision
    92  	nextRevisionID int
    93  	tracer         StateTracer
    94  	trace          bool
    95  	accessList     *accessList
    96  	balanceInc     map[types.Address]*BalanceIncrease // Map of balance increases (without first reading the account)
    97  
    98  	snap    *Snapshot
    99  	codeMap map[types.Hash][]byte
   100  	height  uint64
   101  }
   102  
   103  // Create a new state from a given trie
   104  func New(stateReader StateReader) *IntraBlockState {
   105  	return &IntraBlockState{
   106  		stateReader:       stateReader,
   107  		stateObjects:      map[types.Address]*stateObject{},
   108  		stateObjectsDirty: map[types.Address]struct{}{},
   109  		nilAccounts:       map[types.Address]struct{}{},
   110  		logs:              map[types.Hash][]*block.Log{},
   111  		journal:           newJournal(),
   112  		accessList:        newAccessList(),
   113  		balanceInc:        map[types.Address]*BalanceIncrease{},
   114  	}
   115  }
   116  
   117  func (sdb *IntraBlockState) BeginWriteSnapshot() {
   118  	sdb.snap = NewWritableSnapshot()
   119  }
   120  
   121  func (sdb *IntraBlockState) BeginWriteCodes() {
   122  	sdb.codeMap = make(map[types.Hash][]byte, 0)
   123  }
   124  
   125  func (sdb *IntraBlockState) CodeHashes() map[types.Hash][]byte {
   126  	// it should be called end of block execute
   127  	for addr, stateObject := range sdb.stateObjects {
   128  		_, isDirty := sdb.stateObjectsDirty[addr]
   129  		if isDirty && (stateObject.created || !stateObject.selfdestructed) && stateObject.code != nil && stateObject.dirtyCode {
   130  			h := types.Hash{}
   131  			h.SetBytes(stateObject.CodeHash())
   132  			sdb.codeMap[h] = stateObject.code
   133  		}
   134  	}
   135  	return sdb.codeMap
   136  }
   137  
   138  func (sdb *IntraBlockState) SetHeight(height uint64) {
   139  	sdb.height = height
   140  }
   141  
   142  func (sdb *IntraBlockState) Snap() *Snapshot {
   143  	return sdb.snap
   144  }
   145  
   146  func (sdb *IntraBlockState) SetOutHash(hash types.Hash) {
   147  	if sdb.snap == nil || !sdb.snap.CanWrite() {
   148  		return
   149  	}
   150  	sdb.snap.OutHash = hash
   151  }
   152  
   153  func (sdb *IntraBlockState) WrittenSnapshot(hash types.Hash) []byte {
   154  	if sdb.snap == nil || !sdb.snap.CanWrite() {
   155  		return nil
   156  	}
   157  	if sdb.snap.Items != nil {
   158  		sort.Sort(sdb.snap.Items)
   159  	}
   160  	sdb.snap.OutHash = hash
   161  	b, err := rlp.EncodeToBytes(sdb.snap)
   162  	if err != nil {
   163  		return nil
   164  	}
   165  	sdb.snap = nil
   166  	return b
   167  }
   168  
   169  func (s *IntraBlockState) SetGetOneFun(f1 GetOneFun) {
   170  	s.snap.SetGetFun(f1)
   171  }
   172  
   173  func (sdb *IntraBlockState) PrepareReadableSnapshot(data []byte) error {
   174  	snap, err := ReadSnapshotData(data)
   175  	if err != nil {
   176  		return err
   177  	}
   178  	sdb.snap = snap
   179  	return nil
   180  }
   181  
   182  func (sdb *IntraBlockState) SetSnapshot(snap *Snapshot) {
   183  	snap.accounts = make(map[string]int, len(snap.Items))
   184  	snap.storage = make(map[string]int, len(snap.Items))
   185  	for k, v := range snap.Items {
   186  		if len(v.Key) == types.AddressLength {
   187  			snap.accounts[*(*string)(unsafe.Pointer(&v.Key))] = k
   188  		} else {
   189  			snap.storage[*(*string)(unsafe.Pointer(&v.Key))] = k
   190  		}
   191  	}
   192  	sdb.snap = snap
   193  }
   194  
   195  func (sdb *IntraBlockState) SetTracer(tracer StateTracer) {
   196  	sdb.tracer = tracer
   197  }
   198  
   199  func (sdb *IntraBlockState) SetTrace(trace bool) {
   200  	sdb.trace = trace
   201  }
   202  
   203  // setErrorUnsafe sets error but should be called in medhods that already have locks
   204  func (sdb *IntraBlockState) setErrorUnsafe(err error) {
   205  	if sdb.savedErr == nil {
   206  		sdb.savedErr = err
   207  	}
   208  }
   209  
   210  func (sdb *IntraBlockState) Error() error {
   211  	return sdb.savedErr
   212  }
   213  
   214  func (sdb *IntraBlockState) SetStateReader(reader StateReader) {
   215  	sdb.stateReader = reader
   216  }
   217  
   218  func (sdb *IntraBlockState) GetStateReader() StateReader {
   219  	return sdb.stateReader
   220  }
   221  
   222  // Reset clears out all ephemeral state objects from the state db, but keeps
   223  // the underlying state trie to avoid reloading data for the next operations.
   224  func (sdb *IntraBlockState) Reset() {
   225  	sdb.stateObjects = make(map[types.Address]*stateObject)
   226  	sdb.stateObjectsDirty = make(map[types.Address]struct{})
   227  	sdb.thash = types.Hash{}
   228  	sdb.bhash = types.Hash{}
   229  	sdb.txIndex = 0
   230  	sdb.logs = make(map[types.Hash][]*block.Log)
   231  	sdb.logSize = 0
   232  	sdb.clearJournalAndRefund()
   233  	sdb.accessList = newAccessList()
   234  	sdb.balanceInc = make(map[types.Address]*BalanceIncrease)
   235  }
   236  
   237  func (sdb *IntraBlockState) AddLog(log2 *block.Log) {
   238  	sdb.journal.append(addLogChange{txhash: sdb.thash})
   239  	log2.TxHash = sdb.thash
   240  	log2.BlockHash = sdb.bhash
   241  	log2.TxIndex = uint(sdb.txIndex)
   242  	log2.Index = sdb.logSize
   243  	sdb.logs[sdb.thash] = append(sdb.logs[sdb.thash], log2)
   244  	sdb.logSize++
   245  }
   246  
   247  func (sdb *IntraBlockState) GetLogs(hash types.Hash) []*block.Log {
   248  	return sdb.logs[hash]
   249  }
   250  
   251  func (sdb *IntraBlockState) Logs() []*block.Log {
   252  	var logs []*block.Log
   253  	for _, lgs := range sdb.logs {
   254  		logs = append(logs, lgs...)
   255  	}
   256  	return logs
   257  }
   258  
   259  // AddRefund adds gas to the refund counter
   260  func (sdb *IntraBlockState) AddRefund(gas uint64) {
   261  	sdb.journal.append(refundChange{prev: sdb.refund})
   262  	sdb.refund += gas
   263  }
   264  
   265  // SubRefund removes gas from the refund counter.
   266  // This method will panic if the refund counter goes below zero
   267  func (sdb *IntraBlockState) SubRefund(gas uint64) {
   268  	sdb.journal.append(refundChange{prev: sdb.refund})
   269  	if gas > sdb.refund {
   270  		sdb.setErrorUnsafe(fmt.Errorf("refund counter below zero"))
   271  	}
   272  	sdb.refund -= gas
   273  }
   274  
   275  // Exist reports whether the given account address exists in the state.
   276  // Notably this also returns true for suicided accounts.
   277  func (sdb *IntraBlockState) Exist(addr types.Address) bool {
   278  	if sdb.tracer != nil {
   279  		err := sdb.tracer.CaptureAccountRead(addr)
   280  		if sdb.trace {
   281  			fmt.Println("CaptureAccountRead err", err)
   282  		}
   283  	}
   284  	s := sdb.getStateObject(addr)
   285  	return s != nil && !s.deleted
   286  }
   287  
   288  // Empty returns whether the state object is either non-existent
   289  // or empty according to the EIP161 specification (balance = nonce = code = 0)
   290  func (sdb *IntraBlockState) Empty(addr types.Address) bool {
   291  	if sdb.tracer != nil {
   292  		err := sdb.tracer.CaptureAccountRead(addr)
   293  		if sdb.trace {
   294  			fmt.Println("CaptureAccountRead err", err)
   295  		}
   296  	}
   297  	so := sdb.getStateObject(addr)
   298  	return so == nil || so.deleted || so.empty()
   299  }
   300  
   301  // GetBalance retrieves the balance from the given address or 0 if object not found
   302  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   303  func (sdb *IntraBlockState) GetBalance(addr types.Address) *uint256.Int {
   304  	if sdb.tracer != nil {
   305  		err := sdb.tracer.CaptureAccountRead(addr)
   306  		if sdb.trace {
   307  			fmt.Println("CaptureAccountRead err", err)
   308  		}
   309  	}
   310  	stateObject := sdb.getStateObject(addr)
   311  	if stateObject != nil && !stateObject.deleted {
   312  		return stateObject.Balance()
   313  	}
   314  	return uint256.NewInt(0)
   315  }
   316  
   317  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   318  func (sdb *IntraBlockState) GetNonce(addr types.Address) uint64 {
   319  	if sdb.tracer != nil {
   320  		err := sdb.tracer.CaptureAccountRead(addr)
   321  		if sdb.trace {
   322  			fmt.Println("CaptureAccountRead err", err)
   323  		}
   324  	}
   325  	stateObject := sdb.getStateObject(addr)
   326  	if stateObject != nil && !stateObject.deleted {
   327  		return stateObject.Nonce()
   328  	}
   329  
   330  	return 0
   331  }
   332  
   333  // TxIndex returns the current transaction index set by Prepare.
   334  func (sdb *IntraBlockState) TxIndex() int {
   335  	return sdb.txIndex
   336  }
   337  
   338  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   339  func (sdb *IntraBlockState) GetCode(addr types.Address) []byte {
   340  	if sdb.tracer != nil {
   341  		err := sdb.tracer.CaptureAccountRead(addr)
   342  		if sdb.trace {
   343  			fmt.Println("CaptureAccountRead err", err)
   344  		}
   345  	}
   346  	stateObject := sdb.getStateObject(addr)
   347  	if stateObject != nil && !stateObject.deleted {
   348  		if sdb.trace {
   349  			fmt.Printf("GetCode %x, returned %d\n", addr, len(stateObject.Code()))
   350  		}
   351  		code := stateObject.Code()
   352  		if len(code) > 0 && sdb.codeMap != nil {
   353  			sdb.codeMap[types.BytesToHash(stateObject.CodeHash())] = code
   354  		}
   355  		return code
   356  	}
   357  	if sdb.trace {
   358  		fmt.Printf("GetCode %x, returned nil\n", addr)
   359  	}
   360  	return nil
   361  }
   362  
   363  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   364  func (sdb *IntraBlockState) GetCodeSize(addr types.Address) int {
   365  	if sdb.tracer != nil {
   366  		err := sdb.tracer.CaptureAccountRead(addr)
   367  		if sdb.trace {
   368  			fmt.Println("CaptureAccountRead err", err)
   369  		}
   370  	}
   371  	stateObject := sdb.getStateObject(addr)
   372  	if stateObject == nil || stateObject.deleted {
   373  		return 0
   374  	}
   375  	if stateObject.code != nil {
   376  		return len(stateObject.code)
   377  	}
   378  	len, err := sdb.stateReader.ReadAccountCodeSize(addr, stateObject.data.Incarnation, stateObject.data.CodeHash)
   379  	if err != nil {
   380  		sdb.setErrorUnsafe(err)
   381  	}
   382  	if len > 0 && sdb.codeMap != nil {
   383  		code, _ := sdb.stateReader.ReadAccountCode(addr, stateObject.data.Incarnation, types.BytesToHash(stateObject.CodeHash()))
   384  		sdb.codeMap[types.BytesToHash(stateObject.CodeHash())] = code
   385  	}
   386  	return len
   387  }
   388  
   389  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   390  func (sdb *IntraBlockState) GetCodeHash(addr types.Address) types.Hash {
   391  	if sdb.tracer != nil {
   392  		err := sdb.tracer.CaptureAccountRead(addr)
   393  		if sdb.trace {
   394  			fmt.Println("CaptureAccountRead err", err)
   395  		}
   396  	}
   397  	stateObject := sdb.getStateObject(addr)
   398  	if stateObject == nil || stateObject.deleted {
   399  		return types.Hash{}
   400  	}
   401  	return types.BytesToHash(stateObject.CodeHash())
   402  }
   403  
   404  // GetState retrieves a value from the given account's storage trie.
   405  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   406  func (sdb *IntraBlockState) GetState(addr types.Address, key *types.Hash, value *uint256.Int) {
   407  	stateObject := sdb.getStateObject(addr)
   408  	if stateObject != nil && !stateObject.deleted {
   409  		stateObject.GetState(key, value)
   410  	} else {
   411  		value.Clear()
   412  	}
   413  }
   414  
   415  // GetCommittedState retrieves a value from the given account's committed storage trie.
   416  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   417  func (sdb *IntraBlockState) GetCommittedState(addr types.Address, key *types.Hash, value *uint256.Int) {
   418  	stateObject := sdb.getStateObject(addr)
   419  	if stateObject != nil && !stateObject.deleted {
   420  		stateObject.GetCommittedState(key, value)
   421  	} else {
   422  		value.Clear()
   423  	}
   424  }
   425  
   426  func (sdb *IntraBlockState) HasSuicided(addr types.Address) bool {
   427  	stateObject := sdb.getStateObject(addr)
   428  	if stateObject == nil {
   429  		return false
   430  	}
   431  	if stateObject.deleted {
   432  		return false
   433  	}
   434  	if stateObject.created {
   435  		return false
   436  	}
   437  	return stateObject.selfdestructed
   438  }
   439  
   440  /*
   441   * SETTERS
   442   */
   443  
   444  // AddBalance adds amount to the account associated with addr.
   445  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   446  func (sdb *IntraBlockState) AddBalance(addr types.Address, amount *uint256.Int) {
   447  	if sdb.trace {
   448  		fmt.Printf("AddBalance %x, %d\n", addr, amount)
   449  	}
   450  	if sdb.tracer != nil {
   451  		err := sdb.tracer.CaptureAccountWrite(addr)
   452  		if sdb.trace {
   453  			fmt.Println("CaptureAccountWrite err", err)
   454  		}
   455  	}
   456  	// If this account has not been read, add to the balance increment map
   457  	_, needAccount := sdb.stateObjects[addr]
   458  	if !needAccount && addr == ripemd && amount.IsZero() {
   459  		needAccount = true
   460  	}
   461  	if !needAccount {
   462  		sdb.journal.append(balanceIncrease{
   463  			account:  &addr,
   464  			increase: *amount,
   465  		})
   466  		bi, ok := sdb.balanceInc[addr]
   467  		if !ok {
   468  			bi = &BalanceIncrease{}
   469  			sdb.balanceInc[addr] = bi
   470  		}
   471  		bi.increase.Add(&bi.increase, amount)
   472  		bi.count++
   473  		return
   474  	}
   475  
   476  	stateObject := sdb.GetOrNewStateObject(addr)
   477  	stateObject.AddBalance(amount)
   478  }
   479  
   480  // SubBalance subtracts amount from the account associated with addr.
   481  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   482  func (sdb *IntraBlockState) SubBalance(addr types.Address, amount *uint256.Int) {
   483  	if sdb.trace {
   484  		fmt.Printf("SubBalance %x, %d\n", addr, amount)
   485  	}
   486  	if sdb.tracer != nil {
   487  		err := sdb.tracer.CaptureAccountWrite(addr)
   488  		if sdb.trace {
   489  			fmt.Println("CaptureAccountWrite err", err)
   490  		}
   491  
   492  	}
   493  
   494  	stateObject := sdb.GetOrNewStateObject(addr)
   495  	if stateObject != nil {
   496  		stateObject.SubBalance(amount)
   497  	}
   498  }
   499  
   500  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   501  func (sdb *IntraBlockState) SetBalance(addr types.Address, amount *uint256.Int) {
   502  	if sdb.tracer != nil {
   503  		err := sdb.tracer.CaptureAccountWrite(addr)
   504  		if sdb.trace {
   505  			fmt.Println("CaptureAccountWrite err", err)
   506  		}
   507  	}
   508  
   509  	stateObject := sdb.GetOrNewStateObject(addr)
   510  	if stateObject != nil {
   511  		stateObject.SetBalance(amount)
   512  	}
   513  }
   514  
   515  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   516  func (sdb *IntraBlockState) SetNonce(addr types.Address, nonce uint64) {
   517  	if sdb.tracer != nil {
   518  		err := sdb.tracer.CaptureAccountWrite(addr)
   519  		if sdb.trace {
   520  			fmt.Println("CaptureAccountWrite err", err)
   521  		}
   522  	}
   523  
   524  	stateObject := sdb.GetOrNewStateObject(addr)
   525  	if stateObject != nil {
   526  		stateObject.SetNonce(nonce)
   527  	}
   528  }
   529  
   530  // DESCRIBED: docs/programmers_guide/guide.md#code-hash
   531  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   532  func (sdb *IntraBlockState) SetCode(addr types.Address, code []byte) {
   533  	if sdb.tracer != nil {
   534  		err := sdb.tracer.CaptureAccountWrite(addr)
   535  		if sdb.trace {
   536  			fmt.Println("CaptureAccountWrite err", err)
   537  		}
   538  	}
   539  
   540  	stateObject := sdb.GetOrNewStateObject(addr)
   541  	if stateObject != nil {
   542  		stateObject.SetCode(crypto.Keccak256Hash(code), code)
   543  	}
   544  }
   545  
   546  // DESCRIBED: docs/programmers_guide/guide.md#address---identifier-of-an-account
   547  func (sdb *IntraBlockState) SetState(addr types.Address, key *types.Hash, value uint256.Int) {
   548  	stateObject := sdb.GetOrNewStateObject(addr)
   549  	if stateObject != nil {
   550  		stateObject.SetState(key, value)
   551  	}
   552  }
   553  
   554  // SetStorage replaces the entire storage for the specified account with given
   555  // storage. This function should only be used for debugging.
   556  func (sdb *IntraBlockState) SetStorage(addr types.Address, storage Storage) {
   557  	stateObject := sdb.GetOrNewStateObject(addr)
   558  	if stateObject != nil {
   559  		stateObject.SetStorage(storage)
   560  	}
   561  }
   562  
   563  // SetIncarnation sets incarnation for account if account exists
   564  func (sdb *IntraBlockState) SetIncarnation(addr types.Address, incarnation uint16) {
   565  	stateObject := sdb.GetOrNewStateObject(addr)
   566  	if stateObject != nil {
   567  		stateObject.setIncarnation(incarnation)
   568  	}
   569  }
   570  
   571  func (sdb *IntraBlockState) GetIncarnation(addr types.Address) uint16 {
   572  	stateObject := sdb.getStateObject(addr)
   573  	if stateObject != nil {
   574  		return stateObject.data.Incarnation
   575  	}
   576  	return 0
   577  }
   578  
   579  // Suicide marks the given account as suicided.
   580  // This clears the account balance.
   581  //
   582  // The account's state object is still available until the state is committed,
   583  // getStateObject will return a non-nil account after Suicide.
   584  func (sdb *IntraBlockState) Suicide(addr types.Address) bool {
   585  	if sdb.tracer != nil {
   586  		err := sdb.tracer.CaptureAccountRead(addr)
   587  		if sdb.trace {
   588  			fmt.Println("CaptureAccountRead err", err)
   589  		}
   590  		err = sdb.tracer.CaptureAccountWrite(addr)
   591  		if sdb.trace {
   592  			fmt.Println("CaptureAccountWrite err", err)
   593  		}
   594  	}
   595  	stateObject := sdb.getStateObject(addr)
   596  	if stateObject == nil || stateObject.deleted {
   597  		return false
   598  	}
   599  	sdb.journal.append(selfdestructChange{
   600  		account:     &addr,
   601  		prev:        stateObject.selfdestructed,
   602  		prevbalance: *stateObject.Balance(),
   603  	})
   604  	stateObject.markSelfdestructed()
   605  	stateObject.created = false
   606  	stateObject.data.Balance.Clear()
   607  
   608  	return true
   609  }
   610  
   611  func (sdb *IntraBlockState) getStateObject(addr types.Address) (stateObject *stateObject) {
   612  	// Prefer 'live' objects.
   613  	if obj := sdb.stateObjects[addr]; obj != nil {
   614  		return obj
   615  	}
   616  
   617  	// Load the object from the database.
   618  	if _, ok := sdb.nilAccounts[addr]; ok {
   619  		if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred {
   620  			return sdb.createObject(addr, nil)
   621  		}
   622  		return nil
   623  	}
   624  	account, err := sdb.stateReader.ReadAccountData(addr)
   625  	if err != nil {
   626  		sdb.setErrorUnsafe(err)
   627  		return nil
   628  	}
   629  	if account == nil {
   630  		sdb.nilAccounts[addr] = struct{}{}
   631  		if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred {
   632  			return sdb.createObject(addr, nil)
   633  		}
   634  		return nil
   635  	}
   636  
   637  	// snap write
   638  	if sdb.snap != nil && sdb.snap.CanWrite() {
   639  		sdb.snap.AddAccount(addr, account)
   640  	}
   641  
   642  	// Insert into the live set.
   643  	obj := newObject(sdb, addr, account, account)
   644  	sdb.setStateObject(addr, obj)
   645  	return obj
   646  }
   647  
   648  func (sdb *IntraBlockState) setStateObject(addr types.Address, object *stateObject) {
   649  	if bi, ok := sdb.balanceInc[addr]; ok && !bi.transferred {
   650  		object.data.Balance.Add(&object.data.Balance, &bi.increase)
   651  		bi.transferred = true
   652  		sdb.journal.append(balanceIncreaseTransfer{bi: bi})
   653  	}
   654  	sdb.stateObjects[addr] = object
   655  }
   656  
   657  // Retrieve a state object or create a new state object if nil.
   658  func (sdb *IntraBlockState) GetOrNewStateObject(addr types.Address) *stateObject {
   659  	stateObject := sdb.getStateObject(addr)
   660  	if stateObject == nil || stateObject.deleted {
   661  		stateObject = sdb.createObject(addr, stateObject /* previous */)
   662  	}
   663  	return stateObject
   664  }
   665  
   666  // createObject creates a new state object. If there is an existing account with
   667  // the given address, it is overwritten.
   668  func (sdb *IntraBlockState) createObject(addr types.Address, previous *stateObject) (newobj *stateObject) {
   669  	ac := new(account.StateAccount)
   670  	var original *account.StateAccount
   671  	if previous == nil {
   672  		original = &account.StateAccount{}
   673  	} else {
   674  		original = &previous.original
   675  	}
   676  	newobj = newObject(sdb, addr, ac, original)
   677  	newobj.setNonce(0) // sets the object to dirty
   678  	if previous == nil {
   679  		sdb.journal.append(createObjectChange{account: &addr})
   680  	} else {
   681  		sdb.journal.append(resetObjectChange{account: &addr, prev: previous})
   682  	}
   683  	sdb.setStateObject(addr, newobj)
   684  	return newobj
   685  }
   686  
   687  // CreateAccount explicitly creates a state object. If a state object with the address
   688  // already exists the balance is carried over to the new account.
   689  //
   690  // CreateAccount is called during the EVM CREATE operation. The situation might arise that
   691  // a contract does the following:
   692  //
   693  //  1. sends funds to sha(account ++ (nonce + 1))
   694  //  2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
   695  //
   696  // Carrying over the balance ensures that AMT doesn't disappear.
   697  func (sdb *IntraBlockState) CreateAccount(addr types.Address, contractCreation bool) {
   698  	if sdb.tracer != nil {
   699  		err := sdb.tracer.CaptureAccountRead(addr)
   700  		if sdb.trace && err != nil {
   701  			log.Error("error while CaptureAccountRead", "err", err)
   702  		}
   703  
   704  		err = sdb.tracer.CaptureAccountWrite(addr)
   705  		if sdb.trace && err != nil {
   706  			log.Error("error while CaptureAccountWrite", "err", err)
   707  		}
   708  	}
   709  
   710  	var prevInc uint16
   711  	previous := sdb.getStateObject(addr)
   712  	if contractCreation {
   713  		if previous != nil && previous.selfdestructed {
   714  			prevInc = previous.data.Incarnation
   715  		} else {
   716  			inc, err := sdb.stateReader.ReadAccountIncarnation(addr)
   717  			if sdb.trace && err != nil {
   718  				log.Error("error while ReadAccountIncarnation", "err", err)
   719  			}
   720  			if err == nil {
   721  				prevInc = inc
   722  			}
   723  		}
   724  	}
   725  
   726  	newObj := sdb.createObject(addr, previous)
   727  	if previous != nil {
   728  		newObj.data.Balance.Set(&previous.data.Balance)
   729  		newObj.data.Initialised = true
   730  	}
   731  
   732  	if contractCreation {
   733  		newObj.created = true
   734  		newObj.data.Incarnation = prevInc + 1
   735  	} else {
   736  		newObj.selfdestructed = false
   737  	}
   738  }
   739  
   740  // Snapshot returns an identifier for the current revision of the state.
   741  func (sdb *IntraBlockState) Snapshot() int {
   742  	id := sdb.nextRevisionID
   743  	sdb.nextRevisionID++
   744  	sdb.validRevisions = append(sdb.validRevisions, revision{id, sdb.journal.length()})
   745  	return id
   746  }
   747  
   748  // RevertToSnapshot reverts all state changes made since the given revision.
   749  func (sdb *IntraBlockState) RevertToSnapshot(revid int) {
   750  	// Find the snapshot in the stack of valid snapshots.
   751  	idx := sort.Search(len(sdb.validRevisions), func(i int) bool {
   752  		return sdb.validRevisions[i].id >= revid
   753  	})
   754  	if idx == len(sdb.validRevisions) || sdb.validRevisions[idx].id != revid {
   755  		panic(fmt.Errorf("revision id %v cannot be reverted", revid))
   756  	}
   757  	snapshot := sdb.validRevisions[idx].journalIndex
   758  
   759  	// Replay the journal to undo changes and remove invalidated snapshots
   760  	sdb.journal.revert(sdb, snapshot)
   761  	sdb.validRevisions = sdb.validRevisions[:idx]
   762  }
   763  
   764  // GetRefund returns the current value of the refund counter.
   765  func (sdb *IntraBlockState) GetRefund() uint64 {
   766  	return sdb.refund
   767  }
   768  
   769  func updateAccount(EIP161Enabled bool, isAura bool, stateWriter StateWriter, addr types.Address, stateObject *stateObject, isDirty bool) error {
   770  	emptyRemoval := EIP161Enabled && stateObject.empty() && (!isAura || addr != SystemAddress)
   771  	if stateObject.selfdestructed || (isDirty && emptyRemoval) {
   772  		if err := stateWriter.DeleteAccount(addr, &stateObject.original); err != nil {
   773  			return err
   774  		}
   775  		stateObject.deleted = true
   776  	}
   777  	if isDirty && (stateObject.created || !stateObject.selfdestructed) && !emptyRemoval {
   778  		stateObject.deleted = false
   779  		// Write any contract code associated with the state object
   780  		if stateObject.code != nil && stateObject.dirtyCode {
   781  			if err := stateWriter.UpdateAccountCode(addr, stateObject.data.Incarnation, stateObject.data.CodeHash, stateObject.code); err != nil {
   782  				return err
   783  			}
   784  		}
   785  		if stateObject.created {
   786  			if err := stateWriter.CreateContract(addr); err != nil {
   787  				return err
   788  			}
   789  		}
   790  		if err := stateObject.updateTrie(stateWriter); err != nil {
   791  			return err
   792  		}
   793  		if err := stateWriter.UpdateAccountData(addr, &stateObject.original, &stateObject.data); err != nil {
   794  			return err
   795  		}
   796  	}
   797  	return nil
   798  }
   799  
   800  func printAccount(addr types.Address, stateObject *stateObject, isDirty bool) {
   801  	emptyRemoval := stateObject.empty()
   802  	if stateObject.selfdestructed || (isDirty && emptyRemoval) {
   803  		fmt.Printf("delete: %x\n", addr)
   804  	}
   805  	if isDirty && (stateObject.created || !stateObject.selfdestructed) && !emptyRemoval {
   806  		// Write any contract code associated with the state object
   807  		if stateObject.code != nil && stateObject.dirtyCode {
   808  			fmt.Printf("UpdateCode: %x,%x\n", addr, stateObject.CodeHash())
   809  		}
   810  		if stateObject.created {
   811  			fmt.Printf("CreateContract: %x\n", addr)
   812  		}
   813  		stateObject.printTrie()
   814  		if stateObject.data.Balance.IsUint64() {
   815  			fmt.Printf("UpdateAccountData: %x, balance=%d, nonce=%d\n", addr, stateObject.data.Balance.Uint64(), stateObject.data.Nonce)
   816  		} else {
   817  			div := uint256.NewInt(1_000_000_000)
   818  			fmt.Printf("UpdateAccountData: %x, balance=%d*%d, nonce=%d\n", addr, uint256.NewInt(0).Div(&stateObject.data.Balance, div).Uint64(), div.Uint64(), stateObject.data.Nonce)
   819  		}
   820  	}
   821  }
   822  
   823  // FinalizeTx should be called after every transaction.
   824  func (sdb *IntraBlockState) FinalizeTx(chainRules *params.Rules, stateWriter StateWriter) error {
   825  	for addr, bi := range sdb.balanceInc {
   826  		if !bi.transferred {
   827  			sdb.getStateObject(addr)
   828  		}
   829  	}
   830  	for addr := range sdb.journal.dirties {
   831  		so, exist := sdb.stateObjects[addr]
   832  		if !exist {
   833  			// ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2
   834  			// That tx goes out of gas, and although the notion of 'touched' does not exist there, the
   835  			// touch-event will still be recorded in the journal. Since ripeMD is a special snowflake,
   836  			// it will persist in the journal even though the journal is reverted. In this special circumstance,
   837  			// it may exist in `sdb.journal.dirties` but not in `sdb.stateObjects`.
   838  			// Thus, we can safely ignore it here
   839  			continue
   840  		}
   841  
   842  		if err := updateAccount(chainRules.IsSpuriousDragon, chainRules.IsAura, stateWriter, addr, so, true); err != nil {
   843  			return err
   844  		}
   845  
   846  		sdb.stateObjectsDirty[addr] = struct{}{}
   847  	}
   848  	// Invalidate journal because reverting across transactions is not allowed.
   849  	sdb.clearJournalAndRefund()
   850  	return nil
   851  }
   852  
   853  func (sdb *IntraBlockState) SoftFinalise() {
   854  	for addr := range sdb.journal.dirties {
   855  		_, exist := sdb.stateObjects[addr]
   856  		if !exist {
   857  			// ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2
   858  			// That tx goes out of gas, and although the notion of 'touched' does not exist there, the
   859  			// touch-event will still be recorded in the journal. Since ripeMD is a special snowflake,
   860  			// it will persist in the journal even though the journal is reverted. In this special circumstance,
   861  			// it may exist in `sdb.journal.dirties` but not in `sdb.stateObjects`.
   862  			// Thus, we can safely ignore it here
   863  			continue
   864  		}
   865  		sdb.stateObjectsDirty[addr] = struct{}{}
   866  	}
   867  	// Invalidate journal because reverting across transactions is not allowed.
   868  	sdb.clearJournalAndRefund()
   869  }
   870  
   871  // CommitBlock finalizes the state by removing the self destructed objects
   872  // and clears the journal as well as the refunds.
   873  func (sdb *IntraBlockState) CommitBlock(chainRules *params.Rules, stateWriter StateWriter) error {
   874  	for addr, bi := range sdb.balanceInc {
   875  		if !bi.transferred {
   876  			sdb.getStateObject(addr)
   877  		}
   878  	}
   879  	return sdb.MakeWriteSet(chainRules, stateWriter)
   880  }
   881  
   882  func (sdb *IntraBlockState) BalanceIncreaseSet() map[types.Address]uint256.Int {
   883  	s := map[types.Address]uint256.Int{}
   884  	for addr, bi := range sdb.balanceInc {
   885  		if !bi.transferred {
   886  			s[addr] = bi.increase
   887  		}
   888  	}
   889  	return s
   890  }
   891  
   892  func (sdb *IntraBlockState) MakeWriteSet(chainRules *params.Rules, stateWriter StateWriter) error {
   893  	for addr := range sdb.journal.dirties {
   894  		sdb.stateObjectsDirty[addr] = struct{}{}
   895  	}
   896  	for addr, stateObject := range sdb.stateObjects {
   897  		_, isDirty := sdb.stateObjectsDirty[addr]
   898  		if err := updateAccount(chainRules.IsSpuriousDragon, chainRules.IsAura, stateWriter, addr, stateObject, isDirty); err != nil {
   899  			return err
   900  		}
   901  	}
   902  	// Invalidate journal because reverting across transactions is not allowed.
   903  	sdb.clearJournalAndRefund()
   904  	return nil
   905  }
   906  
   907  func (sdb *IntraBlockState) Print() {
   908  	for addr, stateObject := range sdb.stateObjects {
   909  		_, isDirty := sdb.stateObjectsDirty[addr]
   910  		_, isDirty2 := sdb.journal.dirties[addr]
   911  
   912  		printAccount(addr, stateObject, isDirty || isDirty2)
   913  	}
   914  }
   915  
   916  // Prepare sets the current transaction hash and index and block hash which is
   917  // used when the EVM emits new state logs.
   918  func (sdb *IntraBlockState) Prepare(thash, bhash types.Hash, ti int) {
   919  	sdb.thash = thash
   920  	sdb.bhash = bhash
   921  	sdb.txIndex = ti
   922  	sdb.accessList = newAccessList()
   923  }
   924  
   925  // no not lock
   926  func (sdb *IntraBlockState) clearJournalAndRefund() {
   927  	sdb.journal = newJournal()
   928  	sdb.validRevisions = sdb.validRevisions[:0]
   929  	sdb.refund = 0
   930  }
   931  
   932  // PrepareAccessList handles the preparatory steps for executing a state transition with
   933  // regards to both EIP-2929 and EIP-2930:
   934  //
   935  // - Add sender to access list (2929)
   936  // - Add destination to access list (2929)
   937  // - Add precompiles to access list (2929)
   938  // - Add the contents of the optional tx access list (2930)
   939  //
   940  // This method should only be called if Yolov3/Berlin/2929+2930 is applicable at the current number.
   941  func (sdb *IntraBlockState) PrepareAccessList(sender types.Address, dst *types.Address, precompiles []types.Address, list transaction.AccessList) {
   942  	sdb.AddAddressToAccessList(sender)
   943  	if dst != nil {
   944  		sdb.AddAddressToAccessList(*dst)
   945  		// If it's a create-tx, the destination will be added inside evm.create
   946  	}
   947  	for _, addr := range precompiles {
   948  		sdb.AddAddressToAccessList(addr)
   949  	}
   950  	for _, el := range list {
   951  		sdb.AddAddressToAccessList(el.Address)
   952  		for _, key := range el.StorageKeys {
   953  			sdb.AddSlotToAccessList(el.Address, key)
   954  		}
   955  	}
   956  }
   957  
   958  // AddAddressToAccessList adds the given address to the access list
   959  func (sdb *IntraBlockState) AddAddressToAccessList(addr types.Address) {
   960  	if sdb.accessList.AddAddress(addr) {
   961  		sdb.journal.append(accessListAddAccountChange{&addr})
   962  	}
   963  }
   964  
   965  // AddSlotToAccessList adds the given (address, slot)-tuple to the access list
   966  func (sdb *IntraBlockState) AddSlotToAccessList(addr types.Address, slot types.Hash) {
   967  	addrMod, slotMod := sdb.accessList.AddSlot(addr, slot)
   968  	if addrMod {
   969  		// In practice, this should not happen, since there is no way to enter the
   970  		// scope of 'address' without having the 'address' become already added
   971  		// to the access list (via call-variant, create, etc).
   972  		// Better safe than sorry, though
   973  		sdb.journal.append(accessListAddAccountChange{&addr})
   974  	}
   975  	if slotMod {
   976  		sdb.journal.append(accessListAddSlotChange{
   977  			address: &addr,
   978  			slot:    &slot,
   979  		})
   980  	}
   981  }
   982  
   983  // AddressInAccessList returns true if the given address is in the access list.
   984  func (sdb *IntraBlockState) AddressInAccessList(addr types.Address) bool {
   985  	return sdb.accessList.ContainsAddress(addr)
   986  }
   987  
   988  // SlotInAccessList returns true if the given (address, slot)-tuple is in the access list.
   989  func (sdb *IntraBlockState) SlotInAccessList(addr types.Address, slot types.Hash) (addressPresent bool, slotPresent bool) {
   990  	return sdb.accessList.Contains(addr, slot)
   991  }
   992  
   993  // GenerateRootHash calculate root hash
   994  func (s *IntraBlockState) GenerateRootHash() types.Hash {
   995  	if len(s.stateObjectsDirty) == 0 {
   996  		return hash.NilHash
   997  	}
   998  
   999  	sortAds := make(types.Addresses, 0, len(s.stateObjectsDirty))
  1000  	for a := range s.stateObjectsDirty {
  1001  		sortAds = append(sortAds, a)
  1002  	}
  1003  	sort.Sort(sortAds)
  1004  	//
  1005  	sha := hash.HasherPool.Get().(crypto.KeccakState)
  1006  	defer hash.HasherPool.Put(sha)
  1007  	sha.Reset()
  1008  
  1009  	for _, address := range sortAds {
  1010  		stateObject := s.getStateObject(address).data
  1011  		err := rlp.Encode(sha, []interface{}{
  1012  			stateObject.Incarnation,
  1013  			stateObject.Balance,
  1014  			stateObject.Nonce,
  1015  			stateObject.Initialised,
  1016  			stateObject.CodeHash,
  1017  			stateObject.Root,
  1018  		})
  1019  		if err != nil {
  1020  			panic("can't encode: " + err.Error())
  1021  		}
  1022  		//log.Info("GenerateRootHash", "address", address)
  1023  	}
  1024  
  1025  	var root types.Hash
  1026  	sha.Read(root[:])
  1027  
  1028  	//log.Info("GenerateRootHash ", "root", root.Hex())
  1029  
  1030  	return root
  1031  }
  1032  
  1033  // IntermediateRoot root
  1034  func (s *IntraBlockState) IntermediateRoot() types.Hash {
  1035  	return s.GenerateRootHash()
  1036  }
  1037  
  1038  func (sdb *IntraBlockState) HasSelfdestructed(addr types.Address) bool {
  1039  	stateObject := sdb.getStateObject(addr)
  1040  	if stateObject == nil {
  1041  		return false
  1042  	}
  1043  	if stateObject.deleted {
  1044  		return false
  1045  	}
  1046  	if stateObject.created {
  1047  		return false
  1048  	}
  1049  	return stateObject.selfdestructed
  1050  }
  1051  
  1052  // Selfdestruct marks the given account as suicided.
  1053  // This clears the account balance.
  1054  //
  1055  // The account's state object is still available until the state is committed,
  1056  // getStateObject will return a non-nil account after Suicide.
  1057  func (sdb *IntraBlockState) Selfdestruct(addr types.Address) bool {
  1058  	stateObject := sdb.getStateObject(addr)
  1059  	if stateObject == nil || stateObject.deleted {
  1060  		return false
  1061  	}
  1062  	sdb.journal.append(selfdestructChange{
  1063  		account:     &addr,
  1064  		prev:        stateObject.selfdestructed,
  1065  		prevbalance: *stateObject.Balance(),
  1066  	})
  1067  	stateObject.markSelfdestructed()
  1068  	stateObject.created = false
  1069  	stateObject.data.Balance.Clear()
  1070  
  1071  	return true
  1072  }
  1073  
  1074  // BeforeStateRoot calculate used state hash
  1075  //
  1076  // it should be invoked after all txs exec
  1077  func (sdb *IntraBlockState) BeforeStateRoot() (hash types.Hash) {
  1078  	if sdb.snap == nil {
  1079  		return types.Hash{}
  1080  	}
  1081  	sort.Sort(sdb.snap.Items)
  1082  	ch := sdb.CodeHashes()
  1083  	hs := make(HashCodes, 0, len(ch))
  1084  	for k, v := range ch {
  1085  		hs = append(hs, &HashCode{Hash: k, Code: v})
  1086  	}
  1087  	sort.Sort(hs)
  1088  	hasher := sha3.NewLegacyKeccak256()
  1089  	EncodeBeforeState(hasher, sdb.snap.Items, hs)
  1090  	hasher.(crypto.KeccakState).Read(hash[:])
  1091  	return
  1092  }