-
Notifications
You must be signed in to change notification settings - Fork 132
[wallet 3/3]: group key support for channel funding #1413
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
Conversation
8939b42
to
ee66eb9
Compare
129dd06
to
76938ad
Compare
Pull Request Test Coverage Report for Build 14358733453Details
💛 - Coveralls |
76938ad
to
2639fa6
Compare
86112a5
to
cdc7cb2
Compare
2639fa6
to
9f24e16
Compare
cdc7cb2
to
be499e2
Compare
db987a5
to
206da82
Compare
be499e2
to
bb88417
Compare
206da82
to
ce40ed7
Compare
7356ae4
to
cd1b95b
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.
very clean changes 🧹
will use the itest to better understand certain details, overall looking good! 👍
AssetSpecifier: specifier, | ||
Amount: amt, | ||
CoinSelectType: tapsend.Bip86Only, | ||
DistinctSpecifier: true, |
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.
after seeing that we default to true
here, I'm not sure in which scenarios we'd want to use false
?
Will we ever have the freedom of choosing whether we'll use the ID or the groupKey of a specifier that has both? Seems to me that the intuitive choice is always picking the groupKey, but LMK what you think
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.
The thing is, we already have that case. Remember when we added the itest that creates channels from a grouped asset (but only a single tranche so it would work with the code we had before this change)?
In that case we only specify the asset ID in the funding request. But because it's a grouped asset, the new logic would then also query the DB and set the group key in the specifier. And in that case we actually want to query with both, so we only fetch exactly the asset ID we supplied (and not just any asset from the group).
// Then we'll create the OP_RETURN leaf with the asset ID to make the | ||
// resulting script key unique. | ||
opReturnLeaf, err := asset.NewNonSpendableScriptLeaf( | ||
asset.OpReturnVersion, id[:], |
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.
could there be a proof collision here if we somehow ended up having the same id[:]
?
Is this collision taking place within the transfer's namespace or is it global?
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.
This is only within a single on-chain outpoint (e.g. the funding transaction). The universe has uniqueness over the tuple (group_key_or_asset_id, script_key, outpoint)
. Which for multiple tranches of the same group key would all be the same for the individual UTXOs committed to the channel (because group_key
would be set since it's a grouped asset, see how the universe ID works). So we just need to de-duplicate the script key by adding the asset ID to its tapscript path. And since we'd only at most have one UTXO per asset ID, there should be no additional collision possible (see comments above about merging multiple inputs of the same asset ID into a single one within the channel).
if err != nil { | ||
return lfn.Errf[wire.TxWitness]("unable to serialize control "+ | ||
"block: %w", err) | ||
useUniqueScriptKey := len(vPackets) > 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.
we assume that two different vPacket's may not use the same asset ID?
if yes could throw a comment for clarity
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.
Correct. The definition for a vPacket that we arrived at is that it reflects all the changes of a single assetID within one on-chain transaction. Meaning that all the inputs and all the outputs of one asset ID within a transfer would be merged into the same vPacket. Will add a comment to make more clear.
@@ -7073,7 +7073,7 @@ func (r *rpcServer) FundChannel(ctx context.Context, | |||
} | |||
|
|||
assetID, groupKey, err := parseAssetSpecifier( | |||
req.GetAssetId(), "", nil, "", | |||
req.GetAssetId(), "", req.GetGroupKey(), "", |
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.
added something similar in 667080c
5f63baa
to
6e98981
Compare
@guggero, remember to re-request review from reviewers when ready |
We've decided to only ever use a single asset ID within a virtual packet. Which means we'd use multiple virtual packets to represent transfers for different asset IDs. So we don't need those early TODOs anymore.
We defined a while ago that an entry in the transfer table corresponds to one on-chain transaction. That means, such a transfer can house multiple virtual packets from different asset IDs. The transfer inputs already reflect that correctly. But the outputs were lacking the asset ID that indicates what virtual packet the output belonged to. This commit fixes the problem by adding the asset ID to the transfer output struct.
The wrong error was assigned, which caused the proof delivery failures to not surface correctly.
Not sure why the asset ID was never used in the database proof query. But now that we potentially have multiple asset outputs with the same script key but different asset IDs in the same anchor transaction, it's crucial we also add this to the query.
We changed the semantics around transfers when we implemented committing multiple asset transfers to a single TX. We now allow multiple virtual packets to be combined in a single transfer. Which means we have one entry in the transfer table for each on-chain transaction. But each transfer can have inputs and outputs from different asset IDs (meaning different active vPackets). This implies that it's also possible to have multiple transfer outputs with the same script key but different asset IDs, which means we need to change the way we identify the proof files.
One allocation entry means one on-chain output. So we should not create multiple allocations for the same balance (e.g. if there are multiple asset pieces with different asset IDs in the local or remote balance). Instead we just create one allocation for the sum, then let the coin distribution algorithm decide what output goes where.
We're doing the same thing in three places, this commit unifies the code by using the same function everywhere.
We always add the witness to the commitment TX before we create any of the commitment outputs. So this witness should already be correct.
To avoid a proof collision in the universe, we need to make sure we derive unique funding output script keys for multiple asset IDs within the same channel funding outpoint. We do that by adding a second OP_RETURN leaf into the tapscript tree of the funding script key. That should ensure uniqueness of the top-level Taproot output key and only requires us to slightly alter the control block when creating the witness (it will now include an inclusion proof element for the OP_RETURN leaf).
6e98981
to
5f672a7
Compare
Addressed all comments. |
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 🥕
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 ⚡
tACK ✔️
Adds the ability to fund multiple tranches of a grouped asset into a channel.
Corresponding itest: lightninglabs/lightning-terminal#987