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 }