github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/keeper/abci.go (about)

     1  package keeper
     2  
     3  import (
     4  	"math/big"
     5  
     6  	"github.com/fibonacci-chain/fbc/x/evm/watcher"
     7  
     8  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
     9  
    10  	"github.com/ethereum/go-ethereum/common"
    11  
    12  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    13  
    14  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    15  
    16  	ethtypes "github.com/ethereum/go-ethereum/core/types"
    17  	"github.com/fibonacci-chain/fbc/x/evm/types"
    18  )
    19  
    20  // BeginBlock sets the block hash -> block height map for the previous block height
    21  // and resets the Bloom filter and the transaction count to 0.
    22  func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
    23  	if req.Header.GetHeight() == tmtypes.GetMarsHeight() {
    24  		migrateDataInMarsHeight(ctx, k)
    25  	}
    26  
    27  	if req.Header.LastBlockId.GetHash() == nil || req.Header.GetHeight() < 1 {
    28  		return
    29  	}
    30  
    31  	// Gas costs are handled within msg handler so costs should be ignored
    32  	ctx.SetGasMeter(sdk.NewInfiniteGasMeter())
    33  
    34  	// Set the hash -> height and height -> hash mapping.
    35  	currentHash := req.Hash
    36  	lastHash := req.Header.LastBlockId.GetHash()
    37  	height := req.Header.GetHeight() - 1
    38  
    39  	blockHash := common.BytesToHash(currentHash)
    40  	k.SetHeightHash(ctx, uint64(height), common.BytesToHash(lastHash))
    41  	k.SetBlockHeight(ctx, lastHash, height)
    42  	// Add latest block height and hash to cache
    43  	k.AddHeightHashToCache(req.Header.GetHeight(), blockHash.Hex())
    44  
    45  	// reset counters that are used on CommitStateDB.Prepare
    46  	if !ctx.IsTraceTx() {
    47  		k.Bloom = big.NewInt(0)
    48  		k.TxCount = 0
    49  		k.LogSize = 0
    50  		k.LogsManages.Reset()
    51  		k.Bhash = blockHash
    52  
    53  		//that can make sure latest block has been committed
    54  		k.UpdatedAccount = k.UpdatedAccount[:0]
    55  		k.EvmStateDb = types.CreateEmptyCommitStateDB(k.GenerateCSDBParams(), ctx)
    56  		k.EvmStateDb.StartPrefetcher("evm")
    57  		k.Watcher.NewHeight(uint64(req.Header.GetHeight()), blockHash, req.Header)
    58  	}
    59  
    60  	if tmtypes.DownloadDelta {
    61  		types.GetEvmParamsCache().SetNeedParamsUpdate()
    62  		types.GetEvmParamsCache().SetNeedBlockedUpdate()
    63  	}
    64  }
    65  
    66  // EndBlock updates the accounts and commits state objects to the KV Store, while
    67  // deleting the empty ones. It also sets the bloom filers for the request block to
    68  // the store. The EVM end block logic doesn't update the validator set, thus it returns
    69  // an empty slice.
    70  func (k *Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
    71  	// Gas costs are handled within msg handler so costs should be ignored
    72  	ctx.SetGasMeter(sdk.NewInfiniteGasMeter())
    73  
    74  	// set the block bloom filter bytes to store
    75  	bloom := ethtypes.BytesToBloom(k.Bloom.Bytes())
    76  	k.SetBlockBloom(ctx, req.Height, bloom)
    77  
    78  	if types.GetEnableBloomFilter() {
    79  		// the hash of current block is stored when executing BeginBlock of next block.
    80  		// so update section in the next block.
    81  		if indexer := types.GetIndexer(); indexer != nil {
    82  			if types.GetIndexer().IsProcessing() {
    83  				// notify new height
    84  				go func() {
    85  					indexer.NotifyNewHeight(ctx)
    86  				}()
    87  			} else {
    88  				interval := uint64(req.Height - tmtypes.GetStartBlockHeight())
    89  				if interval >= (indexer.GetValidSections()+1)*types.BloomBitsBlocks {
    90  					go types.GetIndexer().ProcessSection(ctx, k, interval, k.Watcher.GetBloomDataPoint())
    91  				}
    92  			}
    93  		}
    94  	}
    95  
    96  	if watcher.IsWatcherEnabled() && k.Watcher.IsFirstUse() {
    97  		store := ctx.KVStore(k.storeKey)
    98  		iteratorBlockedList := sdk.KVStorePrefixIterator(store, types.KeyPrefixContractBlockedList)
    99  		defer iteratorBlockedList.Close()
   100  		for ; iteratorBlockedList.Valid(); iteratorBlockedList.Next() {
   101  			vaule := iteratorBlockedList.Value()
   102  			if len(vaule) == 0 {
   103  				k.Watcher.SaveContractBlockedListItem(iteratorBlockedList.Key()[1:])
   104  			} else {
   105  				k.Watcher.SaveContractMethodBlockedListItem(iteratorBlockedList.Key()[1:], vaule)
   106  			}
   107  		}
   108  
   109  		iteratorDeploymentWhitelist := sdk.KVStorePrefixIterator(store, types.KeyPrefixContractDeploymentWhitelist)
   110  		defer iteratorDeploymentWhitelist.Close()
   111  		for ; iteratorDeploymentWhitelist.Valid(); iteratorDeploymentWhitelist.Next() {
   112  			k.Watcher.SaveContractDeploymentWhitelistItem(iteratorDeploymentWhitelist.Key()[1:])
   113  		}
   114  
   115  		k.Watcher.Used()
   116  	}
   117  
   118  	if watcher.IsWatcherEnabled() {
   119  		params := k.GetParams(ctx)
   120  		k.Watcher.SaveParams(params)
   121  
   122  		k.Watcher.SaveBlock(bloom)
   123  
   124  		k.Watcher.SaveBlockStdTxHash()
   125  	}
   126  
   127  	k.UpdateInnerBlockData()
   128  
   129  	k.Commit(ctx)
   130  
   131  	return []abci.ValidatorUpdate{}
   132  }
   133  
   134  // migrateDataInMarsHeight migrates data from evm store to param store
   135  // 0. chainConfig
   136  // 1. white address list
   137  // 2. blocked addresses list
   138  func migrateDataInMarsHeight(ctx sdk.Context, k *Keeper) {
   139  	csdb := types.CreateEmptyCommitStateDB(k.GeneratePureCSDBParams(), ctx)
   140  	newStore := k.paramSpace.CustomKVStore(ctx)
   141  
   142  	// 0. migrate chainConfig
   143  	config, _ := k.GetChainConfig(ctx)
   144  	newStore.Set(types.KeyPrefixChainConfig, k.cdc.MustMarshalBinaryBare(config))
   145  
   146  	// 1、migrate white list
   147  	whiteList := csdb.GetContractDeploymentWhitelist()
   148  	for i := 0; i < len(whiteList); i++ {
   149  		newStore.Set(types.GetContractDeploymentWhitelistMemberKey(whiteList[i]), []byte(""))
   150  	}
   151  
   152  	// 2.1、deploy blocked list
   153  	blockedList := csdb.GetContractBlockedList()
   154  	for i := 0; i < len(blockedList); i++ {
   155  		newStore.Set(types.GetContractBlockedListMemberKey(blockedList[i]), []byte(""))
   156  	}
   157  
   158  	// 2.2、migrate blocked method list
   159  	methodBlockedList := csdb.GetContractMethodBlockedList()
   160  	for i := 0; i < len(methodBlockedList); i++ {
   161  		if !methodBlockedList[i].IsAllMethodBlocked() {
   162  			types.SortContractMethods(methodBlockedList[i].BlockMethods)
   163  			value := k.cdc.MustMarshalJSON(methodBlockedList[i].BlockMethods)
   164  			sortedValue := sdk.MustSortJSON(value)
   165  			newStore.Set(types.GetContractBlockedListMemberKey(methodBlockedList[i].Address), sortedValue)
   166  		}
   167  	}
   168  }