比特币内存池交易为何要数祖先和后代:ancestor与descendant字段怎么读

查一笔未确认比特币交易的详情时,ancestorcount和descendantcount统计的是这笔交易在内存池中与其他未确认交易形成的依赖关系:前者是它在内存池内通过输入引用向上追溯到的未确认祖先交易数量,后者是依赖它、花费其输出的未确认后代交易数量。依据 Bitcoin Core 的 getmempoolentry 接口文档,两个数字都包含这笔交易自身——文档对 ancestorcount 的说明是“in-mempool ancestor transactions(including this one)”,对 descendantcount 是“in-mempool descendant transactions(including this one)”。因此一笔既无未确认前序、也无未确认后续的交易,这两个字段都显示为 1,而不是 0。需要留意的是,已确认的祖先不计入内存池统计。

祖先交易、后代交易、内存池
本文涉及的概念与核对环节。

要理解这两个计数,先要理解内存池里的“家族关系”。比特币交易的输入必须引用此前某笔交易的输出。如果被引用的那笔交易尚未被打包进区块,它就先停留在内存池中,新交易便与它形成了未确认的父子关系。getmempoolentry 返回结果中的 depends 数组列出“被本交易用作输入的未确认交易”,即父交易;spentby 数组列出“花费本交易输出的未确认交易”,即子交易。沿 depends 方向往上追溯,所有未确认的前序交易都是祖先;沿 spentby 方向往下延伸,所有未确认的后续交易都是后代。一笔交易之所以会“牵连”其他未确认交易,正是因为它与它们通过输入输出引用串在同一条未确认链条上。

与计数配套的还有体积和费用字段,读法同样以“包含自身”为口径。ancestorsize 是这笔交易及其全部内存池祖先的虚拟交易大小(vsize,按 BIP 141 定义,见证数据享受折扣),descendantsize 是这笔交易及其全部内存池后代的虚拟大小。费用方面,返回对象中的 fees.ancestor 和 fees.descendant 分别给出祖先集合与后代集合的 modified fees 总额,同样包含本交易;文档中单独的 ancestorfees、descendantfees 字段已被标记为 DEPRECATED,新代码应读取 fees 对象内的对应值。这些字段描述的都是内存池内的统计口径,接口本身并不涉及交易何时被打包进区块。

这些数字的用途在于表达交易在内存池中的家族规模。Bitcoin Core 的内存池策略会对交易家族规模设限,具体上限以对应版本策略为准;一条链上的祖先或后代越多、体积越大,就越接近这一边界。因此,查看一笔交易的 ancestorcount 与 descendantcount,可以判断它处在多长的未确认链条中、牵动多少笔其他交易。作为一般性说明,这些字段只反映本节点内存池的当前状态,不同节点因接收顺序和策略差异,统计结果可能不同。

举例来说(以下为说明性假设,非真实交易):若交易 C 花费了未确认交易 B 的输出,而 B 又花费了未确认交易 A 的输出,且 A 已确认,那么对 C 调用 getmempoolentry,其 depends 会列出 B,ancestorcount 为 2(B 与 C 自身),descendantcount 为 1(仅 C 自身);对 B 而言,ancestorcount 为 1(仅自身,因为 A 已确认不在内存池),descendantcount 为 2(B 与 C)。若此后又有交易 D 花费 C 的输出,C 的 descendantcount 变为 2,B 的则变为 3。可见同一家族中不同位置的交易,读出的祖先与后代数量并不相同,判断某笔交易的影响范围时,应以该交易自身返回的字段为准。

原始资料

developer.bitcoin.org

上一篇 币安行情里聚合成交与原始成交有何区别,该看哪个