-
Notifications
You must be signed in to change notification settings - Fork 491
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
Explicitly allow funding_locked early, and include scid. #895
Conversation
This lets you add your brand new channel to routehints. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
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.
Concept ACK, I like the fact that it's really simple and minimal: the gist of this PR is that turbo channels are simply about ignoring accept_channel.minimum_depth
. Any node can send funding_locked
whenever they want, and the receiver decides whether to trust it at that point or wait for confirmations before sending theirs. No need for a feature bit or explicit negotiation, which is nice.
@pm47 curious to have your feedback on that, I think it should be easy to migrate Phoenix to this mechanism.
can simply start using the channel instantly by sending | ||
`funding_locked`. This raises the problem of how to use this new | ||
channel in route hints, since it does not yet have a block number. | ||
For this reason, a convincing fake number can be use; when the real |
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.
nit:
For this reason, a convincing fake number can be use; when the real | |
For this reason, a convincing fake number can be used; when the real |
- SHOULD set `short_channel_id` | ||
- if it is the sole contributor to the funding transaction, or has reason to trust the peer: | ||
- MAY send `funding_locked` before the funding transaction has reached `minimum_depth` | ||
- MAY set `short_channel_id` to a fake value, if it will route payments to that `short_channel_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.
nit: indent should be the same as the previous line
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 the idea here is to leave the derivation of this value up to both sides? Some implementations of zero conf channels I've seen in the wild, prescribe a schema (like using some bits from the pending chan ID which is selected by the funder as is anyway) so both sides can use the same value until things are confirmed on-chain, and a "real" scid is generated.
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.
On the other hand, the freedom allowed here to implementations is attractive, since one side is effectively just telling the other "I'm referring to that channel using this value until it confirms". The other direction can use another value as long as the receiver remembers that value (and doesn't even need to write it to disk?) when it sees it in an onion payload.
- MAY set `short_channel_id` to a fake value, if it will route payments to that `short_channel_id`. | ||
- otherwise: | ||
- MUST wait until the funding transaction has reached `minimum_depth` before sending this message. | ||
- SHOULD re-transmit `funding_locked` if the `short_channel_id` for this chanel has changed. |
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.
Is this necessary? It feels like nodes should instead watch confirmations on the funding tx to figure out the real short_channel_id
by themselves instead of trusting anything their peer gives them? But it's true that it doesn't hurt to send it as an FYI...
btw, nit:
- SHOULD re-transmit `funding_locked` if the `short_channel_id` for this chanel has changed. | |
- SHOULD re-transmit `funding_locked` if the `short_channel_id` for this channel has changed. |
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 this is one of those things where it doesn't hurt, this way nodes explicitly ensure that they're using teh same scid
value as otherwise the channel may not be able to be routed over.
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 should probably specify the semantics here, though - like, that both SCIDs remain active forever?
- SHOULD re-transmit `funding_locked` if the `short_channel_id` for this chanel has changed. | ||
|
||
|
||
The sender: |
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.
Remove?
Things that are unclear to me:
|
Yes, this is fully backwards-compatible. When you receive
If you want to disable payments in both directions, just don't send your If you want to disable in only one direction, you can simply refuse to forward by failing htlcs just after they've been added. However you cannot prevent htlcs from being added to the commit tx (unless you force-close), but I don't think it creates an attack vector if you don't forward (but I could be wrong, this deserves a deeper investigation if that's something you plan on implementing). |
I believe you're right, it's still money of the funder. The biggest potential issue I see is being penalized by some quality-measuring algorithms. Could we have some "please don't forward yet" flag, so that such algorithms could take it into account? I think it could be translated to marking the channel as offline. |
This opens up a big can of worms, I would personally like to avoid it. You can't enforce it anyway (you can't prevent your peer from sending you an htlc), apart from force-closing your channel, so why bother? Imagine that there is I'd really like to avoid these games of trying to make nice to quality-measuring algorithms (which are probably inherently buggy because they depend on heuristics that can prove wrong in practice). |
Would it make sense to gossip it as disabled but still forward? It'd work similarly to a private channel for the time being. Or maybe not signing announcement is enough? |
2. types: | ||
1. type: 1 (`short_channel_id`) | ||
2. data: | ||
* [`short_channel_id`:`short_channel_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.
So this scid can be made up? Is the expectation that once it has a stable ID, it's sent each time on reconnection to allow both sides to synchronize?
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.
Maybe name it something like short_channel_id_alias
to make the semantics more clear? Presumably the SCID here would be something that the counterparty knows to forward to, so the user could also put it in invoices, etc?
- SHOULD set `short_channel_id` | ||
- if it is the sole contributor to the funding transaction, or has reason to trust the peer: | ||
- MAY send `funding_locked` before the funding transaction has reached `minimum_depth` | ||
- MAY set `short_channel_id` to a fake value, if it will route payments to that `short_channel_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.
So the idea here is to leave the derivation of this value up to both sides? Some implementations of zero conf channels I've seen in the wild, prescribe a schema (like using some bits from the pending chan ID which is selected by the funder as is anyway) so both sides can use the same value until things are confirmed on-chain, and a "real" scid is generated.
- MAY set `short_channel_id` to a fake value, if it will route payments to that `short_channel_id`. | ||
- otherwise: | ||
- MUST wait until the funding transaction has reached `minimum_depth` before sending this message. | ||
- SHOULD re-transmit `funding_locked` if the `short_channel_id` for this chanel has changed. |
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 this is one of those things where it doesn't hurt, this way nodes explicitly ensure that they're using teh same scid
value as otherwise the channel may not be able to be routed over.
@@ -409,26 +409,49 @@ this channel will continue to use `option_static_remotekey` or `option_anchor_ou | |||
|
|||
This message indicates that the funding transaction has reached the `minimum_depth` asked for in `accept_channel`. Once both nodes have sent this, the channel enters normal operating mode. | |||
|
|||
As an extension, nodes which entirely funded the channel themselves, |
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.
I think this needs a feature bit, as it would allow nodes that want to actively open these zero conf channels to seek out other peers that want to accept them.
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.
Also it's possible some nodes treat the early sending of funding locked as a protocol-level error?
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.
Also it's possible some nodes treat the early sending of funding locked as a protocol-level error?
That would be very surprising, you can't be sure that a funding_locked
is early, when you think it's early it may be in fact your view of the blockchain that's late. Considering this a protocol error would be a mistake, when you simply need to wait for your view of the blockchain to catch up and send your own funding_locked
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.
I think this needs a feature bit, as it would allow nodes that want to actively open these zero conf channels to seek out other peers that want to accept them.
I'm really hesitant on that one. At first I agreed with you (and we've defined a feature bit for that in Phoenix). But the issue is that it's not actually binding. If Alice advertises that she accepts 0-conf, you open a channel to her, but then in fact she doesn't send her funding_locked
early, you'll feel a bit cheated.
But I wouldn't hold a grudge against Alice: it's dangerous for her to accept 0-conf from any random node that comes up, so we can't expect her to universally do 0-conf...she would probably do 0-conf based on a set of heuristics (is she funder or fundee? what channel type is this? is this channel part of a service she benefits from, such as opening on-the-fly for a fee?).
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.
I'm pretty dubious of this as a general-purpose extension. I'm not sure that, in practice, you'd ever really use this by going out and finding public nodes that accept 0conf payments, its more of an extension for nodes to use when communicating with their wallet vendor's or their own node, ie manually configured.
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.
I think this proposal would benefit from a feature bit. I can see in the future situation where you're seeking instant inbound liquidity because the missed economic opportunity will cost you higher than the loss multiplied by the odds of double-spend event realization. If one has to probe-and-engage-in-opening %X of the network to see who is willingly to zero-conf you're moving away from the instant effect.
Further, w.r.t to the unsafety of 0-conf, I still think trust won't be binary, one might rely on other heuristics to decide if it's a "random" node or not, e.g already-opened channels, reputation scoring, pre-paid tokens, ...
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.
I'm really hesitant on that one. At first I agreed with you (and we've defined a feature bit for that in Phoenix). But the issue is that it's not actually binding.
So the idea here is to use it along-side the new explicit chan funding feature. We can even make the feature bits dependent on it as well. This way a node can preferentially reject zero conf funding attempts w/ nodes for w/e reason (isn't their wallet provider, etc, etc).
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.
well. This way a node can preferentially reject zero conf funding attempts w/ nodes for w/e reason (isn't their wallet provider, etc, etc).
Why would you do that?
I can see in the future situation where you're seeking instant inbound liquidity because the missed economic opportunity will cost you higher than the loss multiplied by the odds of double-spend event realization. If one has to probe-and-engage-in-opening %X of the network to see who is willingly to zero-conf you're moving away from the instant effect.
Wouldn't this still imply a separate negotiation mechanism? If you want liquidity you'll probably engage one of the two liquidity negotiation markets that exist now. Advertising the bit is explicitly advertising "I am vulnerable to some funds-stealing attacks, please come and get it".
All that said, I think there's room for a feature bit that implies support, but not use, of the new TLV. If we expand the utility here beyond just zero conf to include SCID aliases that can be useful to advertise. Of course then the feature bit would be useless for the purpose of finding peers that will offer you unsafe forwarding features.
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 the idea here is to use it along-side the new explicit chan funding feature.
Unfortunately even having a channel_type
for this doesn't solve the issue, it would still be non-binding.
Even if your peer says ok to a 0-conf channel_type
, they may decide to wait for confirmations anyway and you can't do anything about it (apart from avoiding this node in the future).
This matches what Matt says in All that said, I think there's room for a feature bit that implies support, but not use, of the new TLV.
. There is some value in advertising "I may do 0-conf for you" with a feature bit, but there's a big red flag that there's no guarantee and peers shouldn't expect it to always be 0-conf.
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.
Even if your peer says ok to a 0-conf channel_type, they may decide to wait for confirmations anyway and you can't do anything about it (apart from avoiding this node in the future).
Ah yeah totally makes sense, up to them if they send it or not, but either side can sort of initiate it first, letting the other side decide if they wish to cooperate in zero conf land or not. Agreed re a bit for support but not compelling usage of given the way things are specified as is.
- SHOULD set `short_channel_id` | ||
- if it is the sole contributor to the funding transaction, or has reason to trust the peer: | ||
- MAY send `funding_locked` before the funding transaction has reached `minimum_depth` | ||
- MAY set `short_channel_id` to a fake value, if it will route payments to that `short_channel_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.
On the other hand, the freedom allowed here to implementations is attractive, since one side is effectively just telling the other "I'm referring to that channel using this value until it confirms". The other direction can use another value as long as the receiver remembers that value (and doesn't even need to write it to disk?) when it sees it in an onion payload.
for the following commitment transaction, derived as specified in | ||
[BOLT #3](03-transactions.md#per-commitment-secret-requirements). | ||
- SHOULD set `short_channel_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.
There should be some restrictions on SCID here if its not real - I think we'll want to avoid accidentally conflicting if we can. IIRC some folks have been using random numbers below the segwit activation height, which seems reasonable, its something like 58 bits which isn't infinite, but probably enough entropy to not worry about it, but that means this should say you MUST set it to a random value or something.
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.
On the one hand, you get to set it, if you break it you get to keep both pieces. "I will refer to this channel as X" and then you open a real channel X and you don't know which one to fwd payments to.
But that may not be obvious, so I'll add some advice.
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.
Hmm, I suppose they aren't used in gossip messages so its maybe ok that they collide? It does feel awkward that we'll let them collide in the spec just because colliding namespaces feel wrong, but I don't see any obvious issues since you can argue its just a local namespace that happens to overlap with a separate global one.
If you're the 0-conf fundee and starts with a Note, I think even adding HTLCs to your fundee's commitment transaction might be unsafe/DoSy in the anchor output model, where it might trigger you to lock up more fee-bumping liquidity. |
Started implementing this on the LDK side. A few things need clarification, I think. In the reestablish flow should probably drop the "MUST NOT retransmit funding_locked" in case of reconnection after some commitment messages have been exchanged. In general, I think we should allow nodes to send new SCID aliases any time they want, allowing rotating SCID aliases as the counterparty sees fit (though they MUST store all previous SCID aliases they've provided and accept them for inbound routing forever). Semantics around the contents of the fucking_locked after a few commitments have been exchanged are also somewhat confusing. I guess we can always say "always send the first per commitment point again and again", because I'm not sure how else you'd do it without race conditions that are hard to resolve. Presumably we can also just say that if commitments have been exchanged the values must be ignored. |
It's pretty close to what we have in Phoenix (we send |
In practice, how do y'all plan to handle colliding scid from different peers? So I have peers A and B, we're doing zero conf channel funding, but then they both send the same fake scid to use to identify their channel in the invoice/onion, etc. Using the pubkey based routing (#814) addresses this AFAICT since those values are unlikely to collide. With pubkey based routing, you also don't need to worry about the scid at all, and can just use the same peer pubkey value and also eventually update it, plus you don't have such a small address space that you need to worry about collisions. The other advantage of the pubkey approach is that you don't need to to handle the logic of "switching over" to using the "real" scid once the channel is eventually (or maybe it never is really?) confirmed. Otherwise it seems you'd need to sort of interactively reject a colliding scid and force the peer to reconnect again to present you with a "valid" value? |
Yes, if you push me money it's always safe for me to spend it. But I decided this corner case was not worth explicitly supporting TBH, and most people seem more interested in "oh, I bought a channel off bitrefill, sure I trust it". |
Who cares? If Bob and Carol both refer to their Alice channels as X, no problem. Alice only needs to know what Bob uses so she can write routehints.
I believe you're overthinking? (Aside: I've been idly considering a scheme where we get rid of all scids, and require nodes to prove control of some UTXO, then announce channels, say 1 channel per 10,000sat rounded up or something. This weakens anti-spam, but also greatly reduces chain-to-lightning linkage. This scheme has other problems (what if you spend your node utxo? how do we identify channels for channel_update?), but if someone wants something to think about... |
This corner case was the original motivation for Turbo channels and has a nice property of strictly improving zeroconf security in trades (buy a channel from ATM). Other implementations, while not strictly wrong, reduce security by introducing a TTP. There's another edge case: if I buy from ATM which opens turbo channel with additional liquidity and then I buy again before the initial channel confirms I should be able to reuse the channel without loss of security but I imagine it'd be quite annoying to implement.
Yes please!!!!! |
Yes, nobody cared enough to propose a spec change for Turbo Channels, which is disturbing. Note that you can still implement this, but it's not clear it's a spec issue? If you offer me free money, I can take it: this provides a mechanism to do so. |
I think the alias should last until you send announcement_signatures, if any. I don't think rolling multiple aliases should be explicitly supported. |
OK, I've created an alternate proposal, in PR #910 That one:
vs. This one:
It changed enough that I made a new PR. |
See #565 This PR (and #910) should actually say closes #565
Actually, I just realized it should be enough as-is:
There's just one little case: the directly connected peer could attempt to route-out. It could help adding a bit to inform the peer to not do that or the wallets implementing this could simply avoid to send through actually unconfirmed channels. |
Did you mean to say everyone who believes they won't be a victim of theft? |
Am I? Put simply: if two peers send the same
What does Alice do when an onion that wants to route to channel |
This lets you add your brand new channel to routehints, and also sanity check the peer in case of chain splits.