github.com/waltonchain/waltonchain_gwtc_src@v1.1.4-0.20201225072101-8a298c95a819/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-wtc 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-wtc 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 Wtc Subprotocol. 18 package les 19 20 import ( 21 "fmt" 22 "sync" 23 "time" 24 25 "github.com/wtc/go-wtc/accounts" 26 "github.com/wtc/go-wtc/common" 27 "github.com/wtc/go-wtc/common/hexutil" 28 "github.com/wtc/go-wtc/consensus" 29 "github.com/wtc/go-wtc/core" 30 "github.com/wtc/go-wtc/core/types" 31 "github.com/wtc/go-wtc/wtc" 32 "github.com/wtc/go-wtc/wtc/downloader" 33 "github.com/wtc/go-wtc/wtc/filters" 34 "github.com/wtc/go-wtc/wtc/gasprice" 35 "github.com/wtc/go-wtc/wtcdb" 36 "github.com/wtc/go-wtc/event" 37 "github.com/wtc/go-wtc/internal/ethapi" 38 "github.com/wtc/go-wtc/light" 39 "github.com/wtc/go-wtc/log" 40 "github.com/wtc/go-wtc/node" 41 "github.com/wtc/go-wtc/p2p" 42 "github.com/wtc/go-wtc/p2p/discv5" 43 "github.com/wtc/go-wtc/params" 44 rpc "github.com/wtc/go-wtc/rpc" 45 ) 46 47 type LightWtc struct { 48 odr *LesOdr 49 relay *LesTxRelay 50 chainConfig *params.ChainConfig 51 // Channel for shutting down the service 52 shutdownChan chan bool 53 // Handlers 54 peers *peerSet 55 txPool *light.TxPool 56 blockchain *light.LightChain 57 protocolManager *ProtocolManager 58 serverPool *serverPool 59 reqDist *requestDistributor 60 retriever *retrieveManager 61 // DB interfaces 62 chainDb wtcdb.Database // Block chain database 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) (*LightWtc, error) { 77 chainDb, err := eth.CreateDB(ctx, config, "lightchaindata") 78 if err != nil { 79 return nil, err 80 } 81 chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) 82 if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { 83 return nil, genesisErr 84 } 85 log.Info("Chain configuration", "config", chainConfig) 86 87 peers := newPeerSet() 88 quitSync := make(chan struct{}) 89 90 eth := &LightWtc{ 91 chainConfig: chainConfig, 92 chainDb: chainDb, 93 eventMux: ctx.EventMux, 94 peers: peers, 95 reqDist: newRequestDistributor(peers, quitSync), 96 accountManager: ctx.AccountManager, 97 engine: eth.CreateConsensusEngine(ctx, config, chainConfig, chainDb), 98 shutdownChan: make(chan bool), 99 networkId: config.NetworkId, 100 } 101 102 eth.relay = NewLesTxRelay(peers, eth.reqDist) 103 eth.serverPool = newServerPool(chainDb, quitSync, ð.wg) 104 eth.retriever = newRetrieveManager(peers, eth.reqDist, eth.serverPool) 105 eth.odr = NewLesOdr(chainDb, eth.retriever) 106 if eth.blockchain, err = light.NewLightChain(eth.odr, eth.chainConfig, eth.engine); err != nil { 107 return nil, err 108 } 109 // Rewind the chain in case of an incompatible config upgrade. 110 if compat, ok := genesisErr.(*params.ConfigCompatError); ok { 111 log.Warn("Rewinding chain to upgrade configuration", "err", compat) 112 eth.blockchain.SetHead(compat.RewindTo) 113 core.WriteChainConfig(chainDb, genesisHash, chainConfig) 114 } 115 116 eth.txPool = light.NewTxPool(eth.chainConfig, eth.blockchain, eth.relay) 117 if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, true, config.NetworkId, eth.eventMux, eth.engine, eth.peers, eth.blockchain, nil, chainDb, eth.odr, eth.relay, quitSync, ð.wg); err != nil { 118 return nil, err 119 } 120 eth.ApiBackend = &LesApiBackend{eth, nil} 121 gpoParams := config.GPO 122 if gpoParams.Default == nil { 123 gpoParams.Default = config.GasPrice 124 } 125 eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, gpoParams) 126 return eth, nil 127 } 128 129 func lesTopic(genesisHash common.Hash) discv5.Topic { 130 return discv5.Topic("LES@" + common.Bytes2Hex(genesisHash.Bytes()[0:8])) 131 } 132 133 type LightDummyAPI struct{} 134 135 // Etherbase is the address that mining rewards will be send to 136 func (s *LightDummyAPI) Etherbase() (common.Address, error) { 137 return common.Address{}, fmt.Errorf("not supported") 138 } 139 140 // Coinbase is the address that mining rewards will be send to (alias for Etherbase) 141 func (s *LightDummyAPI) Coinbase() (common.Address, error) { 142 return common.Address{}, fmt.Errorf("not supported") 143 } 144 145 // Hashrate returns the POW hashrate 146 func (s *LightDummyAPI) Hashrate() hexutil.Uint { 147 return 0 148 } 149 150 // Mining returns an indication if this node is currently mining. 151 func (s *LightDummyAPI) Mining() bool { 152 return false 153 } 154 155 // APIs returns the collection of RPC services the wtc package offers. 156 // NOTE, some of these services probably need to be moved to somewhere else. 157 func (s *LightWtc) APIs() []rpc.API { 158 return append(ethapi.GetAPIs(s.ApiBackend), []rpc.API{ 159 { 160 Namespace: "eth", 161 Version: "1.0", 162 Service: &LightDummyAPI{}, 163 Public: true, 164 }, { 165 Namespace: "eth", 166 Version: "1.0", 167 Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), 168 Public: true, 169 }, { 170 Namespace: "eth", 171 Version: "1.0", 172 Service: filters.NewPublicFilterAPI(s.ApiBackend, true), 173 Public: true, 174 }, { 175 Namespace: "net", 176 Version: "1.0", 177 Service: s.netRPCService, 178 Public: true, 179 }, 180 }...) 181 } 182 183 func (s *LightWtc) ResetWithGenesisBlock(gb *types.Block) { 184 s.blockchain.ResetWithGenesisBlock(gb) 185 } 186 187 func (s *LightWtc) BlockChain() *light.LightChain { return s.blockchain } 188 func (s *LightWtc) TxPool() *light.TxPool { return s.txPool } 189 func (s *LightWtc) Engine() consensus.Engine { return s.engine } 190 func (s *LightWtc) LesVersion() int { return int(s.protocolManager.SubProtocols[0].Version) } 191 func (s *LightWtc) Downloader() *downloader.Downloader { return s.protocolManager.downloader } 192 func (s *LightWtc) EventMux() *event.TypeMux { return s.eventMux } 193 194 // Protocols implements node.Service, returning all the currently configured 195 // network protocols to start. 196 func (s *LightWtc) Protocols() []p2p.Protocol { 197 return s.protocolManager.SubProtocols 198 } 199 200 // Start implements node.Service, starting all internal goroutines needed by the 201 // Wtc protocol implementation. 202 func (s *LightWtc) Start(srvr *p2p.Server) error { 203 log.Warn("Light client mode is an experimental feature") 204 s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.networkId) 205 s.serverPool.start(srvr, lesTopic(s.blockchain.Genesis().Hash())) 206 s.protocolManager.Start() 207 return nil 208 } 209 210 // Stop implements node.Service, terminating all internal goroutines used by the 211 // Wtc protocol. 212 func (s *LightWtc) Stop() error { 213 s.odr.Stop() 214 s.blockchain.Stop() 215 s.protocolManager.Stop() 216 s.txPool.Stop() 217 218 s.eventMux.Stop() 219 220 time.Sleep(time.Millisecond * 200) 221 s.chainDb.Close() 222 close(s.shutdownChan) 223 224 return nil 225 }