go libp2p kad dht
重要的参数
alpha: 同一时间最多只能向alpha个节点查询。默认值为10
beta: 迭代查询结束条件,所有非unreachable的节点按照距离排序后,前beta个节点全部都查询过即可结束。默认值为3
K(bucketSize): 默认值为20
- 迭代查询开始时,从K桶中选取最多K个节点。
- 迭代查询结束后,所有非unreachable的节点按照距离排序,向前(最多)K个节点中那些未查询或者正在查询的节点发起查询。
- FindProviders和GetValue需要找到K个记录才能结束查找。
- handleGetValue,handleGetProviders和handleFindPeer会从K桶中选取最多K个节点信息,回复给对方
请求
var Message_MessageType_value = map[string]int32{"PUT_VALUE": 0,"GET_VALUE": 1,"ADD_PROVIDER": 2,"GET_PROVIDERS": 3,"FIND_NODE": 4,"PING": 5,
}
所有DHT节点收到请求后,调用各请求的处理函数,然后将发送者的节点ID保存到路由表中。
FindPeer
首先在本地查找,如果当前已经和该peer连接,或者可连接(之前连接过,优雅关闭了),则查询结束。否则向外迭代查询,发送"FIND_NODE"请求。
其它节点收到请求后,如果目标节点是自己,就将自己的节点信息发回去,否则将K桶中距离最近的K个节点信息回复给对方。
PutValue
首先在本地查找记录,如果本地有记录,且value比本地记录更旧,则报错返回;否则向外迭代查询,发送"FIND_NODE"请求,得到一批距离key最近的节点(最多K个),向它们发送"PUT_VALUE"请求,将记录发给它们。
其它节收到"PUT_VALUE"请求后,首先和本地记录进行比较,比本地记录新就替换。
GetValue
首先在本地查找,同时向外迭代查询,发送"GET_VALUE"请求,得到一些记录和距离资源最近的节点信息(最多K个),通过对这些记录进行比较,得到最新的记录,然后向这些节点中那些没有返回记录或者返回旧的记录的节点发送"PUT_VALUE"请求,将记录发给它们。
其它节点收到"GET_VALUE"请求后,将本地记录和K桶中距离最近的K个节点信息回复给对方。
value
value目前默认有两个validator: pk和ipns。pk用于验证ID和公钥是否匹配,无所谓新旧。
ipns记录可能是最新的,也可能是旧的。先比较序列号(Sequence),相等则比较有效期(validity),如果还是相等最后通过比较字节大小来判断。
type IpnsEntry struct {Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`Signature []byte `protobuf:"bytes,2,req,name=signature" json:"signature,omitempty"`ValidityType *IpnsEntry_ValidityType `protobuf:"varint,3,opt,name=validityType,enum=ipns.pb.IpnsEntry_ValidityType" json:"validityType,omitempty"`Validity []byte `protobuf:"bytes,4,opt,name=validity" json:"validity,omitempty"`Sequence *uint64 `protobuf:"varint,5,opt,name=sequence" json:"sequence,omitempty"`Ttl *uint64 `protobuf:"varint,6,opt,name=ttl" json:"ttl,omitempty"`// in order for nodes to properly validate a record upon receipt, they need the public// key associated with it. For old RSA keys, its easiest if we just send this as part of// the record itself. For newer ed25519 keys, the public key can be embedded in the// peerID, making this field unnecessary.PubKey []byte `protobuf:"bytes,7,opt,name=pubKey"
}
value的pb结构是Record,Record带有时间戳,但是该时间戳没有被使用,datastore的value时间戳是保存时的时间戳。
// Record represents a dht record that contains a value
// for a key value pair
type Record struct {// The key that references this recordKey []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`// The actual value this record is storingValue []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`// Time the record was received, set by receiverTimeReceived string `protobuf:"bytes,5,opt,name=timeReceived,proto3" json:"timeReceived,omitempty"`
}
值得注意的是,handleGetValue从datastore获取到value后,会检查value的时间,如果距离上次保存已经超过(默认)36h,则视为无效(本着对其它节点负责的态度?)。
PutValue和handlePutValue由于是写操作,所以不需检查时间戳,而GetValue也没有检查这个时间戳,可能是因为记录虽旧,但有好过无。
Provide
首先将provider记录保存在本地,接着向外迭代查询,发送"FIND_NODE"请求,得到一批距离key最近的节点(最多K个),向它们发送"ADD_PROVIDER"请求,将记录发给它们。
其它节点收到"ADD_PROVIDER"请求后,先将provider中的节点信息添加到peerstore,再将记录保存起来。
FindProviders
首先在本地查找,如果本地有不少于K个(该资源的)provider记录,则查询结束,否则向外迭代查询,发送"GET_PROVIDERS"请求。
其它节点收到请求后,将其本地(该资源的)所有provider记录以及K桶中距离最近的K个节点信息回复给对方。
provider
provider记录可能是有效的,也可能无效,所以FindProviders得到的是一组(最多K个)记录,这些记录只要有一个是有效的即可。
所有provider记录由ProviderManager管理,provider结构本身并没有时间戳,而是在添加provider时附带时间戳,以便ProviderManager定期对那些过期的provider记录进行清理。
type Message_Peer struct {// ID of a given peer.Id byteString `protobuf:"bytes,1,opt,name=id,proto3,customtype=byteString" json:"id"`// multiaddrs for a given peerAddrs [][]byte `protobuf:"bytes,2,rep,name=addrs,proto3" json:"addrs,omitempty"`// used to signal the sender's connection capabilities to the peerConnection Message_ConnectionType `protobuf:"varint,3,opt,name=connection,proto3,enum=dht.pb.Message_ConnectionType" json:"connection,omitempty"`
}
思考:
provider记录没有签名,是否可以构造大量的虚假provider记录,对网络进行DDOS攻击?
go libp2p kad dht相关推荐
- go libp2p kad record详解
go libp2p kad的value可用于存放任意数据,目前kad默认在value中存放了ipns和pk这两种数据(pk也是为ipns服务的,详情请阅读我的另一篇博文<ipns实现机制解读&g ...
- libp2p kad 迭代查询
描述 迭代查询是libp2p kad中的关键部分,kad通过迭代查询不断逼近目标,这个目标可能是peer,可能是provider,也有可能是value. 过程 选取K桶中距离key最近的(最多)K个节 ...
- IPFS、区块链的libp2p
IPFS基本定义 IPFS即InterPlanetary File System,是一个基于内容寻址的.分布式 的.新型超媒体传输协议.IPFS支持创建完全分布式的应用.它旨在使 网络更快.更安全.更 ...
- 百度超级链XChain(2)p2p网络
1. 定义 非结构化p2p网络 结构化p2p网络:结构化p2p最普遍的实现方案是使用分布式哈希表(DHT),eg. 以太坊网络. 1.1 NAT技术 通过将局域网内的主机地址映射为互联网上的有效ip地 ...
- service数据保存_精通IPFS:IPFS 保存内容之下篇
在上一篇文章中,我们指出在builder/builder.js文件中调用调用pull函数进行保存文件,这篇文章我们就来详细研究下这个过程. 设置源流为 file.content. 调用 chunker ...
- libed2k源码导读:(二)Session接口以及实现分析
第二章 Session接口以及实现分析 目录 第二章 Session接口以及实现分析 2.1 获取会话状态 2.2 管理会话中所有的传输任务 2.3 管理点对点连接 2.4 管理alert 2.4.1 ...
- 区块链入门--准备搭建自己的区块链
最近在B站上看到一个Hyperleger Fabric搭建自己的区块链的视频,把里面的内容整理了出来.个人认为其中如何下载安装Docker,利用Hyperleger中的插件,实际搭建的过程讲述的并不清 ...
- P2P网络编程-2-案例实践:P2P聊天应用
文章目录 一.初代版本 1.1 简介 1.2 代码与解析 1.3 测试运行 二.节点发现 2.1 简介 2.2 代码与解析 2.3 测试运行 三.总结 3.1 libp2p节点发现构建流程 3.2 l ...
- dht网络 kad协议 bencode编码 Java版 自给自足的磁力链接爬虫
java 版本的实现 githbu地址 (求各位给几个start 小星星啦 拜谢) https://github.com/readmlll/dht-spider 1.导入idea 在入口类DhtNet ...
最新文章
- 如何用一句话证明你学过 NLP ?
- 访问 IIS 元数据库失败解决问题的方法
- 配置Apache服务器的PHP运行环境
- boost::strict_lock相关的测试程序
- 创建 Spring容器的三种方式
- 征集.NET中国峰会议题
- redis 查询缓存_Redis缓存总结:淘汰机制、缓存雪崩、数据不一致....
- 用nginx做了一下反向代理,得到的ip地址都是127.0.0.1
- python中sklearn中的Imputer模块改动
- JavaScript案例一:Window弹窗案例
- 《剑指offer》第五十八题(左旋转字符串)
- vs2015+opencv+dilb+于仕琪人类识别算法对人脸特征点进行检测
- laravel 软删除
- 求这个字符串中的最大的数字字符串
- 专业CDR插件牛为设计大师
- python爬虫,从hao123爬取网址信息
- 20180108 自省
- 实施工作20190313
- createCaptureSession()
- 一笔画问题(nyoj 42)
热门文章
- 全国地区 mysql表_数据库表地址数据(中国地区)
- Visual Studio 2022中kbhit()函数与getch()函数的书写问题
- 2021全国大学生电子设计竞赛A题
- Mac上的取色器(拾色器)的比较 - 正版Mac版的取色器软件
- 基于PHP+MySQL的学生信息管理系统
- ISP嵌入式平台/成像sensor
- java爬虫教程 百度云_java视频教程java爬虫实战项目httpclient hbase springmvc solr
- Windows10 镜像(正版和原版)
- 面试百度新浪头条b站阿里的研发实习生面试记录
- 6-6 快速播放音频和视频预加载