-
Notifications
You must be signed in to change notification settings - Fork 36.5k
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
qa: Ensure consistent use of decimals instead of floats #31595
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/31595. ReviewsSee the guideline for information on the review process. 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. |
This change fixes tests for Python 3.12.8 and 3.13.1 on NetBSD.
eacc587
to
4fc1056
Compare
🚧 At least one of the CI tasks failed. HintsTry to run the tests locally, according to the documentation. However, a CI failure may still
Leave a comment here, if you need help tracking down a confusing failure. |
It would be good to explain this a bit better and provide a |
Sure! I've updated the PR description with the |
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'm not sure about this, aren't we just masking a bigger problem (i.e. treating floats as if they were real numbers).
Also, can we update any one of the CI tasks to use the latest python to make sure we don't have to fix these manually all the time?
@@ -560,7 +561,7 @@ def check_tx_counts(final: bool) -> None: | |||
prev_tx = n0.getblock(spend_coin_blockhash, 3)['tx'][0] | |||
prevout = {"txid": prev_tx['txid'], "vout": 0, "scriptPubKey": prev_tx['vout'][0]['scriptPubKey']['hex']} | |||
privkey = n0.get_deterministic_priv_key().key | |||
raw_tx = n1.createrawtransaction([prevout], {getnewdestination()[2]: 24.99}) | |||
raw_tx = n1.createrawtransaction([prevout], {getnewdestination()[2]: Decimal("24.99")}) |
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.
Is it important this is a Decimal?
raw_tx = n1.createrawtransaction([prevout], {getnewdestination()[2]: Decimal("24.99")}) | |
raw_tx = n1.createrawtransaction([prevout], {getnewdestination()[2]: "24.99"}) |
Seems to pass as well - floating point values weren't defined to be this precise anyway
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.
Is it important this is a Decimal?
I confirm that your patch works.
... floating point values weren't defined to be this precise anyway
See @mzumsande's comment.
self.generate(node, nblocks=1, sync_fun=lambda: self.sync_all(self.nodes[:2])) | ||
|
||
utxos = wallet.listunspent(addresses=[address]) | ||
psbt = wallet.createpsbt([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{wallet.getnewaddress(): 0.9999}]) | ||
psbt = wallet.createpsbt([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{wallet.getnewaddress(): Decimal("0.9999")}]) |
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.
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, but I'm not familiar with the Python linter capabilities.
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.
It should be trivial to write a python function that accepts json (value/dict/array) and fails if any value is float. The function could be run in authproxy
@@ -78,17 +78,17 @@ def test_psbt_incomplete_after_invalid_modification(self): | |||
node = self.nodes[2] | |||
wallet = node.get_wallet_rpc(self.default_wallet_name) | |||
address = wallet.getnewaddress() | |||
wallet.sendtoaddress(address=address, amount=1.0) | |||
wallet.sendtoaddress(address=address, amount=Decimal("1.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.
is this really better than before?
wallet.sendtoaddress(address=address, amount=Decimal("1.0")) | |
wallet.sendtoaddress(address=address, amount=1) |
or
wallet.sendtoaddress(address=address, amount=Decimal("1.0")) | |
wallet.sendtoaddress(address=address, amount="1") |
Both seem to work
That's the plan for the nightly builds. The working branch is 250102-decimal-demo. |
It'd be good if you could explain what changed in Python 3.12+, and why this is only relevant on NetBSD. (a nightly build isn't strictly needed given many devs already use the latest version of Python locally). |
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.
See python/cpython#128005 (long discussion, skip to this post to save time) for more background on this.
This is NetBSD-specific, and apparently caused by a pkgsrc patch which inadvertently caused sys.float_repr_style
to be "legacy". So the question is if this qualifies as a bug in NetBSD or not and whether we need to accomodate it by moving to Decimals.
@mzumsande thanks for providing the actual context. Given the above, this doesn't seem like a great change. |
The NetBSD's bug in the Python build system has been fixed: |
I could see this going in a different way: not storing RPC parameters as python floats, and changing all such usages to strings instead (as shown in #31595 (comment)). |
I agree with that plus #31595 (comment). |
Why? While we are currently relying on the |
Concept ACK. |
See also #31420 which tried to achieve a similar thing by adding conversion functions with typed parameters. |
Consider two lines from bitcoin/test/functional/rpc_psbt.py Line 683 in a0f0c48
bitcoin/test/functional/rpc_psbt.py Line 706 in a0f0c48
For a code reader without deep knowledge of our test framework, it is quite confusing why two different approaches are used in identical cases. |
Yes, the thing is, |
On NetBSD, with newer Python versions 3.12.8 and 3.13.1, many functional tests fail due to
float
numbers internal representation.A typical error looks as follows:
Running the same test with
--tracerpc
:This PR fixes this issue by consistent use of
Decimal
numbers.