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