go ethereum之p2p

简介

p2p是以太坊节点网络层的骨架,夹在底层 TCP/UDP 和应用协议(eth、snap、les)之间,管三件事:节点发现(谁在线)、连接管理(怎么连上、怎么断)、消息多路复用(连上了跑什么协议)

重要结构

主要有

  • Server
  • Peer:表示一个连接

Server结构定义为

typeServerstruct{// Config fields may not be modified while the server is running.Config// Hooks for testing. These are useful because we can inhibit// the whole protocol stack.newTransportfunc(net.Conn,*ecdsa.PublicKey)transport newPeerHookfunc(*Peer)listenFuncfunc(network,addrstring)(net.Listener,error)lock sync.Mutex// protects runningrunningboollistener net.Listener ourHandshake*protoHandshake loopWG sync.WaitGroup// loop, listenLooppeerFeed event.Feed log log.Logger nodedb*enode.DB localnode*enode.LocalNode discv4*discover.UDPv4 discv5*discover.UDPv5 discmix*enode.FairMix dialsched*dialScheduler// This is read by the NAT port mapping loop.portMappingRegisterchan*portMapping// Channels into the run loop.quitchanstruct{}addtrustedchan*enode.Node removetrustedchan*enode.Node peerOpchanpeerOpFunc peerOpDonechanstruct{}delpeerchanpeerDrop checkpointPostHandshakechan*conn checkpointAddPeerchan*conn// State of run loop and listenLoop.inboundHistory expHeap}

Config:p2p服务端配置
listener:监听器,接受连接
discv4,discv5,discmix:节点发现
dialsched:向外连接
peerOp:对接操作
localnode:结点的ENR

Peer结构定义为

typePeerstruct{rw*conn runningmap[string]*protoRW log log.Logger created mclock.AbsTime wg sync.WaitGroup protoErrchanerrorclosedchanstruct{}pingRecvchanstruct{}discchanDiscReason// events receives message send / receive events if setevents*event.Feed testPipe*MsgPipeRW// for testing}

启动

通过Start启动p2p,主要作以下事项

  • setupLocalNode:创建dev2p handshake和localnode
  • setupPortMapping:开启端口映射循环,根据NAT配置执行不同的协程
  • setupListening:开启监听协程listenLoop处理外部连接
  • setupDiscovery:开启节点发现,根据配置开启发现服务discv4,discv5
  • setupDialScheduler:开启拨号调度器dialScheduler,开启两个协程readNodesloop
  • srv.run():处理通道事件,如新连接等