libp2p在比特币,以太坊,filecoin中是去中心化网络层面的核心技术。 golang有开源一个libp2p的框架。似乎看起来好难。……
我研究问题的方式是:剥离皮肉,留下骨干,然后再把皮肉贴回去,调试的方式去进一步研究。不然隔着那么多的东西,你很难看清楚是怎么实现的。 libp2p 其实贼简单只是比较绕一些,本质上跟http一样简单。

libp2p要素:

  • 节点拓扑,用kademlia算法的实现原理算法实现
  • 打洞,tcp层面实现。网络打洞
  • 消息传递,用广播协议?哦,不,广播协议刹不住车,需要一个带刹车的算法:Gossip 算法。关于Gossip算法的文章
  • 文件传输,既然能打洞,http就可以实现一个文件传输

Gossip 协议简单描述:

消息从网状拓扑种的一个节点发起,消息带id和消息流水号(初始消息流水号是1,每转一层消息流水号加1)。 收到消息的节点会把消息流水号加1后,再转发给周边挨着的节点。 其它节点收到消息后,会判断消息id在一段时间内(例如5分钟)出现过没有,如果没有出现过,且消息的目标地址不是自身的uuid,则传递给周边的节点。 如果消息出现过,则判断流水号id比自己大的才会接受,流水号比自己小的的消息就忽略掉(如此,消息传递是有方向的,不会出现广播风暴)。 举个例子,一篇草原,地皮上的干草交错着贴在地面,这时候你扔一个点燃了的火柴棍(比作libp2p里面的消息)往草地上面一扔,火苗就会形成一个圆向周边扩散。 一根干草会同时面临周围其它挨着的已经燃烧了的草的感染,而烧成灰烬的地方,不能被感染,只会点燃没有烧过的干草。(消息会小范围内部重复,消息不会遗漏,消息有一定的延迟)。 这个就是Gossip 算法的精髓。

基于上面的3个技术,用golang去实现一个libp2p的基本框架并无大碍