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