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

feat: actually check push data bytes #743

Merged
merged 1 commit into from
Sep 7, 2024

Conversation

ChrisCho-H
Copy link
Contributor

Miniscript witness item can be maximum 72 bytes(except length prefix), but it only throws error when it's >= 4294967296 bytes as only dependant on PushBytesError from bitcoin crate. I've changed the logic to check the maximum length internally so that actual check can be done.

@apoelstra
Copy link
Member

Is it possible to hit these new error paths? I think the Satisfier trait is only able to produce witnesses that are in-range (no matter how maliciously you implement it) because all its methods return types that have limited size.

@apoelstra
Copy link
Member

Oh, of course, the script itself could be too large! Ok concept ACK.

@apoelstra
Copy link
Member

....which I think is also what's triggering your new tighter expect in witness_to_scriptsig. Interesting. I think this is an existing panicking bug in rust-miniscript. (Though kinda an academic one since to trigger it in our existing code you need to construct a Miniscript which encodes to more than 4Gb.) (But upstream we are considering tightening this to 32M to match Bitcoin consensus rules, and in that case we need to fix this!!)

@ChrisCho-H
Copy link
Contributor Author

ChrisCho-H commented Sep 6, 2024

My trigger is actually just the error message of All pushes in miniscript are < 73 bytes. It seems weird not to check the maximum bytes with such error message.

However, I've realized that it needs to allow the script itself from your comment... maybe we can allow 520 bytes(using MAX_SCRIPT_ELEMENT_SIZE) for redeem script(which is the last element of vector for p2sh, but not for bare) and 72 bytes for others?

The problem you mentioned might belong to PushBytes itself in bitcoin crate, not specific to witness_to_scriptsig.

@ChrisCho-H
Copy link
Contributor Author

ChrisCho-H commented Sep 6, 2024

I've added the logic to check the size of redeem script and other push separately 9dbaad3.

Or we might change only the error message, which confuses.

@apoelstra
Copy link
Member

I would suggest squashing these two commits because they have substantial overlap in the code that they change.

Secondly, I'm struggling to understand the point of calling map_err and and_then on something we're just going to unwrap.

My suggestion, if you want to make the assertion more precise, would be to add a debug_assert above the push line, then change the expect message to just say "checked above".

Your method of checking whether we are on the last push is also pretty inefficient. One better way to do this is to add .enumerate() to the iterator and then compare the index to witness.len() - 1.

@apoelstra
Copy link
Member

It can also be a real assert if you want. No need to debug_assert.

@ChrisCho-H ChrisCho-H force-pushed the feature/push-bytes-check branch from 9dbaad3 to 324b33d Compare September 7, 2024 06:11
@ChrisCho-H
Copy link
Contributor Author

Thanks for great review! I've fixed following your suggestion.

@apoelstra
Copy link
Member

324b33d is looking great!

But now it doesn't look like witness_to_scriptsig actually returns an error anywhere :).

Could this PR be reduced to just adding the new assertions and not changing the signature of witness_to_scriptsig at all?

@ChrisCho-H ChrisCho-H force-pushed the feature/push-bytes-check branch from 324b33d to e2e9281 Compare September 7, 2024 16:05
@ChrisCho-H
Copy link
Contributor Author

You are right. No need to change the original signature. Reduced down by e2e9281!

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 e2e9281 successfully ran local tests; thanks for iterating!

@apoelstra apoelstra merged commit 51cadfc into rust-bitcoin:master Sep 7, 2024
30 checks passed
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.

2 participants