Skip to content

Conversation

@apoelstra
Copy link
Member

This introduces a new iter module with facilities for iterating over tree structures, and uses it to eliminate a bunch of recursion.

There's a lot more "obvious" work after this, so I figured I'd PR this now for review and then do followup ones if it's accepted.

Then there's some less obvious work around getting rid of the recursion in Expression::from_str and tightening up the memory allocation/locality there, and some even less obvious work in improving memory allocation/locality in Miniscript. But even if those later stages don't work out, this is a step in the right direction because it eliminates a bunch of stack overflow vectors, and reduces the amount of code.

@apoelstra apoelstra force-pushed the 2023-07--dag-overhaul branch from 311135f to 6250791 Compare July 14, 2023 23:50
Introduces the new `iter` module which provides iteration abilities over
various tree-like structures. This is largely copied from
rust-simplicity, but is both simpler (because there is no sharing) and
more complicated (because we need to handle n-ary nodes, not just binary
ones).

This currently uses Arc<[T]> in a number of places; we should eventually
replace these with some sort of ArrayVec-type structure.
This is a breaking change because we no longer implement `ForEachKey` on
`Terminal`. But IMHO we should never have implemented that trait (or any
trait, really..) directly on `Terminal`. The fact that we did was just
an implementation detail of how we used to do a lot of iteration.
@apoelstra apoelstra force-pushed the 2023-07--dag-overhaul branch 3 times, most recently from 654e234 to 0576007 Compare July 15, 2023 14:48
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.

Some commits are empty? Is that intentional.

ACK 0576007.

_ => {}
}
}
true
Copy link
Member

Choose a reason for hiding this comment

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

After reading about possible compiler optimization speedup from using functional style code. I feel we can write this as:

  self.pre_order_iter().all(|ms| match ms.node {
      Terminal::PkK(ref p) => pred(p),
      Terminal::PkH(ref p) => pred(p),
      Terminal::Multi(_, ref keys) | Terminal::MultiA(_, ref keys) => {
          keys.iter().all(|k| pred(k))
      }
      _ => true,
  })

Copy link
Member

Choose a reason for hiding this comment

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

@sanket1729
Copy link
Member

Agreed, this is a step in the right direction.

@sanket1729
Copy link
Member

I can merge these and address the nits in a follow up PR. Just waiting for your response about the empty commits.

@apoelstra
Copy link
Member Author

@sanket1729 no, I'll remove the empty commits. I believe those occur during rebasing when my gpg agent fails to sign a commit.

I'll do that and then you can merge this. For optimizations I think we should first introduce a wider set of benchmarks (miniscript parsing from string, decoding from script, serializing to string, encoding to script, then some borderline-trivial key conversions etc).

This is again a breaking change because we remove the trait impl from
`Terminal`, but again I don't think the trait impl should've existed.

This also exposed an "off-label" use of `real_translate_pk` to convert
context types as well as pk types, which I apparently explicitly reviewed
and ACKed when reviewing rust-bitcoin#426, but which in retrospect looks a little
funny. Rename this function to translate_pk_ctx so it's clear that it's
doing two jobs.
As usual, we remove a method of the same name from `Terminal`, which is
a breaking change.
As always, dropping the same method from Terminal
@apoelstra apoelstra force-pushed the 2023-07--dag-overhaul branch from 0576007 to 67e91b9 Compare July 16, 2023 13:37
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.

reACK 67e91b9

@sanket1729 sanket1729 merged commit 9cf6e9d into rust-bitcoin:master Jul 16, 2023
@apoelstra apoelstra deleted the 2023-07--dag-overhaul branch July 17, 2023 13:22
@@ -0,0 +1,93 @@
// Written in 2023 by Andrew Poelstra <apoelstra@wpsoftware.net>
Copy link
Member

Choose a reason for hiding this comment

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

Hey @apoelstra, I saw this line and wondered if you added it as a habit or if I have been annoying you by removing them? Or was this PR just before we discussed all that? Cheers.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it predates your PR to remove these. I would've just mildlessly copied the line from other files.

I'm certainly not annoyed :).

Copy link
Member

Choose a reason for hiding this comment

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

Sweet man, cheers.

heap-coder added a commit to heap-coder/rust-miniscript that referenced this pull request Sep 27, 2025
67e91b9115031c7f773b67314370685e0c5d2f03 miniscript: eliminate recursion in substitute_raw_pkh (Andrew Poelstra)
d858ffc30643261189d805391e5a17a26cc53f80 miniscript: remove recursion from script_size (Andrew Poelstra)
8c32a19b4813b7030bc6851a30a1d38ce4241bc3 miniscript: eliminate recursion from TranslatePk (Andrew Poelstra)
2930938783f9953e1c1c9b3f14ab7131b92e1787 miniscript: eliminate recursion in for_each_key (Andrew Poelstra)
3c0ff73d14e0a570225cec3a543bb0191e38acda iter: add module, copied in large from rust-simplicity (Andrew Poelstra)

Pull request description:

  This introduces a new `iter` module with facilities for iterating over tree structures, and uses it to eliminate a bunch of recursion.

  There's a lot more "obvious" work after this, so I figured I'd PR this now for review and then do followup ones if it's accepted.

  Then there's some less obvious work around getting rid of the recursion in `Expression::from_str` and tightening up the memory allocation/locality there, and some even less obvious work in improving memory allocation/locality in `Miniscript`. But even if those later stages don't work out, this is a step in the right direction because it eliminates a bunch of stack overflow vectors, and reduces the amount of code.

ACKs for top commit:
  sanket1729:
    reACK 67e91b9115031c7f773b67314370685e0c5d2f03

Tree-SHA512: 30038e2e185f9ff5a87d32508a03db61f7de9997900ce381df3974f5dc1818402a2b444808907f5d849f7ca2f9812dd0c2f578a4fbad56ef2cd01b9382a60d70
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.

3 participants