Skip to content

refactor(mempool): Add Iterator to replace TxsFront and TxsWaitChan methods#3459

Merged
hvanz merged 8 commits intomainfrom
hvanz/mempool-iterator-3303
Jul 9, 2024
Merged

refactor(mempool): Add Iterator to replace TxsFront and TxsWaitChan methods#3459
hvanz merged 8 commits intomainfrom
hvanz/mempool-iterator-3303

Conversation

@hvanz
Copy link
Collaborator

@hvanz hvanz commented Jul 8, 2024

Closes #3303

This PR adds:

  • the Entry interface, implemented by the existing mempoolTx data type,
  • the Iterator interface, with one method WaitNextCh() <-chan Entry.

On the routine that sends transactions to a peer, we can now use an Iterator to select the next mempool entry to send, instead of the methods TxsFront and TxsWaitChan in CListMempool. These two methods leak implementation details about the CList and are now marked as deprecated. Now all the logic needed to wait for and pick the next available entry is implemented in CListMempool.WaitNextCh.


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

@hvanz hvanz added the mempool label Jul 8, 2024
@hvanz hvanz self-assigned this Jul 8, 2024
@hvanz hvanz marked this pull request as ready for review July 8, 2024 16:37
@hvanz hvanz requested a review from a team as a code owner July 8, 2024 16:37
@hvanz hvanz requested a review from a team July 8, 2024 16:37
hvanz and others added 2 commits July 9, 2024 09:24
Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
Copy link
Collaborator

@melekes melekes left a comment

Choose a reason for hiding this comment

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

👍 Not sure about channel closing and retrying semantics, otherwise LGTM

select {
case entry = <-iter.WaitNextCh():
// If the entry we were looking at got garbage collected (removed), try again.
if entry == nil {
Copy link
Collaborator

@melekes melekes Jul 9, 2024

Choose a reason for hiding this comment

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

If we reach the end of the list, do we also retry here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In principle, yes, that's what would happen.

Here, entry is nil either because Clist.Front or CElement.Next returned nil. If Next returns nil because it's at the end of the list and the list is not empty, we shouldn't set the cursor to nil because we will start iterating from the beginning of the list, sending the same transactions more than once. The other reason I see that both Front and Next return nil is when the entry got removed just before calling these functions. I've seen these scenarios happen in unit tests, but they are difficult to reproduce.

I think it's better to investigate these scenarios in another issue; this PR should be just a refactoring.

if iter.cursor != nil {
ch <- iter.cursor.Value.(Entry)
}
close(ch)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remember that closing a channel also sends a nil value

case entry = <-iter.WaitNextCh():

will fire with nil and we will execute continue

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The receiver will get nil when closing the channel without sending any message on it. This happens when iter.cursor == nil. When iter.cursor != nil, it first send the message on the channel and then it closes it, but the receiver (line 227) already got the message. (I checked this behaviour on the code.)

Copy link
Collaborator Author

@hvanz hvanz Jul 9, 2024

Choose a reason for hiding this comment

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

To make it more clear I can change it to:

if iter.cursor != nil {
    ch <- iter.cursor.Value.(Entry)
} else {
    close(ch)
}

In the first case the garbage collector will take care of closing the channel.

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.

🎸🎸

@hvanz hvanz added this pull request to the merge queue Jul 9, 2024
Merged via the queue into main with commit d4a82b7 Jul 9, 2024
@hvanz hvanz deleted the hvanz/mempool-iterator-3303 branch July 9, 2024 19:27
github-merge-queue bot pushed a commit that referenced this pull request Aug 9, 2024
… fails (#3647)

Fixes a bug introduced in #3459 where instead of retrying the same tx
when the peer is lagging, it was skipping it and moving on to the next
entry. The same used to happen when sending the transaction failed:
instead of retrying to send, it skipped it and proceeded to the next tx.
This PR also reverts #3430, which was not working as expected.

Note that the first commit introduces a new test
`TestMempoolReactorSendLaggingPeer` that initially fails and then it's
fixed:
https://github.com/cometbft/cometbft/actions/runs/10300181146/job/28509056466?pr=3647

---

#### PR checklist

- [X] Tests written/updated
- ~~[ ] 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
mergify bot pushed a commit that referenced this pull request Aug 9, 2024
… fails (#3647)

Fixes a bug introduced in #3459 where instead of retrying the same tx
when the peer is lagging, it was skipping it and moving on to the next
entry. The same used to happen when sending the transaction failed:
instead of retrying to send, it skipped it and proceeded to the next tx.
This PR also reverts #3430, which was not working as expected.

Note that the first commit introduces a new test
`TestMempoolReactorSendLaggingPeer` that initially fails and then it's
fixed:
https://github.com/cometbft/cometbft/actions/runs/10300181146/job/28509056466?pr=3647

---

#### PR checklist

- [X] Tests written/updated
- ~~[ ] 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

(cherry picked from commit 1ac8832)

# Conflicts:
#	mempool/reactor.go
hvanz added a commit that referenced this pull request Aug 9, 2024
… fails (backport #3647) (#3657)

Fixes a bug introduced in #3459 where instead of retrying the same tx
when the peer is lagging, it was skipping it and moving on to the next
entry. The same used to happen when sending the transaction failed:
instead of retrying to send, it skipped it and proceeded to the next tx.
This PR also reverts #3430, which was not working as expected.

Note that the first commit introduces a new test
`TestMempoolReactorSendLaggingPeer` that initially fails and then it's
fixed:
https://github.com/cometbft/cometbft/actions/runs/10300181146/job/28509056466?pr=3647

---

#### PR checklist

- [X] Tests written/updated
- ~~[ ] 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
<hr>This is an automatic backport of pull request #3647 done by
[Mergify](https://mergify.com).

---------

Co-authored-by: Hernán Vanzetto <15466498+hvanz@users.noreply.github.com>
Co-authored-by: hvanz <hernan.vanzetto@gmail.com>
@hvanz
Copy link
Collaborator Author

hvanz commented Sep 12, 2024

@Mergifyio backport v1.x

@mergify
Copy link
Contributor

mergify bot commented Sep 12, 2024

backport v1.x

✅ Backports have been created

Details

mergify bot pushed a commit that referenced this pull request Sep 12, 2024
…han` methods (#3459)

Closes #3303

This PR adds:
- the `Entry` interface, implemented by the existing `mempoolTx` data
type,
- the `Iterator` interface, with one method `WaitNextCh() <-chan Entry`.

On the routine that sends transactions to a peer, we can now use an
`Iterator` to select the next mempool entry to send, instead of the
methods `TxsFront` and `TxsWaitChan` in `CListMempool`. These two
methods leak implementation details about the CList and are now marked
as deprecated. Now all the logic needed to wait for and pick the next
available entry is implemented in `CListMempool.WaitNextCh`.

---

#### PR checklist

- [X] 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: Anton Kaliaev <anton.kalyaev@gmail.com>
(cherry picked from commit d4a82b7)

# Conflicts:
#	mempool/clist_mempool_test.go
#	mempool/reactor.go
mergify bot pushed a commit that referenced this pull request Sep 16, 2024
… fails (#3647)

Fixes a bug introduced in #3459 where instead of retrying the same tx
when the peer is lagging, it was skipping it and moving on to the next
entry. The same used to happen when sending the transaction failed:
instead of retrying to send, it skipped it and proceeded to the next tx.
This PR also reverts #3430, which was not working as expected.

Note that the first commit introduces a new test
`TestMempoolReactorSendLaggingPeer` that initially fails and then it's
fixed:
https://github.com/cometbft/cometbft/actions/runs/10300181146/job/28509056466?pr=3647

---

#### PR checklist

- [X] Tests written/updated
- ~~[ ] 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

(cherry picked from commit 1ac8832)

# Conflicts:
#	mempool/reactor_test.go
hvanz added a commit that referenced this pull request Sep 16, 2024
… fails (backport #3647) (#4109)

Fixes a bug introduced in #3459 where instead of retrying the same tx
when the peer is lagging, it was skipping it and moving on to the next
entry. The same used to happen when sending the transaction failed:
instead of retrying to send, it skipped it and proceeded to the next tx.
This PR also reverts #3430, which was not working as expected.

Note that the first commit introduces a new test
`TestMempoolReactorSendLaggingPeer` that initially fails and then it's
fixed:
https://github.com/cometbft/cometbft/actions/runs/10300181146/job/28509056466?pr=3647

---

#### PR checklist

- [X] Tests written/updated
- ~~[ ] 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
<hr>This is an automatic backport of pull request #3647 done by
[Mergify](https://mergify.com).

---------

Co-authored-by: Hernán Vanzetto <15466498+hvanz@users.noreply.github.com>
Co-authored-by: hvanz <hernan.vanzetto@gmail.com>
mergify bot added a commit that referenced this pull request Sep 16, 2024
…han` methods (backport #3459) (#4089)

Closes #3303 

This PR adds:
- the `Entry` interface, implemented by the existing `mempoolTx` data
type,
- the `Iterator` interface, with one method `WaitNextCh() <-chan Entry`.

On the routine that sends transactions to a peer, we can now use an
`Iterator` to select the next mempool entry to send, instead of the
methods `TxsFront` and `TxsWaitChan` in `CListMempool`. These two
methods leak implementation details about the CList and are now marked
as deprecated. Now all the logic needed to wait for and pick the next
available entry is implemented in `CListMempool.WaitNextCh`.

---

#### PR checklist

- [X] 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
<hr>This is an automatic backport of pull request #3459 done by
[Mergify](https://mergify.com).

---------

Co-authored-by: Hernán Vanzetto <15466498+hvanz@users.noreply.github.com>
Co-authored-by: hvanz <hernan.vanzetto@gmail.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

mempool: fix TxsFront and TxsWaitChan in CListMempool that leak implementation details

3 participants