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

vPSBT: add sighash support (no version bump) #779

Merged
merged 3 commits into from
Feb 20, 2024

Conversation

GeorgeTsagk
Copy link
Member

Description

This PR replaces #759 , as it introduces simple sighash functionality (SIGHASH_ALL and SIGHASH_NONE) for vPSBTs without changing the way we create the virtual transactions that are being signed. This allows us to be backwards compatible and does not require a new script version.

@GeorgeTsagk GeorgeTsagk self-assigned this Jan 31, 2024
@GeorgeTsagk GeorgeTsagk marked this pull request as draft January 31, 2024 22:42
itest/psbt_test.go Outdated Show resolved Hide resolved
tapscript/send.go Outdated Show resolved Hide resolved
tapscript/send.go Outdated Show resolved Hide resolved
tapscript/tx.go Outdated Show resolved Hide resolved
tapscript/tx.go Outdated Show resolved Hide resolved
vm/vm.go Outdated Show resolved Hide resolved
vm/vm.go Show resolved Hide resolved
require.NoError(t.t, err)

// Edit the already signed PSBT and change the output amounts. This
// should be ok as we used SIGHASH_NONE for the input's signature.
Copy link
Member

Choose a reason for hiding this comment

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

Should also test swapping out the dest script. This is an important component for the non-interactive swap demo.

itest/test_list_on_test.go Outdated Show resolved Hide resolved
@GeorgeTsagk GeorgeTsagk force-pushed the vpsbt-sighash-simple branch 3 times, most recently from 27ac081 to 5d4a45f Compare February 6, 2024 16:05
@GeorgeTsagk GeorgeTsagk marked this pull request as ready for review February 6, 2024 16:20
@dstadulis dstadulis added psbt VM virtual machine sighash labels Feb 6, 2024
@dstadulis dstadulis requested a review from guggero February 6, 2024 19:46
Copy link
Member

@guggero guggero left a comment

Choose a reason for hiding this comment

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

Nice, looks pretty good! Mostly nits now 🎉

vm/vm.go Outdated Show resolved Hide resolved
vm/vm.go Outdated Show resolved Hide resolved
proof/append_test.go Outdated Show resolved Hide resolved
@GeorgeTsagk GeorgeTsagk force-pushed the vpsbt-sighash-simple branch 2 times, most recently from 1f277ad to 63c043a Compare February 7, 2024 14:37
vm/vm.go Outdated

// If we are commiting to the outputs, we need to also perform
// an inflation check.
if sighashFlag != txscript.SigHashNone {
Copy link
Member Author

Choose a reason for hiding this comment

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

We probably don't want to always do this?

This if is useful when vPSBTs are partially constructed and passed around, as tapd will run the vm on psbts that are being signed.

But at the same time we don't want to have transfers that are never checked in terms of supply.

For a vPSBT that has only one input of SigHashNone we need to signal when the inflation check should be performed or not, when there's no intention of further adding more inputs that commit to all inputs/outputs.

Copy link
Member

Choose a reason for hiding this comment

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

Copying my answer from chat:

I think we only should skip the check at sign time but not at validation time. I think I mentioned this before, but the current check we have in the SignVirtualPsbt code where we validate the signature directly after signing probably needs to be removed or updated in any case. Otherwise we couldn't use that RPC for multi-signature as it would always fail for the first signer(s). So maybe we can pass in a boolean isSigning into the VM so we know we can skip some checks

Copy link
Member

Choose a reason for hiding this comment

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

If it's about the validation flow for vPSBTs, then I think for that flow, we can just compute the tapscript sighash directly and validate the signature given the available information. This way, we don't need a special case in the VM that could possibly be exploited with some edge case (valid sig that actually_does_ do inflation).

I think by the time we get to the layer of fully validating a proof file, we want the strictness checks possible to avoid inadvertent vectors that allow side stepping the rule set.

Copy link
Member

Choose a reason for hiding this comment

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

Reading in more of the diff: this won't work as intended if the virtual tx at this point is incomplete (output doesn't have the true value/amount).

Also the check (if it were needed, I don't think it is) needs to actually apply the sighash mask to extract the value rather than do a plain equality check.

@GeorgeTsagk
Copy link
Member Author

diff significantly reduced, also tidied up the commits a bit, PTAL

Copy link
Member

@guggero guggero left a comment

Choose a reason for hiding this comment

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

LGTM 🎉

vm/vm.go Outdated Show resolved Hide resolved
vm/vm_test.go Outdated Show resolved Hide resolved
vm/vm.go Outdated

// Check that we support the provided sighash flag.
switch sighashFlag {
case txscript.SigHashDefault, txscript.SigHashAll,
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to officially support some flags vs others? Stuff like single or anyonecan pay has no bearing at this level. It's also the case that the logic above doesn't exhaustively extract sighashes: it assumes keyspend only. All sigs within the witness can also have sighashes, eg: someone doing OP_CHECKSGIADD.

Copy link
Member

Choose a reason for hiding this comment

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

Also sighash values are masks, you can't just compare directly.

Copy link
Member Author

Choose a reason for hiding this comment

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

Stuff like single or anyonecan pay has no bearing at this level

So should I allow them even though they'll have no effect, or a malformed effect?

vm/vm.go Outdated Show resolved Hide resolved
vm/vm.go Outdated

// If we are commiting to the outputs, we need to also perform
// an inflation check.
if sighashFlag != txscript.SigHashNone {
Copy link
Member

Choose a reason for hiding this comment

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

Reading in more of the diff: this won't work as intended if the virtual tx at this point is incomplete (output doesn't have the true value/amount).

Also the check (if it were needed, I don't think it is) needs to actually apply the sighash mask to extract the value rather than do a plain equality check.

vm/vm.go Show resolved Hide resolved
@GeorgeTsagk GeorgeTsagk requested a review from guggero February 12, 2024 17:28
Copy link
Member

@guggero guggero left a comment

Choose a reason for hiding this comment

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

Hmm, I'm confused. Did something get lost in a rebase somewhere? Because I don't see the actual changes for supporting SigHashNone anymore... Also makes me wonder why the unit/integration tests still run file? Or am I missing something?

tapscript/interface.go Outdated Show resolved Hide resolved
tapscript/send_test.go Outdated Show resolved Hide resolved
vm/vm.go Show resolved Hide resolved
vm/vm.go Show resolved Hide resolved
Copy link
Member

@guggero guggero left a comment

Choose a reason for hiding this comment

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

Hmm, I'm confused. Did something get lost in a rebase somewhere? Because I don't see the actual changes for supporting SigHashNone anymore... Also makes me wonder why the unit/integration tests still run file? Or am I missing something?

Okay, I guess I missed the part that we already hooked in the vPSBTs sighash flag into the actual sign descriptor. So all good here (after addressing nits).

Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

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

LGTM 🕸️

@Roasbeef Roasbeef merged commit 58f9854 into lightninglabs:main Feb 20, 2024
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
psbt sighash VM virtual machine
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

4 participants