Documentation ¶
Overview ¶
Package kbucket 提供了基于Kademlia DHT的路由表实现
Package kbucket implements a kademlia 'k-bucket' routing table.
Index ¶
- Variables
- func Closer(a, b peer.ID, key string) bool
- func CommonPrefixLen(a, b ID) int
- func SortClosestPeers(peers []peer.ID, target ID) []peer.ID
- func XOR(a, b []byte) []byte
- type ID
- type PeerInfo
- type RoutingTable
- func (rt *RoutingTable) AddPeer(ctx context.Context, h host.Host, pi peer.AddrInfo, mode int, queryPeer bool, ...) (bool, error)
- func (rt *RoutingTable) Close() error
- func (rt *RoutingTable) Find(id peer.ID) peer.ID
- func (rt *RoutingTable) GenRandPeerID(targetCpl uint) (peer.ID, error)
- func (rt *RoutingTable) GenRandomKey(targetCpl uint) (ID, error)
- func (rt *RoutingTable) GetDiversityStats() []peerdiversity.CplDiversityStats
- func (rt *RoutingTable) GetPeerInfos() []PeerInfo
- func (rt *RoutingTable) GetTrackedCplsForRefresh() []time.Time
- func (rt *RoutingTable) ListPeers(mode ...int) []peer.ID
- func (rt *RoutingTable) MarkAllPeersIrreplaceable()
- func (rt *RoutingTable) NPeersForCpl(cpl uint) int
- func (rt *RoutingTable) NearestPeer(id ID) peer.ID
- func (rt *RoutingTable) NearestPeers(id ID, count int, mode ...int) []peer.ID
- func (rt *RoutingTable) Print(mode ...int)
- func (rt *RoutingTable) RemovePeer(p peer.ID)
- func (rt *RoutingTable) ResetCplRefreshedAtForID(id ID, newTime time.Time)
- func (rt *RoutingTable) Size(mode ...int) int
- func (rt *RoutingTable) TryAddPeer(p peer.ID, mode int, queryPeer bool, isReplaceable bool) (bool, error)
- func (rt *RoutingTable) UpdateLastSuccessfulOutboundQueryAt(p peer.ID, t time.Time) bool
- func (rt *RoutingTable) UpdateLastUsefulAt(p peer.ID, t time.Time) bool
- func (rt *RoutingTable) UsefulNewPeer(p peer.ID) bool
Constants ¶
This section is empty.
Variables ¶
var ErrLookupFailure = fmt.Errorf("failed to find any peer in table")
ErrLookupFailure 表示路由表查询未返回任何结果时的错误。这不是预期行为。
var ErrPeerRejectedHighLatency = fmt.Errorf("对等节点被拒绝:延迟太高")
ErrPeerRejectedHighLatency:表示对等节点被拒绝的错误,原因是延迟太高。
var ErrPeerRejectedNoCapacity = fmt.Errorf("对等节点被拒绝:容量不足")
ErrPeerRejectedNoCapacity:表示对等节点被拒绝的错误,原因是容量不足。
Functions ¶
func Closer ¶
Closer 判断两个节点中哪个更接近目标键。 参数:
- a: 第一个节点的 Peer ID
- b: 第二个节点的 Peer ID
- key: 目标键
返回值:
- bool: 如果节点 a 比节点 b 更接近键 key,则返回 true;否则返回 false
func CommonPrefixLen ¶
CommonPrefixLen 计算两个 ID 的公共前缀长度。 参数:
- a: 第一个 ID
- b: 第二个 ID
返回值:
- int: 两个 ID 的公共前缀长度(以位为单位)
func SortClosestPeers ¶
SortClosestPeers 按照与目标节点的升序距离对给定的对等节点进行排序。
参数:
- peers: 要排序的对等节点 ID 列表
- target: 目标节点 ID
返回值:
- []peer.ID: 按距离排序后的对等节点 ID 列表
Types ¶
type ID ¶
type ID []byte
ID 是一个在 XORKeySpace 中的 DHT ID 的类型。 类型 dht.ID 表示其内容已从 peer.ID 或 util.Key 进行了哈希处理。这统一了键空间。
func ConvertPeerID ¶
ConvertPeerID 通过哈希处理 Peer ID(Multihash)创建一个 DHT ID。 参数:
- id: 要转换的 peer.ID
返回值:
- ID: 转换后的 DHT ID
type PeerInfo ¶
type PeerInfo struct { Id peer.ID // 对等节点的唯一标识符 Mode int // 对等节点的运行模式(如 DHT 服务器/客户端) LastUsefulAt time.Time // 对等节点上次对我们有用的时间点(参见 DHT 文档中有用性的定义) LastSuccessfulOutboundQueryAt time.Time // 我们最后一次从该对等节点获得成功查询响应的时间点 AddedAt time.Time // 该对等节点被添加到路由表的时间点 // contains filtered or unexported fields }
PeerInfo 包含了 K-Bucket 中一个对等节点的所有相关信息。
type RoutingTable ¶
type RoutingTable struct { // 通知函数 PeerRemoved func(peer.ID) // 对等节点被移除时的通知函数。 PeerAdded func(peer.ID) // 对等节点被添加时的通知函数。 // contains filtered or unexported fields }
RoutingTable 定义了路由表。
func CreateRoutingTable ¶
func CreateRoutingTable(h host.Host, opt *fscfg.Options, noOpThreshold time.Duration) (*RoutingTable, error)
CreateRoutingTable 创建带有多样性过滤器的路由表 参数:
- h: libp2p 主机实例
- opt: 配置选项
- noOpThreshold: 无操作阈值
返回值:
- *RoutingTable: 创建的路由表实例
- error: 如果创建失败则返回错误
func NewRoutingTable ¶
func NewRoutingTable(bucketsize int, localID ID, latency time.Duration, m peerstore.Metrics, usefulnessGracePeriod time.Duration, df *peerdiversity.Filter) (*RoutingTable, error)
NewRoutingTable 使用给定的桶大小、本地 ID 和延迟容忍度创建一个新的路由表。 参数:
- bucketsize: 桶的大小
- localID: 本地节点的 ID
- latency: 最大可接受的延迟
- m: 延迟指标
- usefulnessGracePeriod: 对等节点的宽限期
- df: 多样性过滤器
返回值:
- *RoutingTable: 新创建的路由表
- error: 如果创建失败则返回错误
func (*RoutingTable) AddPeer ¶
func (rt *RoutingTable) AddPeer(ctx context.Context, h host.Host, pi peer.AddrInfo, mode int, queryPeer bool, isReplaceable bool) (bool, error)
AddPeer 尝试将对等节点添加到路由表 参数:
- h: libp2p 主机实例
- pi: 要添加的对等节点地址信息
- mode: 运行模式
- queryPeer: 是否是查询对等节点
- isReplaceable: 是否可替换
返回值:
- bool: 如果对等节点成功添加则返回 true
- error: 如果添加失败则返回错误
func (*RoutingTable) Close ¶
func (rt *RoutingTable) Close() error
Close 关闭路由表及其所有关联的进程。 可以安全地多次调用此函数。
返回值:
- error: 如果关闭失败则返回错误
func (*RoutingTable) Find ¶
func (rt *RoutingTable) Find(id peer.ID) peer.ID
Find 根据给定的 ID 查找特定的节点,如果找不到则返回 nil
参数:
- id: 要查找的对等节点 ID
返回值:
- peer.ID: 找到的对等节点 ID,如果未找到则返回空字符串
func (*RoutingTable) GenRandPeerID ¶
func (rt *RoutingTable) GenRandPeerID(targetCpl uint) (peer.ID, error)
GenRandPeerID 为给定的公共前缀长度(Cpl)生成一个随机的对等节点 ID。
参数:
- targetCpl: 目标公共前缀长度
返回值:
- peer.ID: 生成的随机对等节点 ID
- error: 如果生成失败则返回错误
func (*RoutingTable) GenRandomKey ¶
func (rt *RoutingTable) GenRandomKey(targetCpl uint) (ID, error)
GenRandomKey 根据提供的公共前缀长度(Cpl)生成一个匹配的随机键。
参数:
- targetCpl: 目标公共前缀长度
返回值:
- ID: 生成的随机键
- error: 如果生成失败则返回错误
func (*RoutingTable) GetDiversityStats ¶
func (rt *RoutingTable) GetDiversityStats() []peerdiversity.CplDiversityStats
GetDiversityStats 返回路由表的多样性统计信息
返回值:
- []peerdiversity.CplDiversityStats: 多样性统计信息,如果未配置多样性过滤器则返回 nil
func (*RoutingTable) GetPeerInfos ¶
func (rt *RoutingTable) GetPeerInfos() []PeerInfo
GetPeerInfos 返回我们在桶中存储的对等节点信息。
返回值:
- []PeerInfo: 包含所有对等节点信息的切片
func (*RoutingTable) GetTrackedCplsForRefresh ¶
func (rt *RoutingTable) GetTrackedCplsForRefresh() []time.Time
GetTrackedCplsForRefresh 返回我们正在追踪的用于刷新的 Cpl 时间戳列表。
返回值:
- []time.Time: 每个 Cpl 对应的最后刷新时间的切片。调用者可以自由修改返回的切片,因为它是一个防御性副本。
func (*RoutingTable) ListPeers ¶
func (rt *RoutingTable) ListPeers(mode ...int) []peer.ID
ListPeers 返回路由表中所有节点的 ID 列表 参数:
- mode: 可选参数,用于过滤特定运行模式的节点 如果不指定,则返回所有节点 如果指定,则只返回该运行模式下的节点
返回值:
- []peer.ID: 符合条件的节点 ID 列表
示例:
// 获取所有节点列表 allPeers := rt.ListPeers() // 获取服务器模式(mode=1)的节点列表 serverPeers := rt.ListPeers(1) // 获取客户端模式(mode=0)的节点列表 clientPeers := rt.ListPeers(0)
func (*RoutingTable) MarkAllPeersIrreplaceable ¶
func (rt *RoutingTable) MarkAllPeersIrreplaceable()
MarkAllPeersIrreplaceable 将路由表中的所有对等节点标记为不可替换。 这意味着我们永远不会替换表中的现有对等节点以为新对等节点腾出空间。 但是,可以通过调用 `RemovePeer` API 来删除它们。
func (*RoutingTable) NPeersForCpl ¶
func (rt *RoutingTable) NPeersForCpl(cpl uint) int
NPeersForCpl 返回给定 Cpl 的对等节点数量。 参数:
- cpl: 公共前缀长度
返回值:
- int: 具有给定 Cpl 的对等节点数量
func (*RoutingTable) NearestPeer ¶
func (rt *RoutingTable) NearestPeer(id ID) peer.ID
NearestPeer 返回距离给定 ID 最近的单个节点
参数:
- id: 目标 ID
返回值:
- peer.ID: 最近的对等节点 ID,如果未找到则返回空字符串
func (*RoutingTable) NearestPeers ¶
NearestPeers 返回距离给定 ID 最近的 'count' 个节点的列表
参数:
- id: 目标 ID
- count: 要返回的最近节点数量
- mode: 可选参数,用于约束目标节点的运行模式
返回值:
- []peer.ID: 最近节点的 ID 列表
func (*RoutingTable) Print ¶
func (rt *RoutingTable) Print(mode ...int)
Print 打印路由表的详细信息到标准输出 打印内容包括: - 路由表的基本配置(桶大小、最大延迟等) - 每个桶中节点的详细信息(ID、模式、延迟等) - 节点统计信息(总数、过滤后数量等)
参数:
- mode: 可选参数,用于过滤特定运行模式的节点 如果不指定,则打印所有节点 如果指定,则只打印该运行模式下的节点
示例:
// 打印所有节点信息 rt.Print() // 打印服务器模式(mode=1)的节点信息 rt.Print(1) // 打印客户端模式(mode=0)的节点信息 rt.Print(0)
func (*RoutingTable) RemovePeer ¶
func (rt *RoutingTable) RemovePeer(p peer.ID)
RemovePeer 在调用者确定某个对等节点对查询不再有用时应调用此方法。 例如:对等节点可能停止支持 DHT 协议。 它从路由表中驱逐该对等节点。
参数:
- p: 要移除的对等节点 ID
func (*RoutingTable) ResetCplRefreshedAtForID ¶
func (rt *RoutingTable) ResetCplRefreshedAtForID(id ID, newTime time.Time)
ResetCplRefreshedAtForID 重置给定 ID 的公共前缀长度(Cpl)的刷新时间。
参数:
- id: 要重置的 ID
- newTime: 新的刷新时间
func (*RoutingTable) Size ¶
func (rt *RoutingTable) Size(mode ...int) int
Size 返回路由表中的节点总数 参数:
- mode: 可选参数,用于过滤特定运行模式的节点数量 如果不指定,则返回所有节点数量 如果指定,则只返回该运行模式下的节点数量
返回值:
- int: 符合条件的节点总数
示例:
// 获取所有节点数量 totalSize := rt.Size() // 获取服务器模式(mode=1)的节点数量 serverSize := rt.Size(1) // 获取客户端模式(mode=0)的节点数量 clientSize := rt.Size(0)
func (*RoutingTable) TryAddPeer ¶
func (rt *RoutingTable) TryAddPeer(p peer.ID, mode int, queryPeer bool, isReplaceable bool) (bool, error)
TryAddPeer 尝试将对��节点添加到路由表。 如果对等节点已经存在于路由表中并且之前已经查询过,则此调用不执行任何操作。 如果对等节点已经存在于路由表中但之前没有进行过查询,则将其 LastUsefulAt 值设置为当前时间。 这需要这样做是因为当我们第一次连接到对等节点时,我们不会将其标记为"有用"(通过设置 LastUsefulAt 值)。
如果对等节点是一个查询对等节点,即我们查询过它或它查询过我们,我们将 LastSuccessfulOutboundQuery 设置为当前时间。 如果对等节点只是一个我们连接到的对等节点/它连接到我们而没有进行任何 DHT 查询,则认为它没有 LastSuccessfulOutboundQuery。
如果对等节点所属的逻辑桶已满且不是最后一个桶,我们尝试用新的对等节点替换该桶中上次成功的出站查询时间超过允许阈值的现有对等节点。 如果该桶中不存在这样的对等节点,则不将对等节点添加到路由表中,并返回错误 "ErrPeerRejectedNoCapacity"。
参数:
- p: 要添加的对等节点 ID,用于唯一标识一个对等节点
- mode: 运行模式,指定路由表的工作模式,影响对等节点的添加策略
- queryPeer: 是否是查询对等节点,如果为 true 表示这是一个我们主动查询过或者查询过我们的节点, 这类节点在路由表中更价值,因为它们参与了 DHT 查询
- isReplaceable: 是否可替换,如果为 true 表示当桶满时,此节点可以被新的节点替换掉。 这通常用于控制路由表的更新策略,避免重要节点被随意替换
返回值:
- bool: 如果对等节点是新添加到路由表中的,则返回 true;否则返回 false
- error: 如果添加失败则返回错误
func (*RoutingTable) UpdateLastSuccessfulOutboundQueryAt ¶
UpdateLastSuccessfulOutboundQueryAt 更新对等节点最后一次成功响应我们查询的时间。 这个时间戳用于评估对等节点的活跃度和可靠性。 如果一个对等节点长期没有成功响应查询,说明它可能已经离线或不可用,可以考虑将其从路由表中移除。
参数:
- p: 要更新的对等节点 ID
- t: 新的时间戳
返回值:
- bool: 如果更新成功则返回 true,否则返回 false
func (*RoutingTable) UpdateLastUsefulAt ¶
UpdateLastUsefulAt 更新对等节点最后一次对我们有帮助的时间。 对等节点为我们的查询提供有价值的响应时(例如返回我们需要的数据或者提供有效的路由信息),应该更新这个时间戳。 这个时间戳用于评估对等节点的价值,帮助我们在路由表空间有限时决定保留哪些节点。经常提供帮助的节点更有可能被保留在路由表中。
参数:
- p: 要更新的对等节点 ID
- t: 新的时间戳
返回值:
- bool: 如果更新成功则返回 true,否则返回 false
func (*RoutingTable) UsefulNewPeer ¶
func (rt *RoutingTable) UsefulNewPeer(p peer.ID) bool
UsefulNewPeer 验证给定的 peer.ID 是否适合路由表。 如果对等节点尚未在路由表中,或者与 peer.ID 对应的桶没有满,或者它包含可替换的对等节点,或者它是最后一个桶且添加对等节点会拆分该桶,则返回 true。
参数:
- p: 要验证的对等节点 ID
返回值:
- bool: 如果对等节点适合路由表则返回 true,否则返回 false