Skip to content

fix(iter): translate_pk to iterate in left-to-right order - #1025

Open
trevarj wants to merge 2 commits into
rust-bitcoin:masterfrom
trevarj:fix-1022-translate-pk-ltr
Open

fix(iter): translate_pk to iterate in left-to-right order#1025
trevarj wants to merge 2 commits into
rust-bitcoin:masterfrom
trevarj:fix-1022-translate-pk-ltr

Conversation

@trevarj

@trevarj trevarj commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

First commit is the actual conversion. Deleted all the
RtlPostOrderIter stuff, which is a breaking change. Let me know if you
want that in a separate commit.

Second commit with the Ext trait can be dropped, but I didn't want to
ruin the readability of Terminal mappings.

Closes #1022

@apoelstra

Copy link
Copy Markdown
Member

In 66c6c9e:

Let's keep rtl_post_order_iter. It's part of the API and implementors of TreeLike get it for free. (And I use TreeLike in a bunch of downstream projects, though I don't know that I ever use the rtl iterator..)

`Miniscript::translate_pk` and `Descriptor::translate_pk`, along with
the concrete and semantic policy equivalents, drove their
reconstruction from a right-to-left post-order iterator. That existed
only so a node could be rebuilt as
`Terminal::AndB(stack.pop().unwrap(), stack.pop().unwrap())`.

- iterate with `post_order_iter` everywhere `rtl_post_order_iter` was used
- bind popped children explicitly so they are passed in left-to-right order
- take n-ary children off the stack with `split_off` rather than repeated pops

Fixes rust-bitcoin#1022
Add a crate-private `StackExt` trait on `Vec<T>` with helper methods
for reconstructing Thresholds.

- `pop2`/`pop3` pop the top two or three elements and pass them, left to
  right, to a constructor or closure
- `pop_n` pops the top `n` elements in order, for the `Vec`-shaped policy nodes
- `pop_thresh` pops a threshold's children and rebuilds it with the same `k`
@trevarj
trevarj force-pushed the fix-1022-translate-pk-ltr branch from 6b3e854 to b413b93 Compare August 16, 2026 14:47
@trevarj

trevarj commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

In 66c6c9e:

Let's keep rtl_post_order_iter. It's part of the API and implementors of TreeLike get it for free. (And I use TreeLike in a bunch of downstream projects, though I don't know that I ever use the rtl iterator..)

restored it and amended into the first commit.

@apoelstra

Copy link
Copy Markdown
Member

In b413b93:

I'd suggest squashing these two commits since the second largely overwrites the first. I like the idea of pulling this into a StackExt trait. Though all the methods should be #[inline] I think.

Then, I don't like the use of split_off, which allocates a whole new vector. You should be able to use Vec::drain to "directly" turn the end of the stack vector into an iterator.

@trevarj

trevarj commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

In b413b93:

I'd suggest squashing these two commits since the second largely overwrites the first. I like the idea of pulling this into a StackExt trait. Though all the methods should be #[inline] I think.

Then, I don't like the use of split_off, which allocates a whole new vector. You should be able to use Vec::drain to "directly" turn the end of the stack vector into an iterator.

roger that. i had it separate in case i needed to drop it off

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.

We should fix translate_pk to iterate in left-to-right order

2 participants