go-ethereum源码阅读 - 1.transcation的监听和接收

geth代码中变量简洁的命名方式让我看的真酸爽....


比如这种:


r := srv.DialRatio


fd  net.Conn


还有go语言不需要声明的接口实现方式更是让人蛋疼,


暗搓搓的实现了这个接口,只能搜索一下才能知道丫实现了。






思路:


geth启动时启动了udp和tcp两个协议进行监听,默认30303端口,该端口用于节点发现和节点间消息通讯,8485端口是rpc调用时使用的,用来和客户端交互。


tcp监听实现了节点间传递消息,握手之后并不断开,一直在握手状态,节点间消息传递先进行密钥协商之后使用对称密钥进行消息加密传输,和ssl的过程类似


udp监听实现了节点查找






看代码:


1.入口main.go->utils.StartNode(stack)


2.p2p.server.go ->func (srv *Server) Start() (err error) 方法


这两部很简单,一步一步看过去就可以找到server.go,节点的维护代码几乎都在server.go中


3.server.go->func (srv *Server) listenLoop() {


该方法先是启动监听:


fd, err = srv.listener.Accept()


4.c := &conn{fd: fd, transport: srv.newTransport(fd), flags: flags, cont: make(chan error)}


然后把fd这个链接赋值给conn自定义结构体


5.if c.id, err = c.doEncHandshake(srv.PrivateKey, dialDest); err != nil {


进行密钥协商


6.err = srv.checkpoint(c, srv.addpeer)


把conn放到队列中,conn中的fd就是tcp connection


7.case c := <-srv.addpeer:


监听到队列中有值,启动peer


go srv.runPeer(p)


以上这些代码都在server.go中,所以需要整体的看一遍






之后就在p2p->peer.go中


8.func (srv *Server) runPeer(p *Peer) {


由server创建并启动


9.func (p *Peer) run() (remoteRequested bool, err error) {


func (p *Peer) readLoop(errc chan<- error) {


10.p2p.rlpx


func (rw *rlpxFrameRW) ReadMsg() (msg Msg, err error) {


读取消息并解密


11.p2p.peer


func (p *Peer) handle(msg Msg) error {


msg.Code:


handshakeMsg = 0x00
discMsg      = 0x01
pingMsg      = 0x02
pongMsg      = 0x03
getPeersMsg  = 0x04
peersMsg     = 0x05
每个节点会定期的ping和pong






peer来实现消息读取,然后调用handle解析,构造transcation,然后使用txpool.go存储


整个transcation接收的流程就是这样。





你可能感兴趣的:(go-ethereum源码阅读 - 1.transcation的监听和接收)