Skip to content

Conversation

hebasto
Copy link
Member

@hebasto hebasto commented Sep 25, 2021

This PR improves code readability.

Only safe cases with guarantee of no undefined behavior.

@DrahtBot
Copy link
Contributor

DrahtBot commented Sep 25, 2021

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #23497 (Add src/node/ and src/wallet/ code to node:: and wallet:: namespaces by ryanofsky)
  • #10443 (Add fee_est tool for debugging fee estimation code by ryanofsky)

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.

@theStack
Copy link
Contributor

Concept ACK

@jarolrod
Copy link
Member

Concept ACK

std::clamp is standard in C++17 and is certainly a nice cleanup versus the existing code. Additionally, this is not a breaking change for windows builders as this is available since VS2015.

@kiminuo
Copy link
Contributor

kiminuo commented Sep 27, 2021

Concept ACK

I wonder whether this is a good candidate or not:

blockcount = std::max(0, std::min(blockcount, pindex->nHeight - 1));

@hebasto
Copy link
Member Author

hebasto commented Sep 27, 2021

@kiminuo

I wonder whether this is a good candidate or not:

blockcount = std::max(0, std::min(blockcount, pindex->nHeight - 1));

Some tests fail with this line being changed.

@kiminuo
Copy link
Contributor

kiminuo commented Sep 27, 2021

@kiminuo

I wonder whether this is a good candidate or not:

blockcount = std::max(0, std::min(blockcount, pindex->nHeight - 1));

In case you think it is a good candidate for changing to std::clamp, it would be helpful to post how you changed the line and a test failure details.

@hebasto
Copy link
Member Author

hebasto commented Sep 27, 2021

@kiminuo

In case you think it is a good candidate for changing to std::clamp, it would be helpful to post how you changed the line and a test failure details.

Here are the branch and tests.

Branch: 7583dee
CI tests: https://cirrus-ci.com/build/4594368825786368

@laanwj
Copy link
Member

laanwj commented Sep 27, 2021

Ouch-if tests fail that means the behavior is not the same. I think we should be careful here. For the C++11 transition we even had an explicit rule not to do all-over-the-place code modernization like this, it's very easy to accidentally introduce a bug. I'm all for using clamp but might be better to introduce it when code is changed anyway.

@maflcko
Copy link
Member

maflcko commented Sep 27, 2021

This is not a trivial replacement. With std::min/max the argument order doesn't matter (min(a,b)==min(b,a)). However, with std::clamp, the order must be exactly right and there is only one correct order.

@martinus
Copy link
Contributor

martinus commented Sep 27, 2021

I think the test has failed because std::clamp's behavior is undefined when when the lo value is bigger than the hi value. For std::clamp(blockcount, 0, pindex->nHeight - 1) this is possible when pindex->nHeight==0

the order must be exactly right and there is only one correct order.

Not only that, there can be cases where there is no order that is always correct :)

@hebasto
Copy link
Member Author

hebasto commented Sep 28, 2021

Updated 82c4e71 -> bf4838e (pr23095.04 -> pr23095.05):

  • rebased
  • addressed comments

Copy link
Contributor

@martinus martinus left a comment

Choose a reason for hiding this comment

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

Code review ACK bf4838e

@hebasto
Copy link
Member Author

hebasto commented Sep 29, 2021

Updated bf4838e -> 665353f (pr23095.05 -> pr23095.06, diff):

  • fixed fuzz test

This change improves code readability.
@hebasto
Copy link
Member Author

hebasto commented Oct 27, 2021

Updated 665353f -> 512dcf7 (pr23095.06 -> pr23095.07) due to the conflict with #23137.

@@ -64,7 +64,7 @@ BlockAssembler::BlockAssembler(CChainState& chainstate, const CTxMemPool& mempoo
{
blockMinFeeRate = options.blockMinFeeRate;
// Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity:
nBlockMaxWeight = std::max<size_t>(4000, std::min<size_t>(MAX_BLOCK_WEIGHT - 4000, options.nBlockMaxWeight));
nBlockMaxWeight = std::clamp<size_t>(options.nBlockMaxWeight, 4000, MAX_BLOCK_WEIGHT - 4000);
Copy link
Member

@laanwj laanwj Nov 9, 2021

Choose a reason for hiding this comment

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

Can we please add a static assert that MAX_BLOCK_WEIGHT >= 8000?

Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't it be better to have a clamp function that does this by default, internally and at compile time? The condition must hold for all call sites.

Copy link
Member

Choose a reason for hiding this comment

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

Though in most cases it's not possible to verify it at compile time, this would handle only the 'between two constexpr' case. In other cases there might be non-trivial error handling.

Copy link
Member

Choose a reason for hiding this comment

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

For the cases where it is not possible to verify at compile time, crashing the node seems preferable over UB. Or is this something that sanitizers can spot?

@laanwj
Copy link
Member

laanwj commented Nov 9, 2021

Code review ACK 512dcf7
I checked all the changes and they look correct to me.

@maflcko
Copy link
Member

maflcko commented Nov 9, 2021

Slightly tend toward NACK. It is non-trivial to review (#23095 (comment)) and easily introduces UB, if the second or third argument are not compile time constants (#23095 (comment)).

@hebasto
Copy link
Member Author

hebasto commented Nov 21, 2021

It is non-trivial to review (#23095 (comment)) and easily introduces UB.

Closing.

@hebasto hebasto closed this Nov 21, 2021
@maflcko
Copy link
Member

maflcko commented Nov 22, 2021

Maybe write a Clamp<int64_t, /*min=*/-1, /*max=*/3>(var); wrapper that has static asserts built in, and another one Clamp that copies std::clamp's signature that asserts/throws/returns optional on UB?

@bitcoin bitcoin locked and limited conversation to collaborators Nov 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants