Skip to content

Conversation

jonatack
Copy link
Member

@jonatack jonatack commented Dec 2, 2020

As part of our migration to sat/vB feerates that began with #20305, this pull should resolve #20534 and improve/reduce the size of #20391 that adds a setfeerate RPC in sat/vB, as well as for a future estimatefeerate RPC in sat/vB. The code changes are less than 40 lines. Most of the diff is test coverage, as these changes touch a number of RPCs.

Changes:

  • add CFeeRate::FromSatB and CFeeRate::FromBtcKb named constructors
  • add a CFeeRate::IsZero() class member helper to replace == CFeeRate(0) conditionals and avoid object allocations/constructions
  • add a FeeRateFromValueInSatB() utility function that calls AmountFromValue() and then performs an additional check for non-representable CFeeRate values in the range between 0 and 0.001 sat/vB
  • add unit and functional tests and fill some current fee rate gaps in the functional test coverage

@DrahtBot
Copy link
Contributor

DrahtBot commented Dec 2, 2020

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.

@maflcko
Copy link
Member

maflcko commented Dec 2, 2020

the error message and error code should be the same when an invalid BTC/kb amount is rejected

@maflcko
Copy link
Member

maflcko commented Dec 2, 2020

Concept ACK

@jonatack
Copy link
Member Author

jonatack commented Dec 2, 2020

the error message and error code should be the same when an invalid BTC/kb amount is rejected

The other "too-low" fee messages I am aware of are:

Amount out of range
Fee rate (%s) is lower than the minimum fee rate setting
txfee cannot be less than min relay tx fee
txfee cannot be less than wallet min fee
Invalid amount
Invalid amount for -paytxfee=: '%s' (must be at least %s)
Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)
Invalid amount for -fallbackfee=: '%s'
Invalid amount for -%s=: '%s

@maflcko
Copy link
Member

maflcko commented Dec 2, 2020

It would be confusing if 0.00000001 and 0.000000001 produced different error messages

@jonatack
Copy link
Member Author

jonatack commented Dec 2, 2020

fee_rate=0.000000001

error code: -3
error message:
Invalid amount

...which is not a great error message, as it indicates neither which argument is invalid, nor why. How about:

fee_rate=0.00000001

error code: -3
error message:
Invalid amount for fee_rate (must be at least 0.001 sat/vB)

This is close to these similar error messages:

Invalid amount for -paytxfee=: '%s' (must be at least %s)
Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)
Invalid amount for -fallbackfee=: '%s'
Invalid amount for -%s=: '%s

@jonatack
Copy link
Member Author

jonatack commented Dec 3, 2020

Just found a bug in RPC send. It only allows fee rates to be passed as a number, not as a string. Fixing with a commit here since it fits with the changes. Edit: fixed in #20573 (merged).

@maflcko
Copy link
Member

maflcko commented Dec 3, 2020

...which is not a great error message, as it indicates neither which argument is invalid, nor why.

Then the error message should be fixed. But that is an issue that can be solve completely separate. It shouldn't be a reason to make the behaviour inconsistent.

@jonatack jonatack force-pushed the non-representable-CFeeRate-check branch from 307ecc5 to 03b30e9 Compare December 4, 2020 12:27
@jonatack
Copy link
Member Author

jonatack commented Dec 4, 2020

...which is not a great error message, as it indicates neither which argument is invalid, nor why.

Then the error message should be fixed. But that is an issue that can be solve completely separate. It shouldn't be a reason to make the behaviour inconsistent.

Done. Fixing the rpc send bug and improving the AmountFromValue error messages in separate pulls.

Copy link
Contributor

@fjahr fjahr left a comment

Choose a reason for hiding this comment

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

TBH, I don't understand how this can close #20534 if the behavior is kept consistent. After merge the behavior described there is still the same. An error is caught at the "right" place internally but if the user can't tell the difference this rather seems to be a refactor?

@jonatack
Copy link
Member Author

jonatack commented Dec 5, 2020

The bug fix is that the response is consistent, though I agree it somewhat less user friendly. I have a follow-up that improves the error responses here and in AmountFromValue.

@jonatack
Copy link
Member Author

jonatack commented Dec 5, 2020

I wonder if this check shouldn't be in AmountFromValue and apply to fundrawtransaction and walletcreatefundedpsbt as well.

@jonatack
Copy link
Member Author

jonatack commented Dec 5, 2020

E.g. zero is ok for those but between zero and 0.001 sat/vB is invalid.

@maflcko
Copy link
Member

maflcko commented Dec 5, 2020

the check should be in AmountFromValue. My issue is purely about parsing decimals, not about specific rpcs.

To clarify, I might be misunderstanding what you fix here, but approach NACK if this is a fix for the parsing issue I created.

@jonatack jonatack force-pushed the non-representable-CFeeRate-check branch from 03b30e9 to d580e9c Compare December 6, 2020 19:50
@jonatack jonatack changed the title wallet: check for non-representable CFeeRates (0-0.0009 sat/vB) policy, wallet, refactor: check for non-representable CFeeRates Dec 6, 2020
@jonatack
Copy link
Member Author

jonatack commented Dec 6, 2020

Pulled in the CFeeRate::FromSatB and CFeeRate::FromBtcKb named constructors from the setfeerate PR, added a CFeeRate::IsZero() class member helper, and used these to build a FeeRateFromValueInSatB() utility function. Added unit test coverage for each of these. This should handle the case of parsing decimals for fee rates constructed from sat/vB UniValue values.

@jonatack jonatack force-pushed the non-representable-CFeeRate-check branch from 7d6c6aa to 670c6ef Compare December 7, 2020 14:55
@jonatack
Copy link
Member Author

jonatack commented Dec 7, 2020

rebased

Copy link
Contributor

@fjahr fjahr 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

Thanks for compressing this a bit, makes it easier to review for me at least. I had some thoughts but no major issues. Will follow up soon with another pass.

@jonatack jonatack force-pushed the non-representable-CFeeRate-check branch from 1fc25a4 to 236f556 Compare January 26, 2021 16:31
@jonatack
Copy link
Member Author

Thanks for reviewing @fjahr, updated with your feedback per git diff 1fc25a4 236f556

@fjahr
Copy link
Contributor

fjahr commented Jan 26, 2021

Code review ACK 236f556

Copy link
Member

@jarolrod jarolrod left a comment

Choose a reason for hiding this comment

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

ACK 236f556

This PR fixes the behavior shown in #20534

Master: Not representable, should through error code: -3

./src/bitcoin-cli -regtest -named sendtoaddress address=<addr> amount=1.23 fee_rate=0.0009

error code: -6
error message:
Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)

PR: throws error code: -3

./src/bitcoin-cli -regtest -named sendtoaddress address=<addr> amount=1.23 fee_rate=0.0009

error code: -3
error message:
Invalid amount

@maflcko maflcko changed the title policy, wallet, refactor: check for non-representable CFeeRates policy, wallet: check for non-representable CFeeRates Jan 27, 2021
@maflcko maflcko changed the title policy, wallet: check for non-representable CFeeRates wallet: check for non-representable CFeeRates Jan 27, 2021
@maflcko
Copy link
Member

maflcko commented Jan 27, 2021

(changed title because the only behaviour changes are in the wallet and this is not a refactor)

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

Approach re-NACK

Concept ACK

NACK 236f556 😰

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

NACK 236f556708fb619167b72cca451d0048a9274646 😰
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUgD5Av/Xab0IOByGeikbyUJLvFeyqNKCpgDZOwPp8IH3gMOw0RsQSOTba1Mw/mi
TYwJbgZs861puVMSvVGcdp3knH4GsE2SnhX/h3h3ozL1lEu0s4K0uksel7PtrwWH
Om4oCDT3kNNAcrGE/HBvCk723gx3JwT5zOWbBv6X//ESGrkUM9+yMbg3od4HBhmG
o24Ju8mugPXPKY9eQ+IG2RzXWItZPVVJIQBOVgD5awIBy15rgK50oOnLbT/8Mw8/
xbgaOZJzmt+3VczxsOTX+Qp+FMvX1fEJgO4Blsrk5bx2COy+tMst3lU16Vw9vcjh
huXxo7VdqiFPZB/q0BRg1Ysxl2o8o6ldKhrFm/W6Vtr5v3iIYxg7PTVjZAsJY98a
6DFpasP/KkWRwJSbqT63GETinOE+hKlu8sZO2X8R0NRGsyF+d9Lkyjq0FJsn4GDu
fcPe1KUYGa0nKQB7TvbZSBHxZ/eM84Qg1tCtX88rVLgXtuQCnFt92aW0l5PScw1I
4tC98cjZ
=4KcO
-----END PGP SIGNATURE-----

Timestamp of file with hash d9e37613c2875ff346833a9cd2c564a076e87e0eb46dd8c7fa743c1e891d0796 -

const CAmount amount{AmountFromValue(value)};
const CFeeRate fee_rate{CFeeRate::FromSatB(amount)};
if (fee_rate.IsZero() && amount != 0) {
// passed value is an unrepresentable fee rate between 0 and 0.001 sat/vB
Copy link
Member

Choose a reason for hiding this comment

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

8885b72: Whether a feerate is representable or not has nothing to do with 0

9.99999999999999999999999999999 isn't representable and also isn't zero

Copy link
Member

Choose a reason for hiding this comment

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

You need to fix this in AmountFromValue, as I pointed out earlier: #20546 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you explain how and why this needs to be in AmountFromValue? Do we pass in an is_sat_b_fee_rate bool to it, so it has context? Is that an improvement over a dedicated function? I feel like I'm failing to read your mind on this since a couple months now.

Copy link
Member Author

Choose a reason for hiding this comment

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

dropped the comment

Copy link
Member

Choose a reason for hiding this comment

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

AmountFromValue parses the string and fails if the amount is not representable, thus any check about representability should be in AmountFromValue.

btc/kb are representable when there are at most 8 digits. sat/b are representable when there are at most 3 digits. How you pass in the digits shouldn't matter. Can be done as normal argument or template argument (and function alias, if this makes the code easier to read).

@jonatack
Copy link
Member Author

jonatack commented Jan 27, 2021

This PR fixes the behavior shown in #20534

Master: Not representable, should through error code: -3

./src/bitcoin-cli -regtest -named sendtoaddress address=<addr> amount=1.23 fee_rate=0.0009

error code: -6
error message:
Fee rate (0.000 sat/vB) is lower than the minimum fee rate setting (1.000 sat/vB)

PR: throws error code: -3

./src/bitcoin-cli -regtest -named sendtoaddress address=<addr> amount=1.23 fee_rate=0.0009

error code: -3
error message:
Invalid amount

Thanks for testing! This shows that the error message here isn't as helpful as it could be, but I have a branch that improves the various error messages as a follow-up.

@jonatack
Copy link
Member Author

NACK 236f556

Can you explain why?

@maflcko
Copy link
Member

maflcko commented Jan 27, 2021

NACK 236f556

Can you explain why?

because it doesn't fix the bug. See:

$ ./src/bitcoin-cli -named sendtoaddress address=bcrt1qwkmhqum095zau5rf2velq55cq938vrd7uw8m4r amount=1.23 fee_rate=31.999999999999999999999
error code: -3
error message:
Invalid amount
$ ./src/bitcoin-cli -named sendtoaddress address=bcrt1qwkmhqum095zau5rf2velq55cq938vrd7uw8m4r amount=1.23 fee_rate=31.99999999
ac1ee7d06c8a276a148bf2378539c957bba643ba343f102779d618d5c95b9049

Both calls should fail because the amount is not representable

@jonatack
Copy link
Member Author

Ah, thanks for explaining. I thought that comment was referring to the commit.

@DrahtBot
Copy link
Contributor

DrahtBot commented Apr 5, 2021

🐙 This pull request conflicts with the target branch and needs rebase.

Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft".

@jonatack
Copy link
Member Author

Can you explain why?

because it doesn't fix the bug. See:

$ ./src/bitcoin-cli -named sendtoaddress address=bcrt1qwkmhqum095zau5rf2velq55cq938vrd7uw8m4r amount=1.23 fee_rate=31.99999999
ac1ee7d06c8a276a148bf2378539c957bba643ba343f102779d618d5c95b9049

This patch fixes the issue described in #20534 "values smaller than 0.001 sat/B can't be represented by CFeeRate, but they are not rejected" but I agree this should also be fixed. The approach here won't suffice so am trying a different one.

@jonatack
Copy link
Member Author

Closing for now in favor of #21786.

@jonatack jonatack closed this Apr 27, 2021
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 18, 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.

sat/b values aren't validated to be in-range
8 participants