跳转到正文
buybitcoinsmart

术语表 /节点与软件

清单(inventory)

又称清单、Inventory。

清单(inventory)是什么?
清单(inventory)是节点向其对等节点通告的对象标识符列表,用于说明该节点持有哪些交易和区块,而暂不发送其中任何一项。

先通告,再按需交付。这一模式使网络不至于被重复数据淹没:每个条目占36字节,即4字节的类型标签加32字节的哈希,单条 inv 消息最多可携带50,000个条目。已经持有该对象的对等节点不会再请求它,这部分带宽也就不会被消耗。

运作方式

清单条目是一个数对:一个说明对象类型的数字,以及标识该对象的哈希。

类型代码是较小的整数。1表示交易,2表示区块,3表示旧版布隆过滤器方案中的过滤区块,4表示紧凑区块,5表示以见证哈希标识的交易。在类型值之上设置0x40000000 位,即标记携带见证数据的变体,因此支持 segwit 的对等节点会请求 MSG_WITNESS_BLOCK,而较旧的节点则会请求普通区块。

这一交互分三步进行。节点发送 inv,列出新增的内容。对等节点扫描该列表,忽略所有已识别的条目,并以 getdata 作答,只列出自己缺少的内容。节点随后发送这些对象,每个对象一条消息;如果某个对象此后已被丢弃,则回复 notfound。50,000这一上限背后的算术值得留意:50,000个条目乘以每条36字节为1,800,000字节,完全在单条消息4,000,000字节的上限之内,而 Bitcoin Core 中有一条编译期断言,使这两个常量保持相互一致。

时间安排是一项隐私控制,而不是实现层面的细节。Bitcoin Core 不会在获知一笔交易的瞬间就立即通告它。通告会被分批,并按随机计时器释放,对出站对等节点平均为2秒,对入站对等节点平均为5秒,因此连接着许多节点的观察者无法借助到达顺序推断一笔付款从何处发起。区块则完全跳过这一延迟,因为没有什么需要隐藏,而几秒钟就意味着金钱。

向每个对等节点喊出每一个哈希代价高昂,Erlay 是提出的解决办法:对等节点定期对账彼此所持内容的简短摘要(sketch),而不是向各个方向泛洪标识符。

在哪里会遇到它

清单是节点网络接口上最嘈杂、也最容易观察到的内容。

getpeerinfo 调用按消息类型列出流量明细,inv 几乎总是计数最大的几项之一。连接良好的节点会把相当一部分带宽用于通告最终无人需要的哈希。这也是一笔付款会先在某个区块浏览器上出现、数秒后才出现在另一个浏览器上的原因:它们是各自独立的观察者,从网络的不同位置听到各自不同的通告。

有一个值得改掉的习惯:inv 并不是承诺。节点可以通告一笔交易,几分钟后在内存池已满时将其逐出,而且无须向任何人更正。

清单 vs 内存池

清单是一条消息;内存池是一个存储,两者中只有一个会在当下之后继续存在。inv 告诉对等节点某个哈希存在于某处。内存池则是节点已实际验证、保存在内存中并愿意转发或挖入区块的未确认交易的集合,默认大小为300 MB,淘汰策略是先丢弃费率最低的交易。观察您的 txid 通过 inv 通告传播,只能说明网络听说了您的这笔付款,并不能说明一小时后是否还有人持有它。

请勿混淆

常见问题

我的交易出现在 inv 通告中,是否意味着它会被确认?

不是。inv 只说明某个节点听说过这笔交易,仅此而已。该节点可能在几分钟后内存池已满时将其丢弃,也没有任何矿工必须将其打包,因此只有确认才能最终定论。

为什么我的节点在通告交易之前会有延迟?

出于隐私考虑。Bitcoin Core 按随机计时器分批发送交易通告,对出站对等节点平均为2秒,对入站对等节点平均为5秒,因此连接着许多节点的观察者无法借助到达顺序判断一笔付款源自何处。

相关术语

节点与软件中的更多术语

阅读本页英文版