众所周知,Bitcoin是建立在p2p网络上的,但是具体的通信过程一直没有搞懂,所以特意去bitcoin的Developer Guid上去了解了一下。由于本人英文水平有限,理解难免有偏差的地方,希望大家多多指正。
参考网址:https://bitcoin.org/en/developer-guide#p2p-network
============================================================
关键字:
SPV: Simplified Payment Verification, A method for verifying if particular transactions are included in a block without downloading the entire block. The method is used by some lightweight Bitcoin clients, 例如比特币钱包节点.
BitcoinJ:
Bitcoin Core:
==============================================================
(1)p2p网络是一个overlay网络,依据特定的p2p协议构建在现有的物理网络之上,在Bitcoin中不是只有一层网络。
Consensus rules do not cover networking, so Bitcoin programs may use alternative networks and protocols, such as the high-speed block relay network used by some miners and the dedicated transaction information servers used by some wallets that provide SPV-level security.
ps: 所谓的high-speed block relay network 就是一些大型挖矿节点和交易平台之间传输消息的快速通道,专门给这些狗大户用的。 dedicated transaction information servers 就是给这些轻型客户端钱包节点用的,反正你又不挖矿,又不参与校验,没必要把不相关的交易传给你。说好的所有节点平等呢?
(2)不是所有的全节点都保留着所有的交易数据,全节点之间也有不同。
Full nodes download and verify every block and transaction prior to relaying them to other nodes. Archival nodes are full nodes which store the entire blockchain and can serve historical blocks to other nodes. Pruned nodes are full nodes which do not store the entire blockchain.
ps: Pruned nodes (阉割版全节点)能否挖矿?有待论证。
Peer Discovery
首先,无论在那种协议的网络中,通信的先决条件就是先找到对方。假设你是一个刚加入p2p网络中的新节点,人生地不熟的谁也不认识,你怎么去发现其他节点?又怎么让其他节点知道你?在Bitcoin的网络中,它是这样做的:
在Bitcoin 客户端 中硬编码进去几个DNS seeds的地址(跟传统的域名解析不一样,说白了就是节点地址索引服务器,而所谓的硬编码就是写死在代码里面),你能从这些种子节点获取其他节点的ip和端口,同时DNS seed 也会把你的地址记录进去。但总是从DNS seed中去获取地址访问压力太大,而且还存在着中间人攻击的危险,所以尽量避免从DNS seeds 去获取地址.
对于避免过度依赖DNS seeds,Bitcoin core 和 BitcoinJ 做法不同:
Bitcoin core: 由于在Bitcoin 的网络中 一个结点可以将自己的 peers list 发送给其他节点,这样就可以免去对与DNS的依赖。利用这一点,Bitcoin core以后每次启动的时候直接去链接这些节点就可以了,不用再次去DNS seed获取。Bitcoin core 为了避免因为对于DNS seed的依赖而造成问题会将已知的节点记录在peer list(存储在本地数据库中,不会因为节点重启而消失),在每次需要发送消息的时候,它会花费11s的时间尝试和peer list中的节点建立链接,如果有任何一个节点在超时之前可以链接上,就不用去DNS seed获取地址。
BitcoinJ:Bitcoin core 的方式虽然可以降低访问DNS seed的次数,但是peer list 的节点并不是时时刻刻都能访问的,它们可能因为网络故障无法通信,也可能因为地址变更而失效。如果你足够‘走运’,可能一个节点都链接不上而作无用功。这势必会给交易带来延迟,给用户很不好的体验。 专注于轻型钱包快捷支付的BitcoinJs为了避免延迟同时也为了避免中间人攻击 ,每次都会使用不同的DNS seed取获取当前运行的节点。
同时以上两种都会硬编码进去一些在版本发布期间长时间活跃而且稳定的节点地址(比如一些狗大户的),Bitcoin core 在DNS seed 60s内没有响应的时侯会尝试链接这些节点。
未完待续。