Skip to content

Conversation

maflcko
Copy link
Member

@maflcko maflcko commented May 4, 2021

Currently the constructor is architecture dependent. This is confusing for several reasons:

  • It is impossible to create a transaction larger than the max value of uint32_t, so a 64-bit size_t is not needed
  • Policy (and consensus) code should be arch-independent
  • The current code will print spurious compile errors when compiled on 32-bit systems:
policy/feerate.cpp:23:22: warning: result of comparison of constant 9223372036854775807 with expression of type 'size_t' (aka 'unsigned int') is always true [-Wtautological-constant-out-of-range-compare]
    assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));

Fix all issues by making it arch-independent. Also, fix {} style according to dev notes.

@practicalswift
Copy link
Contributor

Strong concept ACK

I've always found the now cleaned up code confusing. Thanks for making the code easier to reason about.

@maflcko
Copy link
Member Author

maflcko commented May 4, 2021

I wrote the assert in #7796, so it might be partially my fault

@practicalswift
Copy link
Contributor

Also, fix {} style according to dev notes.

Good!

Important note which may not be immediately clear for all reviewers:

int32_t i{j}; is not necessarily equivalent to int32_t i = j; or int32_t i(j);.

Thus the choice of {}-initialization is not a cosmetic style choice.

int32_t i{j}; is the preferred choice not because it looks nicer, but because it is safer.

Safer how?

Live demo:

$ cling
[cling]$ #include <cstdint>
[cling]$ int64_t j = 2147483648
(long) 2147483648
[cling]$ int32_t non_uniform_1 = j
(int) -2147483648
[cling]$ int32_t non_uniform_2(j)
(int) -2147483648
[cling]$ int32_t uniform{j}
input_line_9:2:18: error: non-constant-expression cannot be narrowed from type 'int64_t' (aka 'long') to 'int32_t' (aka 'int') in initializer list

Note the silent narrowing from 2147483648 to -2147483648 for = j and (j), but not for {j}.

That is why the {}-initializer syntax is said to be safer than the other forms of initializations: by using {} we're guaranteed not to be hit by an unexpected narrowing conversion.

See also C++ Core Guidelines: ES.23: Prefer the {}-initializer syntax.

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

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

Approach ACK

Maybe write "architecture" instead of "arch" (I first thought this was about arch linux 😄)

@maflcko maflcko changed the title refactor: Make CFeeRate constructor arch-independent refactor: Make CFeeRate constructor architecture-independent May 4, 2021
@DrahtBot
Copy link
Contributor

DrahtBot commented May 4, 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:

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.

@practicalswift
Copy link
Contributor

Our automated reviewer friend -fsanitize=integer found the need to also update the fee rate fuzzing harness to make it stay in sync with the function signature changes suggested in this PR :)

test/fuzz/fee_rate.cpp:25:31: runtime error: implicit conversion from type 'size_t' (aka 'unsigned long') of value 55834574847 (64-bit, unsigned) to type 'uint32_t' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned)

@maflcko
Copy link
Member Author

maflcko commented May 5, 2021

Thanks, fixed

Copy link
Contributor

@promag promag 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 fa77633.

@maflcko maflcko force-pushed the 2105-feerate branch 2 times, most recently from fa8cd28 to fa748a6 Compare May 12, 2021 13:20
Copy link
Contributor

@promag promag 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 fa748a6.

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

Concept ACK

Right now the initialization of nSize from num_bytes is slightly different in the ctor CFeeRate::CFeeRate(...) and the method CFeeRate::GetFee(...). Both could use const int64_t nSize{num_bytes}, as also suggested at one place by promag (#21848 (comment))?

Copy link
Contributor

@theStack theStack 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 fa12128
nit: Doesn't matter much in those short methods, but if for any reason you need to retouch, you could add a const in front of int64_t nSize{num_bytes}; (both instances).

@maflcko
Copy link
Member Author

maflcko commented May 18, 2021

Added const

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

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

re-ACK fafd121

@maflcko maflcko requested a review from promag May 24, 2021 06:20
Copy link
Contributor

@promag promag 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 fafd121.

#include <tinyformat.h>

CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_)
CFeeRate::CFeeRate(const CAmount& nFeePaid, uint32_t num_bytes)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit

CFeeRate::CFeeRate(const CAmount& nFeePaid, uint32_t num_bytes)
    : nSatoshisPerK(num_bytes > 0 ? nFeePaid * 1000 / int64_t{num_bytes} : 0)
{
}

And make const CAmount nSatoshisPerK.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice, but adding const can be done in a follow-up

@maflcko maflcko merged commit ce4a852 into bitcoin:master May 24, 2021
@maflcko maflcko deleted the 2105-feerate branch May 24, 2021 09:21
@hebasto
Copy link
Member

hebasto commented May 24, 2021

This PR effectively fixes the bug from #19735.

👍

sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 25, 2021
gwillen pushed a commit to ElementsProject/elements that referenced this pull request Jun 1, 2022
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 16, 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.

9 participants