Skip to content

Remove CheckedHrpString::validate_segwit method - #288

Merged
apoelstra merged 3 commits into
rust-bitcoin:masterfrom
apoelstra:2026-07/segwit-validate
Jul 30, 2026
Merged

Remove CheckedHrpString::validate_segwit method#288
apoelstra merged 3 commits into
rust-bitcoin:masterfrom
apoelstra:2026-07/segwit-validate

Conversation

@apoelstra

@apoelstra apoelstra commented Jul 24, 2026

Copy link
Copy Markdown
Member

This appears to be a helper function for SegwitHrpString::new which shouldn't have been in the public API. In fact, it's not even very useful in the private API -- once you remove all the redundant checks then it's only 3-4 lines of code which are better off inlined into SegwitHrpString::new.

Fixes #274

Fixes #291

@tcharding tcharding left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK db43371

@tcharding

tcharding commented Jul 27, 2026

Copy link
Copy Markdown
Member

diffstat +24 -52 with improved checks - WIN. Thanks man.

@clarkmoody clarkmoody left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK db43371

@apoelstra
apoelstra force-pushed the 2026-07/segwit-validate branch from db43371 to d661b2c Compare July 27, 2026 16:33
@apoelstra

Copy link
Copy Markdown
Member Author

Fixed formatting (sorry)

This method is weirdly confused. It does some, but not all, of the
checks required for a CheckedHrpString to be a valid Segwit string. Some
of the checks it *does* do (in particular, the empty data and maximum
length checks) are redundant with checks done in SegwitHrpString::new.

It does not check that the witness version is a valid witness version.
But worse, it *cannot* check that the witness version matches the
checksum, because CheckedHrpString does not keep track of the checksum
that was used when constructing it, and Segwit uses a different checksum
depending on its version number.

It appears that this method is a helper method for SegwitHrpString::new
which got into the public API (by accident?). But it doesn't make sense
for the public to call it, and it doesn't even really make sense for
SegwitHrpString::new to call it, since it does overlapping checks so
that inlining it turns out to be only 3-4 lines of code.

It was also called by SegwitHrpString::new_bech32, a very weird method
which is covered in "do not use this" warnings but which is apparently
needed for old PSBT users or something. This method lacks several of the
checks of SegwitHrpString::new, including the length checks. To fix
this, we refactor SegwitHrpString::new into a new `new_internal` method
which has a boolean flag to override the bech32/bech32m switch, and then
both SegwitHrpString::new and SegwitHrpString::new_bech32 can just pass
through to this.

So the result is a net reduction in code, despite an increase in the
number of checks that we're doing.

The next commit will delete even more code, since a consequence of this
refactor is that the CheckedHrpString::hrpstring_length field is no
longer used.

This mess originates in rust-bitcoin#117
by Tobin -- but in his defense, he was implementing a huge feature and
there was a ton of review iteration, so it's unsurprising that some
weirdness slipped in.
This was only used by the broken segwit validation functions, which were
removed in the last commit.
@apoelstra
apoelstra force-pushed the 2026-07/segwit-validate branch from d661b2c to 9e69b81 Compare July 27, 2026 18:53
@apoelstra

Copy link
Copy Markdown
Member Author

Added regression test for #291 which this apparently fixes too.

@apoelstra
apoelstra force-pushed the 2026-07/segwit-validate branch from 9e69b81 to cfded00 Compare July 27, 2026 19:05

@tcharding tcharding left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ACK cfded00

@apoelstra

Copy link
Copy Markdown
Member Author

On cfded00 successfully ran local tests

@apoelstra
apoelstra merged commit 4a96295 into rust-bitcoin:master Jul 30, 2026
22 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.

Index-out-of-bounds panic in SegwitHrpstring::new_bech32 on empty data part CheckedHrpstring::validate_segwit accepts witness version > 16

3 participants