You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

42 lines
2.3 KiB

  1. # BFT time in Tendermint
  2. Tendermint provides a deterministic, Byzantine fault-tolerant, source of time.
  3. Time in Tendermint is defined with the Time field of the block header.
  4. It satisfies the following properties:
  5. - Time Monotonicity: Time is monotonically increasing, i.e., given
  6. a header H1 for height h1 and a header H2 for height `h2 = h1 + 1`, `H1.Time < H2.Time`.
  7. - Time Validity: Given a set of Commit votes that forms the `block.LastCommit` field, a range of
  8. valid values for the Time field of the block header is defined only by
  9. Precommit messages (from the LastCommit field) sent by correct processes, i.e.,
  10. a faulty process cannot arbitrarily increase the Time value.
  11. In the context of Tendermint, time is of type int64 and denotes UNIX time in milliseconds, i.e.,
  12. corresponds to the number of milliseconds since January 1, 1970. Before defining rules that need to be enforced by the
  13. Tendermint consensus protocol, so the properties above holds, we introduce the following definition:
  14. - median of a set of `Vote` messages is equal to the median of `Vote.Time` fields of the corresponding `Vote` messages
  15. We ensure Time Monotonicity and Time Validity properties by the following rules:
  16. - let rs denotes `RoundState` (consensus internal state) of some process. Then
  17. `rs.ProposalBlock.Header.Time == median(rs.LastCommit) &&
  18. rs.Proposal.Timestamp == rs.ProposalBlock.Header.Time`.
  19. - Furthermore, when creating the `vote` message, the following rules for determining `vote.Time` field should hold:
  20. - if `rs.Proposal` is defined then
  21. `vote.Time = max(rs.Proposal.Timestamp + 1, time.Now())`, where `time.Now()`
  22. denotes local Unix time in milliseconds.
  23. - if `rs.Proposal` is not defined and `rs.Votes` contains +2/3 of the corresponding vote messages (votes for the
  24. current height and round, and with the corresponding type (`Prevote` or `Precommit`)), then
  25. `vote.Time = max(median(getVotes(rs.Votes, vote.Height, vote.Round, vote.Type)), time.Now())`,
  26. where `getVotes` function returns the votes for particular `Height`, `Round` and `Type`.
  27. The second rule is relevant for the case when a process jumps to a higher round upon receiving +2/3 votes for a higher
  28. round, but the corresponding `Proposal` message for the higher round hasn't been received yet.