github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/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 VNT Subprotocol. 18 package les 19 20 import ( 21 "fmt" 22 "sync" 23 "time" 24 25 "github.com/vntchain/go-vnt/accounts" 26 "github.com/vntchain/go-vnt/common" 27 "github.com/vntchain/go-vnt/consensus" 28 "github.com/vntchain/go-vnt/core" 29 "github.com/vntchain/go-vnt/core/bloombits" 30 "github.com/vntchain/go-vnt/core/rawdb" 31 "github.com/vntchain/go-vnt/core/types" 32 "github.com/vntchain/go-vnt/event" 33 "github.com/vntchain/go-vnt/internal/vntapi" 34 "github.com/vntchain/go-vnt/light" 35 "github.com/vntchain/go-vnt/log" 36 "github.com/vntchain/go-vnt/node" 37 "github.com/vntchain/go-vnt/params" 38 "github.com/vntchain/go-vnt/rpc" 39 "github.com/vntchain/go-vnt/vnt" 40 "github.com/vntchain/go-vnt/vnt/downloader" 41 "github.com/vntchain/go-vnt/vnt/filters" 42 "github.com/vntchain/go-vnt/vnt/gasprice" 43 "github.com/vntchain/go-vnt/vntdb" 44 "github.com/vntchain/go-vnt/vntp2p" 45 ) 46 47 type LightVnt struct { 48 config *vnt.Config 49 50 odr *LesOdr 51 relay *LesTxRelay 52 chainConfig *params.ChainConfig 53 // Channel for shutting down the service 54 shutdownChan chan bool 55 // Handlers 56 peers *peerSet 57 txPool *light.TxPool 58 blockchain *light.LightChain 59 protocolManager *ProtocolManager 60 serverPool *serverPool 61 reqDist *requestDistributor 62 retriever *retrieveManager 63 // DB interfaces 64 chainDb vntdb.Database // Block chain database 65 66 bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests 67 bloomIndexer, chtIndexer, bloomTrieIndexer *core.ChainIndexer 68 69 ApiBackend *LesApiBackend 70 71 eventMux *event.TypeMux 72 engine consensus.Engine 73 accountManager *accounts.Manager 74 75 networkId uint64 76 netRPCService *vntapi.PublicNetAPI 77 78 wg sync.WaitGroup 79 } 80 81 func New(ctx *node.ServiceContext, config *vnt.Config) (*LightVnt, error) { 82 chainDb, err := vnt.CreateDB(ctx, config, "lightchaindata") 83 if err != nil { 84 return nil, err 85 } 86 chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) 87 if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { 88 return nil, genesisErr 89 } 90 log.Info("Initialised chain configuration", "config", chainConfig) 91 92 peers := newPeerSet() 93 quitSync := make(chan struct{}) 94 95 lvnt := &LightVnt{ 96 config: config, 97 chainConfig: chainConfig, 98 chainDb: chainDb, 99 eventMux: ctx.EventMux, 100 peers: peers, 101 reqDist: newRequestDistributor(peers, quitSync), 102 accountManager: ctx.AccountManager, 103 engine: vnt.CreateConsensusEngine(ctx, chainConfig, chainDb), 104 shutdownChan: make(chan bool), 105 networkId: config.NetworkId, 106 bloomRequests: make(chan chan *bloombits.Retrieval), 107 bloomIndexer: vnt.NewBloomIndexer(chainDb, light.BloomTrieFrequency), 108 chtIndexer: light.NewChtIndexer(chainDb, true), 109 bloomTrieIndexer: light.NewBloomTrieIndexer(chainDb, true), 110 } 111 112 lvnt.relay = NewLesTxRelay(peers, lvnt.reqDist) 113 lvnt.serverPool = newServerPool(chainDb, quitSync, &lvnt.wg) 114 lvnt.retriever = newRetrieveManager(peers, lvnt.reqDist, lvnt.serverPool) 115 lvnt.odr = NewLesOdr(chainDb, lvnt.chtIndexer, lvnt.bloomTrieIndexer, lvnt.bloomIndexer, lvnt.retriever) 116 if lvnt.blockchain, err = light.NewLightChain(lvnt.odr, lvnt.chainConfig, lvnt.engine); err != nil { 117 return nil, err 118 } 119 lvnt.bloomIndexer.Start(lvnt.blockchain) 120 // Rewind the chain in case of an incompatible config upgrade. 121 if compat, ok := genesisErr.(*params.ConfigCompatError); ok { 122 log.Warn("Rewinding chain to upgrade configuration", "err", compat) 123 lvnt.blockchain.SetHead(compat.RewindTo) 124 rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig) 125 } 126 127 lvnt.txPool = light.NewTxPool(lvnt.chainConfig, lvnt.blockchain, lvnt.relay) 128 if lvnt.protocolManager, err = NewProtocolManager(lvnt.chainConfig, true, ClientProtocolVersions, config.NetworkId, lvnt.eventMux, lvnt.engine, lvnt.peers, lvnt.blockchain, nil, chainDb, lvnt.odr, lvnt.relay, lvnt.serverPool, quitSync, &lvnt.wg); err != nil { 129 return nil, err 130 } 131 lvnt.ApiBackend = &LesApiBackend{lvnt, nil} 132 gpoParams := config.GPO 133 if gpoParams.Default == nil { 134 gpoParams.Default = config.GasPrice 135 } 136 lvnt.ApiBackend.gpo = gasprice.NewOracle(lvnt.ApiBackend, gpoParams) 137 return lvnt, nil 138 } 139 140 // func lesTopic(genesisHash common.Hash, protocolVersion uint) discv5.Topic { 141 // var name string 142 // switch protocolVersion { 143 // case lpv1: 144 // name = "LES" 145 // case lpv2: 146 // name = "LES2" 147 // default: 148 // panic(nil) 149 // } 150 // return discv5.Topic(name + "@" + common.Bytes2Hex(genesisHash.Bytes()[0:8])) 151 // } 152 153 type LightDummyAPI struct{} 154 155 // Coinbase is the address that block producing rewards will be send to 156 func (s *LightDummyAPI) Coinbase() (common.Address, error) { 157 return common.Address{}, fmt.Errorf("not supported") 158 } 159 160 // Producing returns an indication if this node is currently producing block. 161 func (s *LightDummyAPI) Producing() bool { 162 return false 163 } 164 165 // APIs returns the collection of RPC services the hubble package offers. 166 // NOTE, some of these services probably need to be moved to somewhere else. 167 func (s *LightVnt) APIs() []rpc.API { 168 return append(vntapi.GetAPIs(s.ApiBackend), []rpc.API{ 169 { 170 Namespace: "core", 171 Version: "1.0", 172 Service: &LightDummyAPI{}, 173 Public: true, 174 }, { 175 Namespace: "core", 176 Version: "1.0", 177 Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), 178 Public: true, 179 }, { 180 Namespace: "core", 181 Version: "1.0", 182 Service: filters.NewPublicFilterAPI(s.ApiBackend, true), 183 Public: true, 184 }, { 185 Namespace: "net", 186 Version: "1.0", 187 Service: s.netRPCService, 188 Public: true, 189 }, 190 }...) 191 } 192 193 func (s *LightVnt) ResetWithGenesisBlock(gb *types.Block) { 194 s.blockchain.ResetWithGenesisBlock(gb) 195 } 196 197 func (s *LightVnt) BlockChain() *light.LightChain { return s.blockchain } 198 func (s *LightVnt) TxPool() *light.TxPool { return s.txPool } 199 func (s *LightVnt) Engine() consensus.Engine { return s.engine } 200 func (s *LightVnt) LesVersion() int { return int(s.protocolManager.SubProtocols[0].Version) } 201 func (s *LightVnt) Downloader() *downloader.Downloader { return s.protocolManager.downloader } 202 func (s *LightVnt) EventMux() *event.TypeMux { return s.eventMux } 203 204 // Protocols implements node.Service, returning all the currently configured 205 // network protocols to start. 206 func (s *LightVnt) Protocols() []vntp2p.Protocol { 207 return s.protocolManager.SubProtocols 208 } 209 210 // Start implements node.Service, starting all internal goroutines needed by the 211 // VNT protocol implementation. 212 func (s *LightVnt) Start(srvr *vntp2p.Server) error { 213 s.startBloomHandlers() 214 log.Warn("Light client mode is an experimental feature") 215 s.netRPCService = vntapi.NewPublicNetAPI(srvr, s.networkId) 216 // clients are searching for the first advertised protocol in the list 217 protocolVersion := AdvertiseProtocolVersions[0] 218 fmt.Println(protocolVersion) 219 s.serverPool.start(srvr) 220 // s.serverPool.start(srvr, lesTopic(s.blockchain.Genesis().Hash(), protocolVersion)) 221 s.protocolManager.Start(s.config.LightPeers) 222 return nil 223 } 224 225 // Stop implements node.Service, terminating all internal goroutines used by the 226 // VNT protocol. 227 func (s *LightVnt) Stop() error { 228 s.odr.Stop() 229 if s.bloomIndexer != nil { 230 s.bloomIndexer.Close() 231 } 232 if s.chtIndexer != nil { 233 s.chtIndexer.Close() 234 } 235 if s.bloomTrieIndexer != nil { 236 s.bloomTrieIndexer.Close() 237 } 238 s.blockchain.Stop() 239 s.protocolManager.Stop() 240 s.txPool.Stop() 241 242 s.eventMux.Stop() 243 244 time.Sleep(time.Millisecond * 200) 245 s.chainDb.Close() 246 close(s.shutdownChan) 247 248 return nil 249 }