bolts icon indicating copy to clipboard operation
bolts copied to clipboard

Funding Timeout Recovery proposal

Open cdecker opened this issue 4 years ago • 3 comments
trafficstars

Since we recently strengthened the "you're allowed to forget" rule I though it might be nice to revisit the state that this leaves the funder in. When a fundee forgets about a channel, the funder is forced to either double-spend the funding transaction (if possible), or use the negotiated commitment transaction, which usually has much higher fees attached than necessary, and results in the funds being unavailable until the to_us timeout expires.

This proposal describes a minimal set of information a fundee might want to keep around, to assist the funder to recover its funds. It basically boils down to writing a blank check to the funder and the funder can then implement arbitrary recovery logic. The blank check is limited to the channel in question via the funding_privkey which is channel specific.

In addition. it adds a small facility, based on the same ground-work, to recover funds from malleated funding transactions, which we've had one recently due to the user importing the private key into an external wallet and manipulating the funding transaction there before broadcasting. It might be a rare case, but I think it's a nice escape hatch to use if anything goes bad. In that case it was re-negotiating a close on a funding transaction alias.

Update: #866 was filed as a competing variant based on exchanging the keys. Please continue discussing trade-offs here, so we don't spread the discussion over two PRs.

Closes #866

cdecker avatar Mar 15 '21 14:03 cdecker

I also proposed the "give the funding_key" to @cdecker but I wasn't sure anyone would be comfortable with it....

rustyrussell avatar Mar 29 '21 19:03 rustyrussell

I also proposed the "give the funding_key" to @cdecker but I wasn't sure anyone would be comfortable with it....

This came up in the last IRC meeting with many attendees preferring that route "just send the multi-sig private key" instead of the blank check out. Although this route is much simpler, IMO it's to be avoided (in favor of the original proposal) as:

  • We make no requirements w.r.t the method of derivation used for the private keys. Depending on the implementation, leaking those keys could compromise other keys if non hardened derivation is used.
  • It creates a new foot-gun where a user could possibly be manipulated into sending the keys while the actually is still active, thereby forfeiting all their funds.
  • Just even the thought of "users just sending their private keys of the wire" should make us all shudder...

Roasbeef avatar Apr 07 '21 00:04 Roasbeef

I added the KEYOLO variant as #866 as promised during the last spec meeting, however I find the more restricted variant exchanging just the sighash_none signature a bit more palatable, as it clearly has fewer requirements on the way the fundee funding_privkey is derived. I added the requirement for hardened derivation multiple times, but some implementers might eventually forget about it.

To summarize the differences:

  • KEYOLO is less fingerprintable on-chain, given that it doesn't require a non-default sighash-flag.
  • KEYOLO also covers the case of a user sending funds to a funding output script, outside of a channel funding.
    • Should we consider this part of our spec at all? We can't prevent users from doing dumb things, neither should we. And this only applies when they happen to send to a channel that timed out anyway, i.e., if they send to a channel script that was used the funds are unrecoverable even with KEYOLO.
  • It creates a new foot-gun where a user could possibly be manipulated into sending the keys while the actually is still active, thereby forfeiting all their funds.

I'm afraid this is even the case with the more restrictive #854 proposal: if you send out a sighash_none signature as per this proposal, and then fail to mark the channel as inactive, then whatever you do going forward could race with a close transaction that the funder can now create using that signature. All the invalidation logic just went out the window. Hence my insistence on marking the channel as unusable before exchanging signatures. Ideally we'd mark the channel as forgotten/abandoned on a timeout, and generate the signature only as a reaction to getting a re-establish for a channel that is already marked abandoned in the committed state to disk. This avoids having to deal with some edge-cases like marking in a DB transaction while queuing the message, and then rolling back or abandoning the DB transaction, but not clearing the message queue.

cdecker avatar Apr 26 '21 16:04 cdecker