-
Notifications
You must be signed in to change notification settings - Fork 38.7k
p2p, bugfix: use NetPermissions::HasFlag() in CConnman::Bind() #21644
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
p2p, bugfix: use NetPermissions::HasFlag() in CConnman::Bind() #21644
Conversation
|
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. |
vasild
left a comment
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.
ACK 693af714ea264cd5edeadecaa0e7762cfe377e5a
Some non-blocker comments below.
I think it is - the reasoning must be that we do not want to advertise our listen address if it has |
PF_NOBAN is a multi-flag that includes PF_DOWNLOAD, so the conditional in CConnman::Bind() using a bitwise AND will return the same result for both the "noban" status and the "download" status. Example: `PF_DOWNLOAD` is `0b1000000` `PF_NOBAN` is `0b1010000` This makes a check like `flags & PF_NOBAN` return `true` even if `flags` is equal to `PF_DOWNLOAD`. If `[email protected]:8765` is specified, then `1.1.1.1:8765` should be added to the list of local addresses. We only want to avoid adding to local addresses (that are advertised) a whitebind that has a `noban@` flag. As a result of a mis-check in `CConnman::Bind()` we would not have added `1.1.1.1:8765` to the local addresses in the example above. Co-authored-by: Vasil Dimov <[email protected]>
693af71 to
acef962
Compare
|
Thanks for the excellent review, @vasild. I added your commit description example from #21668, incorporated your suggestions, followed up on your #21644 (comment) with the last commit, and updated all the commit messages and the PR description. |
ab2a398 to
2d34c48
Compare
vasild
left a comment
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.
ACK 2d34c4874775f9e1fc7e8f02a9817a6898461abd
theStack
left a comment
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.
ACK 2d34c4874775f9e1fc7e8f02a9817a6898461abd
Thanks for fixing!
nit: It's generally better to have more tests rather than less, but personally I don't see much gain in also repeatedly testing the flags with bitmasks, e.g. this part
BOOST_CHECK_EQUAL(download.m_flags, NetPermissionFlags::PF_DOWNLOAD);
BOOST_CHECK(download.m_flags != NetPermissionFlags::PF_NOBAN);
BOOST_CHECK(download.m_flags & NetPermissionFlags::PF_DOWNLOAD);
BOOST_CHECK(download.m_flags & NetPermissionFlags::PF_NOBAN);
is semantically equivalent to
BOOST_CHECK_EQUAL(download.m_flags, NetPermissionFlags::PF_DOWNLOAD);
BOOST_CHECK(NetPermissionFlags::PF_DOWNLOAD != NetPermissionsFlags::PF_NOBAN);
BOOST_CHECK(NetPermissionFlags::PF_DOWNLOAD & NetPermissionsFlags::PF_DOWNLOAD); // tautology?
BOOST_CHECK(NetPermissionFlags::PF_DOWNLOAD & NetPermissionsFlags::PF_NOBAN);
i.e. everything after the first line doesn't test the result related to the previous tryParse-call, but only what bits the PF_ enums consist of internally, which could potentially be confusing to readers of this test at this place.
to clarify/test the relationship and NetPermissions operations involving the NetPermissionFlags PF_NOBAN and PF_DOWNLOAD. Co-authored-by: Vasil Dimov <[email protected]>
NetPermissions::ClearFlag() is currently only called in the codebase with an `f` value of NetPermissionFlags::PF_ISIMPLICIT. If that should change in the future, ClearFlag() should not be called with `f` being a subflag of a multiflag, e.g. NetPermissionFlags::PF_RELAY or NetPermissionFlags::PF_DOWNLOAD, as that would leave `flags` in an invalid state corresponding to none of the existing NetPermissionFlags. Therefore, allow only calling ClearFlag with the implicit flag for now. Co-authored-by: Vasil Dimov <[email protected]>
2d34c48 to
36fb036
Compare
theStack
left a comment
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.
re-ACK 36fb036 ☕
vasild
left a comment
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.
ACK 36fb036
hebasto
left a comment
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 36fb036.
This PR clearly shows how fragile "multibit flags" are. We definitely shouldn't introduce new ones.
From the second "test: add net permissions noban/download unit test coverage" commit I expected that it will fail without the first one. Is it possible to improve tests to prevent regressions in the future?
hebasto
left a comment
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.
ACK 36fb036, I have reviewed the code and it looks OK, I agree it can be merged.
kallewoof
left a comment
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 36fb036
Seems like ClearFlag could be renamed ClearImplicitFlag and remove 2nd argument instead of the assert stuff, but that would make the diff bigger, so no big deal.
|
@kallewoof agree, I thought about removing the argument too, could go one way or the other. |
…onnman::Bind() 36fb036 p2p: allow NetPermissions::ClearFlag() only with PF_ISIMPLICIT (Jon Atack) 4e0d578 test: add net permissions noban/download unit test coverage (Jon Atack) dde69f2 p2p, bugfix: use NetPermissions::HasFlag() in CConnman::Bind() (Jon Atack) Pull request description: This is a bugfix follow-up to bitcoin#16248 and bitcoin#19191 that was noticed in bitcoin#21506. Both v0.21 and master are affected. Since bitcoin#19191, noban is a multi-flag that implies download, so the conditional in `CConnman::Bind()` using a bitwise AND on noban will return the same result for both the noban status and the download status. This means that download peers are incorrectly not being added to local addresses because they are mistakenly seen as noban peers. The second commit adds unit test coverage to illustrate and test the noban/download relationship and the `NetPermissions` operations involving them. The final commit adds documentation and disallows calling `NetPermissions::ClearFlag()` with any second param other than `NetPermissionFlags` "implicit" -- per current usage in the codebase -- because `ClearFlag()` should not be called with any second param that is a subflag of a multiflag, e.g. "relay" or "download," as that would leave the result in an invalid state corresponding to none of the existing NetPermissionFlags. Thanks to Vasil Dimov for noticing this. ACKs for top commit: theStack: re-ACK 36fb036 ☕ vasild: ACK 36fb036 hebasto: ACK 36fb036, I have reviewed the code and it looks OK, I agree it can be merged. kallewoof: Code review ACK 36fb036 Tree-SHA512: 5fbc7ddbf31d06b35bf238f4d77ef311e6b6ef2e1bb9893f32f889c1a0f65774a3710dcb21d94317fe6166df9334a9f2d42630809e7fe8cbd797dd6f6fc49491
7075f60 scripted-diff: update noban documentation in net_processing.cpp (Jon Atack) a95540c scripted-diff: rename NetPermissionFlags enumerators (Jon Atack) 810d092 p2p, refactor: make NetPermissionFlags a uint32 enum class (Jon Atack) 7b55a94 p2p: NetPermissions::HasFlag() pass flags param by value (Jon Atack) 91f6e6e scripted-diff: add NetPermissionFlags scopes where not already present (Jon Atack) Pull request description: While reviewing #20196, I noticed the `NetPermissionFlags` enums are frequently called as if they were scoped, yet are still global. This patch upgrades `NetPermissionFlags` to a scoped class enum and updates the enumerator naming, similarly to #19771. See https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#enum-enumerations for more info. This change would eliminate the class of bugs like #20196 (comment) and #21644, as only defined operations on the flags would compile. ACKs for top commit: laanwj: Code review ACK 7075f60 vasild: ACK 7075f60 Tree-SHA512: 7fcea66ee499f059efc78c934b5f729b3c8573fe304dee2c27c837c2f662b89324790568246d75b2a574cf9f059b42d3551d928996862f4358055eb43521e6f4
|
Only backport to 0.21 needed |
PF_NOBAN is a multi-flag that includes PF_DOWNLOAD, so the conditional in CConnman::Bind() using a bitwise AND will return the same result for both the "noban" status and the "download" status. Example: `PF_DOWNLOAD` is `0b1000000` `PF_NOBAN` is `0b1010000` This makes a check like `flags & PF_NOBAN` return `true` even if `flags` is equal to `PF_DOWNLOAD`. If `[email protected]:8765` is specified, then `1.1.1.1:8765` should be added to the list of local addresses. We only want to avoid adding to local addresses (that are advertised) a whitebind that has a `noban@` flag. As a result of a mis-check in `CConnman::Bind()` we would not have added `1.1.1.1:8765` to the local addresses in the example above. Co-authored-by: Vasil Dimov <[email protected]> Github-Pull: bitcoin#21644 Rebased-From: dde69f2
|
Backported in #22022 |
PF_NOBAN is a multi-flag that includes PF_DOWNLOAD, so the conditional in CConnman::Bind() using a bitwise AND will return the same result for both the "noban" status and the "download" status. Example: `PF_DOWNLOAD` is `0b1000000` `PF_NOBAN` is `0b1010000` This makes a check like `flags & PF_NOBAN` return `true` even if `flags` is equal to `PF_DOWNLOAD`. If `[email protected]:8765` is specified, then `1.1.1.1:8765` should be added to the list of local addresses. We only want to avoid adding to local addresses (that are advertised) a whitebind that has a `noban@` flag. As a result of a mis-check in `CConnman::Bind()` we would not have added `1.1.1.1:8765` to the local addresses in the example above. Co-authored-by: Vasil Dimov <[email protected]> Github-Pull: bitcoin#21644 Rebased-From: dde69f2
This is a bugfix follow-up to #16248 and #19191 that was noticed in #21506. Both v0.21 and master are affected.
Since #19191, noban is a multi-flag that implies download, so the conditional in
CConnman::Bind()using a bitwise AND on noban will return the same result for both the noban status and the download status. This means that download peers are incorrectly not being added to local addresses because they are mistakenly seen as noban peers.The second commit adds unit test coverage to illustrate and test the noban/download relationship and the
NetPermissionsoperations involving them.The final commit adds documentation and disallows calling
NetPermissions::ClearFlag()with any second param other thanNetPermissionFlags"implicit" -- per current usage in the codebase -- becauseClearFlag()should not be called with any second param that is a subflag of a multiflag, e.g. "relay" or "download," as that would leave the result in an invalid state corresponding to none of the existing NetPermissionFlags. Thanks to Vasil Dimov for noticing this.