github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/les/backend.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:38</date> 10 //</624450093159813120> 11 12 13 //包les实现轻以太坊子协议。 14 package les 15 16 import ( 17 "fmt" 18 "sync" 19 "time" 20 21 "github.com/ethereum/go-ethereum/accounts" 22 "github.com/ethereum/go-ethereum/common" 23 "github.com/ethereum/go-ethereum/common/hexutil" 24 "github.com/ethereum/go-ethereum/consensus" 25 "github.com/ethereum/go-ethereum/core" 26 "github.com/ethereum/go-ethereum/core/bloombits" 27 "github.com/ethereum/go-ethereum/core/rawdb" 28 "github.com/ethereum/go-ethereum/core/types" 29 "github.com/ethereum/go-ethereum/eth" 30 "github.com/ethereum/go-ethereum/eth/downloader" 31 "github.com/ethereum/go-ethereum/eth/filters" 32 "github.com/ethereum/go-ethereum/eth/gasprice" 33 "github.com/ethereum/go-ethereum/event" 34 "github.com/ethereum/go-ethereum/internal/ethapi" 35 "github.com/ethereum/go-ethereum/light" 36 "github.com/ethereum/go-ethereum/log" 37 "github.com/ethereum/go-ethereum/node" 38 "github.com/ethereum/go-ethereum/p2p" 39 "github.com/ethereum/go-ethereum/p2p/discv5" 40 "github.com/ethereum/go-ethereum/params" 41 rpc "github.com/ethereum/go-ethereum/rpc" 42 ) 43 44 type LightEthereum struct { 45 lesCommons 46 47 odr *LesOdr 48 relay *LesTxRelay 49 chainConfig *params.ChainConfig 50 //关闭服务的通道 51 shutdownChan chan bool 52 53 //处理程序 54 peers *peerSet 55 txPool *light.TxPool 56 blockchain *light.LightChain 57 serverPool *serverPool 58 reqDist *requestDistributor 59 retriever *retrieveManager 60 61 bloomRequests chan chan *bloombits.Retrieval //接收Bloom数据检索请求的通道 62 bloomIndexer *core.ChainIndexer 63 64 ApiBackend *LesApiBackend 65 66 eventMux *event.TypeMux 67 engine consensus.Engine 68 accountManager *accounts.Manager 69 70 networkId uint64 71 netRPCService *ethapi.PublicNetAPI 72 73 wg sync.WaitGroup 74 } 75 76 func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { 77 chainDb, err := eth.CreateDB(ctx, config, "lightchaindata") 78 if err != nil { 79 return nil, err 80 } 81 chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.ConstantinopleOverride) 82 if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { 83 return nil, genesisErr 84 } 85 log.Info("Initialised chain configuration", "config", chainConfig) 86 87 peers := newPeerSet() 88 quitSync := make(chan struct{}) 89 90 leth := &LightEthereum{ 91 lesCommons: lesCommons{ 92 chainDb: chainDb, 93 config: config, 94 iConfig: light.DefaultClientIndexerConfig, 95 }, 96 chainConfig: chainConfig, 97 eventMux: ctx.EventMux, 98 peers: peers, 99 reqDist: newRequestDistributor(peers, quitSync), 100 accountManager: ctx.AccountManager, 101 engine: eth.CreateConsensusEngine(ctx, chainConfig, &config.Ethash, nil, false, chainDb), 102 shutdownChan: make(chan bool), 103 networkId: config.NetworkId, 104 bloomRequests: make(chan chan *bloombits.Retrieval), 105 bloomIndexer: eth.NewBloomIndexer(chainDb, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), 106 } 107 108 leth.relay = NewLesTxRelay(peers, leth.reqDist) 109 leth.serverPool = newServerPool(chainDb, quitSync, &leth.wg) 110 leth.retriever = newRetrieveManager(peers, leth.reqDist, leth.serverPool) 111 112 leth.odr = NewLesOdr(chainDb, light.DefaultClientIndexerConfig, leth.retriever) 113 leth.chtIndexer = light.NewChtIndexer(chainDb, leth.odr, params.CHTFrequencyClient, params.HelperTrieConfirmations) 114 leth.bloomTrieIndexer = light.NewBloomTrieIndexer(chainDb, leth.odr, params.BloomBitsBlocksClient, params.BloomTrieFrequency) 115 leth.odr.SetIndexers(leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer) 116 117 //注意:newlightchain添加了受信任的检查点,因此它需要具有 118 //索引器已设置,但尚未启动 119 if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, leth.engine); err != nil { 120 return nil, err 121 } 122 //注意:AddChildIndexer启动子级的更新过程 123 leth.bloomIndexer.AddChildIndexer(leth.bloomTrieIndexer) 124 leth.chtIndexer.Start(leth.blockchain) 125 leth.bloomIndexer.Start(leth.blockchain) 126 127 //在不兼容的配置升级时倒带链。 128 if compat, ok := genesisErr.(*params.ConfigCompatError); ok { 129 log.Warn("Rewinding chain to upgrade configuration", "err", compat) 130 leth.blockchain.SetHead(compat.RewindTo) 131 rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig) 132 } 133 134 leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay) 135 if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, light.DefaultClientIndexerConfig, true, config.NetworkId, leth.eventMux, leth.engine, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.relay, leth.serverPool, quitSync, &leth.wg); err != nil { 136 return nil, err 137 } 138 leth.ApiBackend = &LesApiBackend{leth, nil} 139 gpoParams := config.GPO 140 if gpoParams.Default == nil { 141 gpoParams.Default = config.MinerGasPrice 142 } 143 leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams) 144 return leth, nil 145 } 146 147 func lesTopic(genesisHash common.Hash, protocolVersion uint) discv5.Topic { 148 var name string 149 switch protocolVersion { 150 case lpv1: 151 name = "LES" 152 case lpv2: 153 name = "LES2" 154 default: 155 panic(nil) 156 } 157 return discv5.Topic(name + "@" + common.Bytes2Hex(genesisHash.Bytes()[0:8])) 158 } 159 160 type LightDummyAPI struct{} 161 162 //EtherBase是采矿奖励将发送到的地址 163 func (s *LightDummyAPI) Etherbase() (common.Address, error) { 164 return common.Address{}, fmt.Errorf("not supported") 165 } 166 167 //CoinBase是采矿奖励将发送到的地址(EtherBase的别名) 168 func (s *LightDummyAPI) Coinbase() (common.Address, error) { 169 return common.Address{}, fmt.Errorf("not supported") 170 } 171 172 //hashRate返回pow hashRate 173 func (s *LightDummyAPI) Hashrate() hexutil.Uint { 174 return 0 175 } 176 177 //挖掘返回当前是否正在挖掘此节点的指示。 178 func (s *LightDummyAPI) Mining() bool { 179 return false 180 } 181 182 //API返回以太坊包提供的RPC服务集合。 183 //注意,其中一些服务可能需要转移到其他地方。 184 func (s *LightEthereum) APIs() []rpc.API { 185 return append(ethapi.GetAPIs(s.ApiBackend), []rpc.API{ 186 { 187 Namespace: "eth", 188 Version: "1.0", 189 Service: &LightDummyAPI{}, 190 Public: true, 191 }, { 192 Namespace: "eth", 193 Version: "1.0", 194 Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), 195 Public: true, 196 }, { 197 Namespace: "eth", 198 Version: "1.0", 199 Service: filters.NewPublicFilterAPI(s.ApiBackend, true), 200 Public: true, 201 }, { 202 Namespace: "net", 203 Version: "1.0", 204 Service: s.netRPCService, 205 Public: true, 206 }, 207 }...) 208 } 209 210 func (s *LightEthereum) ResetWithGenesisBlock(gb *types.Block) { 211 s.blockchain.ResetWithGenesisBlock(gb) 212 } 213 214 func (s *LightEthereum) BlockChain() *light.LightChain { return s.blockchain } 215 func (s *LightEthereum) TxPool() *light.TxPool { return s.txPool } 216 func (s *LightEthereum) Engine() consensus.Engine { return s.engine } 217 func (s *LightEthereum) LesVersion() int { return int(ClientProtocolVersions[0]) } 218 func (s *LightEthereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader } 219 func (s *LightEthereum) EventMux() *event.TypeMux { return s.eventMux } 220 221 //协议实现node.service,返回所有当前配置的 222 //要启动的网络协议。 223 func (s *LightEthereum) Protocols() []p2p.Protocol { 224 return s.makeProtocols(ClientProtocolVersions) 225 } 226 227 //start实现node.service,启动 228 //以太坊协议实现。 229 func (s *LightEthereum) Start(srvr *p2p.Server) error { 230 log.Warn("Light client mode is an experimental feature") 231 s.startBloomHandlers(params.BloomBitsBlocksClient) 232 s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.networkId) 233 //客户端正在搜索列表中的第一个公告协议 234 protocolVersion := AdvertiseProtocolVersions[0] 235 s.serverPool.start(srvr, lesTopic(s.blockchain.Genesis().Hash(), protocolVersion)) 236 s.protocolManager.Start(s.config.LightPeers) 237 return nil 238 } 239 240 //停止实现node.service,终止由 241 //以太坊协议。 242 func (s *LightEthereum) Stop() error { 243 s.odr.Stop() 244 s.bloomIndexer.Close() 245 s.chtIndexer.Close() 246 s.blockchain.Stop() 247 s.protocolManager.Stop() 248 s.txPool.Stop() 249 s.engine.Close() 250 251 s.eventMux.Stop() 252 253 time.Sleep(time.Millisecond * 200) 254 s.chainDb.Close() 255 close(s.shutdownChan) 256 257 return nil 258 } 259