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