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  }