BFT Time

BFT Time is a Byzantine fault-tolerant algorithm for computing block times.

CometBFT v1.x introduced Proposer-Based Timestamps (PBTS), intended to be a replacement for BFT Time. Users are strongly encouraged to adopt the PBTS algorithm in new chains, or when upgrading existing chains, as the BFT Time algorithm MAY be deprecated in a future version of CometBFT.

Overview

BFT Time computes the Time of a block proposed in height H of consensus from the Timestamp field of the Precommit messages broadcast by validators in the commit Round of the previous height H-1.

In order to commit a block, a node needs to receive Precommit messages for the corresponding BlockID from validators whose cumulative voting power is more than 2/3 of the total voting power. The received Precommit messages should refer to the same round, the commit Round. A set of Precommit messages with the properties above mentioned is a Commit. A Commit set of height H is included in blocks proposed in height H+1.

BFT Time computes the Time field of a block proposed in height H deterministically from the LastCommit field of the block, which is a Commit set from height H-1, using the MedianTime method defined as follows:

The median of a set of values is one of the values of the set, so the Time of a proposed block is one of the Timestamp fields of the Precommit messages included in the LastCommit set of that block.

Example

Consider the following example:

Notice that, no matter what set of Precommit messages with at least 2/3 of the total voting power we choose, the MedianTime value will always be a value among the Timestamp values produced by correct validators. By correct here we assume non-malicious validators whose clocks are reasonably accurated with to time.

Operation

In order to implement BFT Time, validators need to set the Timestamp field of Precommit messages they sign and broadcast, and block proposers need to compute the block Time from the LastCommit set.

Vote Time

When producing a Precommit message, a validator should set the Timestamp field as follows:

  1. Let now be the clock time of the validator.
  2. If LockedBlock is defined, set Timestamp = max(now, LockedBlock.Time + 1ms).
  3. Else if ProposalBlock is defined, set Timestamp = max(now, ProposalBlock.Time + 1ms).
  4. Otherwise, set Timestamp = now.

The LockedBlock, if set, is the block for which the validator is issuing a Precommit. The ProposalBlock is the block proposed in that round; in favorable runs, it matches the LockedBlock.

The validator in practice proposes the Time for the next block when setting the Timestamp of its Precommit. The proposed Time is, by default, the validator’s current clock time. To ensure Time Monotonicity, the Time of the next block should be higher than the Time of the block to be committed in the current height. So if now is smaller than Time, the validator proposes the Time of the block to be committed plus a small delta, set to 1ms.

Proposed Time

The proposer of a round of consensus produces a block to be proposed. The proposed block must include a Commit set from the commit round of the previous height, as the block’s LastCommit field.

The Time for the proposed block is then set as Block.Time = MedianTime(block.LastCommit).

Since the block Time is produced in a deterministic way, every node that receives the proposed block, can validate Block.Time using the same procedure. Blocks with wrongly computed block times are rejected.

Properties

BFT Time guarantees the two main properties for block times:

Notice that the guarantees rely on the fact that the voting power owned by Byzantine validators is limited, more specifically, is less than 1/3 of the total voting power, which is also a requirement for the consensus algorithm.

Decorative Orb