比特币P2P网络的节点发现有两种方式,这两种方式优先选第二种,在没得办法的情况下才使用第一种。
(1)使用DNS seed
比特币源码提供了DNS seed,可以查询到当前可用的一些比特币节点。
DNS节点通常由社区维护。而这些DNS来源可以分为两类:
其中一类是通过扫描整个P2P网络动态地把节点添加到DNS里去。
另一种是人手动把IP地址添加到DNS里去。
可能第二类地址上的节点比较固定,通常提供长期的比特币服务。而第一类地址上的节点比较活跃,随时可能掉线。
不管哪一种,都是主网对外提供8333端口,测试网对外提供18333端口.
但比特币的P2P网络有个问题,那就是比特币节点之间没有进行安全认证的,很容易遭到中间人攻击。作恶节点可能会传输给你它伪造的交易和区块。所以不能完全信任DNS里的节点。
说了这么多,DNS seed到底长啥样?
vSeeds.emplace_back("seed.bitcoin.sipa.be", true); // Pieter Wuille, only supports x1, x5, x9, and xd
vSeeds.emplace_back("dnsseed.bluematt.me", true); // Matt Corallo, only supports x9
vSeeds.emplace_back("dnsseed.bitcoin.dashjr.org", false); // Luke Dashjr
vSeeds.emplace_back("seed.bitcoinstats.com", true); // Christian Decker, supports x1 - xf
vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch", true); // Jonas Schnelli, only supports x1, x5, x9, and xd
vSeeds.emplace_back("seed.btc.petertodd.org", true); // Peter Todd, only supports x1, x5, x9, and xd
上面那一串域名一样的字符串就是DNS seed。
为了测试DNS seed的功能,可以直接使用下面两个命令尝试一下
nslookup DNS域名
dig DNS域名
使用dig命令的效果如下:
;; ANSWER SECTION:
dnsseed.bitcoin.dashjr.org. 3600 IN A 94.227.40.54
dnsseed.bitcoin.dashjr.org. 3600 IN A 93.230.1.90
dnsseed.bitcoin.dashjr.org. 3600 IN A 35.247.128.200
dnsseed.bitcoin.dashjr.org. 3600 IN A 88.198.40.131
dnsseed.bitcoin.dashjr.org. 3600 IN A 13.57.233.166
dnsseed.bitcoin.dashjr.org. 3600 IN A 96.231.141.105
dnsseed.bitcoin.dashjr.org. 3600 IN A 35.212.168.144
dnsseed.bitcoin.dashjr.org. 3600 IN A 188.165.207.50
dnsseed.bitcoin.dashjr.org. 3600 IN A 158.140.144.78
dnsseed.bitcoin.dashjr.org. 3600 IN A 34.86.217.40
dnsseed.bitcoin.dashjr.org. 3600 IN A 76.173.96.84
dnsseed.bitcoin.dashjr.org. 3600 IN A 71.198.208.72
dnsseed.bitcoin.dashjr.org. 3600 IN A 74.118.156.135
dnsseed.bitcoin.dashjr.org. 3600 IN A 43.249.29.188
dnsseed.bitcoin.dashjr.org. 3600 IN A 190.196.60.122
dnsseed.bitcoin.dashjr.org. 3600 IN A 91.65.247.112
dnsseed.bitcoin.dashjr.org. 3600 IN A 39.105.39.182
dnsseed.bitcoin.dashjr.org. 3600 IN A 51.15.166.138
dnsseed.bitcoin.dashjr.org. 3600 IN A 185.107.80.119
dnsseed.bitcoin.dashjr.org. 3600 IN A 61.77.235.17
dnsseed.bitcoin.dashjr.org. 3600 IN A 172.105.225.120
dnsseed.bitcoin.dashjr.org. 3600 IN A 86.190.7.125
dnsseed.bitcoin.dashjr.org. 3600 IN A 47.74.191.34
最后一个字段就是使用DNS可以解析到的IP地址
(2)使用自己保存的节点列表
除了使用DNS seed。比特币还会使用自己保存的peers列表,这个列表保存在数据库里面。
但是这种方式有个缺点,那就是这个列表里的节点有可能已经离线了。所以使用这种方式连接节点可能会产生一些延时。
为了平衡这种延时和尽可能少的使用DNS,比特币做了一个折中做法:
先用数据库里的节点尝试连接,如果11秒钟还没成功连上,就使用DNS seed。更多详情请参看比特币源码
/src/net.cpp
void CConnman::ThreadDNSAddressSeed()
为什么要尽可能少的使用DNS?比特币源码注释里有这么一段话
// goal: only query DNS seeds if address need is acute(紧急的)
// Avoiding DNS seeds when we don't need them improves user privacy by
// creating fewer identifying DNS requests, reduces trust by giving seeds
// less influence on the network topology, and reduces traffic to the seeds.
其实我觉得很重要的一点,就是使用DNS,会有中心化的问题。bitcoin为了去中心化,也想尽可能摆脱DNS。只在没有其他方法的情况下使用DNS。
这点我觉得很重要,能够看出比特币在处理问题上的一贯原则。其实按照道理来说,使用DNS是很好的一种发现节点的做法,甚至感觉更可靠稳定。但为了去中心化,把它作为最后的选项。
(全文完)