Skip to content
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

test: Fix SegwitV0SignatureMsg nLockTime signedness #29400

Merged
merged 1 commit into from
Feb 21, 2024

Conversation

maflcko
Copy link
Member

@maflcko maflcko commented Feb 7, 2024

It is unsigned in Bitcoin Core, so the tests should match it:

ss << txTo.nLockTime;

The bug was introduced when the code was written in 330b0f3.

(Lowercase i means signed, see https://docs.python.org/3/library/struct.html#format-characters)

@DrahtBot
Copy link
Contributor

DrahtBot commented Feb 7, 2024

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

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK epiccurious, Eunovo, achow101

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #29401 (test: Remove struct.pack from almost all places by maflcko)

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.

@DrahtBot DrahtBot added the Tests label Feb 7, 2024
@maflcko
Copy link
Member Author

maflcko commented Feb 7, 2024

This can be tested by passing a transaction with a large locktime and then observing the error:

struct.error: 'i' format requires -2147483648 <= number <= 2147483647

@@ -747,7 +747,7 @@ def SegwitV0SignatureMsg(script, txTo, inIdx, hashtype, amount):
ss += struct.pack("<q", amount)
ss += struct.pack("<I", txTo.vin[inIdx].nSequence)
ss += ser_uint256(hashOutputs)
ss += struct.pack("<i", txTo.nLockTime)
ss += txTo.nLockTime.to_bytes(4, "little")
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we keep the format?

Suggested change
ss += txTo.nLockTime.to_bytes(4, "little")
struct.pack("<I", txTo.nLockTime)

In the instructions you've mentioned it's reproducible - can you add a test that fails before this change, but passes after?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, you can try this with the following diff:

diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index d316c4b602..708e4d7e8f 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -1663,6 +1663,7 @@ class SegWitTest(BitcoinTestFramework):
         pubkeyhash = hash160(pubkey)
         script_pkh = key_to_p2wpkh_script(pubkey)
         tx = CTransaction()
+        tx.nLockTime = 0xffffffff
         tx.vin.append(CTxIn(COutPoint(temp_utxos[0].sha256, temp_utxos[0].n), b""))
         tx.vout.append(CTxOut(temp_utxos[0].nValue, script_pkh))
         tx.wit.vtxinwit.append(CTxInWitness())

To add a test, you may have to disable the locktime by setting the sequence number to the right value as well.

I am happy to push a commit that adds a test, if someone writes one.

Copy link

Choose a reason for hiding this comment

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

can you add a test that fails before this change, but passes after?

Wouldn't that mean that we added a test that tests the test-framework?

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 add a test that fails before this change, but passes after?

Wouldn't that mean that we added a test that tests the test-framework?

Yes, it should be possible to write an internal python unit test to check the behavior of SegwitV0SignatureMsg. An alternative would be to extend a python functional test to cover more values of nLockTime and compare the SegwitV0SignatureMsg behavior against Bitcoin Core via the RPC interface.

@epiccurious
Copy link
Contributor

Tested ACK fab1572.

@Eunovo
Copy link

Eunovo commented Feb 21, 2024

Tested ACK fab1572
Reproduced the error by setting nLockTime to 2147483648

@achow101
Copy link
Member

ACK fab1572

@achow101 achow101 merged commit 88b1229 into bitcoin:master Feb 21, 2024
16 checks passed
@maflcko maflcko deleted the 2402-test-fix-sign-3- branch February 22, 2024 07:46
achow101 added a commit that referenced this pull request Jun 6, 2024
fa52e13 test: Remove struct.pack from almost all places (MarcoFalke)
fa826db scripted-diff: test: Use int.to_bytes over struct packing (MarcoFalke)
faf2a97 test: Use int.to_bytes over struct packing (MarcoFalke)
faf3cd6 test: Normalize struct.pack format (MarcoFalke)

Pull request description:

  `struct.pack` has many issues:

  * The format string consists of characters that may be confusing and may need to be looked up in the documentation, as opposed to using easy to understand self-documenting code.

  This lead to many test bugs, which weren't hit, which is fine, but still confusing. Ref: #29400, #29399, #29363, fa3886b, ...

  Fix all issues by using the built-in `int` helpers `to_bytes` via a scripted diff.

  Review notes:

  * For `struct.pack` and `int.to_bytes` the error behavior is the same, although the error messages are not identical.
  * Two `struct.pack` remain. One for float serialization in a C++ code comment, and one for native serialization.

ACKs for top commit:
  achow101:
    ACK fa52e13
  rkrux:
    tACK [fa52e13](fa52e13)
  theStack:
    Code-review ACK fa52e13

Tree-SHA512: ee80d935b68ae43d1654b047e84ceb80abbd20306df35cca848b3f7874634b518560ddcbc7e714e2e7a19241e153dee64556dc4701287ae811e26e4f8c57fe3e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants