-
Notifications
You must be signed in to change notification settings - Fork 110
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
psbt script spend [3/3]: allow signing for asset script path spends through PSBTs #245
Conversation
cc9aed4
to
8afc879
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Surprisingly small changes to get script working. Only major suggested change is the FetchCommitment usage.
Will revisit to double-check the encode and Taproot logic.
itest/psbt_test.go
Outdated
bobScriptKeyDesc.RawKeyBytes, | ||
) | ||
require.NoError(t.t, err) | ||
bobInternalKeyDesc, err := bobLnd.WalletKitClient.DeriveNextKey( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General comment: Wondering if this is an RPC we should expose from tarod
in the future? May be relevant for tracking which keys to backup as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in re-expose the lnd API used to create keys in the first place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think it could be useful to have this call be threaded through the daemon so we don't need to know what key family to use in lnd
when talking to tarod
. Will add that to the PR that adds the BTC level PSBT stuff (for funding and signing the anchor transactions externally).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent work! Gotta love when a few well crafted abstractions nicely fall into place.
See comments in line, some carried over from the PR before it was split up.
Few things popped out:
- Ensuring that all the decoding + parsing is generic up until we restrict things to a single input deeper within the pipeline.
- Adding a similar coin selection mutex like we have in
lnd
over everything, which ensures that we don't have weird double spending issues. Alternatively, we can pipe everything through the porter and have it do single threaded coin selection + locking accounting. - Update the test to also have a checksig in addition to the pre-image reveal so the vPSBT signing can be exercised there.
|
||
if groupKey != nil { | ||
key := groupKey.GroupPubKey | ||
filter.KeyGroupFilter = key.SerializeCompressed() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't the asset ID enough to be able to uniquely pick out an asset?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, in case of a normal asset where I have multiple coins, we actually need the script key, which I added now. We don't necessarily need the group key for our specific query, but because this function creates a generic filter, I'm leaving that in for now.
rpcserver.go
Outdated
rpcsLog.Debugf("Selected commitment for anchor point %v, requesting "+ | ||
"delivery", inputCommitment.AnchorPoint) | ||
|
||
resp, err := r.cfg.ChainPorter.RequestSignedDelivery( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So then this also assumes that the wallet as is will fully handle all the PSBT components? Could imagine another world where there's another external round to sign the Bitcoin portion (as that has a multi-sig/musig2 layer or w/e).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, definitely. The BTC level PSBT components will come in a later PR and give you full control over how the anchor TX is created, signed and published.
itest/psbt_test.go
Outdated
bobScriptKeyDesc.RawKeyBytes, | ||
) | ||
require.NoError(t.t, err) | ||
bobInternalKeyDesc, err := bobLnd.WalletKitClient.DeriveNextKey( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in re-expose the lnd API used to create keys in the first place?
6773c33
to
57b4bf7
Compare
full value send test needs to be written. |
3a1bfa7
to
16dcf55
Compare
Thanks a lot for all the feedback, @Roasbeef and @jharveyb! I addressed all of the comments and rebased on the latest version of part 2.
Good idea, done!
I agree. Though I think a mutex only adds any value if we can also mark a coin as being used/locked in the DB. I created an issue (#261) to track that.
Yes, done. I'm also going to split off the interactive send changes into a separate PR (I guess it will be [4/3] 😅 ), since the changes were a bit more involved than expected. |
8b32e68
to
1b0a54a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, only nits left IMO + changes in preceding PR.
1b0a54a
to
3067bd9
Compare
Addressed all comments and added the input proof validation as well. |
3067bd9
to
08a32c3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Just have to remove proof{Encoder,Decoder}
.
// Before we sign the transaction, we want to make sure the | ||
// inclusion proof is valid and the asset is actually committed | ||
// in the anchor transaction. | ||
err := verifyInclusionProof(vPkt.Inputs[idx]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably want a TODO here to add a call to ChainBridge
later on? To verify the anchor TX from the proof is in the chain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point! That also reminded me that we didn't check the anchor TX in the input vs. the one in the proof, which I added now. So only the "is the block in the chain" logic remains, for which I added a TODO.
535e7b1
to
3ad1f00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🌳
Just have one clarifying question (about the leaf hashes in the PSBT), and another re a field that doesn't need to be set for a script path spend (the tap tweak).
taroscript/tx.go
Outdated
} | ||
|
||
spendDesc.SignMethod = input.TaprootScriptSpendSignMethod | ||
spendDesc.TapTweak = vIn.TaprootMerkleRoot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the tap tweak needed for a script spend from the tree? This is only needed for keyspend paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, removed.
// One leaf hash and a merkle root means we're signing a specific | ||
// script. | ||
case len(vIn.TaprootMerkleRoot) == sha256.Size && | ||
len(derivation.LeafHashes) == 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this restrict to only a control block of size 1? So you only have a single sibling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we just only support signing for a single leaf at a time. The PSBT spec allows you to specify multiple leaf hashes and that would indicate to the signer that it should create a signature for each of them. But since we always know which path we're going to use, we haven't implemented this in lnd
either. I updated the comment to make it more clear.
To avoid yet another circular dependency, we move the commitment proof related encoders and records into the commitment package.
The asset minting test is currently flaky because the total sum of all asset amounts minted exceeds the database's precision. This should be fixed by building the sum outside of the database. Or by disallowing amounts exceeding a certain number. For now we just fix the flake by choosing smaller random amounts.
This fixes an issue with the itest that the requests were modified in place, affecting the next test that's being run. By copying the request before modifying it, this can be avoided.
3ad1f00
to
24d4368
Compare
Depends on #243.Depends on #244.
Depends on btcsuite/btcd#1942.Fixes #75.
This PR contains the PSBT serialization logic for transporting asset related meta data in a BIP-174 based PSBT packet as well as all the required RPCs to allow creating and sending to a Taro address that locks assets to a script spend path.