重要的参数

alpha: 同一时间最多只能向alpha个节点查询。默认值为10
beta: 迭代查询结束条件,所有非unreachable的节点按照距离排序后,前beta个节点全部都查询过即可结束。默认值为3
K(bucketSize): 默认值为20

  1. 迭代查询开始时,从K桶中选取最多K个节点。
  2. 迭代查询结束后,所有非unreachable的节点按照距离排序,向前(最多)K个节点中那些未查询或者正在查询的节点发起查询。
  3. FindProviders和GetValue需要找到K个记录才能结束查找。
  4. 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相关推荐

  1. go libp2p kad record详解

    go libp2p kad的value可用于存放任意数据,目前kad默认在value中存放了ipns和pk这两种数据(pk也是为ipns服务的,详情请阅读我的另一篇博文<ipns实现机制解读&g ...

  2. libp2p kad 迭代查询

    描述 迭代查询是libp2p kad中的关键部分,kad通过迭代查询不断逼近目标,这个目标可能是peer,可能是provider,也有可能是value. 过程 选取K桶中距离key最近的(最多)K个节 ...

  3. IPFS、区块链的libp2p

    IPFS基本定义 IPFS即InterPlanetary File System,是一个基于内容寻址的.分布式 的.新型超媒体传输协议.IPFS支持创建完全分布式的应用.它旨在使 网络更快.更安全.更 ...

  4. 百度超级链XChain(2)p2p网络

    1. 定义 非结构化p2p网络 结构化p2p网络:结构化p2p最普遍的实现方案是使用分布式哈希表(DHT),eg. 以太坊网络. 1.1 NAT技术 通过将局域网内的主机地址映射为互联网上的有效ip地 ...

  5. service数据保存_精通IPFS:IPFS 保存内容之下篇

    在上一篇文章中,我们指出在builder/builder.js文件中调用调用pull函数进行保存文件,这篇文章我们就来详细研究下这个过程. 设置源流为 file.content. 调用 chunker ...

  6. libed2k源码导读:(二)Session接口以及实现分析

    第二章 Session接口以及实现分析 目录 第二章 Session接口以及实现分析 2.1 获取会话状态 2.2 管理会话中所有的传输任务 2.3 管理点对点连接 2.4 管理alert 2.4.1 ...

  7. 区块链入门--准备搭建自己的区块链

    最近在B站上看到一个Hyperleger Fabric搭建自己的区块链的视频,把里面的内容整理了出来.个人认为其中如何下载安装Docker,利用Hyperleger中的插件,实际搭建的过程讲述的并不清 ...

  8. P2P网络编程-2-案例实践:P2P聊天应用

    文章目录 一.初代版本 1.1 简介 1.2 代码与解析 1.3 测试运行 二.节点发现 2.1 简介 2.2 代码与解析 2.3 测试运行 三.总结 3.1 libp2p节点发现构建流程 3.2 l ...

  9. dht网络 kad协议 bencode编码 Java版 自给自足的磁力链接爬虫

    java 版本的实现 githbu地址 (求各位给几个start 小星星啦 拜谢) https://github.com/readmlll/dht-spider 1.导入idea 在入口类DhtNet ...

最新文章

  1. 如何用一句话证明你学过 NLP ?
  2. 访问 IIS 元数据库失败解决问题的方法
  3. 配置Apache服务器的PHP运行环境
  4. boost::strict_lock相关的测试程序
  5. 创建 Spring容器的三种方式
  6. 征集.NET中国峰会议题
  7. redis 查询缓存_Redis缓存总结:淘汰机制、缓存雪崩、数据不一致....
  8. 用nginx做了一下反向代理,得到的ip地址都是127.0.0.1
  9. python中sklearn中的Imputer模块改动
  10. JavaScript案例一:Window弹窗案例
  11. 《剑指offer》第五十八题(左旋转字符串)
  12. vs2015+opencv+dilb+于仕琪人类识别算法对人脸特征点进行检测
  13. laravel 软删除
  14. 求这个字符串中的最大的数字字符串
  15. 专业CDR插件牛为设计大师
  16. python爬虫,从hao123爬取网址信息
  17. 20180108 自省
  18. 实施工作20190313
  19. createCaptureSession()
  20. 一笔画问题(nyoj 42)

热门文章

  1. 全国地区 mysql表_数据库表地址数据(中国地区)
  2. Visual Studio 2022中kbhit()函数与getch()函数的书写问题
  3. 2021全国大学生电子设计竞赛A题
  4. Mac上的取色器(拾色器)的比较 - 正版Mac版的取色器软件
  5. 基于PHP+MySQL的学生信息管理系统
  6. ISP嵌入式平台/成像sensor
  7. java爬虫教程 百度云_java视频教程java爬虫实战项目httpclient hbase springmvc solr
  8. Windows10 镜像(正版和原版)
  9. 面试百度新浪头条b站阿里的研发实习生面试记录
  10. 6-6 快速播放音频和视频预加载