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