github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/network/protocol.go (about)

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