Skip to content
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

Send channel_announcement for splice transactions on public channels #2968

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

t-bast
Copy link
Member

@t-bast t-bast commented Dec 18, 2024

We now support splicing on public channels: once the splice transaction is confirmed and locked on both sides, nodes will exchange announcement signatures that allows them to create a channel_announcement that they then broadcast to the network.

This requires reworking the data model to include the announcement and the real short_channel_id in each commitment, which lets us cleanly distinguish real short_channel_ids from aliases (which are set at the channel level regardless of the current commitments).

The flow now becomes:

  • when the funding transaction of a commitment confirms, we set the corresponding real short_channel_id in that commitment
  • if the channel is public and we've received channel_ready or splice_locked, we send our announcement_signatures
  • if we receive announcement_signatures for a commitment for which the funding transaction is unconfirmed, we stash it and replay it when the transaction confirms
  • if we receive announcement_signatures for a confirmed commitment, and we don't have a more recently announced commitment, we generate a channel_announcement, store it with the commitment and update our router data

When creating a channel_update for a public channel, we always use the short_channel_id that matches the latest announcement we created. This is very important to guarantee that nodes receiving our updates will not discard them because they cannot match it to a channel.

For private channels, we stop allowing usage of the short_channel_id for routing: scid_alias MUST be used, which ensures that the channel utxo isn't revealed.

Note that when migrating to taproot channels, splice_locked will be used to transmit nonces for the announcement signatures, which will be compatible with the existing flow (and similarly, channel_ready will be used for the initial funding transaction). They are retransmitted on reconnection to ensure that the announcements can be generated.

Don't be scared by the large number of added lines: most of them are JSONs for backwards-compatibility serialization tests.

@t-bast t-bast force-pushed the per-commitment-channel-announcement branch 3 times, most recently from defefb4 to 54de064 Compare December 31, 2024 15:41
@t-bast t-bast changed the title Move channel_announcement to Commitment Add support for announcing public splice transactions Dec 31, 2024
@t-bast t-bast changed the title Add support for announcing public splice transactions Send channel_announcement for splice transactions on public channels Dec 31, 2024
@@ -327,6 +327,14 @@ private[channel] object ChannelCodecs3 {
("claimHtlcDelayedPenaltyTxs" | listOfN(uint16, claimHtlcDelayedOutputPenaltyTxCodec)) ::
("spent" | spentMapCodec)).as[RevokedCommitPublished]

private val shortids: Codec[ShortIdAliases] = (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important note: for channels encoded with v3 or lower, we don't add any migration code, so it looks like we're losing information about the real short_channel_id, but that isn't the case: since we set localFundingStatus to unconfirmed (in ChannelTypes0.scala and ChannelTypes3.scala), we will set a WatchFundingConfirmed when restarting which lets us obtain details about the funding transaction and correctly set the short_channel_id.

@t-bast t-bast force-pushed the per-commitment-channel-announcement branch 2 times, most recently from 29abd57 to 29628d5 Compare January 2, 2025 10:58
@t-bast t-bast marked this pull request as ready for review January 2, 2025 14:51
@t-bast t-bast requested review from remyers and pm47 January 2, 2025 14:51
Copy link
Contributor

@remyers remyers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've taken a first pass and it looks good so far. I've focused mostly on the channel and router behavior; less on the serialization so far.

During a channel reestablishment it seems like we only resend announcement sigs when no announcement was sent during initial funding, but not during splices.

I also have a few questions and suggestions to add tests for a few incidental bug fixes you made during the refactor that probably don't have associated tests.

@t-bast t-bast force-pushed the per-commitment-channel-announcement branch from 29628d5 to 1bf54c1 Compare January 10, 2025 16:59
Copy link
Contributor

@remyers remyers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The serialization code looks pretty straight forward for the most part. I do have one suggestion and found one potential issue related to moving the real scid to the funding status.

remyers
remyers previously approved these changes Jan 15, 2025
@t-bast t-bast dismissed remyers’s stale review January 23, 2025 13:39

The merge-base changed after approval.

@t-bast t-bast force-pushed the per-commitment-channel-announcement branch from 1bf54c1 to ab2a830 Compare January 23, 2025 13:39
We now support splicing on public channels: once the splice transaction
is confirmed and locked on both sides, nodes will exchange announcement
signatures that allows them to create a `channel_announcement` that they
then broadcast to the network.

This requires reworking the data model to include the announcement and
the real `short_channel_id` in each commitment, which lets us cleanly
distinguish real `short_channel_id`s from aliases (which are set at the
channel level regardless of the current commitments).

The flow now becomes:

- when the funding transaction of a commitment confirms, we set the
  corresponding real `short_channel_id` in that commitment
- if the channel is public and we've received `channel_ready` or
  `splice_locked`, we send our `announcement_signatures`
- if we receive `announcement_signatures` for a commitment for which
  the funding transaction is unconfirmed, we stash it and replay it
  when the transaction confirms
- if we receive `announcement_signatures` for a confirmed commitment,
  and we don't have a more recently announced commitment, we generate
  a `channel_announcement`, store it with the commitment and update
  our router data

When creating a `channel_update` for a public channel, we always use
the `short_channel_id` that matches the latest announcement we created.
This is very important to guarantee that nodes receiving our updates
will not discard them because they cannot match it to a channel.

For private channels, we stop allowing usage of the `short_channel_id`
for routing: `scid_alias` MUST be used, which ensures that the channel
utxo isn't revealed.

Note that when migrating to taproot channels, `splice_locked` will be
used to transmit nonces for the announcement signatures, which will be
compatible with the existing flow (and similarly, `channel_ready` will
be used for the initial funding transaction). They are retransmitted
on reconnection to ensure that the announcements can be generated.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants