github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/stream/peer.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  package stream
    26  
    27  import (
    28  	"context"
    29  	"fmt"
    30  	"sync"
    31  	"time"
    32  
    33  	"github.com/ethereum/go-ethereum/metrics"
    34  	"github.com/ethereum/go-ethereum/p2p/protocols"
    35  	"github.com/ethereum/go-ethereum/swarm/log"
    36  	pq "github.com/ethereum/go-ethereum/swarm/network/priorityqueue"
    37  	"github.com/ethereum/go-ethereum/swarm/network/stream/intervals"
    38  	"github.com/ethereum/go-ethereum/swarm/spancontext"
    39  	"github.com/ethereum/go-ethereum/swarm/state"
    40  	"github.com/ethereum/go-ethereum/swarm/storage"
    41  	opentracing "github.com/opentracing/opentracing-go"
    42  )
    43  
    44  var sendTimeout = 30 * time.Second
    45  
    46  type notFoundError struct {
    47  	t string
    48  	s Stream
    49  }
    50  
    51  func newNotFoundError(t string, s Stream) *notFoundError {
    52  	return &notFoundError{t: t, s: s}
    53  }
    54  
    55  func (e *notFoundError) Error() string {
    56  	return fmt.Sprintf("%s not found for stream %q", e.t, e.s)
    57  }
    58  
    59  //
    60  type Peer struct {
    61  	*protocols.Peer
    62  	streamer *Registry
    63  	pq       *pq.PriorityQueue
    64  	serverMu sync.RWMutex
    65  clientMu sync.RWMutex //
    66  	servers  map[Stream]*server
    67  	clients  map[Stream]*client
    68  //
    69  //
    70  //
    71  	clientParams map[Stream]*clientParams
    72  	quit         chan struct{}
    73  }
    74  
    75  type WrappedPriorityMsg struct {
    76  	Context context.Context
    77  	Msg     interface{}
    78  }
    79  
    80  //
    81  func NewPeer(peer *protocols.Peer, streamer *Registry) *Peer {
    82  	p := &Peer{
    83  		Peer:         peer,
    84  		pq:           pq.New(int(PriorityQueue), PriorityQueueCap),
    85  		streamer:     streamer,
    86  		servers:      make(map[Stream]*server),
    87  		clients:      make(map[Stream]*client),
    88  		clientParams: make(map[Stream]*clientParams),
    89  		quit:         make(chan struct{}),
    90  	}
    91  	ctx, cancel := context.WithCancel(context.Background())
    92  	go p.pq.Run(ctx, func(i interface{}) {
    93  		wmsg := i.(WrappedPriorityMsg)
    94  		p.Send(wmsg.Context, wmsg.Msg)
    95  	})
    96  	go func() {
    97  		<-p.quit
    98  		cancel()
    99  	}()
   100  	return p
   101  }
   102  
   103  //
   104  func (p *Peer) Deliver(ctx context.Context, chunk *storage.Chunk, priority uint8) error {
   105  	var sp opentracing.Span
   106  	ctx, sp = spancontext.StartSpan(
   107  		ctx,
   108  		"send.chunk.delivery")
   109  	defer sp.Finish()
   110  
   111  	msg := &ChunkDeliveryMsg{
   112  		Addr:  chunk.Addr,
   113  		SData: chunk.SData,
   114  	}
   115  	return p.SendPriority(ctx, msg, priority)
   116  }
   117  
   118  //
   119  func (p *Peer) SendPriority(ctx context.Context, msg interface{}, priority uint8) error {
   120  	defer metrics.GetOrRegisterResettingTimer(fmt.Sprintf("peer.sendpriority_t.%d", priority), nil).UpdateSince(time.Now())
   121  	metrics.GetOrRegisterCounter(fmt.Sprintf("peer.sendpriority.%d", priority), nil).Inc(1)
   122  	cctx, cancel := context.WithTimeout(context.Background(), sendTimeout)
   123  	defer cancel()
   124  	wmsg := WrappedPriorityMsg{
   125  		Context: ctx,
   126  		Msg:     msg,
   127  	}
   128  	return p.pq.Push(cctx, wmsg, int(priority))
   129  }
   130  
   131  //
   132  func (p *Peer) SendOfferedHashes(s *server, f, t uint64) error {
   133  	var sp opentracing.Span
   134  	ctx, sp := spancontext.StartSpan(
   135  		context.TODO(),
   136  		"send.offered.hashes")
   137  	defer sp.Finish()
   138  
   139  	hashes, from, to, proof, err := s.SetNextBatch(f, t)
   140  	if err != nil {
   141  		return err
   142  	}
   143  //
   144  	if len(hashes) == 0 {
   145  		return nil
   146  	}
   147  	if proof == nil {
   148  		proof = &HandoverProof{
   149  			Handover: &Handover{},
   150  		}
   151  	}
   152  	s.currentBatch = hashes
   153  	msg := &OfferedHashesMsg{
   154  		HandoverProof: proof,
   155  		Hashes:        hashes,
   156  		From:          from,
   157  		To:            to,
   158  		Stream:        s.stream,
   159  	}
   160  	log.Trace("Swarm syncer offer batch", "peer", p.ID(), "stream", s.stream, "len", len(hashes), "from", from, "to", to)
   161  	return p.SendPriority(ctx, msg, s.priority)
   162  }
   163  
   164  func (p *Peer) getServer(s Stream) (*server, error) {
   165  	p.serverMu.RLock()
   166  	defer p.serverMu.RUnlock()
   167  
   168  	server := p.servers[s]
   169  	if server == nil {
   170  		return nil, newNotFoundError("server", s)
   171  	}
   172  	return server, nil
   173  }
   174  
   175  func (p *Peer) setServer(s Stream, o Server, priority uint8) (*server, error) {
   176  	p.serverMu.Lock()
   177  	defer p.serverMu.Unlock()
   178  
   179  	if p.servers[s] != nil {
   180  		return nil, fmt.Errorf("server %s already registered", s)
   181  	}
   182  	os := &server{
   183  		Server:   o,
   184  		stream:   s,
   185  		priority: priority,
   186  	}
   187  	p.servers[s] = os
   188  	return os, nil
   189  }
   190  
   191  func (p *Peer) removeServer(s Stream) error {
   192  	p.serverMu.Lock()
   193  	defer p.serverMu.Unlock()
   194  
   195  	server, ok := p.servers[s]
   196  	if !ok {
   197  		return newNotFoundError("server", s)
   198  	}
   199  	server.Close()
   200  	delete(p.servers, s)
   201  	return nil
   202  }
   203  
   204  func (p *Peer) getClient(ctx context.Context, s Stream) (c *client, err error) {
   205  	var params *clientParams
   206  	func() {
   207  		p.clientMu.RLock()
   208  		defer p.clientMu.RUnlock()
   209  
   210  		c = p.clients[s]
   211  		if c != nil {
   212  			return
   213  		}
   214  		params = p.clientParams[s]
   215  	}()
   216  	if c != nil {
   217  		return c, nil
   218  	}
   219  
   220  	if params != nil {
   221  //
   222  		if err := params.waitClient(ctx); err != nil {
   223  			return nil, err
   224  		}
   225  	}
   226  
   227  	p.clientMu.RLock()
   228  	defer p.clientMu.RUnlock()
   229  
   230  	c = p.clients[s]
   231  	if c != nil {
   232  		return c, nil
   233  	}
   234  	return nil, newNotFoundError("client", s)
   235  }
   236  
   237  func (p *Peer) getOrSetClient(s Stream, from, to uint64) (c *client, created bool, err error) {
   238  	p.clientMu.Lock()
   239  	defer p.clientMu.Unlock()
   240  
   241  	c = p.clients[s]
   242  	if c != nil {
   243  		return c, false, nil
   244  	}
   245  
   246  	f, err := p.streamer.GetClientFunc(s.Name)
   247  	if err != nil {
   248  		return nil, false, err
   249  	}
   250  
   251  	is, err := f(p, s.Key, s.Live)
   252  	if err != nil {
   253  		return nil, false, err
   254  	}
   255  
   256  	cp, err := p.getClientParams(s)
   257  	if err != nil {
   258  		return nil, false, err
   259  	}
   260  	defer func() {
   261  		if err == nil {
   262  			if err := p.removeClientParams(s); err != nil {
   263  				log.Error("stream set client: remove client params", "stream", s, "peer", p, "err", err)
   264  			}
   265  		}
   266  	}()
   267  
   268  	intervalsKey := peerStreamIntervalsKey(p, s)
   269  	if s.Live {
   270  //
   271  		historyKey := peerStreamIntervalsKey(p, NewStream(s.Name, s.Key, false))
   272  		historyIntervals := &intervals.Intervals{}
   273  		err := p.streamer.intervalsStore.Get(historyKey, historyIntervals)
   274  		switch err {
   275  		case nil:
   276  			liveIntervals := &intervals.Intervals{}
   277  			err := p.streamer.intervalsStore.Get(intervalsKey, liveIntervals)
   278  			switch err {
   279  			case nil:
   280  				historyIntervals.Merge(liveIntervals)
   281  				if err := p.streamer.intervalsStore.Put(historyKey, historyIntervals); err != nil {
   282  					log.Error("stream set client: put history intervals", "stream", s, "peer", p, "err", err)
   283  				}
   284  			case state.ErrNotFound:
   285  			default:
   286  				log.Error("stream set client: get live intervals", "stream", s, "peer", p, "err", err)
   287  			}
   288  		case state.ErrNotFound:
   289  		default:
   290  			log.Error("stream set client: get history intervals", "stream", s, "peer", p, "err", err)
   291  		}
   292  	}
   293  
   294  	if err := p.streamer.intervalsStore.Put(intervalsKey, intervals.NewIntervals(from)); err != nil {
   295  		return nil, false, err
   296  	}
   297  
   298  	next := make(chan error, 1)
   299  	c = &client{
   300  		Client:         is,
   301  		stream:         s,
   302  		priority:       cp.priority,
   303  		to:             cp.to,
   304  		next:           next,
   305  		quit:           make(chan struct{}),
   306  		intervalsStore: p.streamer.intervalsStore,
   307  		intervalsKey:   intervalsKey,
   308  	}
   309  	p.clients[s] = c
   310  cp.clientCreated() //
   311  next <- nil        //
   312  	return c, true, nil
   313  }
   314  
   315  func (p *Peer) removeClient(s Stream) error {
   316  	p.clientMu.Lock()
   317  	defer p.clientMu.Unlock()
   318  
   319  	client, ok := p.clients[s]
   320  	if !ok {
   321  		return newNotFoundError("client", s)
   322  	}
   323  	client.close()
   324  	return nil
   325  }
   326  
   327  func (p *Peer) setClientParams(s Stream, params *clientParams) error {
   328  	p.clientMu.Lock()
   329  	defer p.clientMu.Unlock()
   330  
   331  	if p.clients[s] != nil {
   332  		return fmt.Errorf("client %s already exists", s)
   333  	}
   334  	if p.clientParams[s] != nil {
   335  		return fmt.Errorf("client params %s already set", s)
   336  	}
   337  	p.clientParams[s] = params
   338  	return nil
   339  }
   340  
   341  func (p *Peer) getClientParams(s Stream) (*clientParams, error) {
   342  	params := p.clientParams[s]
   343  	if params == nil {
   344  		return nil, fmt.Errorf("client params '%v' not provided to peer %v", s, p.ID())
   345  	}
   346  	return params, nil
   347  }
   348  
   349  func (p *Peer) removeClientParams(s Stream) error {
   350  	_, ok := p.clientParams[s]
   351  	if !ok {
   352  		return newNotFoundError("client params", s)
   353  	}
   354  	delete(p.clientParams, s)
   355  	return nil
   356  }
   357  
   358  func (p *Peer) close() {
   359  	for _, s := range p.servers {
   360  		s.Close()
   361  	}
   362  }