github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/discovery.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 network 26 27 import ( 28 "context" 29 "fmt" 30 "sync" 31 32 "github.com/ethereum/go-ethereum/swarm/pot" 33 ) 34 35 // 36 37 // 38 type discPeer struct { 39 *BzzPeer 40 overlay Overlay 41 sentPeers bool // 42 mtx sync.RWMutex 43 peers map[string]bool // 44 depth uint8 // 45 } 46 47 // 48 func newDiscovery(p *BzzPeer, o Overlay) *discPeer { 49 d := &discPeer{ 50 overlay: o, 51 BzzPeer: p, 52 peers: make(map[string]bool), 53 } 54 // 55 d.seen(d) 56 return d 57 } 58 59 // 60 func (d *discPeer) HandleMsg(ctx context.Context, msg interface{}) error { 61 switch msg := msg.(type) { 62 63 case *peersMsg: 64 return d.handlePeersMsg(msg) 65 66 case *subPeersMsg: 67 return d.handleSubPeersMsg(msg) 68 69 default: 70 return fmt.Errorf("unknown message type: %T", msg) 71 } 72 } 73 74 // 75 func NotifyDepth(depth uint8, h Overlay) { 76 f := func(val OverlayConn, po int, _ bool) bool { 77 dp, ok := val.(*discPeer) 78 if ok { 79 dp.NotifyDepth(depth) 80 } 81 return true 82 } 83 h.EachConn(nil, 255, f) 84 } 85 86 // 87 func NotifyPeer(p OverlayAddr, k Overlay) { 88 f := func(val OverlayConn, po int, _ bool) bool { 89 dp, ok := val.(*discPeer) 90 if ok { 91 dp.NotifyPeer(p, uint8(po)) 92 } 93 return true 94 } 95 k.EachConn(p.Address(), 255, f) 96 } 97 98 // 99 // 100 // 101 // 102 func (d *discPeer) NotifyPeer(a OverlayAddr, po uint8) { 103 // 104 if (po < d.getDepth() && pot.ProxCmp(d.localAddr, d, a) != 1) || d.seen(a) { 105 return 106 } 107 // 108 resp := &peersMsg{ 109 Peers: []*BzzAddr{ToAddr(a)}, 110 } 111 go d.Send(context.TODO(), resp) 112 } 113 114 // 115 // 116 func (d *discPeer) NotifyDepth(po uint8) { 117 // 118 go d.Send(context.TODO(), &subPeersMsg{Depth: po}) 119 } 120 121 /* 122 123 124 125 126 127 128 129 130 131 132 133 134 135 */ 136 137 138 // 139 // 140 // 141 type peersMsg struct { 142 Peers []*BzzAddr 143 } 144 145 // 146 func (msg peersMsg) String() string { 147 return fmt.Sprintf("%T: %v", msg, msg.Peers) 148 } 149 150 // 151 // 152 // 153 func (d *discPeer) handlePeersMsg(msg *peersMsg) error { 154 // 155 if len(msg.Peers) == 0 { 156 return nil 157 } 158 159 for _, a := range msg.Peers { 160 d.seen(a) 161 NotifyPeer(a, d.overlay) 162 } 163 return d.overlay.Register(toOverlayAddrs(msg.Peers...)) 164 } 165 166 // 167 type subPeersMsg struct { 168 Depth uint8 169 } 170 171 // 172 func (msg subPeersMsg) String() string { 173 return fmt.Sprintf("%T: request peers > PO%02d. ", msg, msg.Depth) 174 } 175 176 func (d *discPeer) handleSubPeersMsg(msg *subPeersMsg) error { 177 if !d.sentPeers { 178 d.setDepth(msg.Depth) 179 var peers []*BzzAddr 180 d.overlay.EachConn(d.Over(), 255, func(p OverlayConn, po int, isproxbin bool) bool { 181 if pob, _ := pof(d, d.localAddr, 0); pob > po { 182 return false 183 } 184 if !d.seen(p) { 185 peers = append(peers, ToAddr(p.Off())) 186 } 187 return true 188 }) 189 if len(peers) > 0 { 190 // 191 go d.Send(context.TODO(), &peersMsg{Peers: peers}) 192 } 193 } 194 d.sentPeers = true 195 return nil 196 } 197 198 // 199 // 200 func (d *discPeer) seen(p OverlayPeer) bool { 201 d.mtx.Lock() 202 defer d.mtx.Unlock() 203 k := string(p.Address()) 204 if d.peers[k] { 205 return true 206 } 207 d.peers[k] = true 208 return false 209 } 210 211 func (d *discPeer) getDepth() uint8 { 212 d.mtx.RLock() 213 defer d.mtx.RUnlock() 214 return d.depth 215 } 216 func (d *discPeer) setDepth(depth uint8) { 217 d.mtx.Lock() 218 defer d.mtx.Unlock() 219 d.depth = depth 220 }