Skip to content

Policy fixes #170

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

Merged
merged 7 commits into from
Aug 20, 2023
Merged

Conversation

uncomputable
Copy link
Collaborator

@uncomputable uncomputable commented Aug 16, 2023

Adds fixes to make Policy work with Miniscript, descriptors and the Simplicity wallet.

The only controversial change should be the implementation of Simplicity key traits for every Miniscript key. This introduces a diamond pattern: rust-miniscript → rust-simplicity → elements-miniscript and rust-miniscript → elements-miniscript. The situation is not ideal, but it avoids violating the orphan rule that caused us so much trouble.

In particular we need to convert elements_miniscript::Satisfier (with Miniscript keys) into simplicity::Satisfier (with Simplicity keys). We could make elements_miniscript::Satisfier a subtrait of simplicity::Satisfier, but we would have to do that for every generic implementation of elements_miniscript::Satisfier. We would need to copy code to rust-simplicity and implement simplicity::Satisfier for nonsensical types such as HashMap<Pk, ElementsSig>.

The diamond pattern seems like a good solution that will work until we have a better architecture. It allows us to use Miniscript and Simplicity keys interchangeably, while all the messy Simplicity details stay inside rust-simplicity.

@@ -215,6 +215,19 @@ impl<Pk: SimplicityKey> Policy<Pk> {
_ => {}
}
}

/// Return an iterator over the fragments of the policy.
Copy link
Collaborator

Choose a reason for hiding this comment

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

In a036b0b:

You mention maybe using the dag module in the commit message -- actually we should use the miniscript::iter module which will be available in rust-miniscript 11.0. rust-bitcoin/rust-miniscript#567

But for now it's fine to have a manual implementation.

Copy link
Collaborator Author

@uncomputable uncomputable Aug 18, 2023

Choose a reason for hiding this comment

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

I see. Miniscript's iter module is the cousin of Simplicity's dag module. I look forward to using it :)

@apoelstra
Copy link
Collaborator

Will ACK, but I'd kinda like the std::hash::Hash thing to be changed before merging.

@@ -17,6 +17,7 @@ path = "src/lib.rs"

[dependencies]
bitcoin = { version = "0.30.0", optional = true }
bitcoin-miniscript = { package = "miniscript", version = "10.0" }
Copy link
Collaborator

Choose a reason for hiding this comment

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

In eb055fa:

I am tempted to change this from 10.0 to a range from 8.0.1 to 10. Later we will just bump the 10. Using a range will minimize the amount of grief that we'll have with coordinating new crate versions. (Though arguably we have no need to support miniscript 8 and 9 since those are in the past.)

@apoelstra
Copy link
Collaborator

Actually I do have one request before ACKing -- @uncomputable can you rearrange the first commits so that the miniscript one comes first? That way I can test the entire PR with the same lockfiles, and not have to worry about Cargo.toml changing partway through.

This is the easiest solution to use Miniscript keys in Simplicity
contexts. We focused on subtraits before, which would require changes to
(Elements) Miniscript, but we can also use generic impl blocks, as long
as they are inside rust-simplicity (orphan rule). We removed
elements-miniscript from rust-simplicity to avoid a cyclic dependency.
MiniscriptKey is defined in rust-miniscript, so importing it here does
not create a cycle. We get a diamond pattern where both
elements-miniscript and rust-simplicity depend on the same library,
which should be okay.
We get this for free.
@uncomputable
Copy link
Collaborator Author

Reordered the commits and fixed the two nits. We will need to update the Haskell generators to include a new use statement.

@apoelstra
Copy link
Collaborator

Thanks -- but now the benchmarks are not compiling.

A generic transaction reference is more flexible and will prevent us
from cloning transactions in the upcoming sighash.

Because we changed jet/init/elements.rs, we need to update the Haskell
code that generated the original file.
The signature hashes are different for Simplicity than for Taproot.
Among many things, the Simplicity sighash commits to the annexes of all
inputs, while Taproot only commits to the annex of the local input.
There is no clean way to compute the sighash at the moment; the code is
hidden somewhere in the Elements environment in the C files.
We can naively construct a Rust Elements environment in order to extract
the sighash from its FFI bindings. This requires information (control
block) that we arguably don't need, while other information is left
unused (leaf hash). We should write more direct bindings or implement
the sighash in pure Rust in the future. This will take time, so we make
do with what we have.
The order of fragments doesn't seem to matter, so I chose preorder which
is easy to implement.

I would have used the iterators from dag.rs, but Dag doesn't cover nodes
with arbitrary but fixed outdegree, like Policy::Threshold.
It might be worth to extend Dag in the future, although that could make
the generic code in dag.rs more complicated than it already is.
@uncomputable
Copy link
Collaborator Author

Fixed the benchmarks. Sorry for that. I didn't test them in my local CI.

Copy link
Collaborator

@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 d64e3b2

@apoelstra
Copy link
Collaborator

Heads up that I disabled my "checked-in files match those from Simplicity" check for this ACK.

@apoelstra apoelstra merged commit 676fd16 into BlockstreamResearch:master Aug 20, 2023
@uncomputable uncomputable deleted the policy-fixes branch August 20, 2023 19:29
@uncomputable uncomputable restored the policy-fixes branch August 21, 2023 15:04
@uncomputable uncomputable deleted the policy-fixes branch October 2, 2023 14:27
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