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