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

Refactor, add miniscript parse and compilation functionality #1

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

guggero
Copy link

@guggero guggero commented Jan 21, 2025

Does some refactoring of unit tests, then adds new functionality from the Rust library for parsing and compiling miniscript expressions, including unit tests.

Makes it easy to add more test cases by extracting the test case values
into a JSON based test vector file.
Adds two new functions to parse and compile miniscript to the Rust
wrapper.
Adds the corresponding Go functions for the new Rust functions.
Copy link
Owner

@benma benma left a comment

Choose a reason for hiding this comment

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

Thanks ❤️

Now that this library has a contributor and might move into actual production use, it will also be good to document all structs and functions and remove all panics etc, of course in a different PR.

uses: actions/checkout@v3

- name: Setup go ${{ env.GO_VERSION }}
uses: actions/setup-go@v3
Copy link
Owner

Choose a reason for hiding this comment

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

@v5

runs-on: ubuntu-latest
steps:
- name: git checkout
uses: actions/checkout@v3
Copy link
Owner

Choose a reason for hiding this comment

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

@v4


jobs:
rust-compilation-check:
name: Rust compilation check check
Copy link
Owner

Choose a reason for hiding this comment

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

s/check check/check 😄

# Go needs absolute directories, using the $HOME variable doesn't work here.
GOPATH: /home/runner/work/go

GO_VERSION: '1.22.11'
Copy link
Owner

Choose a reason for hiding this comment

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

@@ -1,3 +1,6 @@
build-wrapper:
cd wrapper && cargo build --release --target wasm32-wasip1
cp wrapper/target/wasm32-wasip1/release/wrapper.wasm descriptors/

unit:
Copy link
Owner

Choose a reason for hiding this comment

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

I prefer unit-test or run-unit-tests, or to drop this completely as go test ./... is easy enough on its own.

_, err := NewDescriptor("tr([e81a5744/48'/0'/0'/2']xpub6Duv8Gj9gZeA3sUo5nUMPEv6FZ81GHn3feyaUej5KqcjPKsYLww4xBX4MmYZUPX5NqzaVJWYdYZwGLECtgQruG4FkZMh566RkfUT2pbzsEg/<0;1>/*,and_v(v:pk([3c157b79/48'/0'/0'/2']xpub6DdSN9RNZi3eDjhZWA8PJ5mSuWgfmPdBduXWzSP91Y3GxKWNwkjyc5mF9FcpTFymUh9C4Bar45b6rWv6Y5kSbi9yJDjuJUDzQSWUh3ijzXP/<0;1>/*),older(65535)))#lg9nqqha")
require.Error(t, err)
require.Contains(t, err.Error(), "Invalid checksum")
type DerivationTestVector struct {
Copy link
Owner

Choose a reason for hiding this comment

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

Can unexport this, derivationTestVector

@@ -22,6 +22,19 @@ const (
NetworkRegtest Network = 2
)

func ParseNetwork(network string) (Network, error) {
Copy link
Owner

Choose a reason for hiding this comment

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

move this to descriptors_test.go? These strings are specific to the unit test vectors only.

Comment on lines +7 to 15
type wasmInstance struct {
mod *wasmModule
ptr uint64
drop func()
}

type Descriptor struct {
mod *wasmModule
ptr uint64
close func()
wasmInstance
}
Copy link
Owner

Choose a reason for hiding this comment

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

What's the purpose of this transformation? I am not a big fan of struct embedding, in my experience it tends to cause more trouble than is worth it. If your goal was to encapsulate the mod/ptr/drop parts, please make it a proper struct field like wasmInstance wasmInstance

OpCodes uint64
}

func ParseMiniscript(script string) (*Miniscript, error) {
Copy link
Owner

Choose a reason for hiding this comment

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

What is exactly the purpose of these two functions that cannot be accomplished with the Descriptor struct? Can't you call NewDescriptor() and to add methods to get the pkScript.

This one specifically only returns types and the op code count, but for what purpose?

Also this seems to hardcode the SegWit context, which seems arbitrary.

}, nil
}

func CompileMiniscript(script string) ([]byte, error) {
Copy link
Owner

Choose a reason for hiding this comment

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

"Compile" is a bit overloaded as a name (and reminds of the policy compiler). MiniscriptToPkScript or something like that would be good. But again, why do we need this when we have NewDescriptor() which can serve the same purpose?

runs-on: ubuntu-latest
steps:
- name: build wrapper
run: make build-wrapper
Copy link
Owner

Choose a reason for hiding this comment

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

Can we add a check here that wrapper.wasm was not changed by this, to ensure the comitted wrapper.wasm file is always up to date?

@guggero
Copy link
Author

guggero commented Jan 22, 2025

Thanks for the quick review and feedback!
Wasn't sure about the future plans for the repo, so I wasn't super strict with code style and cleanliness yet.
But happy to clean it up in the coming days/weeks.

My main intention with this is to eventually be able to replace btcsuite/btcd#1987 with this library.
I assume for integration into a wallet, some more low-level operations around minscript would be required, not just on the descriptor level (could be wrong on that, gonna think about it a bit more).
The other reason for exposing the parsed types and opcodes was to be able to run the full test vectors against the Golang code. But I guess that can still be done without exporting the functions, so I'll do that.

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