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 ¬FoundError{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 }