github.com/iotexproject/iotex-core@v1.14.1-rc1/action/protocol/execution/evm/evmstatedbadapter.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package evm
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/hex"
    11  	"fmt"
    12  	"math/big"
    13  	"sort"
    14  
    15  	"github.com/ethereum/go-ethereum/common"
    16  	"github.com/ethereum/go-ethereum/core/types"
    17  	"github.com/ethereum/go-ethereum/params"
    18  	"github.com/pkg/errors"
    19  	"go.uber.org/zap"
    20  
    21  	"github.com/iotexproject/go-pkgs/hash"
    22  	"github.com/iotexproject/iotex-address/address"
    23  	"github.com/iotexproject/iotex-proto/golang/iotextypes"
    24  
    25  	"github.com/iotexproject/iotex-core/action"
    26  	"github.com/iotexproject/iotex-core/action/protocol"
    27  	accountutil "github.com/iotexproject/iotex-core/action/protocol/account/util"
    28  	"github.com/iotexproject/iotex-core/db/trie"
    29  	"github.com/iotexproject/iotex-core/pkg/log"
    30  	"github.com/iotexproject/iotex-core/state"
    31  )
    32  
    33  type (
    34  	// deleteAccount records the account/contract to be deleted
    35  	deleteAccount map[hash.Hash160]struct{}
    36  
    37  	// contractMap records the contracts being changed
    38  	contractMap map[hash.Hash160]Contract
    39  
    40  	// preimageMap records the preimage of hash reported by VM
    41  	preimageMap map[common.Hash]protocol.SerializableBytes
    42  
    43  	// StateDBAdapter represents the state db adapter for evm to access iotx blockchain
    44  	StateDBAdapter struct {
    45  		sm                         protocol.StateManager
    46  		logs                       []*action.Log
    47  		transactionLogs            []*action.TransactionLog
    48  		err                        error
    49  		blockHeight                uint64
    50  		executionHash              hash.Hash256
    51  		lastAddBalanceAddr         string
    52  		lastAddBalanceAmount       *big.Int
    53  		refund                     uint64
    54  		refundSnapshot             map[int]uint64
    55  		cachedContract             contractMap
    56  		contractSnapshot           map[int]contractMap   // snapshots of contracts
    57  		suicided                   deleteAccount         // account/contract calling Suicide
    58  		suicideSnapshot            map[int]deleteAccount // snapshots of suicide accounts
    59  		preimages                  preimageMap
    60  		preimageSnapshot           map[int]preimageMap
    61  		accessList                 *accessList // per-transaction access list
    62  		accessListSnapshot         map[int]*accessList
    63  		logsSnapshot               map[int]int // logs is an array, save len(logs) at time of snapshot suffices
    64  		txLogsSnapshot             map[int]int
    65  		notFixTopicCopyBug         bool
    66  		asyncContractTrie          bool
    67  		disableSortCachedContracts bool
    68  		useConfirmedNonce          bool
    69  		legacyNonceAccount         bool
    70  		fixSnapshotOrder           bool
    71  		revertLog                  bool
    72  		manualCorrectGasRefund     bool
    73  		suicideTxLogMismatchPanic  bool
    74  		zeroNonceForFreshAccount   bool
    75  	}
    76  )
    77  
    78  // StateDBAdapterOption set StateDBAdapter construction param
    79  type StateDBAdapterOption func(*StateDBAdapter) error
    80  
    81  // DisableSortCachedContractsOption set disable sort cached contracts as true
    82  func DisableSortCachedContractsOption() StateDBAdapterOption {
    83  	return func(adapter *StateDBAdapter) error {
    84  		adapter.disableSortCachedContracts = true
    85  		return nil
    86  	}
    87  }
    88  
    89  // NotFixTopicCopyBugOption set notFixTopicCopyBug as true
    90  func NotFixTopicCopyBugOption() StateDBAdapterOption {
    91  	return func(adapter *StateDBAdapter) error {
    92  		adapter.notFixTopicCopyBug = true
    93  		return nil
    94  	}
    95  }
    96  
    97  // AsyncContractTrieOption set asyncContractTrie as true
    98  func AsyncContractTrieOption() StateDBAdapterOption {
    99  	return func(adapter *StateDBAdapter) error {
   100  		adapter.asyncContractTrie = true
   101  		return nil
   102  	}
   103  }
   104  
   105  // UseConfirmedNonceOption set usePendingNonce as true
   106  func UseConfirmedNonceOption() StateDBAdapterOption {
   107  	return func(adapter *StateDBAdapter) error {
   108  		adapter.useConfirmedNonce = true
   109  		return nil
   110  	}
   111  }
   112  
   113  // LegacyNonceAccountOption set legacyNonceAccount as true
   114  func LegacyNonceAccountOption() StateDBAdapterOption {
   115  	return func(adapter *StateDBAdapter) error {
   116  		adapter.legacyNonceAccount = true
   117  		return nil
   118  	}
   119  }
   120  
   121  // FixSnapshotOrderOption set fixSnapshotOrder as true
   122  func FixSnapshotOrderOption() StateDBAdapterOption {
   123  	return func(adapter *StateDBAdapter) error {
   124  		adapter.fixSnapshotOrder = true
   125  		return nil
   126  	}
   127  }
   128  
   129  // RevertLogOption set revertLog as true
   130  func RevertLogOption() StateDBAdapterOption {
   131  	return func(adapter *StateDBAdapter) error {
   132  		adapter.revertLog = true
   133  		return nil
   134  	}
   135  }
   136  
   137  // ManualCorrectGasRefundOption set manualCorrectGasRefund as true
   138  func ManualCorrectGasRefundOption() StateDBAdapterOption {
   139  	return func(adapter *StateDBAdapter) error {
   140  		// before London EVM activation (at Okhotsk height), in certain cases dynamicGas
   141  		// has caused gas refund to change, which needs to be manually adjusted after
   142  		// the tx is reverted. After Okhotsk height, it is fixed inside RevertToSnapshot()
   143  		adapter.manualCorrectGasRefund = true
   144  		return nil
   145  	}
   146  }
   147  
   148  // SuicideTxLogMismatchPanicOption set suicideTxLogMismatchPanic as true
   149  func SuicideTxLogMismatchPanicOption() StateDBAdapterOption {
   150  	return func(adapter *StateDBAdapter) error {
   151  		adapter.suicideTxLogMismatchPanic = true
   152  		return nil
   153  	}
   154  }
   155  
   156  // ZeroNonceForFreshAccountOption set zeroNonceForFreshAccount as true
   157  func ZeroNonceForFreshAccountOption() StateDBAdapterOption {
   158  	return func(adapter *StateDBAdapter) error {
   159  		adapter.zeroNonceForFreshAccount = true
   160  		return nil
   161  	}
   162  }
   163  
   164  // NewStateDBAdapter creates a new state db with iotex blockchain
   165  func NewStateDBAdapter(
   166  	sm protocol.StateManager,
   167  	blockHeight uint64,
   168  	executionHash hash.Hash256,
   169  	opts ...StateDBAdapterOption,
   170  ) (*StateDBAdapter, error) {
   171  	s := &StateDBAdapter{
   172  		sm:                   sm,
   173  		logs:                 []*action.Log{},
   174  		err:                  nil,
   175  		blockHeight:          blockHeight,
   176  		executionHash:        executionHash,
   177  		lastAddBalanceAmount: new(big.Int),
   178  		refundSnapshot:       make(map[int]uint64),
   179  		cachedContract:       make(contractMap),
   180  		contractSnapshot:     make(map[int]contractMap),
   181  		suicided:             make(deleteAccount),
   182  		suicideSnapshot:      make(map[int]deleteAccount),
   183  		preimages:            make(preimageMap),
   184  		preimageSnapshot:     make(map[int]preimageMap),
   185  		accessList:           newAccessList(),
   186  		accessListSnapshot:   make(map[int]*accessList),
   187  		logsSnapshot:         make(map[int]int),
   188  		txLogsSnapshot:       make(map[int]int),
   189  	}
   190  	for _, opt := range opts {
   191  		if err := opt(s); err != nil {
   192  			return nil, errors.Wrap(err, "failed to execute stateDB creation option")
   193  		}
   194  	}
   195  	// TODO: add combination limitation for useZeroNonceForFreshAccount
   196  	if !s.legacyNonceAccount && s.useConfirmedNonce {
   197  		return nil, errors.New("invalid parameter combination")
   198  	}
   199  	return s, nil
   200  }
   201  
   202  func (stateDB *StateDBAdapter) logError(err error) {
   203  	if stateDB.err == nil {
   204  		stateDB.err = err
   205  	}
   206  }
   207  
   208  // Error returns the first stored error during evm contract execution
   209  func (stateDB *StateDBAdapter) Error() error {
   210  	return stateDB.err
   211  }
   212  
   213  func (stateDB *StateDBAdapter) accountCreationOpts() []state.AccountCreationOption {
   214  	if stateDB.legacyNonceAccount {
   215  		return []state.AccountCreationOption{state.LegacyNonceAccountTypeOption()}
   216  	}
   217  	return nil
   218  }
   219  
   220  // CreateAccount creates an account in iotx blockchain
   221  func (stateDB *StateDBAdapter) CreateAccount(evmAddr common.Address) {
   222  	addr, err := address.FromBytes(evmAddr.Bytes())
   223  	if err != nil {
   224  		log.L().Error("Failed to convert evm address.", zap.Error(err))
   225  		return
   226  	}
   227  	_, err = accountutil.LoadOrCreateAccount(stateDB.sm, addr, stateDB.accountCreationOpts()...)
   228  	if err != nil {
   229  		log.L().Error("Failed to create account.", zap.Error(err))
   230  		stateDB.logError(err)
   231  		return
   232  	}
   233  	log.L().Debug("Called CreateAccount.", log.Hex("addrHash", evmAddr[:]))
   234  }
   235  
   236  // SubBalance subtracts balance from account
   237  func (stateDB *StateDBAdapter) SubBalance(evmAddr common.Address, amount *big.Int) {
   238  	if amount.Cmp(big.NewInt(int64(0))) == 0 {
   239  		return
   240  	}
   241  	// stateDB.GetBalance(evmAddr)
   242  	log.L().Debug(fmt.Sprintf("SubBalance %v from %s", amount, evmAddr.Hex()))
   243  	addr, err := address.FromBytes(evmAddr.Bytes())
   244  	if err != nil {
   245  		log.L().Error("Failed to convert evm address.", zap.Error(err))
   246  		return
   247  	}
   248  	state, err := stateDB.accountState(evmAddr)
   249  	if err != nil {
   250  		log.L().Error("Failed to sub balance.", zap.Error(err))
   251  		stateDB.logError(err)
   252  		return
   253  	}
   254  	if err := state.SubBalance(amount); err != nil {
   255  		log.L().Error("Failed to sub balance.", zap.Error(err))
   256  		stateDB.logError(err)
   257  		return
   258  	}
   259  	if err := accountutil.StoreAccount(stateDB.sm, addr, state); err != nil {
   260  		log.L().Error("Failed to update pending account changes to trie.", zap.Error(err))
   261  		stateDB.logError(err)
   262  	}
   263  }
   264  
   265  // AddBalance adds balance to account
   266  func (stateDB *StateDBAdapter) AddBalance(evmAddr common.Address, amount *big.Int) {
   267  	stateDB.lastAddBalanceAmount.SetUint64(0)
   268  	if amount.Cmp(big.NewInt(int64(0))) == 0 {
   269  		return
   270  	}
   271  	// stateDB.GetBalance(evmAddr)
   272  	log.L().Debug(fmt.Sprintf("AddBalance %v to %s", amount, evmAddr.Hex()))
   273  
   274  	addr, err := address.FromBytes(evmAddr.Bytes())
   275  	if err != nil {
   276  		log.L().Error("Failed to convert evm address.", zap.Error(err))
   277  		return
   278  	}
   279  	var (
   280  		state    *state.Account
   281  		addrHash = hash.BytesToHash160(evmAddr[:])
   282  	)
   283  	if contract, ok := stateDB.cachedContract[addrHash]; ok {
   284  		state = contract.SelfState()
   285  	} else {
   286  		state, err = accountutil.LoadOrCreateAccount(stateDB.sm, addr, stateDB.accountCreationOpts()...)
   287  		if err != nil {
   288  			log.L().Error("Failed to add balance.", log.Hex("addrHash", evmAddr[:]))
   289  			stateDB.logError(err)
   290  			return
   291  		}
   292  	}
   293  	if err := state.AddBalance(amount); err != nil {
   294  		log.L().Error("failed to add balance", zap.Error(err), zap.String("amount", amount.String()))
   295  		stateDB.logError(err)
   296  		return
   297  	}
   298  	if err := accountutil.StoreAccount(stateDB.sm, addr, state); err != nil {
   299  		log.L().Error("Failed to update pending account changes to trie.", zap.Error(err))
   300  		stateDB.logError(err)
   301  	} else {
   302  		// keep a record of latest add balance
   303  		stateDB.lastAddBalanceAddr = addr.String()
   304  		stateDB.lastAddBalanceAmount.SetBytes(amount.Bytes())
   305  	}
   306  }
   307  
   308  // GetBalance gets the balance of account
   309  func (stateDB *StateDBAdapter) GetBalance(evmAddr common.Address) *big.Int {
   310  	state, err := stateDB.accountState(evmAddr)
   311  	if err != nil {
   312  		log.L().Error("Failed to get balance.", zap.Error(err))
   313  		return big.NewInt(0)
   314  	}
   315  	log.L().Debug(fmt.Sprintf("Balance of %s is %v", evmAddr.Hex(), state.Balance))
   316  
   317  	return state.Balance
   318  }
   319  
   320  // IsNewAccount returns true if this is a new account
   321  func (stateDB *StateDBAdapter) IsNewAccount(evmAddr common.Address) bool {
   322  	state, err := stateDB.accountState(evmAddr)
   323  	if err != nil {
   324  		log.L().Error("failed to load account.", zap.Error(err), zap.String("address", evmAddr.Hex()))
   325  		return false
   326  	}
   327  
   328  	return state.IsNewbieAccount()
   329  }
   330  
   331  // GetNonce gets the nonce of account
   332  func (stateDB *StateDBAdapter) GetNonce(evmAddr common.Address) uint64 {
   333  	var pendingNonce uint64
   334  	if stateDB.legacyNonceAccount {
   335  		pendingNonce = uint64(1)
   336  	} else {
   337  		pendingNonce = uint64(0)
   338  	}
   339  	state, err := stateDB.accountState(evmAddr)
   340  	if err != nil {
   341  		log.L().Error("Failed to get nonce.", zap.Error(err))
   342  		// stateDB.logError(err)
   343  	} else {
   344  		if stateDB.zeroNonceForFreshAccount {
   345  			pendingNonce = state.PendingNonceConsideringFreshAccount()
   346  		} else {
   347  			pendingNonce = state.PendingNonce()
   348  		}
   349  	}
   350  	if stateDB.useConfirmedNonce {
   351  		if pendingNonce == 0 {
   352  			panic("invalid pending nonce")
   353  		}
   354  		pendingNonce--
   355  	}
   356  	log.L().Debug("Called GetNonce.",
   357  		zap.String("address", evmAddr.Hex()),
   358  		zap.Uint64("pendingNonce", pendingNonce))
   359  
   360  	return pendingNonce
   361  }
   362  
   363  // SetNonce sets the nonce of account
   364  func (stateDB *StateDBAdapter) SetNonce(evmAddr common.Address, nonce uint64) {
   365  	addr, err := address.FromBytes(evmAddr.Bytes())
   366  	if err != nil {
   367  		log.L().Error("Failed to convert evm address.", zap.Error(err))
   368  		return
   369  	}
   370  	s, err := stateDB.accountState(evmAddr)
   371  	if err != nil {
   372  		log.L().Error("Failed to set nonce.", zap.Error(err))
   373  		// stateDB.logError(err)
   374  		return
   375  	}
   376  	if !stateDB.useConfirmedNonce {
   377  		if nonce == 0 {
   378  			panic("invalid nonce zero")
   379  		}
   380  		nonce--
   381  	}
   382  	log.L().Debug("Called SetNonce.",
   383  		zap.String("address", addr.String()),
   384  		zap.Uint64("nonce", nonce))
   385  	if !s.IsNewbieAccount() || s.AccountType() != 0 || nonce != 0 || stateDB.zeroNonceForFreshAccount {
   386  		if err := s.SetPendingNonce(nonce + 1); err != nil {
   387  			log.L().Panic("Failed to set nonce.", zap.Error(err), zap.String("addr", addr.Hex()), zap.Uint64("pendingNonce", s.PendingNonce()), zap.Uint64("nonce", nonce), zap.String("execution", hex.EncodeToString(stateDB.executionHash[:])))
   388  			stateDB.logError(err)
   389  		}
   390  	}
   391  	if err := accountutil.StoreAccount(stateDB.sm, addr, s); err != nil {
   392  		log.L().Error("Failed to store account.", zap.Error(err))
   393  		stateDB.logError(err)
   394  	}
   395  }
   396  
   397  // SubRefund subtracts refund
   398  func (stateDB *StateDBAdapter) SubRefund(gas uint64) {
   399  	log.L().Debug("Called SubRefund.", zap.Uint64("gas", gas))
   400  	// stateDB.journal.append(refundChange{prev: self.refund})
   401  	if gas > stateDB.refund {
   402  		panic("Refund counter not enough!")
   403  	}
   404  	stateDB.refund -= gas
   405  }
   406  
   407  // AddRefund adds refund
   408  func (stateDB *StateDBAdapter) AddRefund(gas uint64) {
   409  	log.L().Debug("Called AddRefund.", zap.Uint64("gas", gas))
   410  	// stateDB.journal.append(refundChange{prev: self.refund})
   411  	stateDB.refund += gas
   412  }
   413  
   414  // GetRefund gets refund
   415  func (stateDB *StateDBAdapter) GetRefund() uint64 {
   416  	log.L().Debug("Called GetRefund.")
   417  	return stateDB.refund
   418  }
   419  
   420  // Suicide kills the contract
   421  func (stateDB *StateDBAdapter) Suicide(evmAddr common.Address) bool {
   422  	if !stateDB.Exist(evmAddr) {
   423  		log.L().Debug("Account does not exist.", zap.String("address", evmAddr.Hex()))
   424  		return false
   425  	}
   426  	s, err := stateDB.accountState(evmAddr)
   427  	if err != nil {
   428  		log.L().Debug("Failed to get account.", zap.String("address", evmAddr.Hex()))
   429  		return false
   430  	}
   431  	// clears the account balance
   432  	actBalance := new(big.Int).Set(s.Balance)
   433  	if err := s.SubBalance(s.Balance); err != nil {
   434  		log.L().Debug("failed to clear balance", zap.Error(err), zap.String("address", evmAddr.Hex()))
   435  		return false
   436  	}
   437  	addrHash := hash.BytesToHash160(evmAddr.Bytes())
   438  	if _, err := stateDB.sm.PutState(s, protocol.LegacyKeyOption(addrHash)); err != nil {
   439  		log.L().Error("Failed to kill contract.", zap.Error(err))
   440  		stateDB.logError(err)
   441  		return false
   442  	}
   443  	// To ensure data consistency, generate this log after the hard-fork
   444  	// a separate patch file will be created later to provide missing logs before the hard-fork
   445  	// TODO: remove this gating once the hard-fork has passed
   446  	if stateDB.suicideTxLogMismatchPanic {
   447  		// before calling Suicide, EVM will transfer the contract's balance to beneficiary
   448  		// need to create a transaction log on successful suicide
   449  		if stateDB.lastAddBalanceAmount.Cmp(actBalance) == 0 {
   450  			if stateDB.lastAddBalanceAmount.Cmp(big.NewInt(0)) > 0 {
   451  				from, _ := address.FromBytes(evmAddr[:])
   452  				stateDB.addTransactionLogs(&action.TransactionLog{
   453  					Type:      iotextypes.TransactionLogType_IN_CONTRACT_TRANSFER,
   454  					Sender:    from.String(),
   455  					Recipient: stateDB.lastAddBalanceAddr,
   456  					Amount:    stateDB.lastAddBalanceAmount,
   457  				})
   458  			}
   459  		} else {
   460  			log.L().Panic("suicide contract's balance does not match",
   461  				zap.String("suicide", actBalance.String()),
   462  				zap.String("beneficiary", stateDB.lastAddBalanceAmount.String()))
   463  		}
   464  	}
   465  	// mark it as deleted
   466  	stateDB.suicided[addrHash] = struct{}{}
   467  	return true
   468  }
   469  
   470  // HasSuicided returns whether the contract has been killed
   471  func (stateDB *StateDBAdapter) HasSuicided(evmAddr common.Address) bool {
   472  	addrHash := hash.BytesToHash160(evmAddr.Bytes())
   473  	_, ok := stateDB.suicided[addrHash]
   474  	return ok
   475  }
   476  
   477  // SetTransientState sets transient storage for a given account
   478  func (stateDB *StateDBAdapter) SetTransientState(addr common.Address, key, value common.Hash) {
   479  	log.S().Panic("SetTransientState not implemented")
   480  }
   481  
   482  // GetTransientState gets transient storage for a given account.
   483  func (stateDB *StateDBAdapter) GetTransientState(addr common.Address, key common.Hash) common.Hash {
   484  	log.S().Panic("GetTransientState not implemented")
   485  	return common.Hash{}
   486  }
   487  
   488  // Exist checks the existence of an address
   489  func (stateDB *StateDBAdapter) Exist(evmAddr common.Address) bool {
   490  	addr, err := address.FromBytes(evmAddr.Bytes())
   491  	if err != nil {
   492  		log.L().Error("Failed to convert evm address.", zap.Error(err))
   493  		return false
   494  	}
   495  	log.L().Debug("Check existence.", zap.String("address", addr.String()), log.Hex("addrHash", evmAddr[:]))
   496  	addrHash := hash.BytesToHash160(addr.Bytes())
   497  	if _, ok := stateDB.cachedContract[addrHash]; ok {
   498  		return true
   499  	}
   500  	recorded, err := accountutil.Recorded(stateDB.sm, addr)
   501  	if !recorded || err != nil {
   502  		log.L().Debug("Account does not exist.", zap.String("address", addr.String()))
   503  		return false
   504  	}
   505  	return true
   506  }
   507  
   508  // Prepare handles the preparatory steps for executing a state transition with.
   509  // This method must be invoked before state transition.
   510  //
   511  // Berlin fork:
   512  // - Add sender to access list (2929)
   513  // - Add destination to access list (2929)
   514  // - Add precompiles to access list (2929)
   515  // - Add the contents of the optional tx access list (2930)
   516  //
   517  // Potential EIPs:
   518  // - Reset access list (Berlin)
   519  // - Add coinbase to access list (EIP-3651)
   520  // - Reset transient storage (EIP-1153)
   521  func (stateDB *StateDBAdapter) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) {
   522  	if !rules.IsBerlin {
   523  		return
   524  	}
   525  	stateDB.AddAddressToAccessList(sender)
   526  	if dst != nil {
   527  		stateDB.AddAddressToAccessList(*dst)
   528  		// If it's a create-tx, the destination will be added inside evm.create
   529  	}
   530  	for _, addr := range precompiles {
   531  		stateDB.AddAddressToAccessList(addr)
   532  	}
   533  	for _, el := range list {
   534  		stateDB.AddAddressToAccessList(el.Address)
   535  		for _, key := range el.StorageKeys {
   536  			stateDB.AddSlotToAccessList(el.Address, key)
   537  		}
   538  	}
   539  	if rules.IsShanghai { // EIP-3651: warm coinbase
   540  		stateDB.AddAddressToAccessList(coinbase)
   541  	}
   542  }
   543  
   544  // AddressInAccessList returns true if the given address is in the access list
   545  func (stateDB *StateDBAdapter) AddressInAccessList(addr common.Address) bool {
   546  	return stateDB.accessList.ContainsAddress(addr)
   547  }
   548  
   549  // SlotInAccessList returns true if the given (address, slot)-tuple is in the access list
   550  func (stateDB *StateDBAdapter) SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) {
   551  	return stateDB.accessList.Contains(addr, slot)
   552  }
   553  
   554  // AddAddressToAccessList adds the given address to the access list. This operation is safe to perform
   555  // even if the feature/fork is not active yet
   556  func (stateDB *StateDBAdapter) AddAddressToAccessList(addr common.Address) {
   557  	stateDB.accessList.AddAddress(addr)
   558  }
   559  
   560  // AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform
   561  // even if the feature/fork is not active yet
   562  func (stateDB *StateDBAdapter) AddSlotToAccessList(addr common.Address, slot common.Hash) {
   563  	stateDB.accessList.AddSlot(addr, slot)
   564  }
   565  
   566  // Empty returns true if the the contract is empty
   567  func (stateDB *StateDBAdapter) Empty(evmAddr common.Address) bool {
   568  	log.L().Debug("Check whether the contract is empty.")
   569  	s, err := stateDB.accountState(evmAddr)
   570  	if err != nil {
   571  		return true
   572  	}
   573  	// TODO: delete hash.ZeroHash256
   574  	return s.IsNewbieAccount() &&
   575  		s.Balance.Sign() == 0 &&
   576  		(len(s.CodeHash) == 0 || bytes.Equal(s.CodeHash, hash.ZeroHash256[:]))
   577  }
   578  
   579  // RevertToSnapshot reverts the state factory to the state at a given snapshot
   580  func (stateDB *StateDBAdapter) RevertToSnapshot(snapshot int) {
   581  	if err := stateDB.sm.Revert(snapshot); err != nil {
   582  		err := errors.New("unexpected error: state manager's Revert() failed")
   583  		log.L().Error("Failed to revert to snapshot.", zap.Error(err))
   584  		stateDB.logError(err)
   585  		return
   586  	}
   587  	ds, ok := stateDB.suicideSnapshot[snapshot]
   588  	if !ok {
   589  		// this should not happen, b/c we save the suicide accounts on a successful return of Snapshot(), but check anyway
   590  		log.L().Error("Failed to get snapshot.", zap.Int("snapshot", snapshot))
   591  		return
   592  	}
   593  	// restore gas refund
   594  	if !stateDB.manualCorrectGasRefund {
   595  		stateDB.refund = stateDB.refundSnapshot[snapshot]
   596  		delete(stateDB.refundSnapshot, snapshot)
   597  		for i := snapshot + 1; ; i++ {
   598  			if _, ok := stateDB.refundSnapshot[i]; ok {
   599  				delete(stateDB.refundSnapshot, i)
   600  			} else {
   601  				break
   602  			}
   603  		}
   604  	}
   605  	// restore access list
   606  	stateDB.accessList = nil
   607  	stateDB.accessList = stateDB.accessListSnapshot[snapshot]
   608  	{
   609  		delete(stateDB.accessListSnapshot, snapshot)
   610  		for i := snapshot + 1; ; i++ {
   611  			if _, ok := stateDB.accessListSnapshot[i]; ok {
   612  				delete(stateDB.accessListSnapshot, i)
   613  			} else {
   614  				break
   615  			}
   616  		}
   617  	}
   618  	// restore logs and txLogs
   619  	if stateDB.revertLog {
   620  		stateDB.logs = stateDB.logs[:stateDB.logsSnapshot[snapshot]]
   621  		delete(stateDB.logsSnapshot, snapshot)
   622  		for i := snapshot + 1; ; i++ {
   623  			if _, ok := stateDB.logsSnapshot[i]; ok {
   624  				delete(stateDB.logsSnapshot, i)
   625  			} else {
   626  				break
   627  			}
   628  		}
   629  		stateDB.transactionLogs = stateDB.transactionLogs[:stateDB.txLogsSnapshot[snapshot]]
   630  		delete(stateDB.txLogsSnapshot, snapshot)
   631  		for i := snapshot + 1; ; i++ {
   632  			if _, ok := stateDB.txLogsSnapshot[i]; ok {
   633  				delete(stateDB.txLogsSnapshot, i)
   634  			} else {
   635  				break
   636  			}
   637  		}
   638  	}
   639  	// restore the suicide accounts
   640  	stateDB.suicided = nil
   641  	stateDB.suicided = ds
   642  	if stateDB.fixSnapshotOrder {
   643  		delete(stateDB.suicideSnapshot, snapshot)
   644  		for i := snapshot + 1; ; i++ {
   645  			if _, ok := stateDB.suicideSnapshot[i]; ok {
   646  				delete(stateDB.suicideSnapshot, i)
   647  			} else {
   648  				break
   649  			}
   650  		}
   651  	}
   652  	// restore modified contracts
   653  	stateDB.cachedContract = nil
   654  	stateDB.cachedContract = stateDB.contractSnapshot[snapshot]
   655  	for _, addr := range stateDB.cachedContractAddrs() {
   656  		c := stateDB.cachedContract[addr]
   657  		if err := c.LoadRoot(); err != nil {
   658  			log.L().Error("Failed to load root for contract.", zap.Error(err), log.Hex("addrHash", addr[:]))
   659  			return
   660  		}
   661  	}
   662  	if stateDB.fixSnapshotOrder {
   663  		delete(stateDB.contractSnapshot, snapshot)
   664  		for i := snapshot + 1; ; i++ {
   665  			if _, ok := stateDB.contractSnapshot[i]; ok {
   666  				delete(stateDB.contractSnapshot, i)
   667  			} else {
   668  				break
   669  			}
   670  		}
   671  	}
   672  	// restore preimages
   673  	stateDB.preimages = nil
   674  	stateDB.preimages = stateDB.preimageSnapshot[snapshot]
   675  	if stateDB.fixSnapshotOrder {
   676  		delete(stateDB.preimageSnapshot, snapshot)
   677  		for i := snapshot + 1; ; i++ {
   678  			if _, ok := stateDB.preimageSnapshot[i]; ok {
   679  				delete(stateDB.preimageSnapshot, i)
   680  			} else {
   681  				break
   682  			}
   683  		}
   684  	}
   685  }
   686  
   687  func (stateDB *StateDBAdapter) cachedContractAddrs() []hash.Hash160 {
   688  	addrs := make([]hash.Hash160, 0, len(stateDB.cachedContract))
   689  	for addr := range stateDB.cachedContract {
   690  		addrs = append(addrs, addr)
   691  	}
   692  	if !stateDB.disableSortCachedContracts {
   693  		sort.Slice(addrs, func(i, j int) bool { return bytes.Compare(addrs[i][:], addrs[j][:]) < 0 })
   694  	}
   695  	return addrs
   696  }
   697  
   698  // Snapshot returns the snapshot id
   699  func (stateDB *StateDBAdapter) Snapshot() int {
   700  	// save a copy of modified contracts
   701  	c := make(contractMap)
   702  	if stateDB.fixSnapshotOrder {
   703  		for _, addr := range stateDB.cachedContractAddrs() {
   704  			c[addr] = stateDB.cachedContract[addr].Snapshot()
   705  		}
   706  	}
   707  	sn := stateDB.sm.Snapshot()
   708  	if _, ok := stateDB.suicideSnapshot[sn]; ok {
   709  		err := errors.New("unexpected error: duplicate snapshot version")
   710  		if stateDB.fixSnapshotOrder {
   711  			log.L().Panic("Failed to snapshot.", zap.Error(err))
   712  		} else {
   713  			log.L().Error("Failed to snapshot.", zap.Error(err))
   714  		}
   715  		// stateDB.err = err
   716  		return sn
   717  	}
   718  	// record the current gas refund
   719  	stateDB.refundSnapshot[sn] = stateDB.refund
   720  	// record the current log size
   721  	if stateDB.revertLog {
   722  		stateDB.logsSnapshot[sn] = len(stateDB.logs)
   723  		stateDB.txLogsSnapshot[sn] = len(stateDB.transactionLogs)
   724  	}
   725  	// save a copy of current suicide accounts
   726  	sa := make(deleteAccount)
   727  	for k, v := range stateDB.suicided {
   728  		sa[k] = v
   729  	}
   730  	stateDB.suicideSnapshot[sn] = sa
   731  	if !stateDB.fixSnapshotOrder {
   732  		for _, addr := range stateDB.cachedContractAddrs() {
   733  			c[addr] = stateDB.cachedContract[addr].Snapshot()
   734  		}
   735  	}
   736  	stateDB.contractSnapshot[sn] = c
   737  	// save a copy of preimages
   738  	p := make(preimageMap)
   739  	for k, v := range stateDB.preimages {
   740  		p[k] = v
   741  	}
   742  	stateDB.preimageSnapshot[sn] = p
   743  	// save a copy of access list
   744  	stateDB.accessListSnapshot[sn] = stateDB.accessList.Copy()
   745  	return sn
   746  }
   747  
   748  // AddLog adds log whose transaction amount is larger than 0
   749  func (stateDB *StateDBAdapter) AddLog(evmLog *types.Log) {
   750  	log.L().Debug("Called AddLog.", zap.Any("log", evmLog))
   751  	addr, err := address.FromBytes(evmLog.Address.Bytes())
   752  	if err != nil {
   753  		log.L().Error("Failed to convert evm address.", zap.Error(err))
   754  		return
   755  	}
   756  	var topics []hash.Hash256
   757  	for _, evmTopic := range evmLog.Topics {
   758  		var topic hash.Hash256
   759  		copy(topic[:], evmTopic.Bytes())
   760  		topics = append(topics, topic)
   761  	}
   762  	if topics[0] == _inContractTransfer {
   763  		if len(topics) != 3 {
   764  			panic("Invalid in contract transfer topics")
   765  		}
   766  		if amount, zero := new(big.Int).SetBytes(evmLog.Data), big.NewInt(0); amount.Cmp(zero) == 1 {
   767  			from, _ := address.FromBytes(topics[1][12:])
   768  			to, _ := address.FromBytes(topics[2][12:])
   769  			stateDB.addTransactionLogs(&action.TransactionLog{
   770  				Type:      iotextypes.TransactionLogType_IN_CONTRACT_TRANSFER,
   771  				Sender:    from.String(),
   772  				Recipient: to.String(),
   773  				Amount:    amount,
   774  			})
   775  		}
   776  		return
   777  	}
   778  
   779  	stateDB.logs = append(stateDB.logs, &action.Log{
   780  		Address:            addr.String(),
   781  		Topics:             topics,
   782  		Data:               evmLog.Data,
   783  		BlockHeight:        stateDB.blockHeight,
   784  		ActionHash:         stateDB.executionHash,
   785  		NotFixTopicCopyBug: stateDB.notFixTopicCopyBug,
   786  	})
   787  }
   788  
   789  // Logs returns the logs
   790  func (stateDB *StateDBAdapter) Logs() []*action.Log {
   791  	return stateDB.logs
   792  }
   793  
   794  // TransactionLogs returns the transaction logs
   795  func (stateDB *StateDBAdapter) TransactionLogs() []*action.TransactionLog {
   796  	return stateDB.transactionLogs
   797  }
   798  
   799  // AddPreimage adds the preimage of a hash
   800  func (stateDB *StateDBAdapter) AddPreimage(hash common.Hash, preimage []byte) {
   801  	if _, ok := stateDB.preimages[hash]; !ok {
   802  		b := make([]byte, len(preimage))
   803  		copy(b, preimage)
   804  		stateDB.preimages[hash] = b
   805  	}
   806  }
   807  
   808  // ForEachStorage loops each storage
   809  func (stateDB *StateDBAdapter) ForEachStorage(addr common.Address, cb func(common.Hash, common.Hash) bool) error {
   810  	ctt, err := stateDB.getContract(hash.BytesToHash160(addr[:]))
   811  	if err != nil {
   812  		// stateDB.err = err
   813  		return err
   814  	}
   815  	iter, err := ctt.Iterator()
   816  	if err != nil {
   817  		// stateDB.err = err
   818  		return err
   819  	}
   820  
   821  	for {
   822  		key, value, err := iter.Next()
   823  		if err == trie.ErrEndOfIterator {
   824  			// hit the end of the iterator, exit now
   825  			return nil
   826  		}
   827  		if err != nil {
   828  			return err
   829  		}
   830  		ckey := common.Hash{}
   831  		copy(ckey[:], key[:])
   832  		cvalue := common.Hash{}
   833  		copy(cvalue[:], value[:])
   834  		if !cb(ckey, cvalue) {
   835  			return nil
   836  		}
   837  	}
   838  }
   839  
   840  // accountState returns an account state
   841  func (stateDB *StateDBAdapter) accountState(evmAddr common.Address) (*state.Account, error) {
   842  	addrHash := hash.BytesToHash160(evmAddr.Bytes())
   843  	if contract, ok := stateDB.cachedContract[addrHash]; ok {
   844  		return contract.SelfState(), nil
   845  	}
   846  	return accountutil.LoadAccountByHash160(stateDB.sm, addrHash, stateDB.accountCreationOpts()...)
   847  }
   848  
   849  func (stateDB *StateDBAdapter) addTransactionLogs(tlog *action.TransactionLog) {
   850  	stateDB.transactionLogs = append(stateDB.transactionLogs, tlog)
   851  }
   852  
   853  //======================================
   854  // Contract functions
   855  //======================================
   856  
   857  // GetCodeHash returns contract's code hash
   858  func (stateDB *StateDBAdapter) GetCodeHash(evmAddr common.Address) common.Hash {
   859  	addr := hash.BytesToHash160(evmAddr[:])
   860  	codeHash := common.Hash{}
   861  	if contract, ok := stateDB.cachedContract[addr]; ok {
   862  		copy(codeHash[:], contract.SelfState().CodeHash)
   863  		return codeHash
   864  	}
   865  	account, err := accountutil.LoadAccountByHash160(stateDB.sm, addr, stateDB.accountCreationOpts()...)
   866  	if err != nil {
   867  		log.L().Error("Failed to get code hash.", zap.Error(err))
   868  		// TODO (zhi) not all err should be logged
   869  		// stateDB.logError(err)
   870  		return codeHash
   871  	}
   872  	copy(codeHash[:], account.CodeHash)
   873  	return codeHash
   874  }
   875  
   876  // GetCode returns contract's code
   877  func (stateDB *StateDBAdapter) GetCode(evmAddr common.Address) []byte {
   878  	addr := hash.BytesToHash160(evmAddr[:])
   879  	if contract, ok := stateDB.cachedContract[addr]; ok {
   880  		code, err := contract.GetCode()
   881  		if err != nil {
   882  			log.L().Error("Failed to get code hash.", zap.Error(err))
   883  			return nil
   884  		}
   885  		return code
   886  	}
   887  	account, err := accountutil.LoadAccountByHash160(stateDB.sm, addr, stateDB.accountCreationOpts()...)
   888  	if err != nil {
   889  		log.L().Error("Failed to load account state for address.", log.Hex("addrHash", addr[:]))
   890  		return nil
   891  	}
   892  	var code protocol.SerializableBytes
   893  	if _, err = stateDB.sm.State(&code, protocol.NamespaceOption(CodeKVNameSpace), protocol.KeyOption(account.CodeHash[:])); err != nil {
   894  		// TODO: Suppress the as it's too much now
   895  		//log.L().Error("Failed to get code from trie.", zap.Error(err))
   896  		return nil
   897  	}
   898  	return code[:]
   899  }
   900  
   901  // GetCodeSize gets the code size saved in hash
   902  func (stateDB *StateDBAdapter) GetCodeSize(evmAddr common.Address) int {
   903  	code := stateDB.GetCode(evmAddr)
   904  	if code == nil {
   905  		return 0
   906  	}
   907  	log.L().Debug("Called GetCodeSize.", log.Hex("addrHash", evmAddr[:]))
   908  	return len(code)
   909  }
   910  
   911  // SetCode sets contract's code
   912  func (stateDB *StateDBAdapter) SetCode(evmAddr common.Address, code []byte) {
   913  	addr := hash.BytesToHash160(evmAddr[:])
   914  	contract, err := stateDB.getContract(addr)
   915  	if err != nil {
   916  		log.L().Error("Failed to get contract.", zap.Error(err), log.Hex("addrHash", addr[:]))
   917  		stateDB.logError(err)
   918  		return
   919  	}
   920  	contract.SetCode(hash.Hash256b(code), code)
   921  }
   922  
   923  // GetCommittedState gets committed state
   924  func (stateDB *StateDBAdapter) GetCommittedState(evmAddr common.Address, k common.Hash) common.Hash {
   925  	addr := hash.BytesToHash160(evmAddr[:])
   926  	contract, err := stateDB.getContract(addr)
   927  	if err != nil {
   928  		log.L().Error("Failed to get contract.", zap.Error(err), log.Hex("addrHash", addr[:]))
   929  		stateDB.logError(err)
   930  		return common.Hash{}
   931  	}
   932  	v, err := contract.GetCommittedState(hash.BytesToHash256(k[:]))
   933  	if err != nil {
   934  		log.L().Debug("Failed to get committed state.", zap.Error(err))
   935  		stateDB.logError(err)
   936  		return common.Hash{}
   937  	}
   938  	return common.BytesToHash(v)
   939  }
   940  
   941  // GetState gets state
   942  func (stateDB *StateDBAdapter) GetState(evmAddr common.Address, k common.Hash) common.Hash {
   943  	addr := hash.BytesToHash160(evmAddr[:])
   944  	contract, err := stateDB.getContract(addr)
   945  	if err != nil {
   946  		log.L().Error("Failed to get contract.", zap.Error(err), log.Hex("addrHash", addr[:]))
   947  		stateDB.logError(err)
   948  		return common.Hash{}
   949  	}
   950  	v, err := contract.GetState(hash.BytesToHash256(k[:]))
   951  	if err != nil {
   952  		log.L().Debug("Failed to get state.", zap.Error(err))
   953  		stateDB.logError(err)
   954  		return common.Hash{}
   955  	}
   956  	return common.BytesToHash(v)
   957  }
   958  
   959  // SetState sets state
   960  func (stateDB *StateDBAdapter) SetState(evmAddr common.Address, k, v common.Hash) {
   961  	addr := hash.BytesToHash160(evmAddr[:])
   962  	contract, err := stateDB.getContract(addr)
   963  	if err != nil {
   964  		log.L().Error("Failed to get contract.", zap.Error(err), log.Hex("addrHash", addr[:]))
   965  		stateDB.logError(err)
   966  		return
   967  	}
   968  	log.L().Debug("Called SetState", log.Hex("addrHash", evmAddr[:]), log.Hex("k", k[:]))
   969  	if err := contract.SetState(hash.BytesToHash256(k[:]), v[:]); err != nil {
   970  		log.L().Error("Failed to set state.", zap.Error(err), log.Hex("addrHash", addr[:]))
   971  		stateDB.logError(err)
   972  		return
   973  	}
   974  }
   975  
   976  // CommitContracts commits contract code to db and update pending contract account changes to trie
   977  func (stateDB *StateDBAdapter) CommitContracts() error {
   978  	addrStrs := make([]string, 0)
   979  	for addr := range stateDB.cachedContract {
   980  		addrStrs = append(addrStrs, hex.EncodeToString(addr[:]))
   981  	}
   982  	sort.Strings(addrStrs)
   983  
   984  	for _, addrStr := range addrStrs {
   985  		var addr hash.Hash160
   986  		addrBytes, err := hex.DecodeString(addrStr)
   987  		if err != nil {
   988  			return errors.Wrap(err, "failed to decode address hash")
   989  		}
   990  		copy(addr[:], addrBytes)
   991  		if _, ok := stateDB.suicided[addr]; ok {
   992  			// no need to update a suicide account/contract
   993  			continue
   994  		}
   995  		contract := stateDB.cachedContract[addr]
   996  		if err := contract.Commit(); err != nil {
   997  			stateDB.logError(err)
   998  			return errors.Wrap(err, "failed to commit contract")
   999  		}
  1000  		state := contract.SelfState()
  1001  		// store the account (with new storage trie root) into account trie
  1002  		if _, err := stateDB.sm.PutState(state, protocol.LegacyKeyOption(addr)); err != nil {
  1003  			stateDB.logError(err)
  1004  			return errors.Wrap(err, "failed to update pending account changes to trie")
  1005  		}
  1006  	}
  1007  	// delete suicided accounts/contract
  1008  	addrStrs = make([]string, 0)
  1009  	for addr := range stateDB.suicided {
  1010  		addrStrs = append(addrStrs, hex.EncodeToString(addr[:]))
  1011  	}
  1012  	sort.Strings(addrStrs)
  1013  
  1014  	for _, addrStr := range addrStrs {
  1015  		var addr hash.Hash160
  1016  		addrBytes, err := hex.DecodeString(addrStr)
  1017  		if err != nil {
  1018  			return errors.Wrap(err, "failed to decode address hash")
  1019  		}
  1020  		copy(addr[:], addrBytes)
  1021  		if _, err := stateDB.sm.DelState(protocol.LegacyKeyOption(addr)); err != nil {
  1022  			stateDB.logError(err)
  1023  			return errors.Wrapf(err, "failed to delete suicide account/contract %x", addr[:])
  1024  		}
  1025  	}
  1026  	// write preimages to DB
  1027  	addrStrs = make([]string, 0)
  1028  	for addr := range stateDB.preimages {
  1029  		addrStrs = append(addrStrs, hex.EncodeToString(addr[:]))
  1030  	}
  1031  	sort.Strings(addrStrs)
  1032  
  1033  	for _, addrStr := range addrStrs {
  1034  		var k common.Hash
  1035  		addrBytes, err := hex.DecodeString(addrStr)
  1036  		if err != nil {
  1037  			return errors.Wrap(err, "failed to decode address hash")
  1038  		}
  1039  		copy(k[:], addrBytes)
  1040  		v := stateDB.preimages[k]
  1041  		h := make([]byte, len(k))
  1042  		copy(h, k[:])
  1043  		if _, err = stateDB.sm.PutState(v, protocol.NamespaceOption(PreimageKVNameSpace), protocol.KeyOption(h)); err != nil {
  1044  			stateDB.logError(err)
  1045  			return errors.Wrap(err, "failed to update preimage to db")
  1046  		}
  1047  	}
  1048  	return nil
  1049  }
  1050  
  1051  // getContract returns the contract of addr
  1052  func (stateDB *StateDBAdapter) getContract(addr hash.Hash160) (Contract, error) {
  1053  	if contract, ok := stateDB.cachedContract[addr]; ok {
  1054  		return contract, nil
  1055  	}
  1056  	return stateDB.getNewContract(addr)
  1057  }
  1058  
  1059  func (stateDB *StateDBAdapter) getNewContract(addr hash.Hash160) (Contract, error) {
  1060  	account, err := accountutil.LoadAccountByHash160(stateDB.sm, addr, stateDB.accountCreationOpts()...)
  1061  	if err != nil {
  1062  		return nil, errors.Wrapf(err, "failed to load account state for address %x", addr)
  1063  	}
  1064  	contract, err := newContract(addr, account, stateDB.sm, stateDB.asyncContractTrie)
  1065  	if err != nil {
  1066  		return nil, errors.Wrapf(err, "failed to create storage trie for new contract %x", addr)
  1067  	}
  1068  	// add to contract cache
  1069  	stateDB.cachedContract[addr] = contract
  1070  	return contract, nil
  1071  }
  1072  
  1073  // clear clears local changes
  1074  func (stateDB *StateDBAdapter) clear() {
  1075  	stateDB.refundSnapshot = make(map[int]uint64)
  1076  	stateDB.cachedContract = make(contractMap)
  1077  	stateDB.contractSnapshot = make(map[int]contractMap)
  1078  	stateDB.suicided = make(deleteAccount)
  1079  	stateDB.suicideSnapshot = make(map[int]deleteAccount)
  1080  	stateDB.preimages = make(preimageMap)
  1081  	stateDB.preimageSnapshot = make(map[int]preimageMap)
  1082  	stateDB.accessList = newAccessList()
  1083  	stateDB.accessListSnapshot = make(map[int]*accessList)
  1084  	stateDB.logsSnapshot = make(map[int]int)
  1085  	stateDB.txLogsSnapshot = make(map[int]int)
  1086  	stateDB.logs = []*action.Log{}
  1087  	stateDB.transactionLogs = []*action.TransactionLog{}
  1088  }