-
Notifications
You must be signed in to change notification settings - Fork 37.8k
Docs: Improve commenting for coins.cpp|h #18410
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
Conversation
These changes were extracted from #18113. |
0e04b2c
to
97298e5
Compare
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
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. |
Thanks for improving the documentation here. I think this is a clear improvement. ACK 97298e5 |
Concept ACK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK 97298e5. Nice change, great to clean up old pruning references and add more of an explanation about possible_overwrite
} | ||
// If the coin exists in this cache as a spent coin and is DIRTY, then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit "[docs] Improve commenting in coins.cpp|h" (eeeb97b)
It seems like this comment is going into the weeds about when it is safe to set these flags without explaining what the code is trying to do. If I were trying to explain this code I think I'd start off with something like:
"As an optimization, try to set the FRESH flag when the caller has passed possible_overwrite=false and is guaranteeing that the coin was spent or never existed before this call. In this case, the FRESH flag can be applied as long as there's not a previous spent dirty cache entry (from disconnecting a block in a reorg and "spending" the coin to remove it), that hasn't yet been written to the base view."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion. I find my version easier to parse (although I'm biased, of course). The second sentence in your version is:
"In [previous sentence] case, [thing can happen] as long as [condition] (from [cause]) that [subcondition]"
which I find to be a lot to arrange in my head at once. In my version, I've tried to keep the sentence structures simple like "IF [thing] THEN [thing]".
* already exist in the cache. | ||
*/ | ||
void AddCoin(const COutPoint& outpoint, Coin&& coin, bool potential_overwrite); | ||
void AddCoin(const COutPoint& outpoint, Coin&& coin, bool possible_overwrite); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit "[docs] use consistent naming for possible_overwrite" (97298e5)
Not for here, since it's too much change for a documentation PR, but it might be worth considering replacing this bool possible_overwrite param with an inverted bool fresh param. possible_overwrite=false would change to fresh=true, meaning it is safe for AddCoin to assume any existing coin is spent, and possible_overwrite=true would change to fresh=false, meaning it can't make that assumption
(This would be a partial step in the direction I was trying to go in #9384: instead of repeating fresh/dirty logic and implementing it slightly different ways in AddCoin, and SpendCoin, Batchwrite, just doing it one time one way in a CCoinsViewCache::Modifier class.)
Calling the param fresh instead of possible_overwrite would make it more clear this is doing the same freshness logic as BatchWrite et al, and not something different
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this is too much for this PR. Additional documentation around possible_overwrite
or whatever you decide to change it to would be very welcome!
src/coins.cpp
Outdated
// A coin can only be FRESH in the child cache if it doesn't exist | ||
// in any of the ancestor caches. We can therefore mark it FRESH |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In commit "[docs] Improve commenting in coins.cpp|h" (eeeb97b)
"A coin can only be FRESH in the child cache if it doesn't exist in any of the ancestor caches" is too broad a statement, not generally true. You can layer caches arbitrarily and a fresh flag in a child doesn't tell you about the state of the coin in every ancestor cache. It only directly tells you the state of the coin in the immediate parent cache. In this case, we only indirectly know the state of the grandparent coin due to this happening under the itUs == cacheCoins.end()
branch.
Would write this comment more like: "We can mark parent cache entry FRESH here if child cache entry was FRESH. This works because parent cache entry not previously existing and child cache entry being FRESH indicates grandparent coin is spent or doesn't exist."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, we only indirectly know the state of the grandparent coin due to this happening under the itUs == cacheCoins.end() branch.
I don't understand this statement. itUs == cacheCoins.end()
simply tells us that the coin doesn't exist in the parent cache's CCoinsMap
structure. It doesn't tell us anything about the grandparent cache.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, we only indirectly know the state of the grandparent coin due to this happening under the itUs == cacheCoins.end() branch.
If entry has fresh flag and there is no parent entry (itUs == cacheCoins.end()
) then the coin must be spent in the grandparent and therefore it's safe to re-apply the fresh flag
It doesn't tell us anything about the grandparent cache.
Of course, the grandparent might not even be a cache view. But whatever kind of view it is the coin must be spent there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If entry has fresh flag and there is no parent entry (itUs == cacheCoins.end()) then the coin must be spent in the grandparent
I still don't understand this. Can you explain the logic?
(I still believe that no ancestor cache can contain the coin due to the way we build the cache hierarchy, but I don't understand how you reason about just the grandparent cache)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why we're going back and forth on one sentence in a code review comment I made explaining why I thought your code comment was making an unstated assumption. If you don't like my suggestion (which does not mention itUs), feel free to ignore!
My logic is just that in order for a cache entry to wind up with the fresh flag, the coin in its parent view (whether it's a cache or not, whether or not it has entries or is flushed if it is a cache) must be spent. If the parent view is a cache, and doesn't have an entry, the coin must be spent in the grandparent view (again whether or not it's a cache and regardless of whether entries are created).
I am using "spent" here as shorthand for "spent or never existed" in case that what may be confusing. My working definition of "fresh" is "spent in the parent view"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe: "A coin can only be FRESH in the child cache if it doesn't exist (e.g. was spent or never existed) in any of the ancestor caches".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or: "A coin can only be FRESH in the child cache if it doesn't exist (e.g. was spent or never existed) in the parent view, nor in any of the ancestor caches due to the way we build the cache hierarchy."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why we're going back and forth on one sentence in a code review comment I made explaining why I thought your code comment was making an unstated assumption.
Because I'm trying to understand your logic and if there's a gap in my understanding. And if not, whether the comment is needlessly confusing.
in order for a cache entry to wind up with the fresh flag, the coin in its parent view [...] must be spent. If the parent view is a cache, and doesn't have an entry, the coin must be spent in the grandparent view
But isn't this transitive? Can I not equally say "If the grandparent view is a cache, and doesn't have an entry, the coin must be spent in the great-grandparent view" and so on?
Why is this assigned 0.20.0? This is not a bugfix, and the rename might be controversial, so let's better wait for 0.21.0? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working to improve this! I like where it's going, modulo @ryanofsky's good comments and some suggestions and fixups below.
Despite knowing they are different flags I am still trying to avoid thinking of FRESH and DIRTY as mutually exclusive states 🕵️♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the text is clearly better than before. Still hard to understand. Shouldn't have missed the PR review club :(
I think that we could potentially rename |
97298e5
to
98bee55
Compare
I believe I've now addressed all feedback given on this PR up to this point. |
ACK 98bee55 latest documentation changes in
Agreed -- SGTM. Thanks, John. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK 98bee55. No significant changes since last review, just minor copy editing for comments and more specific logic_error string
@instagibbs @MarcoFalke can you help get this over the line? 🙏 |
ACK 98bee55 not going to hold up a clear improvement |
ACK 98bee55 (ideally with follow up PR renaming FRESH to something more intuitive like NEWCOIN) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach ACK 98bee55 I read through once, some questions inline 🛁
Show signature and timestamp
Signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Approach ACK 98bee558700a10afd819cbb685df0b402522ccfa I read through once, some questions inline 🛁
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUjJtgv/VzpBCTOCZbrPOWO33QFvXJjKuCzzTHTShN3o1ssfPyNdl8AOcVRS2H21
GaSkzJRvvUF2XY3Kin7H8ve76VgZATdYrJqQIwiGvDnHTqWKZUauydYhoywwZDMW
gsJdw/G/hM2uRpd5Jdws14LSv+npMYc2L4sw8Y961OOoG/YQUsppwy8/xZVicKgn
ZE0HtfJtrWfoP8SxsSvmQzzfNXNEgMl+0fsAJjBJCr60xkkmqRAh0+LdJoHPgSLo
yFO3xrtLaIKzrzOZycU+Ezrp+58judAhzdQEfwHza6z8/doMxZ5l8y55JyymKnmq
bwEgsIDtSR3H12WKbtiNRnfxxYA7yNzMljCUQKleqPIuP8gTTsUFLZO6ADzXFoJb
kSKj/gm5gmQo538j/4Ge4YN5zk5uw4MFlk1Q0uYYt3KTjCaqEggXxdPIJQOiG5hY
y1zOlEOGt0oG/QKLWVIHehqaeHXFWJYLsbncpDJl/IB5iphSsER8LroEvzFjiIbv
Aatmonqh
=WXZO
-----END PGP SIGNATURE-----
Timestamp of file with hash 1344d8e0d46a4a6d591e9f8a227b79d3b1b0a847972fd99a17aafbdf3e6d428c -
// Otherwise we will need to create it in the parent | ||
// and move the data up and mark it as dirty | ||
// Create the coin in the parent cache, move the data up | ||
// and mark it as dirty. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in commit be549b3:
I don't think inline comments that translate the c++ source code into English are helpful. Instead of repeating the code, they should clarify its intent and provide motivation and background information that is not available from just reading the code. If there is nothing to clarify, no inline comment should be made.
Doxygen comments on the other hand may repeat what the code does on a abstract, higher level to give devs the convenience to not dig into the internal source code of a class or module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, although in this case, I was simply cleaning up a comment that already existed (using otherwise to continue a sentence over two comments is a bad idea because when the code changes comments like this often lose their meaning.
// we must not copy that FRESH flag to the parent as that | ||
// pruned state likely still needs to be communicated to the | ||
// grandparent. | ||
// NOTE: It isn't safe to mark the coin as FRESH in the parent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in commit be549b3:
All inline comments are notes. Without loss of information, this comment can be pruned.
// NOTE: It isn't safe to mark the coin as FRESH in the parent | |
// It isn't safe to mark the coin as FRESH in the parent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. Could probably be improved further.
src/coins.cpp
Outdated
CCoinsCacheEntry& entry = cacheCoins[it->first]; | ||
entry.coin = std::move(it->second.coin); | ||
cachedCoinsUsage += entry.coin.DynamicMemoryUsage(); | ||
entry.flags = CCoinsCacheEntry::DIRTY; | ||
// We can mark it FRESH in the parent if it was FRESH in the child | ||
// Otherwise it might have just been flushed from the parent's cache | ||
// and already exist in the grandparent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you removing the wording "flushed from the parent's cache"? Is it a requirement to flush the child before the parent? If yes, this comment was incorrect, if no, this comment should not be deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment change seems to be controversial (see #18410 (comment)), so I've reverted it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potentially relevant context: #5863 (comment)
Remove references to 'pruned' coins, which don't exist since the move to per-txout coins db.
-BEGIN VERIFY SCRIPT- sed -i -e 's/PRUNED,/SPENT ,/g' ./src/test/coins_tests.cpp sed -i -e 's/PRUNED/SPENT/g' ./src/test/coins_tests.cpp -END VERIFY SCRIPT-
Required after scripted-diff in previous commit.
And other general comment improvements for adding coins.
98bee55
to
21fa0a4
Compare
@MarcoFalke - I've reverted the comment change that you and Russ don't like. Your other two review comments are stylistic, so I've not made any changes for those. |
Re-ACK 21fa0a4 per - // A coin can only be FRESH in the child cache if it doesn't exist
- // in any of the ancestor caches. We can therefore mark it FRESH
- // when flushing to the parent cache.
+ // We can mark it FRESH in the parent if it was FRESH in the child
+ // Otherwise it might have just been flushed from the parent's cache
+ // and already exist in the grandparent
if (it->second.flags & CCoinsCacheEntry::FRESH) { |
Summary: Remove references to 'pruned' coins, which don't exist since the move to per-txout coins db. This is a backport of Core [[bitcoin/bitcoin#18410 | PR18410]] [1/3] bitcoin/bitcoin@c205979 Test Plan: proof-reading Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D8953
Summary: > sed -i -e 's/PRUNED/SPENT/g' ./src/test/coins_tests.cpp This is a backport of Core [[bitcoin/bitcoin#18410 | PR18410]] [2/3] bitcoin/bitcoin@e993696 Depends on D8953 Test Plan: `ninja check` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D8954
Summary: And other general comment improvements for adding coins. This is a backport of Core [[bitcoin/bitcoin#18410 | PR18410]] [3/3] bitcoin/bitcoin@21fa0a4 Depends on D8954 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D8955
21fa0a4 [docs] use consistent naming for possible_overwrite (John Newbery) 2685c21 [tests] small whitespace fixup (John Newbery) e993696 scripted-diff: Rename PRUNED to SPENT in coins tests (John Newbery) c205979 [docs] Improve commenting in coins.cpp|h (John Newbery) Pull request description: - Add full commenting for spentness / DIRTYness / FRESHness and which combinations are valid - Remove the 'pruned' terminology, which doesn't make sense since per-txout chainstate db was merged (bitcoin#10195). - Rename `potential_overwrite` to `possible_overwrite` to standardize terminology (there were previously examples of both, which made searching the codebase difficult). - Make other minor improvements to the comments ACKs for top commit: jonatack: Re-ACK 21fa0a4 per `git diff 98bee55 21fa0a4` the only change since my previous review is the following code commenting diff in `src/coins.cpp::L177-179`; rebuilt/ran unit tests anyway as a sanity check on the unit test changes. Tree-SHA512: 391e01588ef5edb417250080cec17361f982c4454bc5f8c6d78bbd528c68a2bb94373297760691295c24660ce1022ad3ef7599762f736c8eed772ce096d38c3d
21fa0a4 [docs] use consistent naming for possible_overwrite (John Newbery) 2685c21 [tests] small whitespace fixup (John Newbery) e993696 scripted-diff: Rename PRUNED to SPENT in coins tests (John Newbery) c205979 [docs] Improve commenting in coins.cpp|h (John Newbery) Pull request description: - Add full commenting for spentness / DIRTYness / FRESHness and which combinations are valid - Remove the 'pruned' terminology, which doesn't make sense since per-txout chainstate db was merged (bitcoin#10195). - Rename `potential_overwrite` to `possible_overwrite` to standardize terminology (there were previously examples of both, which made searching the codebase difficult). - Make other minor improvements to the comments ACKs for top commit: jonatack: Re-ACK 21fa0a4 per `git diff 98bee55 21fa0a4` the only change since my previous review is the following code commenting diff in `src/coins.cpp::L177-179`; rebuilt/ran unit tests anyway as a sanity check on the unit test changes. Tree-SHA512: 391e01588ef5edb417250080cec17361f982c4454bc5f8c6d78bbd528c68a2bb94373297760691295c24660ce1022ad3ef7599762f736c8eed772ce096d38c3d
21fa0a4 [docs] use consistent naming for possible_overwrite (John Newbery) 2685c21 [tests] small whitespace fixup (John Newbery) e993696 scripted-diff: Rename PRUNED to SPENT in coins tests (John Newbery) c205979 [docs] Improve commenting in coins.cpp|h (John Newbery) Pull request description: - Add full commenting for spentness / DIRTYness / FRESHness and which combinations are valid - Remove the 'pruned' terminology, which doesn't make sense since per-txout chainstate db was merged (bitcoin#10195). - Rename `potential_overwrite` to `possible_overwrite` to standardize terminology (there were previously examples of both, which made searching the codebase difficult). - Make other minor improvements to the comments ACKs for top commit: jonatack: Re-ACK 21fa0a4 per `git diff 98bee55 21fa0a4` the only change since my previous review is the following code commenting diff in `src/coins.cpp::L177-179`; rebuilt/ran unit tests anyway as a sanity check on the unit test changes. Tree-SHA512: 391e01588ef5edb417250080cec17361f982c4454bc5f8c6d78bbd528c68a2bb94373297760691295c24660ce1022ad3ef7599762f736c8eed772ce096d38c3d
21fa0a4 [docs] use consistent naming for possible_overwrite (John Newbery) 2685c21 [tests] small whitespace fixup (John Newbery) e993696 scripted-diff: Rename PRUNED to SPENT in coins tests (John Newbery) c205979 [docs] Improve commenting in coins.cpp|h (John Newbery) Pull request description: - Add full commenting for spentness / DIRTYness / FRESHness and which combinations are valid - Remove the 'pruned' terminology, which doesn't make sense since per-txout chainstate db was merged (bitcoin#10195). - Rename `potential_overwrite` to `possible_overwrite` to standardize terminology (there were previously examples of both, which made searching the codebase difficult). - Make other minor improvements to the comments ACKs for top commit: jonatack: Re-ACK 21fa0a4 per `git diff 98bee55 21fa0a4` the only change since my previous review is the following code commenting diff in `src/coins.cpp::L177-179`; rebuilt/ran unit tests anyway as a sanity check on the unit test changes. Tree-SHA512: 391e01588ef5edb417250080cec17361f982c4454bc5f8c6d78bbd528c68a2bb94373297760691295c24660ce1022ad3ef7599762f736c8eed772ce096d38c3d
potential_overwrite
topossible_overwrite
to standardize terminology (there were previously examples of both, which made searching the codebase difficult).