当前位置: 首页 > 工具软件 > bitcoin-pool > 使用案例 >

bitcoin-memorypool源码分析

唐增
2023-12-01

涉及的bip

  • bip68 交易输出会锁定一段时间不允许消费
  • bip125 如果mempool已经有相同交易输入的交易,具备更高手续费(小费)的新加入交易会替换掉旧的交易。

ctxmempoolentry

存储一个交易的相关信息和其他在mempool中与这个交易有关的祖先、后裔交易的数据。
每当有新的交易添加到mempool,都需要更新这个新交易的所有祖先交易的相关状态。

ctxmempool

存储那些对于the-current-best-chain有效且准备存储到下一个区块的交易。
网络上被见到(seen on the network)的交易(包括在本地节点创建的交易)都会添加到该mempool。除了:

  • 交易手续费不满足最低要求
  • mempool中已有相同交易输入的交易
  • 非标准交易

ctxmempool::mapTx 和 ctxmempoolentry

mapTx是一个 boost::multi_index,并会以四个标准去整理mempool(中的交易):

  • 交易hash
  • 后裔交易的税率,max(feerate of tx,feerate of tx with all descendants(in-mempool transactions that depend on this one))
  • 在mempool中的时间
  • 祖先交易的税率,min(feerate of tx, feerate of tx with all unconfirmed ancestors(in-mempool transactions that a given transaction depends on))

为了加速税率的排序整理,有一个mapLink来维护交易相关的祖先和后裔的集合。

通常情况下,当一个新的交易加入到mempool,它都不会有任何的子交易(类似这种情况的交易是孤儿交易orphan trx),所以在addUnchecked():

  • 更新 新交易的setMemPoolParents来包括所有in-mempool父母
  • 更新 新交易的父母来include该新交易作为儿子
  • 更新 新交易的祖先来以新交易的size和fee来更新他们自身的状态

当一个交易从mempool中剔除,会调用UpdateForRemoveFromMempool()来更新相关的状态:

  • 更新所有in-mempool父母交易不再跟踪该交易(setMempoolChildren)
  • 更新所有in-mempool祖先交易不再包括这个交易的size和fees(in descendant state)
  • 更新所有in-mempool儿子交易不再包括该交易(作为父母交易)

在把一个交易从mempool中剔除时,可能会引发连锁反应,所有的子交易都会成为孤儿交易而被一起剔除,此时就需要计算被移除的交易的集合,否则会产生一个不连续的mempool(也即正常的mempool,应该是一个连续的交易链集合)。

在重组(reorganization)事件中,新加入的交易不存在in-mempool子交易的假设是不成立的。特别地,在新交易加入时,mempool就已经是非连续状态,存在来自于disconnected block的后裔交易(linking交易也可能来自disconnected block,等待加入)。因此,就没有必要再通过addUnchecked来搜索in-mempool中的子交易。相应地,应该调用UpdateTransactionsFromBlock()来更新out-of-block后裔交易的状态(在该函数被调用之前,mempool的状态都是非连续,且mapLinks也是不正确的)。
所有的待再校验的交易(disconnected block trx)会等待重组事件结束以后才全部加入到mempool中,在重组过程中,不会将其加入到mempool中。

 类似资料: