以太坊和libp2p的dht源码概述(一)

这篇具有很好参考价值的文章主要介绍了以太坊和libp2p的dht源码概述(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

以太坊

对应代码位置
github.com\ethereum\go-ethereum\p2p\discover

概述

以太坊实现了udpv4和udpv6两种节点发现。
他们都包含一个table结构体来存储node信息。

会从table 、discovery两个方面叙述。

table

以太坊的定义是 a Kademlia-like index of neighbor nodes
是一个table但不是哈希table
同样有n个buckets
将网络部分抽象成一个名为transport的接口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d2TmC6LV-1667273896916)(/tfl/pictures/202210/tapd_47654106_1666333931_51.png)]
每个节点存到哪个bucket:
距离=len-cpl,距离决定了bucket的index,距离小的在0个桶,距离越远,index越大
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OjcEAr4S-1667273896918)(/tfl/pictures/202210/tapd_47654106_1666942953_37.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xHvP1u25-1667273896918)(/tfl/pictures/202210/tapd_47654106_1666942970_74.png)]

本地节点查询

查询节点函数findnodeByID
会返回所有buckets中所有entries节点。
(没有libp2p那种计算距离每次找最近的)

bucket

type bucket struct {
   entries      []*node // live entries, sorted by time of last contact
   replacements []*node // recently seen nodes to be used if revalidation fails
   ips          netutil.DistinctNetSet
}

entries存储节点,每次顺序添加,并记录节点的添加时间。
add节点时,如果entries的长度超过bucketSize,则写入replacements,(不记录写入时间)

节点验证

默认10秒验证一次,每次随机选择一个bucket验证entries中的最后一个节点。只验证entries不验证replacements。
验证方式就是ping/pong
验证成功则移动到队首,且livenessChecks++。验证失败则从replacements中选一个代替这个验证失败的节点。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-py8DqvyZ-1667273896918)(/tfl/pictures/202210/tapd_47654106_1666593649_3.png)]

lookup(即discovery)

doRefresh函数包含了向其他节点查询的功能lookupRandom
每次随机选择3个节点,3是写死的,默认30分钟执行一次。刚启动时会执行一次。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wmIWdbgU-1667273896919)(/tfl/pictures/202210/tapd_47654106_1666593515_78.png)]

每次执行时new一个lookup,并调用run()方法,lookup方法优先从table里找到邻居,这个找邻居的函数就是findnodeByID,然后再向这些邻居发发送find请求,邻居们再调用自己的findnodeByID把结果返回。

入口(如何启动这一切的)

udpv4合udpv5有个new函数,new一个udpv4实例的时候再new一个tab并启动这个tab不断更新。
提供一个函数Resolve来返回查询到的节点。

libp2p的k桶

本文内容源自下面源码版本
go-libp2p-kbucket@v0.4.7
#高频名词解释
cpl:common prefix length两个ID的公共前缀长度。

功能简介

go-libp2p-kbucket实际是实现了一个路由表,他的结构体命名也是RoutingTable
除了正常增删节点之外,主要功能是查找距离一个节点最近的n个节点的peerID
NearestPeers(id ID, count int) []peer.ID
简单来讲是靠计算他们的前缀来实现的。

bucket

bucket是k桶的基础组成,一个k桶包含n个bucket,每个bucket通过一个链表*list.List来维护节点。
bucket提供最基本从增删改查之外,还有一个计算最大公共前缀的函数,
该函数会遍历list中的每个节点,然后找到公共前缀最大的结果并返回。

RoutRoutingTable 路由表(哈希表)

函数NewRoutingTable会初始化一个路由表,强制需要一个localID,并生成一个bucket放入buckets

add节点

add一个节点时,会计算该节点和localID的公共长度,该长度和len(buckets) 取最小值,该最小值就是bucket的index(bucketID)。
用index从buckets拿出对应的bucket,先判断节点是否已经存在,存在则返回false。
如果这个bucket的长度< rt.bucketsize,则正常插入该bucket,并返回true。
如果这是最后一个bucket(也就是最后一个bucket也满了),则扩展bucket个数,然后重新执行获得index,如果bucket的长度< rt.bucketsize则正常插入该bucket,并返回true。
如果这不是最后一个bucket,会从当前bucket踢出一个replaceable==true的节点然后查询这个新节点。
如果没有能replace的,则返回false,插入失败。

获得最近的节点NearestPeers

先计算target和local的cpl,这个cpl作为index,将对应的bucket的全部节点写入结果数组。
如果数量不够,从cpl后面的bucket开始写入结果集。
如果数量还不够,从cpl前面的bucket依次写入结果集。
然后结果集排序并返回。

go-libp2p-kad-dht

IpfsDHT这个结构体实现了很多interface
文本只关心PeerRouting

// PeerRouting is a way to find address information about certain peers.
// This can be implemented by a simple lookup table, a tracking server,
// or even a DHT.
type PeerRouting interface {
   // FindPeer searches for a peer with given ID, returns a peer.AddrInfo
   // with relevant addresses.
   FindPeer(context.Context, peer.ID) (peer.AddrInfo, error)
}

FindPeer函数会调用dht的runLookupWithFollowup去执行一个lookup操作,
runLookupWithFollowup的参数里有一个回调函数queryFn

具体流程是:
dht.host.Network().Connectedness(id)里找是否已经包含,有就直接返回,没有会启动一个runLookupWithFollowup
runLookupWithFollowup先从自己的routingTable里找到最近的节点(dht.routingTable.NearestPeers
如果结果为空则返回失败。
不为空则run一个query,这个query的结果就是最终结果。这个query包含了哈希表全部的最近节点,对每个节点依次遍历。
遍历的过程是先q.dht.dialPeer,失败则返回,成功则调用回调函数queryFn,通过queryFn拿到新的节点就写入自己的哈希表。无论失败返回还是成功拿到新节点,都会把结果写入一个chan,run出来的query函数里创建的这个chan并一直等待读这个chan,读到则这个节点状态为PeerQueried且将这个节点加入结果集:q.queryPeers.TryAdd(p, up.cause)。最后返回就是读这个结果集q.queryPeers.GetState(p)

queryFn里面的逻辑是
发送一个类型为Message_FIND_NODE的消息
对方收到消息会调用函数 handleFindPeer,该函数会执行dht.routingTable.NearestPeers拿到最近的节点,通过pstore.PeerInfos拿到这些节点的地址并封装成返回值。返回值最终写入一个addrsCh ,从addrsCh中收到的地址写入数组 newAddrs
FullRTdht.h.Connect这些地址
IpfsDHT结构体会返回这些节点的信息文章来源地址https://www.toymoban.com/news/detail-785788.html

到了这里,关于以太坊和libp2p的dht源码概述(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【区块链 | 智能合约】Ethereum源代码(11)- 以太坊核心BlockChain源码分析

    前面几节都在分析以太坊的通信协议,怎么广播,怎么同步,怎么下载。这一节讲讲以太坊的核心模块BlockChain,也就是以太坊的区块链。 一,BlockChain的初始化 Ethereum服务初始化func init() 的时候会调用core.SetupGenesisBlock来加载创始区块。顾名思义,创始区块就是以太坊区块链中

    2024年02月08日
    浏览(32)
  • 区块链——p2p网络模型

            通常情况下,一个区块链系统的P2P网络层主要由以下几部分组成。         覆盖网络可以根据其对应覆盖图的性质分为两类: 无结构化覆盖网络 和 结构化覆盖网络 。无结构化覆盖网络通常基于随机图来建立节点随机从覆盖网络中选取节点作为邻居;而结构化覆盖

    2024年04月27日
    浏览(37)
  • 区块链核心技术-P2P网络

    点对点网络是区块链中核心的技术之一,主要关注的方面是为区块链提供一个稳定的网络结构,用于广播未被打包的交易(交易池中的交易)以及共识过的区块,部分共识算法也需要点对点的网络支撑(如PBFT),另外一个辅助功能,如以太坊的消息网络,也需要点对点网络的

    2023年04月17日
    浏览(47)
  • 区块链入门系列之P2P

    区块链基本概念和名词解释 P2P 共识算法 梅克尔-帕特里夏树 从零开始搭建区块链 为什么前面讲过P2P的概念了这里还要单独起一篇文章来讲解,因为前面只是讲解了P2P的基本概念,即各网络节点间是直接或间接连接起来的。但这里面还涉及到很多网络知识,如果不清楚,是没

    2023年04月19日
    浏览(31)
  • 区块链(6):p2p去中心化介绍

    1 互联网中中心化的服务和去中心化服务的概念介绍 目前的互联网公司大都是中心化的 区块链网络大多是去中心化的 去中心化 2 p2p的简单介绍 java 网络编程:socket编程,netty编程,websoket简单介绍 2.1 节点是如何提供服务的(web编程实现)

    2024年02月08日
    浏览(38)
  • 用Rust实现区块链 - 6 点对点网络(P2P)

    截止到目前,我们在单机上实现了区块链的几乎所有关键特性:随机生成的地址、安全、持久化、工作量证明、UTXO交易。接下来我们将使用rust-libp2p库来实现区块链的p2p网络。 P2P 网络拓扑结构有很多种,有些是中心化拓扑,有些是半中心化拓扑,有些是全分布式拓扑结构。

    2024年01月17日
    浏览(43)
  • 区块链(8):p2p去中心化之websoket服务端实现业务逻辑

    1 业务逻辑 例如 peer1和peer2之间相互通信 peer1通过onopen{ write(Mesage(QUERY_LATEST))} 向peer2发送消息“我要最新的区块”。 peer2通过onMessage收到消息,通过handleMessage方法对消息进行处理。 handleMessage根据消息类型进行处理 RESPONSE_BLOCKCHAIN:返回区块链,RESPONSE_BLOCKCHAIN处理进入handleB

    2024年02月08日
    浏览(31)
  • 不同类型的以太坊区块链及其部署:区块链类型:公有链,联盟链,私有链、安装部署以太坊。

    根据区块链网络类型分类:私有链、联盟链、共有链。 主网:指在现实生活中使用的公有链,例如:比特币、以太坊。 测试网络:不消耗真正的以太币。如:eth、pyethAPP、Geth, Quorum:一致性协议采用:基于Raft的一致性协议和Istanbul BFT协议。(在支持拜占庭容错的环境下应该

    2024年02月04日
    浏览(29)
  • 区块链之以太坊

    对于以太坊中可能出现的replay attack对于账户中的每一笔交易都加上一个nonce值来记录这是第几次交易,然后将nonce值和交易一起进行签名,之后如果有人重放这笔交易,经过验证发现nonce值对应的交易已经执行过一次了,就不再执行了。所以全节点也应该保存每个节点的nonce值

    2024年02月13日
    浏览(27)
  • 以太坊区块链快速入门

    1.什么是以太坊? 以太坊是由社区驱动的技术,为加密货币以太币(ETH)和成千上万的去中心化应用程序提供动力。 属于所有人的银行服务 现实生活中不是每个人都能使用金融服务。但是只要您有网络,就可以访问基于以太坊的借贷和储蓄产品。 更好的隐私保护 使用以太坊

    2024年01月20日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包