github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/protocol.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 //版权所有2016 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package network 26 27 import ( 28 "context" 29 "errors" 30 "fmt" 31 "net" 32 "sync" 33 "time" 34 35 "github.com/ethereum/go-ethereum/crypto" 36 "github.com/ethereum/go-ethereum/p2p" 37 "github.com/ethereum/go-ethereum/p2p/discover" 38 "github.com/ethereum/go-ethereum/p2p/protocols" 39 "github.com/ethereum/go-ethereum/rpc" 40 "github.com/ethereum/go-ethereum/swarm/log" 41 "github.com/ethereum/go-ethereum/swarm/state" 42 ) 43 44 const ( 45 DefaultNetworkID = 3 46 //protocolmaxmsgsize允许的最大消息大小 47 ProtocolMaxMsgSize = 10 * 1024 * 1024 48 //等待超时 49 bzzHandshakeTimeout = 3000 * time.Millisecond 50 ) 51 52 //bzzspec是通用群握手的规范 53 var BzzSpec = &protocols.Spec{ 54 Name: "bzz", 55 Version: 6, 56 MaxMsgSize: 10 * 1024 * 1024, 57 Messages: []interface{}{ 58 HandshakeMsg{}, 59 }, 60 } 61 62 //discovery spec是bzz discovery子协议的规范 63 var DiscoverySpec = &protocols.Spec{ 64 Name: "hive", 65 Version: 5, 66 MaxMsgSize: 10 * 1024 * 1024, 67 Messages: []interface{}{ 68 peersMsg{}, 69 subPeersMsg{}, 70 }, 71 } 72 73 //对等池所需的addr接口 74 type Addr interface { 75 OverlayPeer 76 Over() []byte 77 Under() []byte 78 String() string 79 Update(OverlayAddr) OverlayAddr 80 } 81 82 //对等接口表示实时对等连接 83 type Peer interface { 84 Addr //对等机的地址 85 Conn //实时连接(protocols.peer) 86 LastActive() time.Time //上次激活时间 87 } 88 89 //conn接口表示活动对等连接 90 type Conn interface { 91 ID() discover.NodeID //唯一标识对等池节点的键 92 Handshake(context.Context, interface{}, func(interface{}) error) (interface{}, error) //可以发送消息 93 Send(context.Context, interface{}) error // 94 Drop(error) // 95 Run(func(context.Context, interface{}) error) error // 96 Off() OverlayAddr 97 } 98 99 //bzzconfig捕获配置单元使用的配置参数 100 type BzzConfig struct { 101 OverlayAddr []byte //覆盖网络的基址 102 UnderlayAddr []byte //节点的参考底图地址 103 HiveParams *HiveParams 104 NetworkID uint64 105 LightNode bool 106 } 107 108 //bzz是swarm协议包 109 type Bzz struct { 110 *Hive 111 NetworkID uint64 112 LightNode bool 113 localAddr *BzzAddr 114 mtx sync.Mutex 115 handshakes map[discover.NodeID]*HandshakeMsg 116 streamerSpec *protocols.Spec 117 streamerRun func(*BzzPeer) error 118 } 119 120 //Newzz是Swarm协议的构造者 121 //争论 122 //*BZZ配置 123 //*覆盖驱动程序 124 //*对等存储 125 func NewBzz(config *BzzConfig, kad Overlay, store state.Store, streamerSpec *protocols.Spec, streamerRun func(*BzzPeer) error) *Bzz { 126 return &Bzz{ 127 Hive: NewHive(config.HiveParams, kad, store), 128 NetworkID: config.NetworkID, 129 LightNode: config.LightNode, 130 localAddr: &BzzAddr{config.OverlayAddr, config.UnderlayAddr}, 131 handshakes: make(map[discover.NodeID]*HandshakeMsg), 132 streamerRun: streamerRun, 133 streamerSpec: streamerSpec, 134 } 135 } 136 137 //updateLocalAddr更新正在运行的节点的参考底图地址 138 func (b *Bzz) UpdateLocalAddr(byteaddr []byte) *BzzAddr { 139 b.localAddr = b.localAddr.Update(&BzzAddr{ 140 UAddr: byteaddr, 141 OAddr: b.localAddr.OAddr, 142 }).(*BzzAddr) 143 return b.localAddr 144 } 145 146 //nodeinfo返回节点的覆盖地址 147 func (b *Bzz) NodeInfo() interface{} { 148 return b.localAddr.Address() 149 } 150 151 //协议返回Swarm提供的协议 152 //bzz实现node.service接口 153 //*握手/蜂窝 154 //*发现 155 func (b *Bzz) Protocols() []p2p.Protocol { 156 protocol := []p2p.Protocol{ 157 { 158 Name: BzzSpec.Name, 159 Version: BzzSpec.Version, 160 Length: BzzSpec.Length(), 161 Run: b.runBzz, 162 NodeInfo: b.NodeInfo, 163 }, 164 { 165 Name: DiscoverySpec.Name, 166 Version: DiscoverySpec.Version, 167 Length: DiscoverySpec.Length(), 168 Run: b.RunProtocol(DiscoverySpec, b.Hive.Run), 169 NodeInfo: b.Hive.NodeInfo, 170 PeerInfo: b.Hive.PeerInfo, 171 }, 172 } 173 if b.streamerSpec != nil && b.streamerRun != nil { 174 protocol = append(protocol, p2p.Protocol{ 175 Name: b.streamerSpec.Name, 176 Version: b.streamerSpec.Version, 177 Length: b.streamerSpec.Length(), 178 Run: b.RunProtocol(b.streamerSpec, b.streamerRun), 179 }) 180 } 181 return protocol 182 } 183 184 //API返回BZZ提供的API 185 //*蜂箱 186 //bzz实现node.service接口 187 func (b *Bzz) APIs() []rpc.API { 188 return []rpc.API{{ 189 Namespace: "hive", 190 Version: "3.0", 191 Service: b.Hive, 192 }} 193 } 194 195 //runprotocol是swarm子协议的包装器 196 //返回可分配给p2p.protocol run字段的p2p协议运行函数。 197 //争论: 198 //*P2P协议规范 199 //*以bzzpeer为参数运行函数 200 //此运行函数用于在协议会话期间阻塞 201 //返回时,会话终止,对等端断开连接。 202 //协议等待BZZ握手被协商 203 //bzzpeer上的覆盖地址是通过远程握手设置的。 204 func (b *Bzz) RunProtocol(spec *protocols.Spec, run func(*BzzPeer) error) func(*p2p.Peer, p2p.MsgReadWriter) error { 205 return func(p *p2p.Peer, rw p2p.MsgReadWriter) error { 206 //等待BZZ协议执行握手 207 handshake, _ := b.GetHandshake(p.ID()) 208 defer b.removeHandshake(p.ID()) 209 select { 210 case <-handshake.done: 211 case <-time.After(bzzHandshakeTimeout): 212 return fmt.Errorf("%08x: %s protocol timeout waiting for handshake on %08x", b.BaseAddr()[:4], spec.Name, p.ID().Bytes()[:4]) 213 } 214 if handshake.err != nil { 215 return fmt.Errorf("%08x: %s protocol closed: %v", b.BaseAddr()[:4], spec.Name, handshake.err) 216 } 217 //握手成功,因此构造bzzpeer并运行协议 218 peer := &BzzPeer{ 219 Peer: protocols.NewPeer(p, rw, spec), 220 localAddr: b.localAddr, 221 BzzAddr: handshake.peerAddr, 222 lastActive: time.Now(), 223 LightNode: handshake.LightNode, 224 } 225 226 log.Debug("peer created", "addr", handshake.peerAddr.String()) 227 228 return run(peer) 229 } 230 } 231 232 //performhandshake实现BZZ握手的协商 233 //在群子协议中共享 234 func (b *Bzz) performHandshake(p *protocols.Peer, handshake *HandshakeMsg) error { 235 ctx, cancel := context.WithTimeout(context.Background(), bzzHandshakeTimeout) 236 defer func() { 237 close(handshake.done) 238 cancel() 239 }() 240 rsh, err := p.Handshake(ctx, handshake, b.checkHandshake) 241 if err != nil { 242 handshake.err = err 243 return err 244 } 245 handshake.peerAddr = rsh.(*HandshakeMsg).Addr 246 handshake.LightNode = rsh.(*HandshakeMsg).LightNode 247 return nil 248 } 249 250 //run bzz是bzz基本协议的p2p协议运行函数 251 //与BZZ握手谈判 252 func (b *Bzz) runBzz(p *p2p.Peer, rw p2p.MsgReadWriter) error { 253 handshake, _ := b.GetHandshake(p.ID()) 254 if !<-handshake.init { 255 return fmt.Errorf("%08x: bzz already started on peer %08x", b.localAddr.Over()[:4], ToOverlayAddr(p.ID().Bytes())[:4]) 256 } 257 close(handshake.init) 258 defer b.removeHandshake(p.ID()) 259 peer := protocols.NewPeer(p, rw, BzzSpec) 260 err := b.performHandshake(peer, handshake) 261 if err != nil { 262 log.Warn(fmt.Sprintf("%08x: handshake failed with remote peer %08x: %v", b.localAddr.Over()[:4], ToOverlayAddr(p.ID().Bytes())[:4], err)) 263 264 return err 265 } 266 //如果我们再握手就失败了 267 msg, err := rw.ReadMsg() 268 if err != nil { 269 return err 270 } 271 msg.Discard() 272 return errors.New("received multiple handshakes") 273 } 274 275 //bzz peer是协议的bzz协议视图。peer(本身是p2p.peer的扩展) 276 //实现对等接口和所有接口对等实现:addr、overlaypeer 277 type BzzPeer struct { 278 *protocols.Peer //表示联机对等机的连接 279 localAddr *BzzAddr //本地对等地址 280 *BzzAddr //远程地址->实现addr interface=protocols.peer 281 lastActive time.Time //当互斥锁释放时,时间会更新。 282 LightNode bool 283 } 284 285 func NewBzzTestPeer(p *protocols.Peer, addr *BzzAddr) *BzzPeer { 286 return &BzzPeer{ 287 Peer: p, 288 localAddr: addr, 289 BzzAddr: NewAddrFromNodeID(p.ID()), 290 } 291 } 292 293 //off返回脱机持久性的覆盖对等记录 294 func (p *BzzPeer) Off() OverlayAddr { 295 return p.BzzAddr 296 } 297 298 //LastActive返回上次激活对等机的时间 299 func (p *BzzPeer) LastActive() time.Time { 300 return p.lastActive 301 } 302 303 /* 304 握手 305 306 *版本:协议的8字节整数版本 307 *networkid:8字节整数网络标识符 308 *地址:节点公布的地址,包括底层和覆盖连接。 309 **/ 310 311 type HandshakeMsg struct { 312 Version uint64 313 NetworkID uint64 314 Addr *BzzAddr 315 LightNode bool 316 317 //PeerAddr是对等握手中接收到的地址 318 peerAddr *BzzAddr 319 320 init chan bool 321 done chan struct{} 322 err error 323 } 324 325 //字符串漂亮地打印了握手 326 func (bh *HandshakeMsg) String() string { 327 return fmt.Sprintf("Handshake: Version: %v, NetworkID: %v, Addr: %v, LightNode: %v, peerAddr: %v", bh.Version, bh.NetworkID, bh.Addr, bh.LightNode, bh.peerAddr) 328 } 329 330 //执行启动握手并验证远程握手消息 331 func (b *Bzz) checkHandshake(hs interface{}) error { 332 rhs := hs.(*HandshakeMsg) 333 if rhs.NetworkID != b.NetworkID { 334 return fmt.Errorf("network id mismatch %d (!= %d)", rhs.NetworkID, b.NetworkID) 335 } 336 if rhs.Version != uint64(BzzSpec.Version) { 337 return fmt.Errorf("version mismatch %d (!= %d)", rhs.Version, BzzSpec.Version) 338 } 339 return nil 340 } 341 342 //removehandshake删除具有peerID的对等方的握手 343 //来自BZZ握手商店 344 func (b *Bzz) removeHandshake(peerID discover.NodeID) { 345 b.mtx.Lock() 346 defer b.mtx.Unlock() 347 delete(b.handshakes, peerID) 348 } 349 350 //gethandshake返回peerid远程对等机发送的bzz handshake 351 func (b *Bzz) GetHandshake(peerID discover.NodeID) (*HandshakeMsg, bool) { 352 b.mtx.Lock() 353 defer b.mtx.Unlock() 354 handshake, found := b.handshakes[peerID] 355 if !found { 356 handshake = &HandshakeMsg{ 357 Version: uint64(BzzSpec.Version), 358 NetworkID: b.NetworkID, 359 Addr: b.localAddr, 360 LightNode: b.LightNode, 361 init: make(chan bool, 1), 362 done: make(chan struct{}), 363 } 364 //首次为远程对等机创建handhsake时 365 //它是用init初始化的 366 handshake.init <- true 367 b.handshakes[peerID] = handshake 368 } 369 370 return handshake, found 371 } 372 373 //bzzaddr实现peeraddr接口 374 type BzzAddr struct { 375 OAddr []byte 376 UAddr []byte 377 } 378 379 //地址实现覆盖中要使用的覆盖对等接口 380 func (a *BzzAddr) Address() []byte { 381 return a.OAddr 382 } 383 384 //over返回覆盖地址 385 func (a *BzzAddr) Over() []byte { 386 return a.OAddr 387 } 388 389 //在下面返回参考底图地址 390 func (a *BzzAddr) Under() []byte { 391 return a.UAddr 392 } 393 394 //id返回参考底图enode地址中的nodeid 395 func (a *BzzAddr) ID() discover.NodeID { 396 return discover.MustParseNode(string(a.UAddr)).ID 397 } 398 399 //更新更新更新对等记录的底层地址 400 func (a *BzzAddr) Update(na OverlayAddr) OverlayAddr { 401 return &BzzAddr{a.OAddr, na.(Addr).Under()} 402 } 403 404 //字符串漂亮地打印地址 405 func (a *BzzAddr) String() string { 406 return fmt.Sprintf("%x <%s>", a.OAddr, a.UAddr) 407 } 408 409 //randomaddr是从公钥生成地址的实用方法 410 func RandomAddr() *BzzAddr { 411 key, err := crypto.GenerateKey() 412 if err != nil { 413 panic("unable to generate key") 414 } 415 pubkey := crypto.FromECDSAPub(&key.PublicKey) 416 var id discover.NodeID 417 copy(id[:], pubkey[1:]) 418 return NewAddrFromNodeID(id) 419 } 420 421 //newnodeidfromaddr将底层地址转换为adapters.nodeid 422 func NewNodeIDFromAddr(addr Addr) discover.NodeID { 423 log.Info(fmt.Sprintf("uaddr=%s", string(addr.Under()))) 424 node := discover.MustParseNode(string(addr.Under())) 425 return node.ID 426 } 427 428 //newAddrFromNodeID从discover.nodeID构造BzzAddr 429 //覆盖地址是作为nodeid的散列派生的。 430 func NewAddrFromNodeID(id discover.NodeID) *BzzAddr { 431 return &BzzAddr{ 432 OAddr: ToOverlayAddr(id.Bytes()), 433 UAddr: []byte(discover.NewNode(id, net.IP{127, 0, 0, 1}, 30303, 30303).String()), 434 } 435 } 436 437 //newaddrFromNodeAndPort从discover.nodeid和端口uint16构造bzzaddr 438 //覆盖地址是作为nodeid的散列派生的。 439 func NewAddrFromNodeIDAndPort(id discover.NodeID, host net.IP, port uint16) *BzzAddr { 440 return &BzzAddr{ 441 OAddr: ToOverlayAddr(id.Bytes()), 442 UAddr: []byte(discover.NewNode(id, host, port, port).String()), 443 } 444 } 445 446 //ToOverlayAddr从字节片创建覆盖地址 447 func ToOverlayAddr(id []byte) []byte { 448 return crypto.Keccak256(id) 449 }