1.1 比特币网络

1.1.1 比特币P2P网络穿透

比特币网络是典型的P2P网络,其NAT穿透使用upnp协议,详见Net.cpp部分代码:

#ifdef USE_UPNP
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/miniwget.h>
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/upnperrors.h>
#endif

1.1.2 比特币网络发现

比特币客户端节点第一次启动后,并不知道任何活动的节点IP地址,他们会查询写在比特币内核中硬编码的DNS服务名称(叫做DNS种子),这些DNS服务会回复给他们最新的活跃节点IP地址,建立新的连接。 DNS种子是由比特币维护社区成员:他们中的一些人提供动态DNS种子服务器通过扫描网络自动获得IP地址的活跃节点;其他人提供静态DNS种子,手动更新,更有可能为非活动节点的IP地址。在这两种情况下,节点被添加到DNS种子如果他们运行在默认的比特币端口mainnet 8333或testnet 8333。1
DNS seed:

seed.bitcoin.sipa.be
dnsseed.bluematt.me
dnsseed.bitcoin.dashjr.org
seed.bitcoinstats.com
seed.bitcoinstats.com
seed.btc.petertodd.org

详见Chainparams.cpp代码CMainParams类中的这些DNS sead:

// Note that of those with the service bits flag, most only support a subset of possible options
vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille, only supports x1, x5, x9, and xd
vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me", true)); // Matt Corallo, only supports x9
vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr
vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com", true)); // Christian Decker, supports x1 - xf
vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli, only supports x1, x5, x9, and xd
vSeeds.push_back(CDNSSeedData("petertodd.org", "seed.btc.petertodd.org", true)); // Peter Todd, only supports x1, x5, x9, and xd

除了DNS种子发现网络节点,还有其他的方法,详见Satoshi Client Node Discovery

  • IRC (Internet Relay Chat)互联网中继聊天
  • 自广播
  • 命令行添加

1.1.3 比特币与洋葱网络(Tor)

洋葱网络不是p2p的必备组件,在比特币中主要是为了实现网络匿名和防止窃听。

1.2 bitcoin初始化与启动

比特币程序总入口main()在bitcoind.cpp代码中2:

int main(int argc, char* argv[])
{
    //设置比特币客户端程序的本地运行环境
    SetupEnvironment();

    //链接消息处理
    noui_connect();

    //程序生命周期的消息循环
    return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
}

AppInit()函数:

  • 解析命令行参数
  • 打开数据库目录
  • 读取配置文件
  • 创建进程(如果是守护进程执行)
  • 初始化应用程序AppInitMain(),在init.cpp中

AppInitMain()函数:

  • 设置系统相关任务
  • 参数解析交互
  • 参数检查
  • 启动RPC服务
  • 验证钱包数据库完整性
  • 网络初始化
  • 加载区块链
  • 加载钱包
  • 维护数据目录
  • 导入块
  • 启动节点connman.Start(),在net.cpp
  • 完成

Connman类是CNode类的友类,CConnman::Start()函数:

  • 启动节点网络线程组
    • thread (ThreadGetMyExternalIP)
    • thread (ThreadMapPort)
    • thread (ThreadIRCSeed)
    • thread (ThreadSocketHandler)
    • thread (ThreadOpenConnections)
    • thread (ThreadMessageHandler)
  • ThreadRPCServer() 3

bitcoin协议说明