Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mempool Rechecking all txs blocks consensus #2925

Open
ValarDragon opened this issue Apr 29, 2024 · 8 comments · May be fixed by #3115
Open

Mempool Rechecking all txs blocks consensus #2925

ValarDragon opened this issue Apr 29, 2024 · 8 comments · May be fixed by #3115
Labels
enhancement New feature or request mempool

Comments

@ValarDragon
Copy link
Collaborator

ValarDragon commented Apr 29, 2024

Feature Request

Summary

Rechecking all txs in the mempool seems to block consensus. We see this from:

  • How pprof's look
  • How the code appears

This is problematic as it means larger mempools will delay consensus longer. (Also IBC has a change that creeped in that is causing overly large expenses in RecheckTx)

Here is a copy of a pprof from a live-syncing Osmosis full node during 1 hour, with relatively average tx volume:
image

We see that it blocks Commit right here: https://github.com/cometbft/cometbft/blob/main/state/execution.go#L419-L426

If you look into the relevant code, each recheck call is actually synchronous due to how the callback's are structured.

Problem Definition

We should make the mempool rechecking not block BlockExecutor.ApplyBlock.

Ideally it should only be blocking ProposeBlock until either everything in the mempool is rechecked or blockGas worth of txs are rechecked. It should never be blocking for timeout_prevote

@ValarDragon ValarDragon added enhancement New feature or request needs-triage This issue/PR has not yet been triaged by the team. labels Apr 29, 2024
@andynog andynog added mempool and removed needs-triage This issue/PR has not yet been triaged by the team. labels Apr 29, 2024
@andynog
Copy link
Contributor

andynog commented Apr 29, 2024

There are some refactoring on the re-checking logic happened in this PR #2268, maybe this will not solve the problem from the perspective @ValarDragon reported but just adding here for visibility. @hvanz might have a better opinion in this case.

The mempool recheck can also be controlled with a configuration parameter
https://docs.cometbft.com/v1.0/references/config/config.toml#mempoolrecheck

@hvanz
Copy link
Member

hvanz commented May 1, 2024

Thanks @ValarDragon for reporting this problem! I agree that rechecking should not block consensus, though it will still need to block the mempool for checking new incoming transactions. This is for not breaking the FIFO ordering when rechecking txs.

Currently BlockExecutor.Commit calls mempool.Lock, mempool.FlushAppConn, mempool.Update and mempool.Unlock. It is the only function that calls these mempool methods. We have it in our list to refactor these calls to make the mempool code cleaner and more modular. We'll keep into account the problem you report when addressing the refactoring.

@hvanz
Copy link
Member

hvanz commented May 1, 2024

Also, #2268 is about a corner case in the rechecking logic, not related to current issue.

@ValarDragon
Copy link
Collaborator Author

ValarDragon commented May 2, 2024

I think what we should do here is:

  • Maintain statistics via Atomic instructions in the mempool for "how many bytes", "how many gas" is rechecked, and "are we done rechecking"
  • Always run Update asynchronously. (Mempool updating should not block any consensus timeouts)
    • Update returns once the trackers are rechecked, and the recheck goroutine is started
  • Make the Reap function poll/block until oneof:
    • "We are done rechecking" = true
    • "how many bytes rechecked" < Reap Bytes limit
    • "How much gas is rechecked" < Reap gas limit

@cason
Copy link
Contributor

cason commented May 10, 2024

Should we add this to #2803?

@cason
Copy link
Contributor

cason commented May 10, 2024

If you look into the relevant code, each recheck call is actually synchronous due to how the callback's are structured.

This is a problem by itself, we have probably to address it in another issue.

@cason
Copy link
Contributor

cason commented May 10, 2024

As commented in #3008, we cannot call Commit before flushing the mempool. This is to ensure that all transactions with pending CheckTx are processed before calling Commit. The rationale here is that Commit should update the state used by CheckTx to the new state.

While we can discuss if this is the best way to go, this is the current contract with the ABCI application.

@cason
Copy link
Contributor

cason commented May 10, 2024

The block execution should trigger the execution of Re-CheckTx but I agree that the re-checking should indeed be performed in parallel.

github-merge-queue bot pushed a commit that referenced this issue May 22, 2024
First step to fixing #2925 

PR'ing this to see if we have any test failures. Note that this is safe
in the happy path, as Reap and CheckTx both share this same lock. The
functionality behavior is that:

- Full nodes and non-proposers `timeout_prevote` beginning should not
block on updating the mempool
- Block proposers get _very slight_ increased concurrency before reaping
their next block. (Should be significantly fixed in subsequent PR's in
#2925)
- Reap takes a lock on the mempool mutex, so there is no concurrency
safety issues right now.
- Mempool errors will not halt consensus, instead they just log an error
and call mempool flush. I actually think this may be better behavior? If
we want to preserve the old behavior, we can thread a generic "consensus
halt error" channel perhaps?

I'm not sure how/where to best document this. Please also let me know if
tests need creating. Seems like the create empty block tests sometimes
hit failures, I'll investigate tmrw

Also please feel free to take over this PR, just thought I"d make it to
help us with performance improvements. Happy to get this into an
experimental release to test on mainnets.

---

#### PR checklist

- [ ] Tests written/updated
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] 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 <[email protected]>
PaddyMc pushed a commit to osmosis-labs/cometbft that referenced this issue May 23, 2024
First step to fixing cometbft#2925

PR'ing this to see if we have any test failures. Note that this is safe
in the happy path, as Reap and CheckTx both share this same lock. The
functionality behavior is that:

- Full nodes and non-proposers `timeout_prevote` beginning should not
block on updating the mempool
- Block proposers get _very slight_ increased concurrency before reaping
their next block. (Should be significantly fixed in subsequent PR's in
- Reap takes a lock on the mempool mutex, so there is no concurrency
safety issues right now.
- Mempool errors will not halt consensus, instead they just log an error
and call mempool flush. I actually think this may be better behavior? If
we want to preserve the old behavior, we can thread a generic "consensus
halt error" channel perhaps?

I'm not sure how/where to best document this. Please also let me know if
tests need creating. Seems like the create empty block tests sometimes
hit failures, I'll investigate tmrw

Also please feel free to take over this PR, just thought I"d make it to
help us with performance improvements. Happy to get this into an
experimental release to test on mainnets.

---

- [ ] Tests written/updated
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] 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 <[email protected]>
PaddyMc added a commit to osmosis-labs/cometbft that referenced this issue May 23, 2024
First step to fixing cometbft#2925

PR'ing this to see if we have any test failures. Note that this is safe
in the happy path, as Reap and CheckTx both share this same lock. The
functionality behavior is that:

- Full nodes and non-proposers `timeout_prevote` beginning should not
block on updating the mempool
- Block proposers get _very slight_ increased concurrency before reaping
their next block. (Should be significantly fixed in subsequent PR's in
- Reap takes a lock on the mempool mutex, so there is no concurrency
safety issues right now.
- Mempool errors will not halt consensus, instead they just log an error
and call mempool flush. I actually think this may be better behavior? If
we want to preserve the old behavior, we can thread a generic "consensus
halt error" channel perhaps?

I'm not sure how/where to best document this. Please also let me know if
tests need creating. Seems like the create empty block tests sometimes
hit failures, I'll investigate tmrw

Also please feel free to take over this PR, just thought I"d make it to
help us with performance improvements. Happy to get this into an
experimental release to test on mainnets.

---

- [ ] Tests written/updated
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] 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: Dev Ojha <[email protected]>
Co-authored-by: Sergio Mena <[email protected]>
mergify bot pushed a commit to osmosis-labs/cometbft that referenced this issue May 23, 2024
First step to fixing cometbft#2925

PR'ing this to see if we have any test failures. Note that this is safe
in the happy path, as Reap and CheckTx both share this same lock. The
functionality behavior is that:

- Full nodes and non-proposers `timeout_prevote` beginning should not
block on updating the mempool
- Block proposers get _very slight_ increased concurrency before reaping
their next block. (Should be significantly fixed in subsequent PR's in
- Reap takes a lock on the mempool mutex, so there is no concurrency
safety issues right now.
- Mempool errors will not halt consensus, instead they just log an error
and call mempool flush. I actually think this may be better behavior? If
we want to preserve the old behavior, we can thread a generic "consensus
halt error" channel perhaps?

I'm not sure how/where to best document this. Please also let me know if
tests need creating. Seems like the create empty block tests sometimes
hit failures, I'll investigate tmrw

Also please feel free to take over this PR, just thought I"d make it to
help us with performance improvements. Happy to get this into an
experimental release to test on mainnets.

---

- [ ] Tests written/updated
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] 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: Dev Ojha <[email protected]>
Co-authored-by: Sergio Mena <[email protected]>
(cherry picked from commit 2cea495)
PaddyMc added a commit to osmosis-labs/cometbft that referenced this issue May 23, 2024
… (#71)

First step to fixing cometbft#2925

PR'ing this to see if we have any test failures. Note that this is safe
in the happy path, as Reap and CheckTx both share this same lock. The
functionality behavior is that:

- Full nodes and non-proposers `timeout_prevote` beginning should not
block on updating the mempool
- Block proposers get _very slight_ increased concurrency before reaping
their next block. (Should be significantly fixed in subsequent PR's in
- Reap takes a lock on the mempool mutex, so there is no concurrency
safety issues right now.
- Mempool errors will not halt consensus, instead they just log an error
and call mempool flush. I actually think this may be better behavior? If
we want to preserve the old behavior, we can thread a generic "consensus
halt error" channel perhaps?

I'm not sure how/where to best document this. Please also let me know if
tests need creating. Seems like the create empty block tests sometimes
hit failures, I'll investigate tmrw

Also please feel free to take over this PR, just thought I"d make it to
help us with performance improvements. Happy to get this into an
experimental release to test on mainnets.

---

- [ ] Tests written/updated
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] 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: Dev Ojha <[email protected]>
Co-authored-by: Sergio Mena <[email protected]>
(cherry picked from commit 2cea495)

Co-authored-by: PaddyMc <[email protected]>
beer-1 pushed a commit to initia-labs/cometbft that referenced this issue May 29, 2024
First step to fixing cometbft#2925

PR'ing this to see if we have any test failures. Note that this is safe
in the happy path, as Reap and CheckTx both share this same lock. The
functionality behavior is that:

- Full nodes and non-proposers `timeout_prevote` beginning should not
block on updating the mempool
- Block proposers get _very slight_ increased concurrency before reaping
their next block. (Should be significantly fixed in subsequent PR's in
- Reap takes a lock on the mempool mutex, so there is no concurrency
safety issues right now.
- Mempool errors will not halt consensus, instead they just log an error
and call mempool flush. I actually think this may be better behavior? If
we want to preserve the old behavior, we can thread a generic "consensus
halt error" channel perhaps?

I'm not sure how/where to best document this. Please also let me know if
tests need creating. Seems like the create empty block tests sometimes
hit failures, I'll investigate tmrw

Also please feel free to take over this PR, just thought I"d make it to
help us with performance improvements. Happy to get this into an
experimental release to test on mainnets.

---

- [ ] Tests written/updated
- [x] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] 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 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request mempool
Projects
Status: Todo
4 participants