以太坊go-ethereum源码解析(一)p2p网络通信协议(1)

这段时间在看以太坊开源在github的go-ethereum代码,go语言实现的区块链技术,后续会根据各个模块,推出一系列go-ethereum源码解析文章。

开头

打开工程第一眼看到的就是p2p的package。没办法,谁让我在上家公司做的就是p2p协议的分布式缓存加速,一下子就对p2p来兴趣了。p2p协议也不是啥新鲜玩意儿了,注意这里的p2p是网络上的peer-to-peer,可不是互联网借贷的p2p。

p2p协议

经常下片,特别是岛国爱情动作片的男同胞们都知道BT种子或者磁力链接,而BT下载所用协议BitTorrent就是最经典的公有p2p通信协议。我们平时看电影、看剧、看网综用到的爱奇艺客户端腾讯客户端PPLive客户端(注意,是客户端,不是web网页端),听歌时用到的酷狗QQ音乐,以及最常用的下载软件迅雷,用的都是基于BitTorrent简化后的私有p2p协议。

作为处女座的我,就是爱钻牛角尖。个人认为,严格意义上说,p2p协议应分为广义p2p狭义p2p

非真正的去中心化的广义p2p网络协议。

p2p网络

所谓p2p(peer-to-peer)就是网络上节点到节点之间的连接,这是一种网络拓扑类型。这里的节点指的就是你的计算机或者移动设备上跑着的某个实现有一致p2p通信协议的应用。如上图所示,当你的计算机或者移动设备(如 peer 7)第一次要加入这个p2p网络,没有介绍人,上哪去找这个p2p网络的入口?这里一般有两种方式,用于加入到p2p网络中:

  • 其一,已知该p2p网络中已存在且处于active状态的某个peer节点,跟它连接后,该peer将会共享出整个p2p网络的连接信息。
  • 其二,有个tracker服务器,要进入p2p网络前,先访问这个tracker服务器获取该p2p网络所有节点信息,随后根据从tracker获取的peer信息,连接这些peer,而后加入到该p2p网络中。

例如DHT(Distributed Hash Table)就采用的第一种接入方式(以太坊采用的Kademlia-like算法就是DHT的一种实现算法),而大部分p2p协议应用都会有类tracker服务器的存在,tracker本身就是一个已知的网络中心。tracker宕机不可用,或者已知的peer节点已经下线inactive了,那也就无从进入这个p2p网络了。
因此,我个人认为只有当peer加入到p2p网络(我将这种不考虑接入方式的p2p网络,理解为狭义p2p网络)后,才是真正的去中心化。但p2p网络的接入也是p2p通信协议的重要环节之一,所以.....

狭义p2p网络协议的去中心化

相比传统的C/S网络架构,p2p架构中最重要的特点在于:其网络中的peer之间在地位和功能上是平等的。虽然每个peer可能处理不同的请求,实际提供的资源在具体量化后也会有所差异,但它们都能同时既消耗资源又提供资源。如果把整个p2p网络中的所有资源(包括但不限于运算能力、存储空间、网络带宽等)视为一个总量,那么p2p网络中的资源分布,是分散于各个peer中的。从这一点粗发,p2p网络架构天然是去中心化的、分布式的。

在p2p网络中,peer间联系可分为无结构化的和结构化的。这里简单介绍下,无结构化的p2p网络优点在于组建方便,对网络无结构要求,即使有大量peer同时加入到网络或者下线离开,整个网络也会很稳定。而结构化的优点在于数据查询效率高(这里可以去研究下DHT相关的知识,捞个DHT爬虫的代码看看就有点B数了),缺点是当大量peer同时加入到网络或者下线离开,网络整体稳定性差,性能受影响(emma 不过多展开解释,依旧出门左转 google下DHT,了解下Kademlia,bucket等原理)。

以太坊的p2p协议

以太坊的p2p网络特征:

  1. 网络中随时可能存在一些个体加入和离开网络的情况,但同一时间内大量新旧个体同时发生加入或离开的概率很低(除非那些大矿场同时断电了,哈哈哈)。
  2. 理想状态下每个区块存储的数据应该是相同的。但实际情况会因为广播同步的延迟,导致区块的数据不一致。设计通信机制当然是希望尽可能的高度一致。所以在以太坊p2p网络中,查找数据时,不需要针对某些特定区域以提高效率,更不需要向整个网络猛发送请求。

p2p通信的协议管理模块ProtocolManager

直接上代码了,eth/handler.go

eth/handler.go

以太坊中,管理p2p通信的顶层结构体叫eth.ProtocolManager,它也是eth.Ethereum的核心成员变量之一。UML关系如下图:
图片来自:https://img-blog.csdn.net/20171108141219288?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGVhc3ByaW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
UML图

ProtocolManager主要成员包括:

peertSet来表示缓存相邻peer列表,peerSet map 中的peer表示网络中的一个远端节点。

peertSet

ProtocolManager通过各种通道(newPeerChtxsyncChquitSyncnoMorePeers)和事件订阅(eventMuxtxSubminedBlockSub)的方式,接收和发送包括交易和区块在内的数据更新。

Fetcher存储所有其他peer发送来的有关新数据的Announce消息,并在自身对照后,处理相应的获取请求。

Fetcher

Downloader负责所有向相邻peer主动发起的同步流程。
以太坊的p2p网络中,所有进行通信的两个peer都必须率先经过相互的注册(register),并被添加到各自缓存的peer列表,也就是peerSet对象中,这样的两个peers,就可以称为“相邻”。所以,只要两个peer,如果处于可通信状态,则必定已经“相邻”。
peerSet Register / Unregister

Start(maxPeers int):开启p2p网络

Start(maxPeers int)函数是ProtocolManager的启动函数,它会在eth.Ethereum.Start(maxPeers)中被主动调用。ProtocolManager.Start(maxPeers)会启用4个goroutine去分别执行4个函数。

Start(maxPeers int)

来看下这四个goroutine都在做些什么

pm.txBroadcastLoop()

pm.minedBroadcastLoop()

pm.syncer()


这里的最优peer(BestPeer)指的是什么呢


pm.txsyncLoop()

以上4个goroutine是ProtocolManager向相邻peer主动发起信息的过程。可以看得出,向其他peer主动发起的通信中,按照数据类型可分两类:交易tx和区块block;而按照通信方式划分,亦可分为广播新的单个数据和同步一组同类型数据,这样简单的两两配对,便可组成上述四段流程。

handle(p *peer):相邻peer的回调函数

对于peer间通信而言,除了主动向对方peer发起通信(比如Start()中启动的四个goroutine)之外,还需要一种由对方peer主动调用的数据传输,这种传输不仅仅是由对方peer发给己方,更多的用法是对方peer主动调用一个函数让己方发给它们某些特定数据。这种通信方式,在代码实现上适合用回调来实现。

ProtocolManager.handle()就是这样一个函数,它会在ProtocolManager对象创建时,以回调函数的方式埋入每个p2p.Protocol对象中(实现了Protocol.Run()方法)。之后每当有新peer要与己方建立通信时,如果对方能够支持该Protocol,那么双方就可以顺利的建立并开始通信。


handleMsg的代码比较长,这里就不过多介绍了,有兴趣可以找源码看一下,逻辑简单就是根据不同的消息类型,进行相应的处理。

关于以太坊p2p协议第一篇文章先写到这,内容还有很多,时间有限,只能拆开一部分一部分来写~

参考文献:
https://blog.csdn.net/teaspring/article/details/78455046

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,576评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,515评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,017评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,626评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,625评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,255评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,825评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,729评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,271评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,363评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,498评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,183评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,867评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,338评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,458评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,906评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,507评论 2 359

推荐阅读更多精彩内容