lnd
lnd copied to clipboard
Feature: Liquidity ads (lightning native dual funded channels)
Background
As per the proposed BOLT specification by @niftynei (https://github.com/lightning/bolts/pull/878), there is a way to allow for dual funded channels natively without having to run additional and implementation specific software on top.
The feature is already implemented and rolled out in CLN. ACINQ is currently implementing it for eclair if I understand correctly.
It would be great if the most common lightning implementation would support this feature as well.
There is a feature bounty for this, which I will match up to 10,000,000 sats:
https://btcpay.zerofeerouting.com/apps/6RNpv94dQvWV3n65Fze2xrubbAm/crowdfund
I really hope this feature will be implemented, should make lightning more robust and less dependend on centralized points of failure.
A would-be implementor should first become intimately familiar with the existing dual funding flow in the internal wallet, which was implemented in 2015 or so: https://github.com/lightningnetwork/lnd/blob/7106ea59db9ade78d65bb46605f94637900c0e3f/lnwallet/test/test_interface.go#L444-L655. One will also likely want to look at the history of the reservation system, and how the single funder flow was added after the initial dual funding reservations (see the single prefix/suffix on some of the new methods).
Cool! Thank you for the feedback and the pointers!
I would like to add something in regards to this proposal.
Add also a feature that will lock that channel for a specific CLTV time (agreed by parties) and could not be force closed until at least that block height agreed.
It is useless and painful to have a channel contract to open a dual funded channel that after 1-2 days got forced closed, for various reasons, that users cannot control.
All these force closing channels that happen lately in mass are totally wrong and make unusable LN. In the last 10 days I got 20 channels forced closed. Why? Because somehow on the path the HTLCs got stuck and I am the one penalized for no reason. I am not the one that had the node offline or not forwarding the payment.
Some channels I paid for them and now I got them forced closed. This have to be addressed somehow.
Because somehow on the path the HTLCs got stuck and I am the one penalized for no reason. I am not the one that had the node offline or not forwarding the payment.
In this case your node force-closed the channels. If you don't want this to happen, you could tweak your own code - with the risk that the "offline" counter party steals the funds in said HTLCs. There's a reason why unilateral closes happen automatically, and I'm pretty sure you're not the only node operator who hates it when it happens.
That being said, delaying/disallowing unilateral channel closes is a very bad idea. They are required in certain situations, and aside from bugs there are plenty of situations where the one who issues the close needs to mitigate some kind of risk.
Opening a channel is a contract. A contract must have a grace period. Right now users can't set a specific time, agreed between them, until when the channel is open. The CLTV is used only as a punishment or dispute time, but is NOT the time of the contract. So is useless to have a contract that I don't know when will be void or canceled.
So if you have a renting contract for a house, but the owner will not put any term until you could stay in that house. Then once you paid the rent for the first 3 months, the owner come and kick you out, because the contract doesn't have any term. How is that a bad idea disallowing the owner to kick you out now ?
Contracts usually require trust, either in the other party, or some higher entity. In situations where one node issues a unilateral close automatically, there's some kind of dispute (most likely because one party is offline). The blockchain is the higher entity that settles the dispute. I don't see how this can be fixed, as it's at the core of how the LN works.
Your example lacks the reason for the owner kicking you out. If it's the equivalent of a manual "lncli closechannel --force": sure, that's bad. But what if you (the renter) didn't pay rent, or your check bounced, or you're about to destroy the house?
I'd say we shouldn't have this discussion in here, as it's an underlying problem (property?) of the LN.
@Darth-Coin - that can't work. There always is a reason for automated force-closes, usually to safe one (or both) peer's funds. Prohibiting this will put the peer that can't force-close at a disadvantage.
A channel where both peers want the channel to be force-closed, that can't be force-closed due to some agreement is just dead weight, since both parties would just disable it.
Then create a special signature that both parties have to sign after agree to close that channel before the time.
You're derailing this issue with something unrelated.
is anyone seriously working on this issue?
Hi folks. I've quit my day job and am interested in working on this.
@niftynei's spec for liquidity ads seems to be shelved until the dual funding spec is finalized and merged. I've left feedback on both specs. In particular, I think there's some major changes we should make to liquidity ads around how leases are enforced (CLTV seems simpler and cleaner than the current update_blockheight
hack, and we can easily put timelocks on more branches in HTLCs).
Regardless, dual funding is what we need to implement first in LND, and the spec for that seems more mature. We should be able to implement experimental support for the current spec draft, and update as the spec is finalized. Later we can revisit how to best implement liquidity ads.
I'm currently working on an implementation plan for dual funding. I'll post some ideas here for feedback later this week.
@morehouse - very cool, that you're interested in doing this. Feel free to create a feature branch and / or ask questions here in the ticket. I am unaware of anyone else working on this at the moment.
The bounty raised by me is currently 0.104 BTC plus the 0.1 BTC I will personally give. (so 0.204 BTC as of now). I think we might be able to raise additional awareness if there is some progress. Would love to see liquidity ads happening!
I'm still working through the implementation/testing details, but here's some ideas I have so far. Feedback is appreciated.
Funding Manager
The funding manager needs to handle all the new messages from 02-peer-protocol.md in https://github.com/lightning/bolts/pull/851.
open_channel2 / accept_channel2
These are very similar to open_channel
and accept_channel
, except that the acceptor can contribute funds too.
When we are the acceptor, it is simple to create an lnwallet.InitFundingReserveMsg
with both local and remote funding amounts.
But when we're the opener, we don't know what the peer will contribute until they send accept_channel2
. So we can't provide the exact remote funding amount in InitFundingReserveMsg
. Instead, we can give an estimate based on a minimum amount required by the user. For example, the CLI could be:
$ lncli dualfundchannel node-key local-amt min-remote-amt [max-remote-amt]
We then use min-remote-amt
in the InitFundingReserveMsg
to validate local/remote balances, dust limits, etc. and to choose the required to_self
, max_htlc_value_in_flight_msat
, etc.
Once we get an accept_channel2
back, we verify that the remote's funding amount is within our required range, update the reservation to the exact remote funding amount and revalidate. Note that we don't get to tweak our to_self
, max_htlc_value_in_flight_msat
or other parameters after this, which is a limitation of the protocol.
At this point, we can't call reservation.ProcessContribution
yet, as we don't have the remote's inputs/outputs. So we'll save a partially constructed remoteContribution
in the reservation context.
Interactive Tx Construction
This entails the new tx_add_input
, tx_add_output
, tx_remove_input
, tx_remove_output
, and tx_complete
messages.
Since the wallet has already reserved our inputs and change outputs, and we know how to construct the funding output, the state machine for this interaction is fairly simple. We'll ping-pong with the peer, first sending our inputs one by one, then our outputs, then the funding output if we're the opener. For each message from the peer, we'll validate and add/remove the input/output given.
When we have sent and received a tx_complete
in succession, we can finish constructing the remoteContribution
and call reservation.ProcessContribution
.
Signature Exchange
This is the tricky part.
We need to first exchange commitment_signed
and then tx_signatures
. After we have sent our tx_signatures
, the peer could broadcast the funding transaction at any point, so we need to persist the channel in the DB before sending tx_signatures
. If we don't have the peer's tx_signatures
yet at that point, we can't just call reservation.CompleteReservation
and be done, since it will fail to validate the funding transaction.
We'll need to break apart CompleteReservation
into different parts:
-
AddCommitmentSig
: verifies and stores the peer's commitment signature -
SaveChannel
: saves the pending channel to the DB -
AddFundingTxSigs
: verifies and stores the peer's funding transaction signatures
commitment_signed
After calling ProcessContribution
, we can immediately send our commitment_signed
.
When we get the peer's commitment_signed
, we'll call reservation.AddCommitmentSig
.
tx_signatures
If it is our job to send tx_signatures
first, we'll call reservation.SaveChannel
and then send tx_signatures
. Otherwise, we'll wait for the peer's tx_signatures
.
Once we get the peer's tx_signatures
, we'll call reservation.AddFundingTxSigs
. If we haven't sent our tx_signatures
, we'll do reservation.SaveChannel
and send them. Otherwise we might need to update the saved channel in the DB now that we have funding tx sigs (or maybe we can rely on retransmission of tx_signatures
on restart as currently suggested on the spec).
At this point, we can broadcast the funding transaction.
Handling Failures
Before we sent tx_signatures
We simply remove any wallet reservation and related context, sending an error as a courtesy. We can use failFundingFlow
for this.
After we sent tx_signatures
We must keep the OpenChannel
in the DB and monitor the blockchain until an input is double spent. We can remove the wallet reservation and related context to allow our inputs to be productively double spent in another transaction, but we don't need to proactively double-spend (and incur fees) as long as we keep monitoring the pending channel.
We can monitor for double spends in a new method advancePendingDualChannelState
patterned after advancePendingChannelState
. In addition to watching for the funding txid onchain, it will also watch for double spends of any input in the funding tx. If the funding tx confirms, we will advance the funding state as usual. If an input is double spent, we will remove the pending channel from the DB and exit the current (monitoring) goroutine.
Handling Disconnects
Before we sent tx_signatures
On restart, we automatically forget the reservation and related context. If the peer disconnected and lost state without sending us an error, the current zombie cleanup loop will remove our reservation context after a timeout.
After we sent tx_signatures
On restart, we load the pending OpenChannel
from the DB. Based on a recent update to the spec, we'll need to resend tx_signatures
. To do this, we can add a new TLV to the DB record that contains a list of input indexes signed by us. This will allow us to extract our tx_signatures
from the stored FundingTx
and resend them. If our stored FundingTx
also has signatures from our peer, we can rebroadcast it immediately. Otherwise we wait for the peer to (re)send their tx_signatures
. Since we've already sent our tx_signatures
, we need to spawn a advanceFundingState
goroutine to monitor the onchain state even if we don't have a fully signed FundingTx
to broadcast.
To help a disconnected peer get our tx_signatures
when they come back online, we can always send tx_signatures
in a waitForPeerOnline
loop, as we currently do for funding_locked
.
RBF
We should support RBF replacement of pending channels until they confirm. This feature is not necessary for the MVP, but thinking about it now may influence other aspects of the design.
CLI
$ lncli feebumpchannel chan-id local-amt min-remote-amt [max-remote-amt]
Tracking in-flight channels
We'll maintain an inFlightChannels map[chanID][]*OpenChannel
in the funding manager, tracking all possible versions of a channel that could confirm. On restart, this map will be reconstructed from OpenChannel
s in the DB, and goroutines will be spawned to monitor the blockchain for each possible version.
tx_init_rbf
/ tx_ack_rbf
When handling these messages, nearly all channel parameters are reused from the original open_channel2
/ accept_channel2
. We can put most functionality for this in a new wallet method InitRbfReservation(inFlightChannels, LocalAmt, RemoteAmt)
(see below).
If the peer sends us a new contribution amount that doesn't fit in our min-max range, we abort the RBF attempt.
DB changes
We need to keep track of the funding feerate for each RBF attempt, so we can ensure we're bumping it by at least 25/24 each time. We'll add a field for this to OpenChannel
and serialize it as a TLV in the DB.
Wallet
Since the interactive-tx protocol is more granular than the v1 protocol, it makes sense to break down the wallet / reservation API into smaller functions. As a secondary benefit, we may be able to share more code between the single/dual funding flows.
Note that my thinking here as evolved over the past couple weeks, so the design here doesn't match 100% with what's described in the Funding Manager section above.
Current Flow
v1 Opener
-
lnwallet.InitChannelReservation
-
reservation.SetOurUpfrontShutdown
-
reservation.SetNumConfsRequired
-
reservation.CommitConstraints
-
reservation.ProcessContribution
-
reservation.CompleteReservation
v1 Acceptor
-
lnwallet.InitChannelReservation
-
reservation.SetNumConfsRequired
-
reservation.CommitConstraints
-
reservation.SetOurUpfrontShutdown
-
reservation.ProcessSingleContribution
-
reservation.CompleteReservationSingle
New Flow
v2 Opener
-
lnwallet.InitChannelReservation
- Same as before, plus takes an estimated or actualRemoteFundingAmt
and runs the usual checks. Handles anUpfrontShutdown
script as well. -
reservation.UpdateRemoteFundingAmt
- Updates the remote funding amount to the actual value specified inaccept_channel2
, and reruns affected checks. -
reservation.ProcessChannelParams
- Takes aChannelConstraints
, aChannelContribution
, andNumConfsRequired
, validates them and stores their values in the reservation. Does not attempt to construct the funding tx. -
reservation.ProcessContribution
- Takes the remote's inputs/outputs, compiles and signs the funding tx, and compiles and signs the commitment tx. -
reservation.ProcessCommitmentSig
- Verifies and saves the remote's commitment sig. -
reservation.SaveChannel
- Stores the pendingOpenChannel
in the DB and returns it. -
reservation.ProcessTxSigs
- Verifies and stores the remote's funding tx sigs. -
reservation.Complete
- Removes any references to the reservation from the wallet.
v2 Acceptor
-
lnwallet.InitChannelReservation
- uses the actualRemoteFundingAmt
specified inopen_channel2
. -
reservation.ProcessChannelParams
-
reservation.ProcessContribution
-
reservation.ProcessCommitmentSig
-
reservation.ProcessTxSigs
-
reservation.SaveChannel
-
reservation.Complete
v1 Opener
-
lnwallet.InitChannelReservation
-
reservation.ProcessChannelParams
-
reservation.ProcessContribution
- uses empty inputs/outputs since remote doesn't contribute -
reservation.ProcessCommitmentSig
-
reservation.SaveChannel
-
reservation.Complete
v1 Acceptor
-
lnwallet.InitChannelReservation
-
reservation.ProcessChannelParams
-
reservation.ProcessOutpoint
- stores the outpoint specified infunding_created
and compiles and signs the commitment tx -
reservation.ProcessCommitmentSig
-
reservation.SaveChannel
-
reservation.Complete
RBF Flow
Initiator
-
lnwallet.InitRbfReservation
- Takes a slice of in-flightOpenChannel
s, theLocalFundingAmt
, and an estimatedRemoteFundingAmt
. Extracts the common channel parameters from the firstOpenChannel
, and initializes a reservation from them. Uses a newRbfChannelFunder
to select inputs, preferring inputs already used for the in-flightOpenChannels
. -
reservation.UpdateRemoteFundingAmt
-
reservation.ProcessContribution
-
reservation.ProcessCommitmentSig
-
reservation.SaveChannel
-
reservation.ProcessTxSigs
-
reservation.Complete
Non-initiator
-
lnwallet.InitRbfReservation
- Uses the actualRemoteFundingAmt
specified intx_init_rbf
. -
reservation.ProcessContribution
-
reservation.ProcessCommitmentSig
-
reservation.ProcessTxSigs
-
reservation.SaveChannel
-
reservation.Complete
Misc
Dual Funding Policies
I propose the following initial (experimental) config parameters for handling dual funding requests:
-
dualfund.active=true
- if true, LND will advertise theoption_dual_fund
feature and use the v2 channel protocol when possible. Default false. -
dualfund.match=1.0
- the proportion of theopen_channel2
funding amount that we will match [0.0-2.0]. Default 0. -
dualfund.match-limit=1000000
- the maximum number of sats we will match. Setting it to 0 disables the limit. Default 0.
ChannelAcceptor
Initial MVP
The channel acceptor will need to handle the new lnwire.OpenChannel2
message in addition to lnwire.OpenChannel
. We can add a new DualAccept
to the interface for this, and a new DualChannelAcceptRequest
type to hold the OpenChannel2
.
For RPCAcceptor
, we can pipe the v2 channel data into the existing lnrpc.ChannelAcceptRequest
, dropping the new fields (locktime and funding feerate). This way we can avoid changing the RPCAcceptor
protobuf interface while dual funding is considered experimental.
End goal
Besides full RPCAcceptor
support for the new OpenChannel2
fields, we may also want the ability to specify a local funding amount in the ChannelAcceptResponse
. This would allow the user to write their own logic for handling dual funding requests. However, this doesn't work well for RBF attempts that change the funding amount, since we'll be missing the other OpenChannel2
fields. Perhaps a new ChannelAcceptor.RbfAccept
interface method would be useful.
Marking Dual Funding Experimental
I don't think it makes sense to create an entire RPC sub-server for dual funding, but I didn't see any other examples in the codebase of separating code as experimental. Is an "EXPERIMENTAL" warning in the documentation all we need here?
Implementation & Testing Plan
To simplify code review, I propose we break the implementation into 5 major PRs:
- Open & Accept v2
- Interactive Tx Construction
- Signature Exchange
- CLI / RPCs, itests, docs
- RBF
Open & Accept v2
Implement support for open_channel2
and accept_channel2
. This includes wire support, funding manager logic, some refactoring of the LightningWallet
flow, and some ChannelAcceptor
refactoring for v2.
We'll have fuzz tests for the new wire messages and unit tests for other things. I will also manually test for interop with CLN and eclair.
Interactive Tx Construction
Implement support for cooperatively constructing the funding tx with the peer. This includes wire support for tx_[add|remove]_[input|output]
, tx_complete
, and tx_abort
; funding manager logic and state machine; and likely some LightningWallet
work to handle serial_id
s.
We'll have fuzz tests for the new wire messages and unit tests for other things. I will also manually test for interop with CLN and eclair.
Signature Exchange
Implement support for exchanging commitment and funding tx signatures. This includes wire support for tx_signatuers
, funding manager logic for the exchanges and monitoring pending channel state afterward, refactoring the LightningWallet
flow, updating OpenChannel
DB serialization to encode a list of funding tx inputs we signed, and modifying htlcswitch.channelLink
to retransmit tx_signatures
when necessary.
Testing will be the same as previous PRs, with an emphasis on handling disconnects and other failures after sending tx_signatures
.
CLI / RPCs, itests, docs
Implement the CLI, RPCs, and configuration necessary for the client to dual fund channels. Implement e2e itests using the new RPCs. Document the new experimental configuration and APIs. Reject any RBF attempts for now.
RBF
Implement support for RBFing funding txs. Includes wire support for tx_[init|ack]_rbf
, the new LightningWallet.InitRbfReservation
method, a new RbfChanFunder
to be used by LightningWallet
, funding manager logic for juggling multiple RBF attempts, updating OpenChannel
DB serialization to encode FundingFeeRate
, a new CLI/RPC command to initiate an RBF fee-bump, and itests for RBF.
Next Steps
I'm ready to start implementation. I'll refer back to this design in future PRs and do my best to ease the code review process. If there's any major concerns about anything above, please chime in now before I go too far in the wrong direction.
Hey @morehouse, thx for jotting down your thoughts/planned here before jumping into the implementation. Just catching up with this a bit now, but thought I'd drop a few comments here to help nudge you in the direction.
I think one thing you should keep in mind, is that a lot of the funding/reservation code is super old in terms of lnd's lifetime. Files like lnwallet/reservation.go
and lnwallet/wallet.go
were amongst the very first files to be committed to the lnd wallet (initial milestone was getting our version fo dual funding working back then). As a result, I think we either need to commit early on to do aggressively refactoring, or chose to explicitly leave it out of the set of planned work.
One other thing to keep in mind, is that a mega PR implementing everything in one swoop will be very difficult to review, and will likely just sit in review limbo. As a result, I recommend that you try to chop things up into small pieces when possbile. In addition, there're a few other funding related issue or PRs in the tracker. Helping to address some of the these issues, or help in PR review before creating a very large change will serve to help to give your work weight from the PoV of existing contributors. As always in an open source project, everyone wants to have their pet feature merged, but they don't want to help to review PRs (just take a look at the 138 open PRs we have today).
With that said, some in line comments follow.
open_channel2 / accept_channel2 Once we get an accept_channel2 back, we verify that the remote's funding amount is within our required range, update the reservation to the exact remote funding amount and revalidate.
How will the code determine what the "required" range is on the accepting side? One thing about single funder is that you can kinda jsut accept w/e as long as it doesn't create a crazy imbalance. Do you have any ideas on how you'd want to expose this to the responder? Today we have the channel acceptor itself, which can be a fine spot for this, as then it would mean that any dual funding request must be manually approved. IMO this is how it should be, since dual funding means that you need to commit funds instead of just the other party. If it becomes auto accept, then users could find themselves in a situation where all the funds they had on chain to open to oether peers was instead sucked up by a few peers looking to connect out to the network.
I think one other relevant question here (which I don't think yet has a satifactory answer on the spec level is): how will we attempt to mitigate privacy leafs w.r.t UTXOs? In short, if I want to learn your wallet balance, i just make a series of dual funding requests, and bail out of all of them, collect all the utxos you sent over, rinse and repeat. I think this might be less of an issue if we make them hidden behind the channel acceptor, but I still think we want something here as otherwise this is perfect for any chainalysis like snoopers (trace the UTXOs going into and out of an lnd
node).
Signature Exchange We'll need to break apart CompleteReservation into different parts:
I think we should hesitate to also break down the process into a smaller, more encapsulated state machine.
One thing I didn't see touched on above is the question of: UTXO validation. How would we handle the issue of a peer sending us an invalid or spent input? What if they spend the input after we broadcast the funding transaction? This can result in the wallet funds effectively being stuck, unless we do an explicit double spend. Related to the question of UTXO validation is also if the desired validation mechanism is actually light client compatible or not.
Re double spending our own inputs, this is a relevant PR that we'd likely want to wrap up before the main work here begins: https://github.com/lightningnetwork/lnd/pull/6400.
Dual Funding Policies
See above, I think the channel acceptor route might be preferable, since it lets users have a lot more granular control. AFAICT, these proposed config settings wouldn't be peer aware, so a single peer can repeatedly fund a channel to have all our funds allocated towards them.
@Roasbeef: Thanks for your thoughts and advice.
As a result, I think we either need to commit early on to do aggressively refactoring, or chose to explicitly leave it out of the set of planned work.
Agreed. I think aggressive refactoring is going to be cleanest.
One other thing to keep in mind, is that a mega PR implementing everything in one swoop will be very difficult to review, and will likely just sit in review limbo. As a result, I recommend that you try to chop things up into small pieces when possbile.
As described above (Implementation & Testing Plan), we can easily break the work into 5 logical chunks. We can probably do even smaller PRs at the cost of losing context for some of the changes. But if we're aligned on the overall design, maybe we don't need as much context within the PRs.
In addition, there're a few other funding related issue or PRs in the tracker. Helping to address some of the these issues, or help in PR review before creating a very large change will serve to help to give your work weight from the PoV of existing contributors. As always in an open source project, everyone wants to have their pet feature merged, but they don't want to help to review PRs (just take a look at the 138 open PRs we have today).
I'll take a look and see what outstanding issues make sense to address during this work. And I should be some help with PRs now that I'm familiar with the funding flow.
How will the code determine what the "required" range is on the accepting side? One thing about single funder is that you can kinda jsut accept w/e as long as it doesn't create a crazy imbalance. Do you have any ideas on how you'd want to expose this to the responder? Today we have the channel acceptor itself, which can be a fine spot for this, as then it would mean that any dual funding request must be manually approved. IMO this is how it should be, since dual funding means that you need to commit funds instead of just the other party. If it becomes auto accept, then users could find themselves in a situation where all the funds they had on chain to open to oether peers was instead sucked up by a few peers looking to connect out to the network.
Right, I think full ChannelAcceptor
support is the end goal here. I proposed the default-off dual_fund.match
feature for initial testing and experimentation, which we could probably implement entirely as a ChannelAcceptor
too. If we're concerned about naive users getting burned by the experimental matching feature, we could choose to expose it only via devrpc.
I think one other relevant question here (which I don't think yet has a satifactory answer on the spec level is): how will we attempt to mitigate privacy leafs w.r.t UTXOs? In short, if I want to learn your wallet balance, i just make a series of dual funding requests, and bail out of all of them, collect all the utxos you sent over, rinse and repeat. I think this might be less of an issue if we make them hidden behind the channel acceptor, but I still think we want something here as otherwise this is perfect for any chainalysis like snoopers (trace the UTXOs going into and out of an
lnd
node).
From the spec side, I believe the eventual answer is something like PoDLEs. PoDLEs were deemed too complex for the initial (current) spec, but will likely be needed to properly address the privacy issues you describe, along with some griefing issues.
I'd argue we should leave the privacy concerns to the ChannelAcceptor
for now, where we can do things like only contribute funds for vetted nodes. Users that are dual funding regularly will have their UTXOs publicly known in short order anyway (if they aren't already). Lloyd Fournier expanded this line of reasoning here.
I think we should hesitate to also break down the process into a smaller, more encapsulated state machine.
What are your thoughts on my proposed funding flow in the Wallet section under New Flow?
One thing I didn't see touched on above is the question of: UTXO validation. How would we handle the issue of a peer sending us an invalid or spent input?
The spec dictates that the full prevtx is sent for each input. Thus we can validate by hashing the prevtx and checking the blockchain for the outpoint. This should be light client compatible using BtcWallet.GetUtxo
and the pkScript extracted via btcd.
What if they spend the input after we broadcast the funding transaction? This can result in the wallet funds effectively being stuck, unless we do an explicit double spend.
We will monitor the blockchain for all funding transaction inputs until the transaction confirms or an input is double spent. When a double spend is detected, we release the lock on our UTXOs and (after the double spend has X confirmations) forget about the pending channel. This will allow us to spend the UTXOs at our leisure, without incurring extra fees.
See above, I think the channel acceptor route might be preferable, since it lets users have a lot more granular control. AFAICT, these proposed config settings wouldn't be peer aware, so a single peer can repeatedly fund a channel to have all our funds allocated towards them.
Agreed, let's build the logic into the channel acceptor.
Is anyone working on this? I still have the 10,140,920 sats I collected for this feature.
If nobody comes forward (i.e. being close to have this merged), I will donate the sats to HRF as originally indicated:
https://gist.github.com/zerofeerouting/53f12f329449357a353b9fcfe490b688
@zerofeerouting I'm no longer working on this, though LL has expressed interest in dual funding if someone else wants to take over. I can assist with code reviews since I'm quite familiar with the spec.
I am interested in working on this. I just am getting started with working inside the LND codebase but love to use this project to get myself more engaged