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