为了维护点对点的比特币网络,需要有一个地址来源以便在节点进出时进行连接。比特币协议提供了 getaddr
和 addr
消息,允许节点之间相互传递已知的地址。然而,需要有一个机制来存储这些结果并从中选择节点。同样重要的是,远程节点不能被信任来发送有效的节点,也不能保证不会试图出于恶意目的仅向你提供他们控制的节点。
考虑到这一点,addrmgr
包提供了一个并发安全的地址管理器,用于以非确定性的方式缓存和选择节点。总体思路是调用者将地址添加到地址管理器,并在地址已连接、已知良好和已尝试时通知它。调用者还可以在需要时请求地址。
addrmgr
在内部将地址分组,并以加密随机的方式非确定性地选择这些组。这减少了从同一网络中选择多个地址的概率,从而通常有助于提供更大的节点多样性,更重要的是,极大地降低了攻击者能够强迫你的节点仅连接到他们控制的节点的可能性。
addrmgr
还能够理解可路由性和 Tor 地址,并尽力只返回可路由的地址。此外,它使用调用者提供的信息,包括已连接、已知良好和已尝试的地址,定期清除那些不再表现为良好的节点,同时在选择时偏向已知良好的节点。总体思路是尽最大努力只提供可用的地址。
btcd
是一个用 Go 语言编写的比特币全节点实现,其中包含了一个名为 addrmgr
的包,用于管理比特币网络中的对等节点(peer)的地址信息。addrmgr
负责发现、跟踪和维护网络中活跃节点的地址,从而确保节点能够有效地连接和通信。以下是对 btcd
中 addrmgr
的详细介绍。
addrmgr
包主要用于管理比特币网络中的节点地址。它提供了添加、删除、选择和更新节点地址的功能,确保节点能够发现和连接到其他节点,从而保持网络的连通性。并提供以下功能:
在 btcd
中,addrmgr
的核心结构是 AddrManager
,它负责管理所有的节点地址信息。以下是 AddrManager
结构的定义:
type AddrManager struct {
mtx sync.RWMutex
peersFile string
lookupFunc func(string) ([]net.IP, error)
rand *rand.Rand
key [32]byte
addrIndex map[string]*KnownAddress // address key to ka for all addrs.
addrNew [newBucketCount]map[string]*KnownAddress
addrTried [triedBucketCount]*list.List
started int32
shutdown int32
wg sync.WaitGroup
quit chan struct{}
nTried int
nNew int
lamtx sync.Mutex
localAddresses map[string]*localAddress
version int
}
字段解析:
AddrManager
结构体定义了一个并发安全的地址管理器,用于缓存比特币网络中的潜在节点。以下是各个字段的作用说明:
type AddrManager struct {
mtx sync.RWMutex
peersFile string
lookupFunc func(string) ([]net.IP, error)
rand *rand.Rand
key [32]byte
addrIndex map[string]*KnownAddress // address key to ka for all addrs.
addrNew [newBucketCount]map[string]*KnownAddress
addrTried [triedBucketCount]*list.List
started int32
shutdown int32
wg sync.WaitGroup
quit chan struct{}
nTried int
nNew int
lamtx sync.Mutex
localAddresses map[string]*localAddress
version int
}
KnownAddress
结构体,用于快速查找和访问所有已知地址。AddrManager
是否已经启动。AddrManager
是否已经关闭。localAddresses
的并发访问。AddrManager
的版本。func New(dataDir string, lookupFunc func(string) ([]net.IP, error)) *AddrManager
:从指定路径加载节点地址信息,并创建一个新的地址管理器。func (a *AddrManager) AddAddresses(addrs []*wire.NetAddressV2, srcAddr *wire.NetAddressV2)
:并发安全地增加多个地址func (a *AddrManager) AddAddress(addr, srcAddr *wire.NetAddressV2)
:并发安全地增加地址func (a *AddrManager) AddAddressByIP(addrIP string) error
:通过ip:port
方式增加地址func (a *AddrManager) NumAddresses() int
:返回已知地址的数量。func (a *AddrManager) GetAddress() *KnownAddress
:返回一个应该可路由的地址。它选择一个从可能的地址中随机选择一个,优先考虑那些最近没有使用过。func (a *AddrManager) Connected(addr *wire.NetAddressV2)
func (a *AddrManager) Good(addr *wire.NetAddressV2)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。