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

Enforce segwit v0 script validity when creating address. #1021

Merged
merged 1 commit into from Jun 1, 2022

Conversation

nlanson
Copy link
Contributor

@nlanson nlanson commented May 28, 2022

Adds a check in Address::from_script() that checks if segwit v0 scripts have a valid length.

Fix: #995

@nlanson
Copy link
Contributor Author

nlanson commented May 28, 2022

Related discussion: #648
I believe Address should guarantee validity, so from_script is wrong. It'd be also great to return Result instead of Option but that's for another PR.
Originally posted by @Kixunil in #995 (comment)

I will also do this in a separate PR.

@Eunoia1729
Copy link
Contributor

Eunoia1729 commented May 28, 2022

Was working on the same issue today. Looks good to me!
tACK 971c285

What do you think about adding tests for the same?

@@ -672,6 +672,13 @@ impl Address {

/// Constructs an [`Address`] from an output script (`scriptPubkey`).
pub fn from_script(script: &script::Script, network: Network) -> Option<Address> {
Copy link
Contributor

@dpc dpc May 28, 2022

Choose a reason for hiding this comment

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

It might not be to be done in this PR, but if we have multiple ways of "not turning script into an address", maybe we should make it enum Error { ... list all the ways things can go wrong ... }, so the caller has something better to show to the user than just "didn't turn into address".

Copy link
Contributor Author

@nlanson nlanson May 29, 2022

Choose a reason for hiding this comment

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

Agreed. Address::from_script() and a few other functions should return Result<_, Error> instead of Option<> but this is for another PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

#1022 just to not forget.

@nlanson
Copy link
Contributor Author

nlanson commented May 29, 2022

What do you think about adding tests for the same?

I have left out tests as I thought the change wasn't so significant and existing tests covered cases where it won't fail, however I am happy to add tests for cases where it is expected to fail and squash it into the commit.

@Kixunil
Copy link
Collaborator

Kixunil commented May 30, 2022

tests for cases where it is expected to fail

This would be really great

apoelstra
apoelstra previously approved these changes May 30, 2022
Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

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

ACK 971c285

@apoelstra
Copy link
Member

ACK, though I agree that tests would be greatly appreciated

src/util/address.rs Outdated Show resolved Hide resolved
src/util/address.rs Outdated Show resolved Hide resolved
@nlanson
Copy link
Contributor Author

nlanson commented May 31, 2022

6c10d77 Squashed in unit tests and checks to see if scripts are valid in general if witness version is v0.

I also had a play around with trying to add similar checks for v1 scripts for consistency, however adding the checks would fail one case in test_bip173_350_vectors() so I have left it out for now. However, I think that it would be best to be consistent across v0 and v1 scripts and fail if v1 scripts are invalid as well.

The particular case that fails when the v1 check is present is: ("bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kt5nd6y", "5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6") .
This fails since the address successfully converts into a script through the Address::from_str() function, but the script cannot be converted back into an address through the Address::from_script() function as the script is not a valid p2tr script. Might be intentional but there is a missing check for v1 witness program lengths in Address::from_str()?

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

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

ACK 6c10d77

@tcharding
Copy link
Member

@nlanson I change the issue mention in the PR desciption so that GitHub would pick it up and auto-close the issue when merging. Hope you don't mind.

@nlanson nlanson changed the title Enforce segwit v0 script lengths when creating address. Enforce segwit v0 script validity when creating address. Jun 1, 2022
@sanket1729
Copy link
Member

We also need to check the length of witness program when creating a witness variant of Payload.

Accoridng to definition of witness program in BIP141

A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (for 0 to 16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program".

We need to check the between 2 and 40 bytes constraint in the Payload::from_script function too.

Copy link
Member

@sanket1729 sanket1729 left a comment

Choose a reason for hiding this comment

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

ACK 6c10d77. Left a comment can be addressed in separate PR.

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

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

ACK 6c10d77

@apoelstra apoelstra merged commit 57eaf13 into rust-bitcoin:master Jun 1, 2022
@tcharding
Copy link
Member

We also need to check the length of witness program when creating a witness variant of Payload.

@nlanson do you want this one? Just asking so I dont tread on your toes, cheers.

@nlanson nlanson deleted the addr_from_script_check branch June 2, 2022 01:26
@nlanson
Copy link
Contributor Author

nlanson commented Jun 2, 2022

We also need to check the length of witness program when creating a witness variant of Payload.

@nlanson do you want this one? Just asking so I dont tread on your toes, cheers.

I believe this is already done: #1022 (comment)

ChallengeDev210 pushed a commit to ChallengeDev210/rust-bitcoin that referenced this pull request Aug 1, 2022
…ty when creating address.

6c10d77 Address::from_script() - Check witness v0 program lengths. (Noah)

Pull request description:

  Adds a check in `Address::from_script()` that checks if segwit v0 scripts have a valid length.

  Fix: #995

ACKs for top commit:
  tcharding:
    ACK 6c10d77
  sanket1729:
    ACK 6c10d77. Left a comment can be addressed in separate PR.
  apoelstra:
    ACK 6c10d77

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

Successfully merging this pull request may close these issues.

Bug in Address <-> String conversion?
7 participants