github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/hive.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 "fmt" 29 "sync" 30 "time" 31 32 "github.com/ethereum/go-ethereum/common/hexutil" 33 "github.com/ethereum/go-ethereum/p2p" 34 "github.com/ethereum/go-ethereum/p2p/discover" 35 "github.com/ethereum/go-ethereum/swarm/log" 36 "github.com/ethereum/go-ethereum/swarm/state" 37 ) 38 39 /* 40 41 42 43 44 45 */ 46 47 48 // 49 type Overlay interface { 50 // 51 SuggestPeer() (OverlayAddr, int, bool) 52 // 53 On(OverlayConn) (depth uint8, changed bool) 54 Off(OverlayConn) 55 // 56 Register([]OverlayAddr) error 57 // 58 EachConn([]byte, int, func(OverlayConn, int, bool) bool) 59 // 60 EachAddr([]byte, int, func(OverlayAddr, int, bool) bool) 61 // 62 String() string 63 // 64 BaseAddr() []byte 65 // 66 Healthy(*PeerPot) *Health 67 } 68 69 // 70 type HiveParams struct { 71 Discovery bool // 72 PeersBroadcastSetSize uint8 // 73 MaxPeersPerRequest uint8 // 74 KeepAliveInterval time.Duration 75 } 76 77 // 78 func NewHiveParams() *HiveParams { 79 return &HiveParams{ 80 Discovery: true, 81 PeersBroadcastSetSize: 3, 82 MaxPeersPerRequest: 5, 83 KeepAliveInterval: 500 * time.Millisecond, 84 } 85 } 86 87 // 88 type Hive struct { 89 *HiveParams // 90 Overlay // 91 Store state.Store // 92 addPeer func(*discover.Node) // 93 // 94 lock sync.Mutex 95 ticker *time.Ticker 96 } 97 98 // 99 // 100 // 101 // 102 func NewHive(params *HiveParams, overlay Overlay, store state.Store) *Hive { 103 return &Hive{ 104 HiveParams: params, 105 Overlay: overlay, 106 Store: store, 107 } 108 } 109 110 // 111 // 112 // 113 func (h *Hive) Start(server *p2p.Server) error { 114 log.Info("Starting hive", "baseaddr", fmt.Sprintf("%x", h.BaseAddr()[:4])) 115 // 116 if h.Store != nil { 117 log.Info("Detected an existing store. trying to load peers") 118 if err := h.loadPeers(); err != nil { 119 log.Error(fmt.Sprintf("%08x hive encoutered an error trying to load peers", h.BaseAddr()[:4])) 120 return err 121 } 122 } 123 // 124 h.addPeer = server.AddPeer 125 // 126 h.ticker = time.NewTicker(h.KeepAliveInterval) 127 // 128 go h.connect() 129 return nil 130 } 131 132 // 133 func (h *Hive) Stop() error { 134 log.Info(fmt.Sprintf("%08x hive stopping, saving peers", h.BaseAddr()[:4])) 135 h.ticker.Stop() 136 if h.Store != nil { 137 if err := h.savePeers(); err != nil { 138 return fmt.Errorf("could not save peers to persistence store: %v", err) 139 } 140 if err := h.Store.Close(); err != nil { 141 return fmt.Errorf("could not close file handle to persistence store: %v", err) 142 } 143 } 144 log.Info(fmt.Sprintf("%08x hive stopped, dropping peers", h.BaseAddr()[:4])) 145 h.EachConn(nil, 255, func(p OverlayConn, _ int, _ bool) bool { 146 log.Info(fmt.Sprintf("%08x dropping peer %08x", h.BaseAddr()[:4], p.Address()[:4])) 147 p.Drop(nil) 148 return true 149 }) 150 151 log.Info(fmt.Sprintf("%08x all peers dropped", h.BaseAddr()[:4])) 152 return nil 153 } 154 155 // 156 // 157 // 158 func (h *Hive) connect() { 159 for range h.ticker.C { 160 161 addr, depth, changed := h.SuggestPeer() 162 if h.Discovery && changed { 163 NotifyDepth(uint8(depth), h) 164 } 165 if addr == nil { 166 continue 167 } 168 169 log.Trace(fmt.Sprintf("%08x hive connect() suggested %08x", h.BaseAddr()[:4], addr.Address()[:4])) 170 under, err := discover.ParseNode(string(addr.(Addr).Under())) 171 if err != nil { 172 log.Warn(fmt.Sprintf("%08x unable to connect to bee %08x: invalid node URL: %v", h.BaseAddr()[:4], addr.Address()[:4], err)) 173 continue 174 } 175 log.Trace(fmt.Sprintf("%08x attempt to connect to bee %08x", h.BaseAddr()[:4], addr.Address()[:4])) 176 h.addPeer(under) 177 } 178 } 179 180 // 181 func (h *Hive) Run(p *BzzPeer) error { 182 dp := newDiscovery(p, h) 183 depth, changed := h.On(dp) 184 // 185 if h.Discovery { 186 if changed { 187 // 188 NotifyDepth(depth, h) 189 } else { 190 // 191 dp.NotifyDepth(depth) 192 } 193 } 194 NotifyPeer(p.Off(), h) 195 defer h.Off(dp) 196 return dp.Run(dp.HandleMsg) 197 } 198 199 // 200 // 201 func (h *Hive) NodeInfo() interface{} { 202 return h.String() 203 } 204 205 // 206 // 207 func (h *Hive) PeerInfo(id discover.NodeID) interface{} { 208 addr := NewAddrFromNodeID(id) 209 return struct { 210 OAddr hexutil.Bytes 211 UAddr hexutil.Bytes 212 }{ 213 OAddr: addr.OAddr, 214 UAddr: addr.UAddr, 215 } 216 } 217 218 // 219 func ToAddr(pa OverlayPeer) *BzzAddr { 220 if addr, ok := pa.(*BzzAddr); ok { 221 return addr 222 } 223 if p, ok := pa.(*discPeer); ok { 224 return p.BzzAddr 225 } 226 return pa.(*BzzPeer).BzzAddr 227 } 228 229 // 230 func (h *Hive) loadPeers() error { 231 var as []*BzzAddr 232 err := h.Store.Get("peers", &as) 233 if err != nil { 234 if err == state.ErrNotFound { 235 log.Info(fmt.Sprintf("hive %08x: no persisted peers found", h.BaseAddr()[:4])) 236 return nil 237 } 238 return err 239 } 240 log.Info(fmt.Sprintf("hive %08x: peers loaded", h.BaseAddr()[:4])) 241 242 return h.Register(toOverlayAddrs(as...)) 243 } 244 245 // 246 func toOverlayAddrs(as ...*BzzAddr) (oas []OverlayAddr) { 247 for _, a := range as { 248 oas = append(oas, OverlayAddr(a)) 249 } 250 return 251 } 252 253 // 254 func (h *Hive) savePeers() error { 255 var peers []*BzzAddr 256 h.Overlay.EachAddr(nil, 256, func(pa OverlayAddr, i int, _ bool) bool { 257 if pa == nil { 258 log.Warn(fmt.Sprintf("empty addr: %v", i)) 259 return true 260 } 261 apa := ToAddr(pa) 262 log.Trace("saving peer", "peer", apa) 263 peers = append(peers, apa) 264 return true 265 }) 266 if err := h.Store.Put("peers", peers); err != nil { 267 return fmt.Errorf("could not save peers: %v", err) 268 } 269 return nil 270 }