github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/network/stream/messages.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  //</624450115561590784>
    11  
    12  
    13  package stream
    14  
    15  import (
    16  	"context"
    17  	"fmt"
    18  	"time"
    19  
    20  	"github.com/ethereum/go-ethereum/metrics"
    21  	"github.com/ethereum/go-ethereum/swarm/log"
    22  	bv "github.com/ethereum/go-ethereum/swarm/network/bitvector"
    23  	"github.com/ethereum/go-ethereum/swarm/spancontext"
    24  	"github.com/ethereum/go-ethereum/swarm/storage"
    25  	"github.com/opentracing/opentracing-go"
    26  )
    27  
    28  var syncBatchTimeout = 30 * time.Second
    29  
    30  //流定义唯一的流标识符。
    31  type Stream struct {
    32  //名称用于标识客户机和服务器功能。
    33  	Name string
    34  //key是特定流数据的名称。
    35  	Key string
    36  //Live定义流是否只传递新数据
    37  //对于特定流。
    38  	Live bool
    39  }
    40  
    41  func NewStream(name string, key string, live bool) Stream {
    42  	return Stream{
    43  		Name: name,
    44  		Key:  key,
    45  		Live: live,
    46  	}
    47  }
    48  
    49  //字符串基于所有流字段返回流ID。
    50  func (s Stream) String() string {
    51  	t := "h"
    52  	if s.Live {
    53  		t = "l"
    54  	}
    55  	return fmt.Sprintf("%s|%s|%s", s.Name, s.Key, t)
    56  }
    57  
    58  //subcribeMsg是用于请求流的协议消息(节)
    59  type SubscribeMsg struct {
    60  	Stream   Stream
    61  	History  *Range `rlp:"nil"`
    62  Priority uint8  //通过优先渠道交付
    63  }
    64  
    65  //request subscription msg是节点请求订阅的协议msg
    66  //特定流
    67  type RequestSubscriptionMsg struct {
    68  	Stream   Stream
    69  	History  *Range `rlp:"nil"`
    70  Priority uint8  //通过优先渠道交付
    71  }
    72  
    73  func (p *Peer) handleRequestSubscription(ctx context.Context, req *RequestSubscriptionMsg) (err error) {
    74  	log.Debug(fmt.Sprintf("handleRequestSubscription: streamer %s to subscribe to %s with stream %s", p.streamer.addr, p.ID(), req.Stream))
    75  	if err = p.streamer.Subscribe(p.ID(), req.Stream, req.History, req.Priority); err != nil {
    76  //错误将作为订阅错误消息发送
    77  //不会返回,因为它将阻止任何新消息
    78  //对等点之间的交换超过p2p。相反,将返回错误
    79  //仅当有来自发送订阅错误消息的消息时。
    80  		err = p.Send(ctx, SubscribeErrorMsg{
    81  			Error: err.Error(),
    82  		})
    83  	}
    84  	return err
    85  }
    86  
    87  func (p *Peer) handleSubscribeMsg(ctx context.Context, req *SubscribeMsg) (err error) {
    88  	metrics.GetOrRegisterCounter("peer.handlesubscribemsg", nil).Inc(1)
    89  
    90  	defer func() {
    91  		if err != nil {
    92  //错误将作为订阅错误消息发送
    93  //不会返回,因为它将阻止任何新消息
    94  //对等点之间的交换超过p2p。相反,将返回错误
    95  //仅当有来自发送订阅错误消息的消息时。
    96  			err = p.Send(context.TODO(), SubscribeErrorMsg{
    97  				Error: err.Error(),
    98  			})
    99  		}
   100  	}()
   101  
   102  	log.Debug("received subscription", "from", p.streamer.addr, "peer", p.ID(), "stream", req.Stream, "history", req.History)
   103  
   104  	f, err := p.streamer.GetServerFunc(req.Stream.Name)
   105  	if err != nil {
   106  		return err
   107  	}
   108  
   109  	s, err := f(p, req.Stream.Key, req.Stream.Live)
   110  	if err != nil {
   111  		return err
   112  	}
   113  	os, err := p.setServer(req.Stream, s, req.Priority)
   114  	if err != nil {
   115  		return err
   116  	}
   117  
   118  	var from uint64
   119  	var to uint64
   120  	if !req.Stream.Live && req.History != nil {
   121  		from = req.History.From
   122  		to = req.History.To
   123  	}
   124  
   125  	go func() {
   126  		if err := p.SendOfferedHashes(os, from, to); err != nil {
   127  			log.Warn("SendOfferedHashes error", "peer", p.ID().TerminalString(), "err", err)
   128  		}
   129  	}()
   130  
   131  	if req.Stream.Live && req.History != nil {
   132  //订阅历史流
   133  		s, err := f(p, req.Stream.Key, false)
   134  		if err != nil {
   135  			return err
   136  		}
   137  
   138  		os, err := p.setServer(getHistoryStream(req.Stream), s, getHistoryPriority(req.Priority))
   139  		if err != nil {
   140  			return err
   141  		}
   142  		go func() {
   143  			if err := p.SendOfferedHashes(os, req.History.From, req.History.To); err != nil {
   144  				log.Warn("SendOfferedHashes error", "peer", p.ID().TerminalString(), "err", err)
   145  			}
   146  		}()
   147  	}
   148  
   149  	return nil
   150  }
   151  
   152  type SubscribeErrorMsg struct {
   153  	Error string
   154  }
   155  
   156  func (p *Peer) handleSubscribeErrorMsg(req *SubscribeErrorMsg) (err error) {
   157  //TODO应将错误传递给调用订阅的任何人
   158  	return fmt.Errorf("subscribe to peer %s: %v", p.ID(), req.Error)
   159  }
   160  
   161  type UnsubscribeMsg struct {
   162  	Stream Stream
   163  }
   164  
   165  func (p *Peer) handleUnsubscribeMsg(req *UnsubscribeMsg) error {
   166  	return p.removeServer(req.Stream)
   167  }
   168  
   169  type QuitMsg struct {
   170  	Stream Stream
   171  }
   172  
   173  func (p *Peer) handleQuitMsg(req *QuitMsg) error {
   174  	return p.removeClient(req.Stream)
   175  }
   176  
   177  //offeredhashemsg是一个协议消息,用于提供
   178  //流段
   179  type OfferedHashesMsg struct {
   180  Stream         Stream //河流名称
   181  From, To       uint64 //对等和数据库特定条目计数
   182  Hashes         []byte //哈希流(128)
   183  *HandoverProof        //防交
   184  }
   185  
   186  //提供的字符串漂亮打印
   187  func (m OfferedHashesMsg) String() string {
   188  	return fmt.Sprintf("Stream '%v' [%v-%v] (%v)", m.Stream, m.From, m.To, len(m.Hashes)/HashSize)
   189  }
   190  
   191  //handleofferedhashemsg协议消息处理程序调用传入拖缆接口
   192  //滤波法
   193  func (p *Peer) handleOfferedHashesMsg(ctx context.Context, req *OfferedHashesMsg) error {
   194  	metrics.GetOrRegisterCounter("peer.handleofferedhashes", nil).Inc(1)
   195  
   196  	var sp opentracing.Span
   197  	ctx, sp = spancontext.StartSpan(
   198  		ctx,
   199  		"handle.offered.hashes")
   200  	defer sp.Finish()
   201  
   202  	c, _, err := p.getOrSetClient(req.Stream, req.From, req.To)
   203  	if err != nil {
   204  		return err
   205  	}
   206  
   207  	hashes := req.Hashes
   208  	lenHashes := len(hashes)
   209  	if lenHashes%HashSize != 0 {
   210  		return fmt.Errorf("error invalid hashes length (len: %v)", lenHashes)
   211  	}
   212  
   213  	want, err := bv.New(lenHashes / HashSize)
   214  	if err != nil {
   215  		return fmt.Errorf("error initiaising bitvector of length %v: %v", lenHashes/HashSize, err)
   216  	}
   217  
   218  	ctr := 0
   219  	errC := make(chan error)
   220  	ctx, cancel := context.WithTimeout(ctx, syncBatchTimeout)
   221  
   222  	ctx = context.WithValue(ctx, "source", p.ID().String())
   223  	for i := 0; i < lenHashes; i += HashSize {
   224  		hash := hashes[i : i+HashSize]
   225  
   226  		if wait := c.NeedData(ctx, hash); wait != nil {
   227  			ctr++
   228  			want.Set(i/HashSize, true)
   229  //创建请求并等待块数据到达并存储
   230  			go func(w func(context.Context) error) {
   231  				select {
   232  				case errC <- w(ctx):
   233  				case <-ctx.Done():
   234  				}
   235  			}(wait)
   236  		}
   237  	}
   238  
   239  	go func() {
   240  		defer cancel()
   241  		for i := 0; i < ctr; i++ {
   242  			select {
   243  			case err := <-errC:
   244  				if err != nil {
   245  					log.Debug("client.handleOfferedHashesMsg() error waiting for chunk, dropping peer", "peer", p.ID(), "err", err)
   246  					p.Drop(err)
   247  					return
   248  				}
   249  			case <-ctx.Done():
   250  				log.Debug("client.handleOfferedHashesMsg() context done", "ctx.Err()", ctx.Err())
   251  				return
   252  			case <-c.quit:
   253  				log.Debug("client.handleOfferedHashesMsg() quit")
   254  				return
   255  			}
   256  		}
   257  		select {
   258  		case c.next <- c.batchDone(p, req, hashes):
   259  		case <-c.quit:
   260  			log.Debug("client.handleOfferedHashesMsg() quit")
   261  		case <-ctx.Done():
   262  			log.Debug("client.handleOfferedHashesMsg() context done", "ctx.Err()", ctx.Err())
   263  		}
   264  	}()
   265  //仅当前一批中所有丢失的块都到达时发送wantedkeysmsg
   266  //除了
   267  	if c.stream.Live {
   268  		c.sessionAt = req.From
   269  	}
   270  	from, to := c.nextBatch(req.To + 1)
   271  	log.Trace("set next batch", "peer", p.ID(), "stream", req.Stream, "from", req.From, "to", req.To, "addr", p.streamer.addr)
   272  	if from == to {
   273  		return nil
   274  	}
   275  
   276  	msg := &WantedHashesMsg{
   277  		Stream: req.Stream,
   278  		Want:   want.Bytes(),
   279  		From:   from,
   280  		To:     to,
   281  	}
   282  	go func() {
   283  		log.Trace("sending want batch", "peer", p.ID(), "stream", msg.Stream, "from", msg.From, "to", msg.To)
   284  		select {
   285  		case err := <-c.next:
   286  			if err != nil {
   287  				log.Warn("c.next error dropping peer", "err", err)
   288  				p.Drop(err)
   289  				return
   290  			}
   291  		case <-c.quit:
   292  			log.Debug("client.handleOfferedHashesMsg() quit")
   293  			return
   294  		case <-ctx.Done():
   295  			log.Debug("client.handleOfferedHashesMsg() context done", "ctx.Err()", ctx.Err())
   296  			return
   297  		}
   298  		log.Trace("sending want batch", "peer", p.ID(), "stream", msg.Stream, "from", msg.From, "to", msg.To)
   299  		err := p.SendPriority(ctx, msg, c.priority)
   300  		if err != nil {
   301  			log.Warn("SendPriority error", "err", err)
   302  		}
   303  	}()
   304  	return nil
   305  }
   306  
   307  //WantedHashesMsg是用于发送哈希的协议消息数据
   308  //在offeredhashemsg中提供的下游对等方实际希望发送
   309  type WantedHashesMsg struct {
   310  	Stream   Stream
   311  Want     []byte //位向量,指示批处理中需要哪些键
   312  From, To uint64 //下一个间隔偏移量-如果不继续,则为空
   313  }
   314  
   315  //字符串漂亮打印WantedHashesMsg
   316  func (m WantedHashesMsg) String() string {
   317  	return fmt.Sprintf("Stream '%v', Want: %x, Next: [%v-%v]", m.Stream, m.Want, m.From, m.To)
   318  }
   319  
   320  //handlevantedhashesmsg协议消息处理程序
   321  //*发送下一批未同步的密钥
   322  //*根据WantedHashesMsg发送实际数据块
   323  func (p *Peer) handleWantedHashesMsg(ctx context.Context, req *WantedHashesMsg) error {
   324  	metrics.GetOrRegisterCounter("peer.handlewantedhashesmsg", nil).Inc(1)
   325  
   326  	log.Trace("received wanted batch", "peer", p.ID(), "stream", req.Stream, "from", req.From, "to", req.To)
   327  	s, err := p.getServer(req.Stream)
   328  	if err != nil {
   329  		return err
   330  	}
   331  	hashes := s.currentBatch
   332  //从getbatch块开始在go例程中启动,直到新哈希到达
   333  	go func() {
   334  		if err := p.SendOfferedHashes(s, req.From, req.To); err != nil {
   335  			log.Warn("SendOfferedHashes error", "peer", p.ID().TerminalString(), "err", err)
   336  		}
   337  	}()
   338  //转到p.sendOfferedHashes(s,req.from,req.to)
   339  	l := len(hashes) / HashSize
   340  
   341  	log.Trace("wanted batch length", "peer", p.ID(), "stream", req.Stream, "from", req.From, "to", req.To, "lenhashes", len(hashes), "l", l)
   342  	want, err := bv.NewFromBytes(req.Want, l)
   343  	if err != nil {
   344  		return fmt.Errorf("error initiaising bitvector of length %v: %v", l, err)
   345  	}
   346  	for i := 0; i < l; i++ {
   347  		if want.Get(i) {
   348  			metrics.GetOrRegisterCounter("peer.handlewantedhashesmsg.actualget", nil).Inc(1)
   349  
   350  			hash := hashes[i*HashSize : (i+1)*HashSize]
   351  			data, err := s.GetData(ctx, hash)
   352  			if err != nil {
   353  				return fmt.Errorf("handleWantedHashesMsg get data %x: %v", hash, err)
   354  			}
   355  			chunk := storage.NewChunk(hash, data)
   356  			syncing := true
   357  			if err := p.Deliver(ctx, chunk, s.priority, syncing); err != nil {
   358  				return err
   359  			}
   360  		}
   361  	}
   362  	return nil
   363  }
   364  
   365  //移交表示上游对等方移交流段的声明。
   366  type Handover struct {
   367  Stream     Stream //河流名称
   368  Start, End uint64 //散列索引
   369  Root       []byte //索引段包含证明的根哈希
   370  }
   371  
   372  //handOverfloof表示上游对等端移交流部分的签名语句
   373  type HandoverProof struct {
   374  Sig []byte //签名(哈希(串行化(移交)))
   375  	*Handover
   376  }
   377  
   378  //接管表示下游对等方接管的语句(存储所有数据)
   379  //移交
   380  type Takeover Handover
   381  
   382  //takeoveroof表示下游对等方接管的签名声明
   383  //河道断面
   384  type TakeoverProof struct {
   385  Sig []byte //符号(哈希(序列化(接管)))
   386  	*Takeover
   387  }
   388  
   389  //takeoveroofmsg是下游对等机发送的协议消息
   390  type TakeoverProofMsg TakeoverProof
   391  
   392  //字符串漂亮打印takeoveroofmsg
   393  func (m TakeoverProofMsg) String() string {
   394  	return fmt.Sprintf("Stream: '%v' [%v-%v], Root: %x, Sig: %x", m.Stream, m.Start, m.End, m.Root, m.Sig)
   395  }
   396  
   397  func (p *Peer) handleTakeoverProofMsg(ctx context.Context, req *TakeoverProofMsg) error {
   398  	_, err := p.getServer(req.Stream)
   399  //在拖缆中存储流的最强takeoveroof
   400  	return err
   401  }
   402