Skip to content

docs: ADR-115 predictable block times#2966

Merged
melekes merged 13 commits intomainfrom
2655-predictable-block-times
May 16, 2024
Merged

docs: ADR-115 predictable block times#2966
melekes merged 13 commits intomainfrom
2655-predictable-block-times

Conversation

@melekes
Copy link
Collaborator

@melekes melekes commented May 2, 2024

RENDERED

Refs #2655


PR checklist

  • Tests written/updated
  • Changelog entry added in .changelog (we use unclog to manage our changelog)
  • Updated relevant documentation (docs/ or spec/) and code comments
  • Title follows the Conventional Commits spec

@melekes melekes requested a review from a team as a code owner May 2, 2024 10:46
@melekes melekes requested a review from a team May 2, 2024 10:46
@adizere adizere linked an issue May 2, 2024 that may be closed by this pull request
@melekes melekes self-assigned this May 2, 2024
@ValarDragon
Copy link
Contributor

ValarDragon commented May 2, 2024

Making this a network parameter is great! I fully support doing that!

I actually think we can do one-step better as well though. Right now a block's time is roughly set by 4 steps
---------- Start time counting

  • Proposer(N+1) receives 2/3rd precommits for block N
  • Proposer Executes + Commits block N
  • Proposer waits Timeout_commit
  • Proposer builds block N + 1 and gossips it
  • 2 rounds of 2/3rds voting amongst validator set
  • Proposer(N+2) recieves 2/3rds precommits for block N+1
    ---------- Stop counting

Each of the steps could have variable delay for whatever reason. It would be nice if we made timeout_commit react to the time-since-last-block.

In PBTS, we could do this by saying, block N+1 proposer should wait max(true_minimum_timeout_commit, current_time - block N timestamp - expected_block_time).

And then we lower the true_minimum_timeout_commit to perhaps something like .5s by default, and have most networks parameterize around the expected block time. (which is the happy path for most networks, except the ones trying to shave down block times)

Copy link
Contributor

@tac0turtle tac0turtle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super glad to see this work taking shape. ❤️

@melekes
Copy link
Collaborator Author

melekes commented May 3, 2024

In PBTS, we could do this by saying, block N+1 proposer should wait max(true_minimum_timeout_commit, current_time - block N timestamp - expected_block_time).

What I like about the current proposal is that it doesn't restrict the ABCI dev in any way. There's no max(x, y), no min. The ABCI dev has access to all the info (I believe), so no one is stopping him/her from calculating max(true_minimum_timeout_commit, current_time - block N timestamp - expected_block_time) if he/she desires to do so.

@ValarDragon
Copy link
Contributor

ValarDragon commented May 3, 2024

Oh true, didnt think about that. That sounds great to me!

Copy link

@cason cason left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the ADR can be extended/reworded as follows:

  1. The problem description should make it more precise what we mean by predictable block times. If I understand correctly, we want the medium-to-long term average block time to converge to a desired value. To achieve that, we need to define a form of minimum block time, but also be able to changing it dynamically. Namely, if a block takes longer than expected, we should be able to render the next block(s) faster in order to converge to the desired (average) block time.
  2. Properly define how timeout_commit works, at which extent it can be adopted to achieve the predictable block times goal, and what are its limitations. In addition to the one explained in the text (it is not a global parameter), we have the fact that it is static.
  3. There is a confusion in the text, that I assume also comes from the confusing in the operation of timeout_commit, between block time and the delay between committing a block and proposing the next block. And this is a main concern: we cannot precisely predict the consensus delay for a block, but we can establish a minimum duration for the processing step of a block, i.e., the time from which consensus decides it and the next consensus instance effectively starts.
  4. We need to make it clear that this approach is always best-effort, not only because delays are variable (by block size, by system size, by network conditions), but also because we have nodes that don't follow the protocol. By the way, running a validator node with a timeout_commit parameter that differs from the one defined for the network is a form of misbehavior.

`next_block_delay`. This field's semantics stays essentially the same: delay
between this block and the time when the next block is proposed.

If Comet goes into multiple rounds of consensus, the ABCI application can react
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if the application is aware of the commit round. In any case, different nodes may commit at different rounds.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

different nodes may commit at different rounds.

could you please explain?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A node can commit at round 0, other might decide the same block on block 1. This happens if part of the nodes don't see the precommits of round 0 timely and proceed to round 1.

The canonical commit, in fact, is the one observed by the proposer (for the previous block) and added to the proposed block.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if the application is aware of the commit round.

does the ABCI dev need it? They can simply use real time, no?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should use real time, in particular because the duration of rounds can be pretty variable.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the problem of real time is, of course, that different nodes will process a block at (slightly) different times.

Copy link
Collaborator

@sergio-mena sergio-mena May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have read up to here, so what I say here might be redundant with text below.
My impression is that most applications, in order to leverage this feature:

  • will need to use real --wallclock-- time (having Berachain's use case in mind, where you want to conform to regular wall-clock deadlines)
  • will mandate its nodes to have synchronized clocks (NTP, or other). This is not a big deal since we also require this for PBTS

Comment on lines +60 to +64
Move `timeout_commit` into `FinalizeBlockResponse` as `next_block_delay`. This
field's semantics stays essentially the same: delay between the time when the
current block is committed and the next height is started. The idea is
literally to have the same behavior as `timeout_commit`, while allowing the
application to pick a different value for each height.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, if I'm interpreting this correctly we've tried this here

in our network tests, everything worked as expected and we have very consistent block times. However when we shipped this to a testnet, we frequently failed to reach consensus.

replicating and debugging this issue by changing the clocks of the network instances is next on our list of todos after we switch network testing backends celestiaorg/celestia-core#1333

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for flagging this. We will keep this in mind when implementing this feature.

Copy link

@evan-forbes evan-forbes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm fwiw

Copy link
Collaborator

@sergio-mena sergio-mena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @melekes for this ADR!

I support this way of dealing with timeout_commit over the alternative that has been discussed internally in the past months: moving timeout_commit to ConsensusParams. Your solution is more versatile and powerful for apps and I believe the upgrade path can be made painless (unlike the "move timeout_commit to ConsensusParams" solution).

Comment on lines +52 to +53
`timeout_commit` dynamically (if such feature existed) to give the state
machine some extra time to finish execution.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a block takes a lot of time to execute, that time is expected to be roughly the same at all nodes (although there may be HW differences). So I don't clearly see how increasing timeout_commit in this case would help. While all nodes are executing a long block, the consensus algorithm stays blocked until FinalizeBlock returns.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. I copied this from tendermint/tendermint#5911 (comment). @ValarDragon @sunnya97 can you please clarify what you're hoping to archive in tendermint/tendermint#5911?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because timeout_commit encompasses the block execution.

So, faster nodes will start next height (proposing blocks or expecting for proposals) before slower nodes.

`next_block_delay`. This field's semantics stays essentially the same: delay
between this block and the time when the next block is proposed.

If Comet goes into multiple rounds of consensus, the ABCI application can react
Copy link
Collaborator

@sergio-mena sergio-mena May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have read up to here, so what I say here might be redundant with text below.
My impression is that most applications, in order to leverage this feature:

  • will need to use real --wallclock-- time (having Berachain's use case in mind, where you want to conform to regular wall-clock deadlines)
  • will mandate its nodes to have synchronized clocks (NTP, or other). This is not a big deal since we also require this for PBTS

melekes added a commit that referenced this pull request May 16, 2024
@melekes melekes added this pull request to the merge queue May 16, 2024
Merged via the queue into main with commit c812822 May 16, 2024
@melekes melekes deleted the 2655-predictable-block-times branch May 16, 2024 18:47
github-merge-queue bot pushed a commit that referenced this pull request May 21, 2024
as `next_block_delay`

ADR-115: #2966
Closes #2655 

---

#### PR checklist

- [ ] ~~Tests written/updated~~
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [x] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Sergio Mena <sergio@informal.systems>
teddyding pushed a commit to dydxprotocol/cometbft that referenced this pull request Jun 19, 2024
…bft#3089)

as `next_block_delay`

ADR-115: cometbft#2966
Closes cometbft#2655

---

- [ ] ~~Tests written/updated~~
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [x] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Sergio Mena <sergio@informal.systems>
teddyding pushed a commit to dydxprotocol/cometbft that referenced this pull request Jun 19, 2024
…bft#3089)

as `next_block_delay`

ADR-115: cometbft#2966
Closes cometbft#2655

---

- [ ] ~~Tests written/updated~~
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [x] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Sergio Mena <sergio@informal.systems>
melekes added a commit that referenced this pull request Dec 13, 2024
as `next_block_delay`

ADR-115: #2966
Closes #2655

---

- [ ] ~~Tests written/updated~~
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [x] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Sergio Mena <sergio@informal.systems>
hubcycle pushed a commit to 0xElder/cometbft that referenced this pull request Feb 14, 2025
…bft#3089)

as `next_block_delay`

ADR-115: cometbft#2966
Closes cometbft#2655

---

- [ ] ~~Tests written/updated~~
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [x] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Sergio Mena <sergio@informal.systems>
(cherry picked from commit 259793a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PBTS: Allow Application to Set BlockTimestamp

6 participants