External wallet funding #2672
Conversation
|
Wanted to point out that we have no way of confirming that the amount someone says they're going to fund a channel for is actually the amount that they fund the channel for. We can correct/fix for this once the transaction is broadcast. We have to be given a funding amount, however, as the channel establishment protocol calls for a funding amount in |
|
This needs to be designed carefully. In particular the external wallet must be capable of providing a signed tx without broadcasting it (and clients need to be very aware that it is More concretely, it seems a good amount of duplication of code, thiugh I have not checked all details. I believe the same messages can be leveraged to implement |
We cannot fix anything once funding tx is broadcast. The initial commitment tx signed commits to a specific value for the funding txout. If the external wallet pays a different amount to the same address, the initial commitment is useless. The broadcast of the funding tx needs to be done after the other side signs initial commitment. So the external wallet must sign but not broadcast. If the funding tx is broadcast immediately then the counterparty can refuse to sign the initial commitment unless you |
|
Xref. https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-May/015925.html The above link describes CoinSwap but note that the same funding transaction pattern underlies that protocol. It is unsafe to broadcast the funding tx until the backout tx is signed;if you want to to support wallets that do "sign and broadcast" as a single atomic step (e.g. every custodial wallet) you need |
The duplication is by design, for a few reasons, namely that it's easier to DRY things out than to shoehorn too much divergence into a singular flow, especially at the work in progress stage. But agreed, it does need some consolidation to preserve some maintainability, especially between this and the ongoing dual funding work.
Ah right, my mistake I forgot about the commitment transaction commitments to amounts, I was thinking more from an internal representation standpoint. You're right, that would be unfortunate. A user of this RPC should supply the correct funding amount then, to avoid any of these issues. One way to mitigate this from an interaction standpoint would be to have the user supply a PSBT with the inputs, such that the |
|
Fixes: #644 xref. #644 (comment) for my old proposal of the command interface. The |
Is that really necessary? I was thinking of a flow like:
I imagine a fund-a-friend feature on a mobile Lightning, where Bob tells his phone to open a channel for 0.01btc, it starts negotiation and presents a qr code with the address. Alice scans that, produces tx, presents another QR code with txid and outnum. Bob scans that, and if negotiation completed, Alice tells her wallet to release tx. |
|
Perhaps a reword to "(and clients need to be very aware that it is |
2c0ff6c to
9fba2ba
Compare
rustyrussell
left a comment
There was a problem hiding this comment.
A few minor issues.
Your approach of duplicating code paths rather than starting with a split the existing code paths makes piecemeal review harder; since I can't tell from the patch if you've cut & pasted correctly. We'll end up in the same place, I think, but despite seeming easier this path is more awkward.
You should shuffle the infrastructure changes to the front, since they're trivial to review.
This should not be behind experimental_features; be proud! We also shouldn't turn those on in our test matrix just yet.
I think funding_continue should be called funding_complete. Maybe?
I'll have a go at reunifying the openingd paths (only using your new path) and see what I end up with?
| if (scriptLen == 22 && scriptPubkey[1] != 0x14) | ||
| return NULL; | ||
| if (scriptLen == 34 && scriptPubkey[1] != 0x20) | ||
| return NULL; |
There was a problem hiding this comment.
We already have these helpers in bitcoin/script.c:
if (!is_p2wsh(scriptPubkey, NULL) && !is_p2wpkh(scriptPubkey, NULL))
return NULL;
| #include <common/bech32.h> | ||
|
|
||
| /* Returns NULL if the script is not a P2WPKH or P2WSH */ | ||
| char * encode_scriptpubkey_to_addr(const tal_t *ctx, |
There was a problem hiding this comment.
Style nit: char *encode_ with no space after the *
|
|
||
| out = tal_arr(ctx, char, 73 + strlen(hrp)); | ||
| ok = segwit_addr_encode(out, hrp, 0, scriptPubkey + 2, scriptLen - 2); | ||
| if (!ok) |
There was a problem hiding this comment.
Trivial: I think we can skip the 'ok' var here?
| return command_param_failed(); | ||
|
|
||
| if (*funding_txout_num > UINT16_MAX) | ||
| return command_param_failed(); |
There was a problem hiding this comment.
command_param_failed is kinda magical: you need command_fail() here with a message.
In case of multifundchannel, it is not necessarily so that the fundchannel process is complete on completion of the second step --- if some other counterparty aborts on the second step, then we should not broadcast the funding transaction. Instead we should support a fundchannel_abort that So I would argue that funding_continue is more appropriate name. |
But if funding_continue returns successfully, the channel is funded. It has to be, since we're relying on the external party to broadcast the funding tx. So the |
|
Minor patch needed, to plug memleak: |
That depends on when If it returns before If it returns after I strongly suggest splitting into smaller steps and just monitor the channel state moving to We can always create a plugin that combines multiple steps later, we cannot create a plugin to split up operations. |
Here's one way that Is this an accurate portrayal of a workable |
142a5e6 to
3c78a2b
Compare
|
What happens if That is why we need Xref this thread: https://lists.linuxfoundation.org/pipermail/lightning-dev/2018-January/000905.html In the end I concluded that Funding is not complete until the blockchain says it is complete. |
|
I somewhat agree: it might be nice to be able to cancel even though lightningd thinks we're ready. However, that can be added later and we're too close to release. I also want to remove the fundchannel path from openingd, and always use the other path. But that's easiest done by moving |
|
Still has a memleak, BTW... |
|
Maybe this? 6233855#diff-1130d9d3f990f966967fbc527c10f275R1206 Previous value of Also, is not modifying |
We're going to need this for P2WSH scripts. pull it out into a common file plus adopt the sanity checks so that it will allow for either P2WSH or P2WPKH (previously only encoded P2WPKH scripts)
Looks like copy-paste from another commit didn't update the field for this
Needed for composing a transaction externally to c-lightning, using bitcoind util.
For the `fundchannel_cancel` we're going to want to 'successfully' fail a funding channel operation. This allows us to report it a failure back as an RPC success, instead of automatically failing the RPC request.
Beginnings of wiring up the funding_start rpc command. missing the part that actually starts the funding channel dance.
Useful for adding the funder_start stuff
Fill in details to make fundchannel_start work.
Add method to rpc handler
Make it easier for a user to know what's going on with a channel in `listpeers`.
Some channels won't be opened with a wtx struct, so keep the total funding amount separate from it so we can show some stats for listpeers. Note that we're going to need to update/confirm this once the transaction gets confirmed.
Add an RPC method (not working at the moment) called `fundchannel_continue` that takes as its parameters a node_id and a txid for a transaction (that ostensibly has an output for a channel)
Test for getting through the address generation portion.
3c78a2b to
70fdc5d
Compare
We'll need the outpoint for the funding output.
We need a way to gate allowing continue to proceed or not
Big wiring re-org for funding-continue In openingd, we move the 'persistent' state (their basepoints, pubkey, and the minimum_depth requirement for the opening tx) into the state object. We also look to keep code-reuse between 'continue' and normal 'fundchannel' as high as possible. Both of these call the same 'fundchannel_reply' at the end. In opening_control.c, we remap fundchannel_reply such that it is now aware of the difference between an external/internally funded channel open. It's the same return path, with the difference that one finishes making and broadcasting the funding transaction; the other is skips this.
Provide the option to cancel a funding-opening with a peer. Must either call `fundchannel_cancel` or `fundchannel_continue`
Add to test for fundchannel with composing and broadcasting an external transaction.
Renaming. "complete" more accurately describes what we're doing here.
Let people know what's changed
Manpages for the manpage-god!!
70fdc5d to
dcab321
Compare
|
Fixed "%ls" which should have been "%u"... |
|
Ack dcab321 |
Adds RPC commands for funding a channel via an external wallet.
There's a lot of caveats around the expected behavior of the wallet (uses SegWit ie non-malleable inputs, doesn't broadcast until
continuehas completed, provides the correct funding amount tofundchannel_start) that this doesn't have any way of enforcing. As such, it's behind an experimental flag -- a good plugin could probably paper over the majority of these issues.RPCs added are as follows:
fundchannel_start. Returns a bech32 address that is the funding tx destination.fundchannel_continue. Takes a funding txid and vout, returns the channel_id and confirmation that we've secured the commitment transactions for this channel.fundchannel_cancel. Instead ofcontinue, halts the fund channel flow.Fixes #644