Control Messages
以下网络消息都有助于控制两个peer之间的连接,允许他们相互通知其他网络。
请注意:几乎没有任何控制消息以任何方式进行身份验证,这意味着它们可能包含不正确的或故意制造的有害信息。 此外,本节还未涵盖Tor网络上的P2P协议操作; 如果您想提供有关Tor的信息,请 open an issue。
Addr
addr
(IP地址)消息传达网络上peers的连接信息。 每个想要接受传入连接的peer创建一个addr
消息,提供其连接信息,然后将该消息发送给未经请求的peers。 它的一些peers将这些信息发送给他们的peers(也是未经请求的),其中一些peer将进一步分发,对已经在网络上的任何程序允许peer被分散的发现(Some of its peers send that information to their peers (also unsolicited), some of which further distribute it, allowing decentralized peerdiscovery for any program already on the network。
addr
消息也可以被发送以响应getaddr
消息。
Bytes | Name | Data Type | Description |
---|---|---|---|
Varies | IP address count | compactSize uint | IP地址条目的数量最多可达1,000个。 |
Varies | IP addresses | network IP addresses | IP地址条目。比特币网络IP地址的格式见下表。 |
每个封装的网络IP地址目前使用以下结构:
Bytes | Name | Data Type | Description |
---|---|---|---|
4 | time | uint32 | 在协议版本31402中添加。时间格式采用Unix纪元的时间。 通告自己IP地址的节点会将其设置为当前时间。 通告他们连接的IP地址的节点将其设置为最后一次连接到该节点的时间。 其他只是传达IP地址的节点不应改变时间。 节点可以使用时间字段来避免传送旧的地址信息。 |
8 | services | uint64_t | 节点在其版本消息中公布的服务。 |
16 | IP address | char | IPv6地址采用大端字节顺序。 IPv4地址可以作为IPv4映射的IPv6地址提供 |
2 | port | uint16_t | 端口号以大端字节顺序排列。 请注意,Bitcoin Core 只会连接到具有非标准端口号的节点,作为寻找peers的最后手段。 这是为了防止任何人尝试使用网络来破坏在其他端口上运行的非比特币服务。 |
以下带注释的hexdump显示了addr
消息的一部分。 (消息头已被省略,实际IP地址已被RFC5737保留的IP地址替代。)
fde803 ............................. Address count: 1000
d91f4854 ........................... Epoch time: 1414012889
0100000000000000 ................... Service bits: 01 (network node)
00000000000000000000ffffc0000233 ... IP Address: ::ffff:192.0.2.51
208d ............................... Port: 8333
[...] .............................. (999 more addresses omitted)
Alert
在协议版本311中添加。在协议版本70013中删除,并在Bitcoin Core 0.13.0中发布。
传统的p2p网络警报消息系统已经停用;但是,内部警报,分区检测警告和-alertnotify选项功能仍然存在。有关详细信息,请参阅Alert System Retirement。
FeeFilter
如BIP133所述,在协议版本70013中添加。
feefilter
消息是对接收方的请求,如果交易费率低于feefilter
消息中指定的费率,就不会将任何交易inv
消息发送到发送方。
在 Bitcoin Core 0.12.0 引入mempool限制之后,feefilter
在Bitcoin Core 0.13.0中引入。 feefilter
消息允许一个节点通知它的同伴它不会接受低于指定费率的交易进入它的mempool,因此这些peers可以直接将低于该费率的交易的inv
消息跳过。
Bytes | Name | Data Type | Description |
---|---|---|---|
8 | feerate | uint64_t | 费用率(以每千字节为单位)低于该费率,交易不应传递给该peer。 |
接收方可以选择忽略该消息而不过滤交易inv消息。
fee filter 与bloom过滤器相加。如果SPV客户端加载bloom filter并发送feefilter消息,则只有通过两个过滤器才能发送交易。
但请注意,feefilter对块的传播或对getdata消息的响应没有影响。 例如,如果一个节点通过发送一个包含inv类型MSG_FILTERED_BLOCK
的getdata
消息来请求一个merkleblock
,并且它先前已经向该peer发送了一个feefilter,那么peer应该响应一个包含所有匹配bloom过滤器的交易的merkleblock,即使他们低于feefilter费率。
如果存在,则从mempool消息生成的inv消息将受到feefilter的限制。
下面带注释的hexdump显示了一个feefilter消息。 (消息头已被省略。)
7cbd000000000000 ... satoshis per kilobyte: 48,508
FilterAdd
如BIP37所述,在协议版本70001中添加。
filteradd
消息告诉接收方将单个元素添加到先前设置的bloom filter,例如新的public key。 该元素直接发送给接收方; peer然后使用在filter加载消息中设置的参数来将该元素添加到bloom filter。
由于该元素直接发送到接收方,因此不存在对元素的混淆,也不存在由bloom filter提供的似是而非的隐私。 希望保持更高隐私性的客户端应自行重新计算bloom filter,并使用重新计算的bloom filter发送新的filterload
消息。
Bytes | Name | Data Type | Description |
---|---|---|---|
Varies | element bytes | compactSize uint | 下列元素字段中的字节数。 |
Varies | element | uint8_t[] | 要添加到当前过滤器的元素。 最大为520个字节,这是在pubkey或签名脚本中可以压入堆栈的元素的最大大小。 元素必须以它们在原始交易中出现时使用的字节顺序发送; 例如:hash应以内部字节顺序发送。 |
注意:除非先前使用filterload
消息设置了过滤器,否则将不接受filteradd
消息。
下面带注释的hexdump显示了添加TXID的filteradd
消息。 (消息头已被省略。)该TXID出现在merkleblock
消息中用于示例hexdump的同一个块中; 如果该merkleblock
消息在发送此filteradd
消息后重新发送,则会返回六个hash而不是四个hash。
20 ................................. Element bytes: 32
fdacf9b3eb077412e7a968d2e4f11b9a
9dee312d666187ed77ee7d26af16cb0b ... Element (A TXID)
FilterClear
如BIP37所述,在协议版本70001中添加。
filterclear
消息告诉接收方删除先前设置的bloom filter。这也消除了将version
消息中的relay字段设置为0的效果,允许未过滤的访问宣布新交易的inv
消息。
Bitcoin Core在替换过滤器加载filterload
之前不需要filterclear
消息。它也不需要filterclear
消息之前的filterload
消息。
filterclear消息中没有有效负载。
FilterLoad
如BIP37所述,在协议版本70001中添加。
filterload
消息告诉接收方过滤所有 relayed 的交易,并通过提供的过滤器请求merkle块。 这允许客户接收与其钱包相关的交易,以及可提供合理可否认隐私的可配置假阳性交易率。
Bytes | Name | Data type | Description |
---|---|---|---|
Varies | nFilterBytes | compactSize uint | 以下过滤器位字段中的字节数。 |
Varies | filter | uint8_t[] | 任意字节对齐大小的位字段。最大大小是36,000字节。 |
4 | nHashFuncs | uint32_t | 在此过滤器中使用的hash函数的数量。该字段中允许的最大值为50。 |
4 | nTweak | uint32_t | 一个任意值,用于添加到布隆过滤器使用的hash函数中的种子值。 |
1 | nFlags | uint8_t | 一组控制与匹配的pubkey脚本相对应的outpoint的标志被添加到过滤器中。请参阅下面的更新布隆过滤器小节中的表格。 |
nFlags字段有三个允许值:
Value | Name | Description |
---|---|---|
0 | BLOOM_UPDATE_NONE | 过滤节点不应更新过滤器。 |
1 | BLOOM_UPDATE_ALL | 如果过滤器匹配pubkey脚本中的任何数据元素,则将相应的outpoint添加到过滤器。 |
2 | BLOOM_UPDATE_P2PUBKEY_ONLY | 如果过滤器匹配pubkey脚本中的任何数据元素,并且该脚本是P2PKH或非P2SH付费多重脚本,则相应的outpoint将添加到过滤器中。 |
下面带注释的hexdump显示了一个filterload消息。 (消息头已被省略。)有关如何创建此有效内容的示例,请参阅filterload示例。
02 ......... Filter bytes: 2
b50f ....... Filter: 1010 1101 1111 0000
0b000000 ... nHashFuncs: 11
00000000 ... nTweak: 0/none
00 ......... nFlags: BLOOM_UPDATE_NONE
GetAddr
getaddr
消息请求来自接收节点的addr
消息,最好是具有大量其他接收节点的IP地址的消息。 发送节点可以使用这些IP地址来快速更新其可用节点的数据库,而不是等待未经请求的addr
消息随时间到达。
getaddr
消息中没有payload。
Ping
ping
消息有助于确认接收方仍处于连接状态。 如果在发送ping
消息时遇到TCP / IP错误(例如连接超时),则发送节点可以假设接收节点已断开连接。 对ping
消息的响应是pong
消息。
在协议版本60000之前,ping
消息没有payload。从协议版本60001及所有更高版本开始,消息包含一个字段即nonce。
Bytes | Name | Data Type | Description |
---|---|---|---|
8 | nonce | uint64_t | 如BIP31所述,在协议版本60001中添加。随机的将此随机数分配给此ping 消息。响应pong 消息将包含此随机数以识别它正在回复的ping 消息。 |
下面带注释的hexdump显示了一条ping
消息。 (消息头已被省略。)
0094102111e2af4d ... Nonce
Pong
如BIP31所述,在协议版本60001中添加。
pong
消息回复ping
消息,向ping节点证明ponging节点仍然存在。默认情况下,Bitcoin Core将在20分钟内断开任何未响应ping
消息的客户端。
为了允许节点跟踪等待时间,pong
消息发回与它正在回复的ping
消息相同的nonce。
pong
消息的格式与ping
消息相同;只有消息的header不同。
Reject
如BIP61所述,在协议版本70002中添加。
reject
消息通知接收节点其先前消息之一已被拒绝。
Bytes | Name | Data type | Description |
---|---|---|---|
Varies | message bytes | compactSize uint | 以下消息字段中的字节数。 |
Varies | message | string | 被拒绝的消息类型为不带空填充的ASCII文本。例如:“tx”,“block”或“version”。 |
1 | code | char | 拒绝消息代码。见下表。 |
Varies | reason bytes | compactSize uint | 以下原因字段中的字节数。如果未提供文本原因,则可能为0x00。 |
Varies | reason | string | 在ASCII文本中被拒绝的原因。这不应该显示给用户;它仅用于调试目的。 |
Varies | extra data | varies | 随拒绝提供的可选附加数据。例如,大多数tx消息或block消息的拒绝包括被拒绝的交易或block header的hash。请参阅下面的代码表。 |
下表列出了消息拒绝代码。代码与他们回复的消息类型相关联;例如,对于交易有一个0x10拒绝代码,对于block有一个0x10拒绝代码。
Code | In Reply To | Extra Bytes | Extra Type | Description |
---|---|---|---|---|
0x01 | any message | 0 | N/A | 消息无法解码。要小心拒绝消息反馈循环,其中两个peers各自都不理解对方的拒绝消息,因此请永远将它们来回发送。 |
0x10 | block message |
32 | char[32] | 由于某种原因,阻止无效(无效的工作证明,无效签名等)。额外的数据可能包括被拒绝块的header hash。 |
0x10 | tx message |
32 | char[32] | 交易由于某种原因无效(签名无效,输出值大于输入等)。额外的数据可能包括被拒绝的交易的TXID。 |
0x11 | block message |
32 | char[32] | 该块使用不再受支持的版本。额外的数据可能包括被拒绝块的header hash。 |
0x11 | version message |
0 | N/A | 连接节点正在使用拒绝节点认为过时且不受支持的协议版本。 |
0x12 | tx message |
32 | char[32] | 重复输入支出(双重支出):被拒绝的交易花费与先前接收的交易相同的输入。额外的数据可能包括被拒绝的交易的TXID。 |
0x12 | version message |
0 | N/A | 在此连接中收到多个version 消息。 |
0x40 | tx message |
32 | char[32] | 交易没有被打包或发送,因为拒绝节点认为它是非标准的 - 服务器未知的交易类型或版本。额外的数据可能包括被拒绝的交易的TXID。 |
0x41 | tx message |
32 | char[32] | 一个或多个输出量低于灰尘(dust)的阈值。额外的数据可能包括被拒绝的交易的TXID。 |
0x42 | tx message |
char[32] | 该交易没有足够的费用或优先权进行发送或打包。额外的数据可能包括被拒绝的交易的TXID。 | |
0x43 | block message |
32 | char[32] | 该块属于一个块链,与编译检查点提供的块链不同。额外的数据可能包括被拒绝块的header hash。 |
下面带注释的hexdump显示拒绝消息。 (消息头已被省略。)
02 ................................. Number of bytes in message: 2
7478 ............................... Type of message rejected: tx
12 ................................. Reject code: 0x12 (duplicate)
15 ................................. Number of bytes in reason: 21
6261642d74786e732d696e707574732d
7370656e74 ......................... Reason: bad-txns-inputs-spent
394715fcab51093be7bfca5a31005972
947baf86a31017939575fb2354222821 ... TXID
SendHeaders
sendheaders
消息告诉接收方使用headers
消息而不是inv
消息来发送新的块通告。
sendheaders
消息中没有payload。
VerAck
在协议版本209中添加。
verack
消息确认先前收到的version
消息,通知连接节点它可以开始发送其他消息。 verack
消息没有payload;
Version
version
消息在连接开始时向接收节点提供关于发送节点的信息。在两个peer交换version
消息之前,不会接受其他消息。
如果 version
消息被接受,接收节点应该发送一个verack
消息 - 但是在通过首先发送version
消息初始化它的一半连接之前,没有节点应该发送verack
消息。
Bytes | Name | Data Type | Required/Optional | Description |
---|---|---|---|---|
4 | version | int32_t | Required | 发送节点可以理解的最高协议版本。请参阅协议版本部分。 |
8 | services | uint64_t | Required | 传输节点支持的服务编码为一个位域。请参阅下面的服务代码列表。 |
8 | timestamp | int64_t | Required | 根据发送节点的时钟,当前Unix纪元时间。由于节点将在未来超过两个小时的时间内拒绝时间戳,因此该字段可帮助其他节点确定其时钟错误。 |
8 | addr_recv services | uint64_t | Required | 发送节点感知的接收节点支持的服务。与上面“服务”字段的格式相同。Bitcoin Core将尝试提供准确的信息。 BitcoinJ将默认发送0 |
16 | addr_recv IP address | char | Required | 发送节点以大端字节顺序感知的接收节点的IPv6地址。 IPv4地址可以作为IPv4映射的IPv6地址提供。 Bitcoin Core将尝试提供准确的信息。 默认情况下,BitcoinJ将始终返回:: ffff:127.0.0.1 |
2 | addr_recv port | uint16_t | Required | 发送节点以大端字节顺序感知的接收节点的端口号。 |
8 | addr_trans services | uint64_t | Required | 在协议版本106中添加。发送节点支持的服务。应该与上面的'服务'字段相同。 |
16 | addr_trans IP address | char | Required | 在协议版本106中添加。传输节点的IPv6地址采用大端字节顺序。 IPv4地址可以作为IPv4映射的IPv6地址提供。 如果未知,则设置为:: ffff:127.0.0.1。 |
2 | addr_trans port | uint16_t | Required | 在协议版本106中添加。传输节点的端口号采用大端字节顺序。 |
8 | nonce | uint64_t | Required | 在协议版本106中添加。将随机数随机,可以帮助节点检测与自身的连接。如果nonce为0,则nonce字段将被忽略。如果nonce是其他内容,则节点应在收到以前发送的随机数的版本消息后终止连接。 |
Varies | user_agent bytes | compactSize uint | Required | 在协议版本106中添加。下面的user_agent字段中的字节数。如果是0x00,则不发送用户代理字段。 |
Varies | user_agent | string | Required if user_agent bytes > 0 | 在协议版本106中添加。在协议版本60000中重命名。用户代理由BIP14定义。以前称为subVer。 |
4 | start_height | int32_t | Required | 在协议版本209中添加。发送节点的最佳块链的高度,或者在SPV客户端的情况下,最佳块链的高度。 |
1 | relay | bool | Optional | 如BIP37所述,在协议版本70001中添加。交易relay的flag。 如果为0x00,则在filterload 消息或filterclear 消息之前,不应将发送新消息的inv 消息或t x消息发送给此客户机。 如果relay字段不存在或设置为0x01,则此节点需要inv 消息和tx 消息通告新的交易。 |
以下服务标识符已被分配。
Value | Name | Description |
---|---|---|
0x00 | Unnamed | 这个节点不是一个完整的节点。除了它所发生的交易之外,它可能无法提供任何数据。 |
0x01 | NODE_NETWORK | 这是一个完整的节点,可以询问完整的块。它应该实现其自我报告协议版本中可用的所有协议功能。 |
以下带注释的十六进制转储显示版本消息。 (消息头已被省略,实际IP地址已被RFC5737保留的IP地址替代。)
72110100 ........................... Protocol version: 70002
0100000000000000 ................... Services: NODE_NETWORK
bc8f5e5400000000 ................... Epoch time: 1415483324
0100000000000000 ................... Receiving node's services
00000000000000000000ffffc61b6409 ... Receiving node's IPv6 address
208d ............................... Receiving node's port number
0100000000000000 ................... Transmitting node's services
00000000000000000000ffffcb0071c0 ... Transmitting node's IPv6 address
208d ............................... Transmitting node's port number
128035cbc97953f8 ................... Nonce
0f ................................. Bytes in user agent string: 15
2f5361746f7368693a302e392e332f ..... User agent: /Satoshi:0.9.3/
cf050500 ........................... Start height: 329167
01 ................................. Relay flag: true
家境清寒,整理不易。