github.com/nnlgsakib/mind-dpos@v0.0.0-20230606105614-f3c8ca06f808/les/backend.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package les implements the Light Ethereum Subprotocol. 18 package les 19 20 import ( 21 "fmt" 22 "sync" 23 "time" 24 25 "github.com/TTCECO/gttc/accounts" 26 "github.com/TTCECO/gttc/common" 27 "github.com/TTCECO/gttc/common/hexutil" 28 "github.com/TTCECO/gttc/consensus" 29 "github.com/TTCECO/gttc/core" 30 "github.com/TTCECO/gttc/core/bloombits" 31 "github.com/TTCECO/gttc/core/rawdb" 32 "github.com/TTCECO/gttc/core/types" 33 "github.com/TTCECO/gttc/eth" 34 "github.com/TTCECO/gttc/eth/downloader" 35 "github.com/TTCECO/gttc/eth/filters" 36 "github.com/TTCECO/gttc/eth/gasprice" 37 "github.com/TTCECO/gttc/ethdb" 38 "github.com/TTCECO/gttc/event" 39 "github.com/TTCECO/gttc/internal/ethapi" 40 "github.com/TTCECO/gttc/light" 41 "github.com/TTCECO/gttc/log" 42 "github.com/TTCECO/gttc/node" 43 "github.com/TTCECO/gttc/p2p" 44 "github.com/TTCECO/gttc/p2p/discv5" 45 "github.com/TTCECO/gttc/params" 46 rpc "github.com/TTCECO/gttc/rpc" 47 ) 48 49 type LightEthereum struct { 50 config *eth.Config 51 52 odr *LesOdr 53 relay *LesTxRelay 54 chainConfig *params.ChainConfig 55 // Channel for shutting down the service 56 shutdownChan chan bool 57 // Handlers 58 peers *peerSet 59 txPool *light.TxPool 60 blockchain *light.LightChain 61 protocolManager *ProtocolManager 62 serverPool *serverPool 63 reqDist *requestDistributor 64 retriever *retrieveManager 65 // DB interfaces 66 chainDb ethdb.Database // Block chain database 67 68 bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests 69 bloomIndexer, chtIndexer, bloomTrieIndexer *core.ChainIndexer 70 71 ApiBackend *LesApiBackend 72 73 eventMux *event.TypeMux 74 engine consensus.Engine 75 accountManager *accounts.Manager 76 77 networkId uint64 78 netRPCService *ethapi.PublicNetAPI 79 80 wg sync.WaitGroup 81 } 82 83 func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { 84 chainDb, err := eth.CreateDB(ctx, config, "lightchaindata") 85 if err != nil { 86 return nil, err 87 } 88 chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) 89 if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { 90 return nil, genesisErr 91 } 92 log.Info("Initialised chain configuration", "config", chainConfig) 93 if chainConfig.Alien != nil { 94 log.Info("Initialised alien configuration", "config", *chainConfig.Alien) 95 if config.NetworkId == 1 {// eth.DefaultConfig.NetworkId 96 // change default eth networkid to default ttc networkid 97 config.NetworkId = chainConfig.ChainId.Uint64() 98 } 99 } 100 101 peers := newPeerSet() 102 quitSync := make(chan struct{}) 103 104 leth := &LightEthereum{ 105 config: config, 106 chainConfig: chainConfig, 107 chainDb: chainDb, 108 eventMux: ctx.EventMux, 109 peers: peers, 110 reqDist: newRequestDistributor(peers, quitSync), 111 accountManager: ctx.AccountManager, 112 engine: eth.CreateConsensusEngine(ctx, &config.Ethash, chainConfig, chainDb), 113 shutdownChan: make(chan bool), 114 networkId: config.NetworkId, 115 bloomRequests: make(chan chan *bloombits.Retrieval), 116 bloomIndexer: eth.NewBloomIndexer(chainDb, light.BloomTrieFrequency), 117 chtIndexer: light.NewChtIndexer(chainDb, true), 118 bloomTrieIndexer: light.NewBloomTrieIndexer(chainDb, true), 119 } 120 121 leth.relay = NewLesTxRelay(peers, leth.reqDist) 122 leth.serverPool = newServerPool(chainDb, quitSync, &leth.wg) 123 leth.retriever = newRetrieveManager(peers, leth.reqDist, leth.serverPool) 124 leth.odr = NewLesOdr(chainDb, leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer, leth.retriever) 125 if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine); err != nil { 126 return nil, err 127 } 128 leth.bloomIndexer.Start(leth.blockchain) 129 // Rewind the chain in case of an incompatible config upgrade. 130 if compat, ok := genesisErr.(*params.ConfigCompatError); ok { 131 log.Warn("Rewinding chain to upgrade configuration", "err", compat) 132 leth.blockchain.SetHead(compat.RewindTo) 133 rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig) 134 } 135 136 leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay) 137 if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, true, ClientProtocolVersions, config.NetworkId, leth.eventMux, leth.engine, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.relay, quitSync, &leth.wg); err != nil { 138 return nil, err 139 } 140 leth.ApiBackend = &LesApiBackend{leth, nil} 141 gpoParams := config.GPO 142 if gpoParams.Default == nil { 143 gpoParams.Default = config.GasPrice 144 } 145 leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams) 146 return leth, nil 147 } 148 149 func lesTopic(genesisHash common.Hash, protocolVersion uint) discv5.Topic { 150 var name string 151 switch protocolVersion { 152 case lpv1: 153 name = "LES" 154 case lpv2: 155 name = "LES2" 156 default: 157 panic(nil) 158 } 159 return discv5.Topic(name + "@" + common.Bytes2Hex(genesisHash.Bytes()[0:8])) 160 } 161 162 type LightDummyAPI struct{} 163 164 // Etherbase is the address that mining rewards will be send to 165 func (s *LightDummyAPI) Etherbase() (common.Address, error) { 166 return common.Address{}, fmt.Errorf("not supported") 167 } 168 169 // Coinbase is the address that mining rewards will be send to (alias for Etherbase) 170 func (s *LightDummyAPI) Coinbase() (common.Address, error) { 171 return common.Address{}, fmt.Errorf("not supported") 172 } 173 174 // Hashrate returns the POW hashrate 175 func (s *LightDummyAPI) Hashrate() hexutil.Uint { 176 return 0 177 } 178 179 // Mining returns an indication if this node is currently mining. 180 func (s *LightDummyAPI) Mining() bool { 181 return false 182 } 183 184 // APIs returns the collection of RPC services the ethereum package offers. 185 // NOTE, some of these services probably need to be moved to somewhere else. 186 func (s *LightEthereum) APIs() []rpc.API { 187 return append(ethapi.GetAPIs(s.ApiBackend), []rpc.API{ 188 { 189 Namespace: "eth", 190 Version: "1.0", 191 Service: &LightDummyAPI{}, 192 Public: true, 193 }, { 194 Namespace: "eth", 195 Version: "1.0", 196 Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), 197 Public: true, 198 }, { 199 Namespace: "eth", 200 Version: "1.0", 201 Service: filters.NewPublicFilterAPI(s.ApiBackend, true), 202 Public: true, 203 }, { 204 Namespace: "net", 205 Version: "1.0", 206 Service: s.netRPCService, 207 Public: true, 208 }, 209 }...) 210 } 211 212 func (s *LightEthereum) ResetWithGenesisBlock(gb *types.Block) { 213 s.blockchain.ResetWithGenesisBlock(gb) 214 } 215 216 func (s *LightEthereum) BlockChain() *light.LightChain { return s.blockchain } 217 func (s *LightEthereum) TxPool() *light.TxPool { return s.txPool } 218 func (s *LightEthereum) Engine() consensus.Engine { return s.engine } 219 func (s *LightEthereum) LesVersion() int { return int(s.protocolManager.SubProtocols[0].Version) } 220 func (s *LightEthereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader } 221 func (s *LightEthereum) EventMux() *event.TypeMux { return s.eventMux } 222 223 // Protocols implements node.Service, returning all the currently configured 224 // network protocols to start. 225 func (s *LightEthereum) Protocols() []p2p.Protocol { 226 return s.protocolManager.SubProtocols 227 } 228 229 // Start implements node.Service, starting all internal goroutines needed by the 230 // Ethereum protocol implementation. 231 func (s *LightEthereum) Start(srvr *p2p.Server) error { 232 s.startBloomHandlers() 233 log.Warn("Light client mode is an experimental feature") 234 s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.networkId) 235 // clients are searching for the first advertised protocol in the list 236 protocolVersion := AdvertiseProtocolVersions[0] 237 s.serverPool.start(srvr, lesTopic(s.blockchain.Genesis().Hash(), protocolVersion)) 238 s.protocolManager.Start(s.config.LightPeers) 239 return nil 240 } 241 242 // Stop implements node.Service, terminating all internal goroutines used by the 243 // Ethereum protocol. 244 func (s *LightEthereum) Stop() error { 245 s.odr.Stop() 246 if s.bloomIndexer != nil { 247 s.bloomIndexer.Close() 248 } 249 if s.chtIndexer != nil { 250 s.chtIndexer.Close() 251 } 252 if s.bloomTrieIndexer != nil { 253 s.bloomTrieIndexer.Close() 254 } 255 s.blockchain.Stop() 256 s.protocolManager.Stop() 257 s.txPool.Stop() 258 259 s.eventMux.Stop() 260 261 time.Sleep(time.Millisecond * 200) 262 s.chainDb.Close() 263 close(s.shutdownChan) 264 265 return nil 266 }