【正文】
case == GetBlockBodiesM。}}(Failed to deliver headers, err, err)if err != nil {err := (, headers)if len(headers) 0 || !filter {}headers = (, headers, ())// Irrelevant of the fork checks, send the header to the fetcher just in case}return nil().Debug(Verified to be on the same side of the DAO fork)}return err().Debug(Verified to be on the other side of the DAO fork, dropping) err != nil {amp。// If it39。if filter {filter := len(headers) == 1// Filter out any explicitly requested headers, deliver the rest to the downloader}}return nil = nil()().Debug(Seems to be on the same side of the DAO fork)if verifyDAO {re seemingly on the same chain, disable the drop timerif _, td := ()。 daoHeader != nil {// the peer39。s TD against it. Ifamp。re expending a DAO fork check, maybe it39。headers)。if header := (next)。} else {unknown = true().Warn(GetBlockHeaders skip overflow attack, current, current, skip, , next, next, attacker, infos)infos, _ := ((), , )if next = current {)next = current + + 1current = ()var (// Hash based traversal towards the leaf block !:case != ({}) amp。}}breakunknown = true} else {number = header != nil { i int()+1。amp。amp。amp。amp。query)。// Read the next message from the remote peer, and ensure it39。}```死循環(huán),處理p2p網(wǎng)絡(luò)過來的消息,接著看`handleMsg`方法```func (pm *ProtocolManager) handleMsg(p *peer) error {}return err().Debug(Ethereum message handling failed, err, err) err != nil {// Fetcher負責積累來自各個peer的區(qū)塊通知并安排進行檢索。// 生成一個fetcher}return (blocks), 1) // Mark initial sync done on any fetcher importif (amp。// If fast sync is running, deny importing weird blocksinserter := func(blocks ) (int, error) {}return ().NumberU64()heighter := func() uint64 {}return (blockchain, header, true)validator := func(header *) error { = (mode, chaindb, , blockchain, nil, )// Construct the different synchronisation mechanisms// downloader是全鏈同步工具if p := ((%x, id[:8]))。PeerInfo: func(id ) interface{} {},return ()NodeInfo: func() interface{} {},}return case :return (peer)defer ()(1)case peer:select {peer := (int(version), p, rw)Run: func(p *, rw ) error {Length: ProtocolLengths[i],Version: version,Name: ProtocolName, = append(, {version := version // Closure for the run initialise the subprotocolamp。amp。manager := amp。// Create the protocol manager with the base fields}}```這里面會發(fā)送兩種時間,一種是`NewBlockMsg`,另外一種是`NewBlockHashesMsg`,好了到此本地節(jié)點挖到的塊就通過p2p網(wǎng)絡(luò)的形式開始擴散出去了接著看下一個重要的方法```// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable// with the ethereum network.func NewProtocolManager(config *, mode , networkId uint64, mux *, txpool txPool, engine , blockchain *, chaindb ) (*ProtocolManager, error) {(Announced block, hash, hash, recipients, len(peers), duration, (()))}([]{hash}, []uint64{()})for _, peer := range peers {if (hash, ()) {// Otherwise if the block is indeed in out own chain, announce it}return(Propagated block, hash, hash, recipients, len(transfer), duration, (()))}(block, td)for _, peer := range transfer {transfer := peers[:int((float64(len(peers))))]// Send the block to a subset of our peers}return(Propagating dangling block, number, (), hash, hash)} else {td = new().Add((), ((), ()1)) parent != nil {// Calculate the TD of the block (it39。if propagate {// If propagation is requested, send to a subset of the peerpeers := (hash)hash := ()s requested).func (pm *ProtocolManager) BroadcastBlock(block *, propagate bool) {s peers, or// will only announce it39。 為了最小化出口帶寬使用,我們一次只發(fā)送一個小包。// txsyncLoop負責每個新連接的初始事務同步。go ()// start sync handlers 這個訂閱和上面的那個訂閱采用了兩種不同的模式,這種是標記為Deprecated的訂閱方式。// 訂閱挖礦消息。go () = ()// 訂閱的回執(zhí) = make(chan , txChanSize)txpool有了這種消息會通知給這個txCh。// 廣播交易的通道。// broadcast transactions = maxPeers}}```這里發(fā)送了一個新挖到塊的事件,接著跟,調(diào)用棧是```/geth/ startNode (stack) () /node/() (running) /eth/() /eth/()```()里面```func (pm *ProtocolManager) Start(maxPeers int) {}}()if mustCommitNewWork {((), ())// Insert the block into the set of pending ones to wait for confirmations(events, logs)}events = append(events, {Block: block})if stat == {events = append(events, {Block: block, Hash: (), Logs: logs}))logs = ()events []interface{}var (({Block: block})// 通過p2p的形式將塊廣播到連接的節(jié)點,走的還是channel// Broadcast the block and announce chain insertion event}mustCommitNewWork = false// implicit by posting ChainHeadEventif stat == {// check if canon block and w