程序员区块链

Bitcoin Core P2P网络层

2018-05-28  本文已影响42人  梁瀛渠

[TOC]

数据结构

在任意给定时刻,一个节点总是连接到多个其他节点。默认情况下,一个节点连接到8个其他节点(链出),并允许多达125个链入节点连接进来。

相关常量定义在net.h文件中。

节点集合则由全局变量vNodes维护。

CNode用于表示一个节点。

CNode包含许多属性,其中大部分属性都与底层链路(如套接字,字节流等)有关。

CNode的关键属性如下:

节点发现和节点连接

地址管理

地址管理器用于管理节点的IP地址和端口。(见addrman.h)

设计目标:

为此:

** 时间戳 **

地址管理器也要持续跟踪每个节点的最近活跃情况。时间戳仅在一个地址上更新,并且在时间戳超过20分钟时保存到数据库。 通过理解时间戳的作用,将更加清楚的理解为什么要保持时间戳。

节点发现

节点发现从链路层来讲,就是发现一个节点的IP地址和端口号。有多种方式:

节点连接

节点链接由线程ThreadOpenConnections管理。它负责选择可用的地址,建立链接并在适当的时候释放链接。

而inbound链接则由ThreadSocketHandler负责处理[ThreadMessageHandler]。

对于inbound链接,系统通过select执行IO操作。所以,其支持的inbound数量不会太多,目前,是125个。

插口(Sockets)和消息

Socket线程 (net.cpp)

消息线程

ProcessMessages (net_processing.cpp)

ProcessMessages是net_processing.cpp中的处理和验证交易和区块等相关代码代码的入口点,同时它也处理getaddr, addr等比特币协议相关的消息。该方法主要完成消息的复制并调用ProcessMessage处理消息。

ProcessMessage基本上是一个大型的“开关”,它根据消息类型[NetMsgType]来采取行动。

消息类型列表如下[protocol.cpp]:

namespace NetMsgType {
const char *VERSION="version";
const char *VERACK="verack";
const char *ADDR="addr";
const char *INV="inv";
const char *GETDATA="getdata";
const char *MERKLEBLOCK="merkleblock";
const char *GETBLOCKS="getblocks";
const char *GETHEADERS="getheaders";
const char *TX="tx";
const char *HEADERS="headers";
const char *BLOCK="block";
const char *GETADDR="getaddr";
const char *MEMPOOL="mempool";
const char *PING="ping";
const char *PONG="pong";
const char *NOTFOUND="notfound";
const char *FILTERLOAD="filterload";
const char *FILTERADD="filteradd";
const char *FILTERCLEAR="filterclear";
const char *REJECT="reject";
const char *SENDHEADERS="sendheaders";
const char *FEEFILTER="feefilter";
const char *SENDCMPCT="sendcmpct";
const char *CMPCTBLOCK="cmpctblock";
const char *GETBLOCKTXN="getblocktxn";
const char *BLOCKTXN="blocktxn";
}

SendMessages (main.cpp)

SendMessages创建消息并在peer的vSendMsg队列(双端队列或C ++中的“deque”)中对其进行排队。vSendMsg对象基本上只是序列化的数据。

Locks

P2P层主要的锁有:

拒绝服务的防范措施

一旦发现异常行为的节点,则直接ban掉。

DoS预防框架在2011年引入。

具体见:https://github.com/bitcoin/bitcoin/pull/517

** 被禁节点 **

被禁节点存储在setBanned中。setBanned是map类型的数据结构,定义为typedef std::map<CSubNet, CBanEntry> banmap_t

默认情况下,一个节点被禁止24小时,但可以使用-bantime选项进行配置。

上一篇下一篇

猜你喜欢

热点阅读