github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/network/stream/stream.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:44</date>
    10  //</624450115758723072>
    11  
    12  
    13  package stream
    14  
    15  import (
    16  	"context"
    17  	"errors"
    18  	"fmt"
    19  	"math"
    20  	"reflect"
    21  	"sync"
    22  	"time"
    23  
    24  	"github.com/ethereum/go-ethereum/metrics"
    25  	"github.com/ethereum/go-ethereum/p2p"
    26  	"github.com/ethereum/go-ethereum/p2p/enode"
    27  	"github.com/ethereum/go-ethereum/p2p/protocols"
    28  	"github.com/ethereum/go-ethereum/rpc"
    29  	"github.com/ethereum/go-ethereum/swarm/log"
    30  	"github.com/ethereum/go-ethereum/swarm/network"
    31  	"github.com/ethereum/go-ethereum/swarm/network/stream/intervals"
    32  	"github.com/ethereum/go-ethereum/swarm/state"
    33  	"github.com/ethereum/go-ethereum/swarm/storage"
    34  )
    35  
    36  const (
    37  	Low uint8 = iota
    38  	Mid
    39  	High
    40  	Top
    41  PriorityQueue    = 4    //优先级队列数-低、中、高、顶
    42  PriorityQueueCap = 4096 //队列容量
    43  	HashSize         = 32
    44  )
    45  
    46  //枚举用于同步和检索的选项
    47  type SyncingOption int
    48  type RetrievalOption int
    49  
    50  //同步选项
    51  const (
    52  //同步已禁用
    53  	SyncingDisabled SyncingOption = iota
    54  //注册客户端和服务器,但不订阅
    55  	SyncingRegisterOnly
    56  //客户端和服务器功能都已注册,订阅将自动发送
    57  	SyncingAutoSubscribe
    58  )
    59  
    60  const (
    61  //检索已禁用。主要用于隔离同步功能的测试(即仅同步)
    62  	RetrievalDisabled RetrievalOption = iota
    63  //仅注册检索请求的客户端。
    64  //(轻节点不提供检索请求)
    65  //一旦注册了客户端,总是发送用于检索请求流的订阅
    66  	RetrievalClientOnly
    67  //客户端和服务器功能都已注册,订阅将自动发送
    68  	RetrievalEnabled
    69  )
    70  
    71  //subscriptionUnc用于确定执行订阅时要执行的操作
    72  //通常我们会开始真正订阅节点,但是对于测试,可能需要其他功能
    73  //(请参阅streamer_test.go中的testrequestpeersubscriptions)
    74  var subscriptionFunc func(r *Registry, p *network.Peer, bin uint8, subs map[enode.ID]map[Stream]struct{}) bool = doRequestSubscription
    75  
    76  //传出和传入拖缆构造函数的注册表
    77  type Registry struct {
    78  	addr           enode.ID
    79  	api            *API
    80  	skipCheck      bool
    81  	clientMu       sync.RWMutex
    82  	serverMu       sync.RWMutex
    83  	peersMu        sync.RWMutex
    84  	serverFuncs    map[string]func(*Peer, string, bool) (Server, error)
    85  	clientFuncs    map[string]func(*Peer, string, bool) (Client, error)
    86  	peers          map[enode.ID]*Peer
    87  	delivery       *Delivery
    88  	intervalsStore state.Store
    89  autoRetrieval  bool //自动订阅以检索请求流
    90  	maxPeerServers int
    91  spec           *protocols.Spec   //本协议规范
    92  balance        protocols.Balance //实现协议。平衡,用于记帐
    93  prices         protocols.Prices  //执行协议。价格,为会计提供价格
    94  }
    95  
    96  //RegistryOptions保留NewRegistry构造函数的可选值。
    97  type RegistryOptions struct {
    98  	SkipCheck       bool
    99  Syncing         SyncingOption   //定义同步行为
   100  Retrieval       RetrievalOption //定义检索行为
   101  	SyncUpdateDelay time.Duration
   102  MaxPeerServers  int //注册表中每个对等服务器的限制
   103  }
   104  
   105  //NewRegistry是拖缆构造函数
   106  func NewRegistry(localID enode.ID, delivery *Delivery, syncChunkStore storage.SyncChunkStore, intervalsStore state.Store, options *RegistryOptions, balance protocols.Balance) *Registry {
   107  	if options == nil {
   108  		options = &RegistryOptions{}
   109  	}
   110  	if options.SyncUpdateDelay <= 0 {
   111  		options.SyncUpdateDelay = 15 * time.Second
   112  	}
   113  //检查是否已禁用检索
   114  	retrieval := options.Retrieval != RetrievalDisabled
   115  
   116  	streamer := &Registry{
   117  		addr:           localID,
   118  		skipCheck:      options.SkipCheck,
   119  		serverFuncs:    make(map[string]func(*Peer, string, bool) (Server, error)),
   120  		clientFuncs:    make(map[string]func(*Peer, string, bool) (Client, error)),
   121  		peers:          make(map[enode.ID]*Peer),
   122  		delivery:       delivery,
   123  		intervalsStore: intervalsStore,
   124  		autoRetrieval:  retrieval,
   125  		maxPeerServers: options.MaxPeerServers,
   126  		balance:        balance,
   127  	}
   128  
   129  	streamer.setupSpec()
   130  
   131  	streamer.api = NewAPI(streamer)
   132  	delivery.getPeer = streamer.getPeer
   133  
   134  //如果启用了检索,请注册服务器func,以便为检索请求提供服务(仅限非轻型节点)
   135  	if options.Retrieval == RetrievalEnabled {
   136  		streamer.RegisterServerFunc(swarmChunkServerStreamName, func(_ *Peer, _ string, live bool) (Server, error) {
   137  			if !live {
   138  				return nil, errors.New("only live retrieval requests supported")
   139  			}
   140  			return NewSwarmChunkServer(delivery.chunkStore), nil
   141  		})
   142  	}
   143  
   144  //如果未禁用检索,则注册客户机func(轻节点和普通节点都可以发出检索请求)
   145  	if options.Retrieval != RetrievalDisabled {
   146  		streamer.RegisterClientFunc(swarmChunkServerStreamName, func(p *Peer, t string, live bool) (Client, error) {
   147  			return NewSwarmSyncerClient(p, syncChunkStore, NewStream(swarmChunkServerStreamName, t, live))
   148  		})
   149  	}
   150  
   151  //如果未禁用同步,则会注册同步功能(客户端和服务器)
   152  	if options.Syncing != SyncingDisabled {
   153  		RegisterSwarmSyncerServer(streamer, syncChunkStore)
   154  		RegisterSwarmSyncerClient(streamer, syncChunkStore)
   155  	}
   156  
   157  //如果同步设置为自动订阅同步流,则启动订阅过程。
   158  	if options.Syncing == SyncingAutoSubscribe {
   159  //latestintc函数确保
   160  //-通过for循环内部的处理不会阻止来自in chan的接收
   161  //-处理完成后,将最新的int值传递给循环
   162  //在邻近地区:
   163  //在循环内完成同步更新之后,我们不需要在中间更新
   164  //深度变化,仅限于最新的
   165  		latestIntC := func(in <-chan int) <-chan int {
   166  			out := make(chan int, 1)
   167  
   168  			go func() {
   169  				defer close(out)
   170  
   171  				for i := range in {
   172  					select {
   173  					case <-out:
   174  					default:
   175  					}
   176  					out <- i
   177  				}
   178  			}()
   179  
   180  			return out
   181  		}
   182  
   183  		go func() {
   184  //等待卡德米利亚桌健康
   185  			time.Sleep(options.SyncUpdateDelay)
   186  
   187  			kad := streamer.delivery.kad
   188  			depthC := latestIntC(kad.NeighbourhoodDepthC())
   189  			addressBookSizeC := latestIntC(kad.AddrCountC())
   190  
   191  //同步对对等方订阅的初始请求
   192  			streamer.updateSyncing()
   193  
   194  			for depth := range depthC {
   195  				log.Debug("Kademlia neighbourhood depth change", "depth", depth)
   196  
   197  //通过等待直到没有
   198  //新的对等连接。同步流更新将在否之后完成
   199  //对等机连接的时间至少为SyncUpdateDelay。
   200  				timer := time.NewTimer(options.SyncUpdateDelay)
   201  //硬限制同步更新延迟,防止长延迟
   202  //在一个非常动态的网络上
   203  				maxTimer := time.NewTimer(3 * time.Minute)
   204  			loop:
   205  				for {
   206  					select {
   207  					case <-maxTimer.C:
   208  //达到硬超时时强制同步更新
   209  						log.Trace("Sync subscriptions update on hard timeout")
   210  //请求将订阅同步到新对等方
   211  						streamer.updateSyncing()
   212  						break loop
   213  					case <-timer.C:
   214  //开始同步,因为没有新的同级添加到Kademlia
   215  //一段时间
   216  						log.Trace("Sync subscriptions update")
   217  //请求将订阅同步到新对等方
   218  						streamer.updateSyncing()
   219  						break loop
   220  					case size := <-addressBookSizeC:
   221  						log.Trace("Kademlia address book size changed on depth change", "size", size)
   222  //Kademlia增加了新的同行,
   223  //重置计时器以阻止早期同步订阅
   224  						if !timer.Stop() {
   225  							<-timer.C
   226  						}
   227  						timer.Reset(options.SyncUpdateDelay)
   228  					}
   229  				}
   230  				timer.Stop()
   231  				maxTimer.Stop()
   232  			}
   233  		}()
   234  	}
   235  
   236  	return streamer
   237  }
   238  
   239  //这是一个记帐协议,因此我们需要为规范提供定价挂钩
   240  //为了使模拟能够运行多个节点,而不覆盖钩子的平衡,
   241  //我们需要为每个节点实例构造一个规范实例
   242  func (r *Registry) setupSpec() {
   243  //首先创建“裸”规范
   244  	r.createSpec()
   245  //现在创建定价对象
   246  	r.createPriceOracle()
   247  //如果余额为零,则此节点已在不支持交换的情况下启动(swapEnabled标志为假)
   248  	if r.balance != nil && !reflect.ValueOf(r.balance).IsNil() {
   249  //交换已启用,因此设置挂钩
   250  		r.spec.Hook = protocols.NewAccounting(r.balance, r.prices)
   251  	}
   252  }
   253  
   254  //RegisterClient注册一个传入的拖缆构造函数
   255  func (r *Registry) RegisterClientFunc(stream string, f func(*Peer, string, bool) (Client, error)) {
   256  	r.clientMu.Lock()
   257  	defer r.clientMu.Unlock()
   258  
   259  	r.clientFuncs[stream] = f
   260  }
   261  
   262  //RegisterServer注册传出拖缆构造函数
   263  func (r *Registry) RegisterServerFunc(stream string, f func(*Peer, string, bool) (Server, error)) {
   264  	r.serverMu.Lock()
   265  	defer r.serverMu.Unlock()
   266  
   267  	r.serverFuncs[stream] = f
   268  }
   269  
   270  //用于传入拖缆构造函数的getclient访问器
   271  func (r *Registry) GetClientFunc(stream string) (func(*Peer, string, bool) (Client, error), error) {
   272  	r.clientMu.RLock()
   273  	defer r.clientMu.RUnlock()
   274  
   275  	f := r.clientFuncs[stream]
   276  	if f == nil {
   277  		return nil, fmt.Errorf("stream %v not registered", stream)
   278  	}
   279  	return f, nil
   280  }
   281  
   282  //用于传入拖缆构造函数的getserver访问器
   283  func (r *Registry) GetServerFunc(stream string) (func(*Peer, string, bool) (Server, error), error) {
   284  	r.serverMu.RLock()
   285  	defer r.serverMu.RUnlock()
   286  
   287  	f := r.serverFuncs[stream]
   288  	if f == nil {
   289  		return nil, fmt.Errorf("stream %v not registered", stream)
   290  	}
   291  	return f, nil
   292  }
   293  
   294  func (r *Registry) RequestSubscription(peerId enode.ID, s Stream, h *Range, prio uint8) error {
   295  //检查流是否已注册
   296  	if _, err := r.GetServerFunc(s.Name); err != nil {
   297  		return err
   298  	}
   299  
   300  	peer := r.getPeer(peerId)
   301  	if peer == nil {
   302  		return fmt.Errorf("peer not found %v", peerId)
   303  	}
   304  
   305  	if _, err := peer.getServer(s); err != nil {
   306  		if e, ok := err.(*notFoundError); ok && e.t == "server" {
   307  //仅当未创建此流的服务器时才请求订阅
   308  			log.Debug("RequestSubscription ", "peer", peerId, "stream", s, "history", h)
   309  			return peer.Send(context.TODO(), &RequestSubscriptionMsg{
   310  				Stream:   s,
   311  				History:  h,
   312  				Priority: prio,
   313  			})
   314  		}
   315  		return err
   316  	}
   317  	log.Trace("RequestSubscription: already subscribed", "peer", peerId, "stream", s, "history", h)
   318  	return nil
   319  }
   320  
   321  //订阅启动拖缆
   322  func (r *Registry) Subscribe(peerId enode.ID, s Stream, h *Range, priority uint8) error {
   323  //检查流是否已注册
   324  	if _, err := r.GetClientFunc(s.Name); err != nil {
   325  		return err
   326  	}
   327  
   328  	peer := r.getPeer(peerId)
   329  	if peer == nil {
   330  		return fmt.Errorf("peer not found %v", peerId)
   331  	}
   332  
   333  	var to uint64
   334  	if !s.Live && h != nil {
   335  		to = h.To
   336  	}
   337  
   338  	err := peer.setClientParams(s, newClientParams(priority, to))
   339  	if err != nil {
   340  		return err
   341  	}
   342  	if s.Live && h != nil {
   343  		if err := peer.setClientParams(
   344  			getHistoryStream(s),
   345  			newClientParams(getHistoryPriority(priority), h.To),
   346  		); err != nil {
   347  			return err
   348  		}
   349  	}
   350  
   351  	msg := &SubscribeMsg{
   352  		Stream:   s,
   353  		History:  h,
   354  		Priority: priority,
   355  	}
   356  	log.Debug("Subscribe ", "peer", peerId, "stream", s, "history", h)
   357  
   358  	return peer.SendPriority(context.TODO(), msg, priority)
   359  }
   360  
   361  func (r *Registry) Unsubscribe(peerId enode.ID, s Stream) error {
   362  	peer := r.getPeer(peerId)
   363  	if peer == nil {
   364  		return fmt.Errorf("peer not found %v", peerId)
   365  	}
   366  
   367  	msg := &UnsubscribeMsg{
   368  		Stream: s,
   369  	}
   370  	log.Debug("Unsubscribe ", "peer", peerId, "stream", s)
   371  
   372  	if err := peer.Send(context.TODO(), msg); err != nil {
   373  		return err
   374  	}
   375  	return peer.removeClient(s)
   376  }
   377  
   378  //quit将quitmsg发送到对等端以删除
   379  //流对等客户端并终止流。
   380  func (r *Registry) Quit(peerId enode.ID, s Stream) error {
   381  	peer := r.getPeer(peerId)
   382  	if peer == nil {
   383  		log.Debug("stream quit: peer not found", "peer", peerId, "stream", s)
   384  //如果找不到对等点,则中止请求
   385  		return nil
   386  	}
   387  
   388  	msg := &QuitMsg{
   389  		Stream: s,
   390  	}
   391  	log.Debug("Quit ", "peer", peerId, "stream", s)
   392  
   393  	return peer.Send(context.TODO(), msg)
   394  }
   395  
   396  func (r *Registry) Close() error {
   397  	return r.intervalsStore.Close()
   398  }
   399  
   400  func (r *Registry) getPeer(peerId enode.ID) *Peer {
   401  	r.peersMu.RLock()
   402  	defer r.peersMu.RUnlock()
   403  
   404  	return r.peers[peerId]
   405  }
   406  
   407  func (r *Registry) setPeer(peer *Peer) {
   408  	r.peersMu.Lock()
   409  	r.peers[peer.ID()] = peer
   410  	metrics.GetOrRegisterGauge("registry.peers", nil).Update(int64(len(r.peers)))
   411  	r.peersMu.Unlock()
   412  }
   413  
   414  func (r *Registry) deletePeer(peer *Peer) {
   415  	r.peersMu.Lock()
   416  	delete(r.peers, peer.ID())
   417  	metrics.GetOrRegisterGauge("registry.peers", nil).Update(int64(len(r.peers)))
   418  	r.peersMu.Unlock()
   419  }
   420  
   421  func (r *Registry) peersCount() (c int) {
   422  	r.peersMu.Lock()
   423  	c = len(r.peers)
   424  	r.peersMu.Unlock()
   425  	return
   426  }
   427  
   428  //运行协议运行函数
   429  func (r *Registry) Run(p *network.BzzPeer) error {
   430  	sp := NewPeer(p.Peer, r)
   431  	r.setPeer(sp)
   432  	defer r.deletePeer(sp)
   433  	defer close(sp.quit)
   434  	defer sp.close()
   435  
   436  	if r.autoRetrieval && !p.LightNode {
   437  		err := r.Subscribe(p.ID(), NewStream(swarmChunkServerStreamName, "", true), nil, Top)
   438  		if err != nil {
   439  			return err
   440  		}
   441  	}
   442  
   443  	return sp.Run(sp.HandleMsg)
   444  }
   445  
   446  //通过迭代更新同步订阅以同步流
   447  //卡德米利亚连接和箱子。如果存在同步流
   448  //并且在迭代之后不再需要它们,请求退出
   449  //它们将被发送到适当的对等方。
   450  func (r *Registry) updateSyncing() {
   451  	kad := r.delivery.kad
   452  //所有对等端的所有同步流的映射
   453  //在和中用于删除服务器
   454  //不再需要了
   455  	subs := make(map[enode.ID]map[Stream]struct{})
   456  	r.peersMu.RLock()
   457  	for id, peer := range r.peers {
   458  		peer.serverMu.RLock()
   459  		for stream := range peer.servers {
   460  			if stream.Name == "SYNC" {
   461  				if _, ok := subs[id]; !ok {
   462  					subs[id] = make(map[Stream]struct{})
   463  				}
   464  				subs[id][stream] = struct{}{}
   465  			}
   466  		}
   467  		peer.serverMu.RUnlock()
   468  	}
   469  	r.peersMu.RUnlock()
   470  
   471  //开始从对等方请求订阅
   472  	r.requestPeerSubscriptions(kad, subs)
   473  
   474  //删除不需要订阅的同步服务器
   475  	for id, streams := range subs {
   476  		if len(streams) == 0 {
   477  			continue
   478  		}
   479  		peer := r.getPeer(id)
   480  		if peer == nil {
   481  			continue
   482  		}
   483  		for stream := range streams {
   484  			log.Debug("Remove sync server", "peer", id, "stream", stream)
   485  			err := r.Quit(peer.ID(), stream)
   486  			if err != nil && err != p2p.ErrShuttingDown {
   487  				log.Error("quit", "err", err, "peer", peer.ID(), "stream", stream)
   488  			}
   489  		}
   490  	}
   491  }
   492  
   493  //请求对等订阅对kademlia表中的每个活动对等调用
   494  //并根据对等端的bin向其发送“requestsubscription”
   495  //以及他们与卡德米利亚的关系。
   496  //还要检查“testrequestpeersubscriptions”以了解
   497  //预期行为。
   498  //函数期望:
   499  //*卡德米利亚
   500  //*订阅地图
   501  //*实际订阅功能
   502  //(在测试的情况下,它不做真正的订阅)
   503  func (r *Registry) requestPeerSubscriptions(kad *network.Kademlia, subs map[enode.ID]map[Stream]struct{}) {
   504  
   505  	var startPo int
   506  	var endPo int
   507  	var ok bool
   508  
   509  //卡德米利亚深度
   510  	kadDepth := kad.NeighbourhoodDepth()
   511  //请求订阅所有节点和容器
   512  //nil作为base取节点的base;我们需要传递255作为'eachconn'运行
   513  //从最深的箱子向后
   514  	kad.EachConn(nil, 255, func(p *network.Peer, po int) bool {
   515  //如果同伴的箱子比卡德米利亚的深度浅,
   516  //只应订阅对等机的bin
   517  		if po < kadDepth {
   518  			startPo = po
   519  			endPo = po
   520  		} else {
   521  //如果同伴的垃圾桶等于或深于卡德米利亚的深度,
   522  //从深度到k.maxproxplay的每个bin都应该订阅
   523  			startPo = kadDepth
   524  			endPo = kad.MaxProxDisplay
   525  		}
   526  
   527  		for bin := startPo; bin <= endPo; bin++ {
   528  //做实际订阅
   529  			ok = subscriptionFunc(r, p, uint8(bin), subs)
   530  		}
   531  		return ok
   532  	})
   533  }
   534  
   535  //DoRequestSubscription将实际的RequestSubscription发送到对等端
   536  func doRequestSubscription(r *Registry, p *network.Peer, bin uint8, subs map[enode.ID]map[Stream]struct{}) bool {
   537  	log.Debug("Requesting subscription by registry:", "registry", r.addr, "peer", p.ID(), "bin", bin)
   538  //bin总是小于256,可以安全地将其转换为uint8类型
   539  	stream := NewStream("SYNC", FormatSyncBinKey(bin), true)
   540  	if streams, ok := subs[p.ID()]; ok {
   541  //从映射中删除实时流和历史流,以便在发出退出请求时不会将其删除。
   542  		delete(streams, stream)
   543  		delete(streams, getHistoryStream(stream))
   544  	}
   545  	err := r.RequestSubscription(p.ID(), stream, NewRange(0, 0), High)
   546  	if err != nil {
   547  		log.Debug("Request subscription", "err", err, "peer", p.ID(), "stream", stream)
   548  		return false
   549  	}
   550  	return true
   551  }
   552  
   553  func (r *Registry) runProtocol(p *p2p.Peer, rw p2p.MsgReadWriter) error {
   554  	peer := protocols.NewPeer(p, rw, r.spec)
   555  	bp := network.NewBzzPeer(peer)
   556  	np := network.NewPeer(bp, r.delivery.kad)
   557  	r.delivery.kad.On(np)
   558  	defer r.delivery.kad.Off(np)
   559  	return r.Run(bp)
   560  }
   561  
   562  //handlemsg是委托传入消息的消息处理程序
   563  func (p *Peer) HandleMsg(ctx context.Context, msg interface{}) error {
   564  	switch msg := msg.(type) {
   565  
   566  	case *SubscribeMsg:
   567  		return p.handleSubscribeMsg(ctx, msg)
   568  
   569  	case *SubscribeErrorMsg:
   570  		return p.handleSubscribeErrorMsg(msg)
   571  
   572  	case *UnsubscribeMsg:
   573  		return p.handleUnsubscribeMsg(msg)
   574  
   575  	case *OfferedHashesMsg:
   576  		return p.handleOfferedHashesMsg(ctx, msg)
   577  
   578  	case *TakeoverProofMsg:
   579  		return p.handleTakeoverProofMsg(ctx, msg)
   580  
   581  	case *WantedHashesMsg:
   582  		return p.handleWantedHashesMsg(ctx, msg)
   583  
   584  	case *ChunkDeliveryMsgRetrieval:
   585  //对于检索和同步,处理块传递是相同的,所以让我们将msg
   586  		return p.streamer.delivery.handleChunkDeliveryMsg(ctx, p, ((*ChunkDeliveryMsg)(msg)))
   587  
   588  	case *ChunkDeliveryMsgSyncing:
   589  //对于检索和同步,处理块传递是相同的,所以让我们将msg
   590  		return p.streamer.delivery.handleChunkDeliveryMsg(ctx, p, ((*ChunkDeliveryMsg)(msg)))
   591  
   592  	case *RetrieveRequestMsg:
   593  		return p.streamer.delivery.handleRetrieveRequestMsg(ctx, p, msg)
   594  
   595  	case *RequestSubscriptionMsg:
   596  		return p.handleRequestSubscription(ctx, msg)
   597  
   598  	case *QuitMsg:
   599  		return p.handleQuitMsg(msg)
   600  
   601  	default:
   602  		return fmt.Errorf("unknown message type: %T", msg)
   603  	}
   604  }
   605  
   606  type server struct {
   607  	Server
   608  	stream       Stream
   609  	priority     uint8
   610  	currentBatch []byte
   611  	sessionIndex uint64
   612  }
   613  
   614  //setNextbatch根据会话索引和是否
   615  //溪流是生命或历史。它调用服务器setnextbatch
   616  //并返回批处理散列及其间隔。
   617  func (s *server) setNextBatch(from, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) {
   618  	if s.stream.Live {
   619  		if from == 0 {
   620  			from = s.sessionIndex
   621  		}
   622  		if to <= from || from >= s.sessionIndex {
   623  			to = math.MaxUint64
   624  		}
   625  	} else {
   626  		if (to < from && to != 0) || from > s.sessionIndex {
   627  			return nil, 0, 0, nil, nil
   628  		}
   629  		if to == 0 || to > s.sessionIndex {
   630  			to = s.sessionIndex
   631  		}
   632  	}
   633  	return s.SetNextBatch(from, to)
   634  }
   635  
   636  //传出对等拖缆的服务器接口
   637  type Server interface {
   638  //初始化服务器时调用sessionindex
   639  //获取流数据的当前光标状态。
   640  //基于此索引,实时和历史流间隔
   641  //将在调用setnextbatch之前进行调整。
   642  	SessionIndex() (uint64, error)
   643  	SetNextBatch(uint64, uint64) (hashes []byte, from uint64, to uint64, proof *HandoverProof, err error)
   644  	GetData(context.Context, []byte) ([]byte, error)
   645  	Close()
   646  }
   647  
   648  type client struct {
   649  	Client
   650  	stream    Stream
   651  	priority  uint8
   652  	sessionAt uint64
   653  	to        uint64
   654  	next      chan error
   655  	quit      chan struct{}
   656  
   657  	intervalsKey   string
   658  	intervalsStore state.Store
   659  }
   660  
   661  func peerStreamIntervalsKey(p *Peer, s Stream) string {
   662  	return p.ID().String() + s.String()
   663  }
   664  
   665  func (c *client) AddInterval(start, end uint64) (err error) {
   666  	i := &intervals.Intervals{}
   667  	if err = c.intervalsStore.Get(c.intervalsKey, i); err != nil {
   668  		return err
   669  	}
   670  	i.Add(start, end)
   671  	return c.intervalsStore.Put(c.intervalsKey, i)
   672  }
   673  
   674  func (c *client) NextInterval() (start, end uint64, err error) {
   675  	i := &intervals.Intervals{}
   676  	err = c.intervalsStore.Get(c.intervalsKey, i)
   677  	if err != nil {
   678  		return 0, 0, err
   679  	}
   680  	start, end = i.Next()
   681  	return start, end, nil
   682  }
   683  
   684  //传入对等拖缆的客户端接口
   685  type Client interface {
   686  	NeedData(context.Context, []byte) func(context.Context) error
   687  	BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error)
   688  	Close()
   689  }
   690  
   691  func (c *client) nextBatch(from uint64) (nextFrom uint64, nextTo uint64) {
   692  	if c.to > 0 && from >= c.to {
   693  		return 0, 0
   694  	}
   695  	if c.stream.Live {
   696  		return from, 0
   697  	} else if from >= c.sessionAt {
   698  		if c.to > 0 {
   699  			return from, c.to
   700  		}
   701  		return from, math.MaxUint64
   702  	}
   703  	nextFrom, nextTo, err := c.NextInterval()
   704  	if err != nil {
   705  		log.Error("next intervals", "stream", c.stream)
   706  		return
   707  	}
   708  	if nextTo > c.to {
   709  		nextTo = c.to
   710  	}
   711  	if nextTo == 0 {
   712  		nextTo = c.sessionAt
   713  	}
   714  	return
   715  }
   716  
   717  func (c *client) batchDone(p *Peer, req *OfferedHashesMsg, hashes []byte) error {
   718  	if tf := c.BatchDone(req.Stream, req.From, hashes, req.Root); tf != nil {
   719  		tp, err := tf()
   720  		if err != nil {
   721  			return err
   722  		}
   723  		if err := p.SendPriority(context.TODO(), tp, c.priority); err != nil {
   724  			return err
   725  		}
   726  		if c.to > 0 && tp.Takeover.End >= c.to {
   727  			return p.streamer.Unsubscribe(p.Peer.ID(), req.Stream)
   728  		}
   729  		return nil
   730  	}
   731  	return c.AddInterval(req.From, req.To)
   732  }
   733  
   734  func (c *client) close() {
   735  	select {
   736  	case <-c.quit:
   737  	default:
   738  		close(c.quit)
   739  	}
   740  	c.Close()
   741  }
   742  
   743  //clientparams存储新客户端的参数
   744  //在订阅和初始提供的哈希请求处理之间。
   745  type clientParams struct {
   746  	priority uint8
   747  	to       uint64
   748  //创建客户端时发出信号
   749  	clientCreatedC chan struct{}
   750  }
   751  
   752  func newClientParams(priority uint8, to uint64) *clientParams {
   753  	return &clientParams{
   754  		priority:       priority,
   755  		to:             to,
   756  		clientCreatedC: make(chan struct{}),
   757  	}
   758  }
   759  
   760  func (c *clientParams) waitClient(ctx context.Context) error {
   761  	select {
   762  	case <-ctx.Done():
   763  		return ctx.Err()
   764  	case <-c.clientCreatedC:
   765  		return nil
   766  	}
   767  }
   768  
   769  func (c *clientParams) clientCreated() {
   770  	close(c.clientCreatedC)
   771  }
   772  
   773  //getspec将拖缆规格返回给调用者
   774  //这曾经是一个全局变量,但用于模拟
   775  //多个节点其字段(尤其是钩子)将被覆盖
   776  func (r *Registry) GetSpec() *protocols.Spec {
   777  	return r.spec
   778  }
   779  
   780  func (r *Registry) createSpec() {
   781  //规范是拖缆协议的规范
   782  	var spec = &protocols.Spec{
   783  		Name:       "stream",
   784  		Version:    8,
   785  		MaxMsgSize: 10 * 1024 * 1024,
   786  		Messages: []interface{}{
   787  			UnsubscribeMsg{},
   788  			OfferedHashesMsg{},
   789  			WantedHashesMsg{},
   790  			TakeoverProofMsg{},
   791  			SubscribeMsg{},
   792  			RetrieveRequestMsg{},
   793  			ChunkDeliveryMsgRetrieval{},
   794  			SubscribeErrorMsg{},
   795  			RequestSubscriptionMsg{},
   796  			QuitMsg{},
   797  			ChunkDeliveryMsgSyncing{},
   798  		},
   799  	}
   800  	r.spec = spec
   801  }
   802  
   803  //有责任感的信息需要附加一些元信息
   804  //为了评估正确的价格
   805  type StreamerPrices struct {
   806  	priceMatrix map[reflect.Type]*protocols.Price
   807  	registry    *Registry
   808  }
   809  
   810  //price实现会计接口并返回特定消息的价格
   811  func (sp *StreamerPrices) Price(msg interface{}) *protocols.Price {
   812  	t := reflect.TypeOf(msg).Elem()
   813  	return sp.priceMatrix[t]
   814  }
   815  
   816  //不是硬编码价格,而是得到它
   817  //通过一个函数-它在未来可能非常复杂
   818  func (sp *StreamerPrices) getRetrieveRequestMsgPrice() uint64 {
   819  	return uint64(1)
   820  }
   821  
   822  //不是硬编码价格,而是得到它
   823  //通过一个函数-它在未来可能非常复杂
   824  func (sp *StreamerPrices) getChunkDeliveryMsgRetrievalPrice() uint64 {
   825  	return uint64(1)
   826  }
   827  
   828  //CreatePriceOracle设置一个矩阵,可以查询该矩阵以获取
   829  //通过Price方法发送消息的价格
   830  func (r *Registry) createPriceOracle() {
   831  	sp := &StreamerPrices{
   832  		registry: r,
   833  	}
   834  	sp.priceMatrix = map[reflect.Type]*protocols.Price{
   835  		reflect.TypeOf(ChunkDeliveryMsgRetrieval{}): {
   836  Value:   sp.getChunkDeliveryMsgRetrievalPrice(), //目前任意价格
   837  			PerByte: true,
   838  			Payer:   protocols.Receiver,
   839  		},
   840  		reflect.TypeOf(RetrieveRequestMsg{}): {
   841  Value:   sp.getRetrieveRequestMsgPrice(), //目前任意价格
   842  			PerByte: false,
   843  			Payer:   protocols.Sender,
   844  		},
   845  	}
   846  	r.prices = sp
   847  }
   848  
   849  func (r *Registry) Protocols() []p2p.Protocol {
   850  	return []p2p.Protocol{
   851  		{
   852  			Name:    r.spec.Name,
   853  			Version: r.spec.Version,
   854  			Length:  r.spec.Length(),
   855  			Run:     r.runProtocol,
   856  		},
   857  	}
   858  }
   859  
   860  func (r *Registry) APIs() []rpc.API {
   861  	return []rpc.API{
   862  		{
   863  			Namespace: "stream",
   864  			Version:   "3.0",
   865  			Service:   r.api,
   866  			Public:    true,
   867  		},
   868  	}
   869  }
   870  
   871  func (r *Registry) Start(server *p2p.Server) error {
   872  	log.Info("Streamer started")
   873  	return nil
   874  }
   875  
   876  func (r *Registry) Stop() error {
   877  	return nil
   878  }
   879  
   880  type Range struct {
   881  	From, To uint64
   882  }
   883  
   884  func NewRange(from, to uint64) *Range {
   885  	return &Range{
   886  		From: from,
   887  		To:   to,
   888  	}
   889  }
   890  
   891  func (r *Range) String() string {
   892  	return fmt.Sprintf("%v-%v", r.From, r.To)
   893  }
   894  
   895  func getHistoryPriority(priority uint8) uint8 {
   896  	if priority == 0 {
   897  		return 0
   898  	}
   899  	return priority - 1
   900  }
   901  
   902  func getHistoryStream(s Stream) Stream {
   903  	return NewStream(s.Name, s.Key, false)
   904  }
   905  
   906  type API struct {
   907  	streamer *Registry
   908  }
   909  
   910  func NewAPI(r *Registry) *API {
   911  	return &API{
   912  		streamer: r,
   913  	}
   914  }
   915  
   916  func (api *API) SubscribeStream(peerId enode.ID, s Stream, history *Range, priority uint8) error {
   917  	return api.streamer.Subscribe(peerId, s, history, priority)
   918  }
   919  
   920  func (api *API) UnsubscribeStream(peerId enode.ID, s Stream) error {
   921  	return api.streamer.Unsubscribe(peerId, s)
   922  }
   923