一个区块由区块头、交易、投票(即 commit)以及恶意行为证据列表(例如对冲突投票进行签名)组成。 待处理的证据项优先级高于 mempool 中待处理的交易。 总之,区块大小必须不能超过 ConsensusParams.Block.MaxBytes,如果 ConsensusParams.Block.MaxBytes == -1,则上限为 100MB。

从 mempool 中收割交易

当我们从 mempool 中收割交易时,会通过减去最大区块头大小(MaxHeaderBytes)、区块的最大 protobuf 开销(MaxOverheadForBlock)、上一轮 commit 的大小(如果存在)以及证据大小(如果存在),来计算最大数据大小。在收割过程中,我们还会计入每笔交易各自的 protobuf 开销。
func MaxDataBytes(maxBytes, evidenceBytes int64, valsCount int) int64 {
  return maxBytes -
  MaxOverheadForBlock -
  MaxHeaderBytes -
  MaxCommitBytes(valsCount) -
  evidenceBytes
}
如果 ConsensusParams.Block.MaxBytes == -1,我们会从 mempool 中收割所有待处理交易。

准备提案

按照上述规则从 mempool 收割交易后,CometBFT 会调用应用的 PrepareProposal,并传入刚刚收割得到的交易列表。 作为这次调用的一部分,应用可以删除、新增或重排交易列表中的交易。 RequestPrepareProposal 包含两个重要字段:
  • MaxTxBytes:其值为上文所述 MaxDataBytes 的返回值。 应用返回的交易列表大小必须不能超过这个数值。
  • Txs:包含已收割的交易列表。
有关 PrepareProposal 的更多细节,请参阅规范中的相关部分

验证 mempool 中的交易

在我们接受一笔交易进入 mempool 之前,会检查其大小是否不超过 。 的计算公式与上文相同,只是这里假设不存在任何证据。
func MaxDataBytesNoEvidence(maxBytes int64, valsCount int) int64 {
  return maxBytes -
    MaxOverheadForBlock -
    MaxHeaderBytes -
    MaxCommitBytes(valsCount)
}

A block consists of a header, transactions, votes (the commit), and a list of evidence of malfeasance (eg. signing conflicting votes). Outstanding evidence items get priority over outstanding transactions in the mempool. All in all, the block MUST NOT exceed ConsensusParams.Block.MaxBytes, or 100MB if ConsensusParams.Block.MaxBytes == -1.

Reaping transactions from the mempool

When we reap transactions from the mempool, we calculate maximum data size by subtracting maximum header size (MaxHeaderBytes), the maximum protobuf overhead for a block (MaxOverheadForBlock), the size of the last commit (if present) and evidence (if present). While reaping we account for protobuf overhead for each transaction.
func MaxDataBytes(maxBytes, evidenceBytes int64, valsCount int) int64 {
  return maxBytes -
  MaxOverheadForBlock -
  MaxHeaderBytes -
  MaxCommitBytes(valsCount) -
  evidenceBytes
}
If ConsensusParams.Block.MaxBytes == -1, we reap all outstanding transactions from the mempool

Preparing the proposal

Once the transactions have been reaped from the mempool according to the rules described above, CometBFT calls PrepareProposal to the application with the transaction list that has just been reaped. As part of this call the application can remove, add, or reorder transactions in the transaction list. The RequestPrepareProposal contains two important fields:
  • MaxTxBytes, which contains the value returned by MaxDataBytes described above. The application MUST NOT return a list of transactions whose size exceeds this number.
  • Txs, which contains the list of reaped transactions.
For more details on PrepareProposal, please see the relevant part of the spec

Validating transactions in the mempool

Before we accept a transaction in the mempool, we check if its size is no more than . is calculated using the same formula as above, except we assume there is no evidence.
func MaxDataBytesNoEvidence(maxBytes int64, valsCount int) int64 {
  return maxBytes -
    MaxOverheadForBlock -
    MaxHeaderBytes -
    MaxCommitBytes(valsCount)
}