github.com/Ethersocial/go-esn@v0.3.7/swarm/network/stream/stream.go (about)

     1  // Copyright 2018 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 stream
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"math"
    23  	"sync"
    24  	"time"
    25  
    26  	"github.com/ethersocial/go-esn/metrics"
    27  	"github.com/ethersocial/go-esn/p2p"
    28  	"github.com/ethersocial/go-esn/p2p/enode"
    29  	"github.com/ethersocial/go-esn/p2p/protocols"
    30  	"github.com/ethersocial/go-esn/rpc"
    31  	"github.com/ethersocial/go-esn/swarm/log"
    32  	"github.com/ethersocial/go-esn/swarm/network"
    33  	"github.com/ethersocial/go-esn/swarm/network/stream/intervals"
    34  	"github.com/ethersocial/go-esn/swarm/pot"
    35  	"github.com/ethersocial/go-esn/swarm/state"
    36  	"github.com/ethersocial/go-esn/swarm/storage"
    37  )
    38  
    39  const (
    40  	Low uint8 = iota
    41  	Mid
    42  	High
    43  	Top
    44  	PriorityQueue    = 4    // number of priority queues - Low, Mid, High, Top
    45  	PriorityQueueCap = 4096 // queue capacity
    46  	HashSize         = 32
    47  )
    48  
    49  // Registry registry for outgoing and incoming streamer constructors
    50  type Registry struct {
    51  	addr           enode.ID
    52  	api            *API
    53  	skipCheck      bool
    54  	clientMu       sync.RWMutex
    55  	serverMu       sync.RWMutex
    56  	peersMu        sync.RWMutex
    57  	serverFuncs    map[string]func(*Peer, string, bool) (Server, error)
    58  	clientFuncs    map[string]func(*Peer, string, bool) (Client, error)
    59  	peers          map[enode.ID]*Peer
    60  	delivery       *Delivery
    61  	intervalsStore state.Store
    62  	doRetrieve     bool
    63  	maxPeerServers int
    64  }
    65  
    66  // RegistryOptions holds optional values for NewRegistry constructor.
    67  type RegistryOptions struct {
    68  	SkipCheck       bool
    69  	DoSync          bool
    70  	DoRetrieve      bool
    71  	SyncUpdateDelay time.Duration
    72  	MaxPeerServers  int // The limit of servers for each peer in registry
    73  }
    74  
    75  // NewRegistry is Streamer constructor
    76  func NewRegistry(localID enode.ID, delivery *Delivery, syncChunkStore storage.SyncChunkStore, intervalsStore state.Store, options *RegistryOptions) *Registry {
    77  	if options == nil {
    78  		options = &RegistryOptions{}
    79  	}
    80  	if options.SyncUpdateDelay <= 0 {
    81  		options.SyncUpdateDelay = 15 * time.Second
    82  	}
    83  	streamer := &Registry{
    84  		addr:           localID,
    85  		skipCheck:      options.SkipCheck,
    86  		serverFuncs:    make(map[string]func(*Peer, string, bool) (Server, error)),
    87  		clientFuncs:    make(map[string]func(*Peer, string, bool) (Client, error)),
    88  		peers:          make(map[enode.ID]*Peer),
    89  		delivery:       delivery,
    90  		intervalsStore: intervalsStore,
    91  		doRetrieve:     options.DoRetrieve,
    92  		maxPeerServers: options.MaxPeerServers,
    93  	}
    94  	streamer.api = NewAPI(streamer)
    95  	delivery.getPeer = streamer.getPeer
    96  	streamer.RegisterServerFunc(swarmChunkServerStreamName, func(_ *Peer, _ string, _ bool) (Server, error) {
    97  		return NewSwarmChunkServer(delivery.chunkStore), nil
    98  	})
    99  	streamer.RegisterClientFunc(swarmChunkServerStreamName, func(p *Peer, t string, live bool) (Client, error) {
   100  		return NewSwarmSyncerClient(p, syncChunkStore, NewStream(swarmChunkServerStreamName, t, live))
   101  	})
   102  	RegisterSwarmSyncerServer(streamer, syncChunkStore)
   103  	RegisterSwarmSyncerClient(streamer, syncChunkStore)
   104  
   105  	if options.DoSync {
   106  		// latestIntC function ensures that
   107  		//   - receiving from the in chan is not blocked by processing inside the for loop
   108  		// 	 - the latest int value is delivered to the loop after the processing is done
   109  		// In context of NeighbourhoodDepthC:
   110  		// after the syncing is done updating inside the loop, we do not need to update on the intermediate
   111  		// depth changes, only to the latest one
   112  		latestIntC := func(in <-chan int) <-chan int {
   113  			out := make(chan int, 1)
   114  
   115  			go func() {
   116  				defer close(out)
   117  
   118  				for i := range in {
   119  					select {
   120  					case <-out:
   121  					default:
   122  					}
   123  					out <- i
   124  				}
   125  			}()
   126  
   127  			return out
   128  		}
   129  
   130  		go func() {
   131  			// wait for kademlia table to be healthy
   132  			time.Sleep(options.SyncUpdateDelay)
   133  
   134  			kad := streamer.delivery.kad
   135  			depthC := latestIntC(kad.NeighbourhoodDepthC())
   136  			addressBookSizeC := latestIntC(kad.AddrCountC())
   137  
   138  			// initial requests for syncing subscription to peers
   139  			streamer.updateSyncing()
   140  
   141  			for depth := range depthC {
   142  				log.Debug("Kademlia neighbourhood depth change", "depth", depth)
   143  
   144  				// Prevent too early sync subscriptions by waiting until there are no
   145  				// new peers connecting. Sync streams updating will be done after no
   146  				// peers are connected for at least SyncUpdateDelay period.
   147  				timer := time.NewTimer(options.SyncUpdateDelay)
   148  				// Hard limit to sync update delay, preventing long delays
   149  				// on a very dynamic network
   150  				maxTimer := time.NewTimer(3 * time.Minute)
   151  			loop:
   152  				for {
   153  					select {
   154  					case <-maxTimer.C:
   155  						// force syncing update when a hard timeout is reached
   156  						log.Trace("Sync subscriptions update on hard timeout")
   157  						// request for syncing subscription to new peers
   158  						streamer.updateSyncing()
   159  						break loop
   160  					case <-timer.C:
   161  						// start syncing as no new peers has been added to kademlia
   162  						// for some time
   163  						log.Trace("Sync subscriptions update")
   164  						// request for syncing subscription to new peers
   165  						streamer.updateSyncing()
   166  						break loop
   167  					case size := <-addressBookSizeC:
   168  						log.Trace("Kademlia address book size changed on depth change", "size", size)
   169  						// new peers has been added to kademlia,
   170  						// reset the timer to prevent early sync subscriptions
   171  						if !timer.Stop() {
   172  							<-timer.C
   173  						}
   174  						timer.Reset(options.SyncUpdateDelay)
   175  					}
   176  				}
   177  				timer.Stop()
   178  				maxTimer.Stop()
   179  			}
   180  		}()
   181  	}
   182  
   183  	return streamer
   184  }
   185  
   186  // RegisterClient registers an incoming streamer constructor
   187  func (r *Registry) RegisterClientFunc(stream string, f func(*Peer, string, bool) (Client, error)) {
   188  	r.clientMu.Lock()
   189  	defer r.clientMu.Unlock()
   190  
   191  	r.clientFuncs[stream] = f
   192  }
   193  
   194  // RegisterServer registers an outgoing streamer constructor
   195  func (r *Registry) RegisterServerFunc(stream string, f func(*Peer, string, bool) (Server, error)) {
   196  	r.serverMu.Lock()
   197  	defer r.serverMu.Unlock()
   198  
   199  	r.serverFuncs[stream] = f
   200  }
   201  
   202  // GetClient accessor for incoming streamer constructors
   203  func (r *Registry) GetClientFunc(stream string) (func(*Peer, string, bool) (Client, error), error) {
   204  	r.clientMu.RLock()
   205  	defer r.clientMu.RUnlock()
   206  
   207  	f := r.clientFuncs[stream]
   208  	if f == nil {
   209  		return nil, fmt.Errorf("stream %v not registered", stream)
   210  	}
   211  	return f, nil
   212  }
   213  
   214  // GetServer accessor for incoming streamer constructors
   215  func (r *Registry) GetServerFunc(stream string) (func(*Peer, string, bool) (Server, error), error) {
   216  	r.serverMu.RLock()
   217  	defer r.serverMu.RUnlock()
   218  
   219  	f := r.serverFuncs[stream]
   220  	if f == nil {
   221  		return nil, fmt.Errorf("stream %v not registered", stream)
   222  	}
   223  	return f, nil
   224  }
   225  
   226  func (r *Registry) RequestSubscription(peerId enode.ID, s Stream, h *Range, prio uint8) error {
   227  	// check if the stream is registered
   228  	if _, err := r.GetServerFunc(s.Name); err != nil {
   229  		return err
   230  	}
   231  
   232  	peer := r.getPeer(peerId)
   233  	if peer == nil {
   234  		return fmt.Errorf("peer not found %v", peerId)
   235  	}
   236  
   237  	if _, err := peer.getServer(s); err != nil {
   238  		if e, ok := err.(*notFoundError); ok && e.t == "server" {
   239  			// request subscription only if the server for this stream is not created
   240  			log.Debug("RequestSubscription ", "peer", peerId, "stream", s, "history", h)
   241  			return peer.Send(context.TODO(), &RequestSubscriptionMsg{
   242  				Stream:   s,
   243  				History:  h,
   244  				Priority: prio,
   245  			})
   246  		}
   247  		return err
   248  	}
   249  	log.Trace("RequestSubscription: already subscribed", "peer", peerId, "stream", s, "history", h)
   250  	return nil
   251  }
   252  
   253  // Subscribe initiates the streamer
   254  func (r *Registry) Subscribe(peerId enode.ID, s Stream, h *Range, priority uint8) error {
   255  	// check if the stream is registered
   256  	if _, err := r.GetClientFunc(s.Name); err != nil {
   257  		return err
   258  	}
   259  
   260  	peer := r.getPeer(peerId)
   261  	if peer == nil {
   262  		return fmt.Errorf("peer not found %v", peerId)
   263  	}
   264  
   265  	var to uint64
   266  	if !s.Live && h != nil {
   267  		to = h.To
   268  	}
   269  
   270  	err := peer.setClientParams(s, newClientParams(priority, to))
   271  	if err != nil {
   272  		return err
   273  	}
   274  
   275  	if s.Live && h != nil {
   276  		if err := peer.setClientParams(
   277  			getHistoryStream(s),
   278  			newClientParams(getHistoryPriority(priority), h.To),
   279  		); err != nil {
   280  			return err
   281  		}
   282  	}
   283  
   284  	msg := &SubscribeMsg{
   285  		Stream:   s,
   286  		History:  h,
   287  		Priority: priority,
   288  	}
   289  	log.Debug("Subscribe ", "peer", peerId, "stream", s, "history", h)
   290  
   291  	return peer.SendPriority(context.TODO(), msg, priority)
   292  }
   293  
   294  func (r *Registry) Unsubscribe(peerId enode.ID, s Stream) error {
   295  	peer := r.getPeer(peerId)
   296  	if peer == nil {
   297  		return fmt.Errorf("peer not found %v", peerId)
   298  	}
   299  
   300  	msg := &UnsubscribeMsg{
   301  		Stream: s,
   302  	}
   303  	log.Debug("Unsubscribe ", "peer", peerId, "stream", s)
   304  
   305  	if err := peer.Send(context.TODO(), msg); err != nil {
   306  		return err
   307  	}
   308  	return peer.removeClient(s)
   309  }
   310  
   311  // Quit sends the QuitMsg to the peer to remove the
   312  // stream peer client and terminate the streaming.
   313  func (r *Registry) Quit(peerId enode.ID, s Stream) error {
   314  	peer := r.getPeer(peerId)
   315  	if peer == nil {
   316  		log.Debug("stream quit: peer not found", "peer", peerId, "stream", s)
   317  		// if the peer is not found, abort the request
   318  		return nil
   319  	}
   320  
   321  	msg := &QuitMsg{
   322  		Stream: s,
   323  	}
   324  	log.Debug("Quit ", "peer", peerId, "stream", s)
   325  
   326  	return peer.Send(context.TODO(), msg)
   327  }
   328  
   329  func (r *Registry) NodeInfo() interface{} {
   330  	return nil
   331  }
   332  
   333  func (r *Registry) PeerInfo(id enode.ID) interface{} {
   334  	return nil
   335  }
   336  
   337  func (r *Registry) Close() error {
   338  	return r.intervalsStore.Close()
   339  }
   340  
   341  func (r *Registry) getPeer(peerId enode.ID) *Peer {
   342  	r.peersMu.RLock()
   343  	defer r.peersMu.RUnlock()
   344  
   345  	return r.peers[peerId]
   346  }
   347  
   348  func (r *Registry) setPeer(peer *Peer) {
   349  	r.peersMu.Lock()
   350  	r.peers[peer.ID()] = peer
   351  	metrics.GetOrRegisterGauge("registry.peers", nil).Update(int64(len(r.peers)))
   352  	r.peersMu.Unlock()
   353  }
   354  
   355  func (r *Registry) deletePeer(peer *Peer) {
   356  	r.peersMu.Lock()
   357  	delete(r.peers, peer.ID())
   358  	metrics.GetOrRegisterGauge("registry.peers", nil).Update(int64(len(r.peers)))
   359  	r.peersMu.Unlock()
   360  }
   361  
   362  func (r *Registry) peersCount() (c int) {
   363  	r.peersMu.Lock()
   364  	c = len(r.peers)
   365  	r.peersMu.Unlock()
   366  	return
   367  }
   368  
   369  // Run protocol run function
   370  func (r *Registry) Run(p *network.BzzPeer) error {
   371  	sp := NewPeer(p.Peer, r)
   372  	r.setPeer(sp)
   373  	defer r.deletePeer(sp)
   374  	defer close(sp.quit)
   375  	defer sp.close()
   376  
   377  	if r.doRetrieve {
   378  		err := r.Subscribe(p.ID(), NewStream(swarmChunkServerStreamName, "", false), nil, Top)
   379  		if err != nil {
   380  			return err
   381  		}
   382  	}
   383  
   384  	return sp.Run(sp.HandleMsg)
   385  }
   386  
   387  // updateSyncing subscribes to SYNC streams by iterating over the
   388  // kademlia connections and bins. If there are existing SYNC streams
   389  // and they are no longer required after iteration, request to Quit
   390  // them will be send to appropriate peers.
   391  func (r *Registry) updateSyncing() {
   392  	kad := r.delivery.kad
   393  	// map of all SYNC streams for all peers
   394  	// used at the and of the function to remove servers
   395  	// that are not needed anymore
   396  	subs := make(map[enode.ID]map[Stream]struct{})
   397  	r.peersMu.RLock()
   398  	for id, peer := range r.peers {
   399  		peer.serverMu.RLock()
   400  		for stream := range peer.servers {
   401  			if stream.Name == "SYNC" {
   402  				if _, ok := subs[id]; !ok {
   403  					subs[id] = make(map[Stream]struct{})
   404  				}
   405  				subs[id][stream] = struct{}{}
   406  			}
   407  		}
   408  		peer.serverMu.RUnlock()
   409  	}
   410  	r.peersMu.RUnlock()
   411  
   412  	// request subscriptions for all nodes and bins
   413  	kad.EachBin(r.addr[:], pot.DefaultPof(256), 0, func(p *network.Peer, bin int) bool {
   414  		log.Debug(fmt.Sprintf("Requesting subscription by: registry %s from peer %s for bin: %d", r.addr, p.ID(), bin))
   415  
   416  		// bin is always less then 256 and it is safe to convert it to type uint8
   417  		stream := NewStream("SYNC", FormatSyncBinKey(uint8(bin)), true)
   418  		if streams, ok := subs[p.ID()]; ok {
   419  			// delete live and history streams from the map, so that it won't be removed with a Quit request
   420  			delete(streams, stream)
   421  			delete(streams, getHistoryStream(stream))
   422  		}
   423  		err := r.RequestSubscription(p.ID(), stream, NewRange(0, 0), High)
   424  		if err != nil {
   425  			log.Debug("Request subscription", "err", err, "peer", p.ID(), "stream", stream)
   426  			return false
   427  		}
   428  		return true
   429  	})
   430  
   431  	// remove SYNC servers that do not need to be subscribed
   432  	for id, streams := range subs {
   433  		if len(streams) == 0 {
   434  			continue
   435  		}
   436  		peer := r.getPeer(id)
   437  		if peer == nil {
   438  			continue
   439  		}
   440  		for stream := range streams {
   441  			log.Debug("Remove sync server", "peer", id, "stream", stream)
   442  			err := r.Quit(peer.ID(), stream)
   443  			if err != nil && err != p2p.ErrShuttingDown {
   444  				log.Error("quit", "err", err, "peer", peer.ID(), "stream", stream)
   445  			}
   446  		}
   447  	}
   448  }
   449  
   450  func (r *Registry) runProtocol(p *p2p.Peer, rw p2p.MsgReadWriter) error {
   451  	peer := protocols.NewPeer(p, rw, Spec)
   452  	bp := network.NewBzzPeer(peer)
   453  	np := network.NewPeer(bp, r.delivery.kad)
   454  	r.delivery.kad.On(np)
   455  	defer r.delivery.kad.Off(np)
   456  	return r.Run(bp)
   457  }
   458  
   459  // HandleMsg is the message handler that delegates incoming messages
   460  func (p *Peer) HandleMsg(ctx context.Context, msg interface{}) error {
   461  	switch msg := msg.(type) {
   462  
   463  	case *SubscribeMsg:
   464  		return p.handleSubscribeMsg(ctx, msg)
   465  
   466  	case *SubscribeErrorMsg:
   467  		return p.handleSubscribeErrorMsg(msg)
   468  
   469  	case *UnsubscribeMsg:
   470  		return p.handleUnsubscribeMsg(msg)
   471  
   472  	case *OfferedHashesMsg:
   473  		return p.handleOfferedHashesMsg(ctx, msg)
   474  
   475  	case *TakeoverProofMsg:
   476  		return p.handleTakeoverProofMsg(ctx, msg)
   477  
   478  	case *WantedHashesMsg:
   479  		return p.handleWantedHashesMsg(ctx, msg)
   480  
   481  	case *ChunkDeliveryMsg:
   482  		return p.streamer.delivery.handleChunkDeliveryMsg(ctx, p, msg)
   483  
   484  	case *RetrieveRequestMsg:
   485  		return p.streamer.delivery.handleRetrieveRequestMsg(ctx, p, msg)
   486  
   487  	case *RequestSubscriptionMsg:
   488  		return p.handleRequestSubscription(ctx, msg)
   489  
   490  	case *QuitMsg:
   491  		return p.handleQuitMsg(msg)
   492  
   493  	default:
   494  		return fmt.Errorf("unknown message type: %T", msg)
   495  	}
   496  }
   497  
   498  type server struct {
   499  	Server
   500  	stream       Stream
   501  	priority     uint8
   502  	currentBatch []byte
   503  }
   504  
   505  // Server interface for outgoing peer Streamer
   506  type Server interface {
   507  	SetNextBatch(uint64, uint64) (hashes []byte, from uint64, to uint64, proof *HandoverProof, err error)
   508  	GetData(context.Context, []byte) ([]byte, error)
   509  	Close()
   510  }
   511  
   512  type client struct {
   513  	Client
   514  	stream    Stream
   515  	priority  uint8
   516  	sessionAt uint64
   517  	to        uint64
   518  	next      chan error
   519  	quit      chan struct{}
   520  
   521  	intervalsKey   string
   522  	intervalsStore state.Store
   523  }
   524  
   525  func peerStreamIntervalsKey(p *Peer, s Stream) string {
   526  	return p.ID().String() + s.String()
   527  }
   528  
   529  func (c client) AddInterval(start, end uint64) (err error) {
   530  	i := &intervals.Intervals{}
   531  	err = c.intervalsStore.Get(c.intervalsKey, i)
   532  	if err != nil {
   533  		return err
   534  	}
   535  	i.Add(start, end)
   536  	return c.intervalsStore.Put(c.intervalsKey, i)
   537  }
   538  
   539  func (c client) NextInterval() (start, end uint64, err error) {
   540  	i := &intervals.Intervals{}
   541  	err = c.intervalsStore.Get(c.intervalsKey, i)
   542  	if err != nil {
   543  		return 0, 0, err
   544  	}
   545  	start, end = i.Next()
   546  	return start, end, nil
   547  }
   548  
   549  // Client interface for incoming peer Streamer
   550  type Client interface {
   551  	NeedData(context.Context, []byte) func(context.Context) error
   552  	BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error)
   553  	Close()
   554  }
   555  
   556  func (c *client) nextBatch(from uint64) (nextFrom uint64, nextTo uint64) {
   557  	if c.to > 0 && from >= c.to {
   558  		return 0, 0
   559  	}
   560  	if c.stream.Live {
   561  		return from, 0
   562  	} else if from >= c.sessionAt {
   563  		if c.to > 0 {
   564  			return from, c.to
   565  		}
   566  		return from, math.MaxUint64
   567  	}
   568  	nextFrom, nextTo, err := c.NextInterval()
   569  	if err != nil {
   570  		log.Error("next intervals", "stream", c.stream)
   571  		return
   572  	}
   573  	if nextTo > c.to {
   574  		nextTo = c.to
   575  	}
   576  	if nextTo == 0 {
   577  		nextTo = c.sessionAt
   578  	}
   579  	return
   580  }
   581  
   582  func (c *client) batchDone(p *Peer, req *OfferedHashesMsg, hashes []byte) error {
   583  	if tf := c.BatchDone(req.Stream, req.From, hashes, req.Root); tf != nil {
   584  		tp, err := tf()
   585  		if err != nil {
   586  			return err
   587  		}
   588  		if err := p.SendPriority(context.TODO(), tp, c.priority); err != nil {
   589  			return err
   590  		}
   591  		if c.to > 0 && tp.Takeover.End >= c.to {
   592  			return p.streamer.Unsubscribe(p.Peer.ID(), req.Stream)
   593  		}
   594  		return nil
   595  	}
   596  	// TODO: make a test case for testing if the interval is added when the batch is done
   597  	if err := c.AddInterval(req.From, req.To); err != nil {
   598  		return err
   599  	}
   600  	return nil
   601  }
   602  
   603  func (c *client) close() {
   604  	select {
   605  	case <-c.quit:
   606  	default:
   607  		close(c.quit)
   608  	}
   609  	c.Close()
   610  }
   611  
   612  // clientParams store parameters for the new client
   613  // between a subscription and initial offered hashes request handling.
   614  type clientParams struct {
   615  	priority uint8
   616  	to       uint64
   617  	// signal when the client is created
   618  	clientCreatedC chan struct{}
   619  }
   620  
   621  func newClientParams(priority uint8, to uint64) *clientParams {
   622  	return &clientParams{
   623  		priority:       priority,
   624  		to:             to,
   625  		clientCreatedC: make(chan struct{}),
   626  	}
   627  }
   628  
   629  func (c *clientParams) waitClient(ctx context.Context) error {
   630  	select {
   631  	case <-ctx.Done():
   632  		return ctx.Err()
   633  	case <-c.clientCreatedC:
   634  		return nil
   635  	}
   636  }
   637  
   638  func (c *clientParams) clientCreated() {
   639  	close(c.clientCreatedC)
   640  }
   641  
   642  // Spec is the spec of the streamer protocol
   643  var Spec = &protocols.Spec{
   644  	Name:       "stream",
   645  	Version:    7,
   646  	MaxMsgSize: 10 * 1024 * 1024,
   647  	Messages: []interface{}{
   648  		UnsubscribeMsg{},
   649  		OfferedHashesMsg{},
   650  		WantedHashesMsg{},
   651  		TakeoverProofMsg{},
   652  		SubscribeMsg{},
   653  		RetrieveRequestMsg{},
   654  		ChunkDeliveryMsg{},
   655  		SubscribeErrorMsg{},
   656  		RequestSubscriptionMsg{},
   657  		QuitMsg{},
   658  	},
   659  }
   660  
   661  func (r *Registry) Protocols() []p2p.Protocol {
   662  	return []p2p.Protocol{
   663  		{
   664  			Name:    Spec.Name,
   665  			Version: Spec.Version,
   666  			Length:  Spec.Length(),
   667  			Run:     r.runProtocol,
   668  			// NodeInfo: ,
   669  			// PeerInfo: ,
   670  		},
   671  	}
   672  }
   673  
   674  func (r *Registry) APIs() []rpc.API {
   675  	return []rpc.API{
   676  		{
   677  			Namespace: "stream",
   678  			Version:   "3.0",
   679  			Service:   r.api,
   680  			Public:    true,
   681  		},
   682  	}
   683  }
   684  
   685  func (r *Registry) Start(server *p2p.Server) error {
   686  	log.Info("Streamer started")
   687  	return nil
   688  }
   689  
   690  func (r *Registry) Stop() error {
   691  	return nil
   692  }
   693  
   694  type Range struct {
   695  	From, To uint64
   696  }
   697  
   698  func NewRange(from, to uint64) *Range {
   699  	return &Range{
   700  		From: from,
   701  		To:   to,
   702  	}
   703  }
   704  
   705  func (r *Range) String() string {
   706  	return fmt.Sprintf("%v-%v", r.From, r.To)
   707  }
   708  
   709  func getHistoryPriority(priority uint8) uint8 {
   710  	if priority == 0 {
   711  		return 0
   712  	}
   713  	return priority - 1
   714  }
   715  
   716  func getHistoryStream(s Stream) Stream {
   717  	return NewStream(s.Name, s.Key, false)
   718  }
   719  
   720  type API struct {
   721  	streamer *Registry
   722  }
   723  
   724  func NewAPI(r *Registry) *API {
   725  	return &API{
   726  		streamer: r,
   727  	}
   728  }
   729  
   730  func (api *API) SubscribeStream(peerId enode.ID, s Stream, history *Range, priority uint8) error {
   731  	return api.streamer.Subscribe(peerId, s, history, priority)
   732  }
   733  
   734  func (api *API) UnsubscribeStream(peerId enode.ID, s Stream) error {
   735  	return api.streamer.Unsubscribe(peerId, s)
   736  }