TheCharlatan
commented at 10:07 pm on November 15, 2023:
contributor
Currently the mempool returns and consumes sets of multiindex iterators in its public API. A likely motivation for this over working with references to the actual values is that the multi index interface works with these iterators and not with pointers or references to the actual values.
However, using the iterator type in the setEntries set provides little benefit in practice as applied currently. Its purpose, ownership, and safety semantics often remain ambiguous, and it is hardly used for actually iterating through the data structures. So replace it where possible with CTxMemPoolEntryRefs.
Since CTxMemPoolEntry itself refers to its Parents and Children by CTxMemPoolEntryRef and not txiter, this allowed for an overall reduction of calls to iterator_to. See the docs on iterator_to for more guidance.
No change in the performance of the mempool code was observed in my benchmarks.
This also makes the goal of eliminating boost types from the headers as done in #28335 more feasible.
DrahtBot
commented at 10:07 pm on November 15, 2023:
contributor
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
Conflicts
Reviewers, this pull request conflicts with the following ones:
#29325 (consensus: Store transaction nVersion as uint32_t by achow101)
#29306 (policy: enable sibling eviction for v3 transactions by glozow)
#26593 (tracing: Only prepare tracepoint arguments when actually tracing by 0xB10C)
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
DrahtBot added the label
Refactoring
on Nov 15, 2023
TheCharlatan
commented at 1:11 pm on November 16, 2023:
The p is for parent? Just like before in pit?
maflcko requested review from maflcko
on Nov 16, 2023
DrahtBot removed the label
CI failed
on Nov 16, 2023
maflcko
commented at 4:26 pm on November 16, 2023:
member
I wonder if it is possible to avoid copies of the entry. Currently one one copy is created when inserting into mapTx.
However, now that things are moving toward references, which are easy to copy accidentally. It may lead to bugs such as the one mentioned in the boost docs:
0// The following, though similar to the previous code,
1// does not work: iterator_to accepts a reference to
2// the element in the container, not a copy.
3int x=c.back();
4c.erase(c.iterator_to(x)); // run-time failure ensues
So disallowing copies would be a good belt-and-suspenders?
TheCharlatan
commented at 10:13 pm on November 16, 2023:
contributor
However, now that things are moving toward references, which are easy to copy accidentally. It may lead to bugs such as the one mentioned in the boost docs:
Thanks for highlighting this.
So disallowing copies would be a good belt-and-suspenders?
I did a quick POC where mapTx.insert is replaced with mapTx.emplace_back and the CTxMemPoolEntry constructor arguments are passed to emplace_back. Then I could delete the CTxMemPoolEntry copy constructor. It takes a bit of shuffling around in the fuzzing and test code, as well as the addUnchecked method to forward the required arguments, so not sure if it should go into this PR or a follow up. Let me know what you think.
maflcko
commented at 8:27 am on November 17, 2023:
member
There shouldn’t be any conflicts, so maybe a separate/independent/parallel pull?
theuni
commented at 10:18 pm on November 22, 2023:
member
Concept ACK on avoiding exposing iterators externally.
Exposing references instead seems like a bit of a lateral move though, and I think it’s going to take a good bit of convincing to prove that this is at least as safe than what we have now. Are references guaranteed by Boost to stay valid the same as iters are?
TheCharlatan
commented at 10:48 pm on November 22, 2023:
contributor
and I think it’s going to take a good bit of convincing to prove that this is at least as safe than what we have now.
We’re using the references now to keep track of the parents and children. I don’t see what new assumption this patch is introducing compared to this existing practice.
Are references guaranteed by Boost to stay valid the same as iters are?
I’d be interested in getting an answer to this though. I’m guessing, since we can pass objects without copy or move ctors to the multiindex map, they can’t be moved in memory, so the references should be safe, right?
DrahtBot added the label
Needs rebase
on Nov 24, 2023
TheCharlatan force-pushed
on Nov 24, 2023
TheCharlatan
commented at 6:01 pm on November 24, 2023:
contributor
DrahtBot removed the label
Needs rebase
on Nov 24, 2023
sdaftuar
commented at 1:58 pm on November 28, 2023:
member
Though #28676 is still in draft (and likely will remain that way for a while), my plan is to completely rewrite most of the mempool logic. To minimize rebase effort, I wonder if it would be reasonable to defer mempool refactors for the time being, and just try to ensure that these goals are reflected in that work when it becomes ready for full review?
TheCharlatan
commented at 2:53 pm on November 28, 2023:
contributor
The rebase effort doesn’t seem too bad given that all this change does is go from a complex wrapper type to its simpler underlying type, so it should be very mechanical. From reading through your patch set I also don’t see new complexities arising from novel ways of using the multi index, on the contrary I see places where new calls to mapTx.iterator_to fall away. I should go through the exercise myself though to make sure this PR doesn’t complicate yours.
I get though that there are more fun things to do than rebasing a 64 commit PR because of a silly type change, so if you want to adapt your patch set towards facilitating removing the boost headers from the mempool header files, as well as reducing the number of iterator_to type casts, that sounds good to me too.
achow101 referenced this in commit
535424a10b
on Nov 28, 2023
TheCharlatan force-pushed
on Nov 28, 2023
TheCharlatan
commented at 9:22 pm on November 28, 2023:
contributor
DrahtBot removed the label
Needs rebase
on Dec 1, 2023
sdaftuar
commented at 3:31 pm on December 7, 2023:
member
However, using the iterator type in the setEntries set provides little benefit in practice as applied currently. Its purpose, ownership, and safety semantics often remain ambiguous, and it is hardly used for actually iterating through the data structures. So replace it where possible with CTxMemPoolEntryRefs.
I was thinking about this issue of ownership and safety semantics some more – it seems like that most of the issues around iterators exist with CTxMemPoolEntryRefs as well, which is that they are only valid to hold onto as long as the mempool is locked. Once the lock is released, it’s no longer safe to use mapTx iterators or CTxMemPoolEntryRef’s, because they can be deleted out from under you.
So if we really want to address ownership and safety semantics, I think we need to do something a bit different? (Unfortunately I don’t have any great suggestions.)
DrahtBot added the label
CI failed
on Jan 16, 2024
DrahtBot added the label
Needs rebase
on Feb 10, 2024
TheCharlatan force-pushed
on Feb 10, 2024
TheCharlatan
commented at 9:04 am on February 10, 2024:
contributor
DrahtBot removed the label
CI failed
on Feb 10, 2024
DrahtBot removed the label
Needs rebase
on Feb 10, 2024
DrahtBot added the label
Needs rebase
on Feb 13, 2024
mempool: Replace sets of txiter with CTxMemPoolEntryRefs
Currently the mempool returns and consumes sets of multiindex iterators
in its public API. A likely motivation for this over working with
references to the actual values is that the multi index interface works
with these iterators and not with pointers or references to the actual
values.
However, the iterator type provides little benefit in practice as
applied currently. Its purpose, ownership, and safety semantics often
remain ambiguous, and it is hardly used for actually iterating through
the data structures. So replace it where possible with
CTxMemPoolEntryRefs.
Since CTxMemPoolEntry itself refers to its Parents and Children by
CTxMemPoolEntryRef and not txiter, this allowed for an overall
reduction of calls to iterator_to.
This also makes the long term goal of eliminating boost types from the
headers more feasible.
059fc2a89b
mempool: Remove dead code5e4cf6c1eb
mempool: Remove txiter/setEntries from public interface755b7d86b6
doc: Document CTxMemPoolEntry copy and move constructors7882748c1c
TheCharlatan force-pushed
on Feb 15, 2024
TheCharlatan
commented at 3:46 pm on February 15, 2024:
contributor
DrahtBot removed the label
Needs rebase
on Feb 15, 2024
TheCharlatan
commented at 7:58 am on March 10, 2024:
contributor
Going to close this while work on cluster mempool is happening. Hopefully a solution for leaking the boost types can be found there. Will keep the parent #28335 open.
This is a metadata mirror of the GitHub repository
bitcoin/bitcoin.
This site is not affiliated with GitHub.
Content is generated from a GitHub metadata backup.
generated: 2024-11-23 12:12 UTC
This site is hosted by @0xB10C More mirrored repositories can be found on mirror.b10c.me