Skip to content

Commit ff41c98

Browse files
committed
channeld: handle upgrade match.
We don't actually set desired_type yet, but this handles it. Changelog-EXPERIMENTAL: Protocol: we can now upgrade old channels to `option_static_remotekey` from lightning/bolts#868 Signed-off-by: Rusty Russell <[email protected]>
1 parent c4c598d commit ff41c98

File tree

7 files changed

+197
-3
lines changed

7 files changed

+197
-3
lines changed

channeld/channeld.c

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,50 @@ static bool handle_master_request_later(struct peer *peer, const u8 *msg)
346346
}
347347
return false;
348348
}
349+
350+
static bool channel_type_eq(const struct channel_type *a,
351+
const struct channel_type *b)
352+
{
353+
return featurebits_eq(a->features, b->features);
354+
}
355+
356+
static bool match_type(const struct channel_type *desired,
357+
const struct channel_type *current,
358+
struct channel_type **upgradable)
359+
{
360+
/* Missing fields are possible. */
361+
if (!desired || !current)
362+
return false;
363+
364+
if (channel_type_eq(desired, current))
365+
return true;
366+
367+
for (size_t i = 0; i < tal_count(upgradable); i++) {
368+
if (channel_type_eq(desired, upgradable[i]))
369+
return true;
370+
}
371+
372+
return false;
373+
}
374+
375+
static void set_channel_type(struct channel *channel,
376+
const struct channel_type *type)
377+
{
378+
const struct channel_type *cur = channel_type(tmpctx, channel);
379+
380+
if (channel_type_eq(cur, type))
381+
return;
382+
383+
/* We only allow one upgrade at the moment, so that's it. */
384+
assert(!channel->option_static_remotekey);
385+
assert(feature_offered(type->features, OPT_STATIC_REMOTEKEY));
386+
387+
/* Do upgrade, tell master. */
388+
channel->option_static_remotekey = true;
389+
status_unusual("Upgraded channel to [%s]",
390+
fmt_featurebits(tmpctx, type->features));
391+
wire_sync_write(MASTER_FD, take(towire_channeld_upgraded(NULL, true)));
392+
}
349393
#else /* !EXPERIMENTAL_FEATURES */
350394
static bool handle_master_request_later(struct peer *peer, const u8 *msg)
351395
{
@@ -2477,7 +2521,8 @@ static void peer_reconnect(struct peer *peer,
24772521
&my_current_per_commitment_point, NULL);
24782522

24792523
#if EXPERIMENTAL_FEATURES
2480-
send_tlvs = tlv_channel_reestablish_tlvs_new(tmpctx);
2524+
/* Subtle: we free tmpctx below as we loop, so tal off peer */
2525+
send_tlvs = tlv_channel_reestablish_tlvs_new(peer);
24812526
/* BOLT-upgrade_protocol #2:
24822527
* A node sending `channel_reestablish`, if it supports upgrading channels:
24832528
* - MUST set `next_to_send` the commitment number of the next
@@ -2775,6 +2820,71 @@ static void peer_reconnect(struct peer *peer,
27752820
fmt_featurebits(tmpctx,
27762821
recv_tlvs->upgradable[i]->features));
27772822
}
2823+
2824+
/* BOLT-upgrade_protocol #2:
2825+
*
2826+
* A node receiving `channel_reestablish`:
2827+
* - if it has to retransmit `commitment_signed` or `revoke_and_ack`:
2828+
* - MUST consider the channel feature change failed.
2829+
*/
2830+
if (retransmit_commitment_signed || retransmit_revoke_and_ack) {
2831+
status_debug("No upgrade: we retransmitted");
2832+
/* BOLT-upgrade_protocol #2:
2833+
*
2834+
* - if `next_to_send` is missing, or not equal to the
2835+
* `next_commitment_number` it sent:
2836+
* - MUST consider the channel feature change failed.
2837+
*/
2838+
} else if (!recv_tlvs->next_to_send) {
2839+
status_debug("No upgrade: no next_to_send received");
2840+
} else if (*recv_tlvs->next_to_send != peer->next_index[LOCAL]) {
2841+
status_debug("No upgrade: they're retransmitting");
2842+
/* BOLT-upgrade_protocol #2:
2843+
*
2844+
* - if updates are pending on either sides' commitment transaction:
2845+
* - MUST consider the channel feature change failed.
2846+
*/
2847+
/* Note that we can have HTLCs we *want* to add or remove
2848+
* but haven't yet: thats OK! */
2849+
} else if (pending_updates(peer->channel, LOCAL, true)
2850+
|| pending_updates(peer->channel, REMOTE, true)) {
2851+
status_debug("No upgrade: pending changes");
2852+
} else {
2853+
const struct tlv_channel_reestablish_tlvs *initr, *ninitr;
2854+
const struct channel_type *type;
2855+
2856+
if (peer->channel->opener == LOCAL) {
2857+
initr = send_tlvs;
2858+
ninitr = recv_tlvs;
2859+
} else {
2860+
initr = recv_tlvs;
2861+
ninitr = send_tlvs;
2862+
}
2863+
2864+
/* BOLT-upgrade_protocol #2:
2865+
*
2866+
* - if `desired_type` matches `current_type` or any
2867+
* `upgradable` `upgrades`:
2868+
* - MUST consider the channel type to be `desired_type`.
2869+
* - otherwise:
2870+
* - MUST consider the channel feature change failed.
2871+
* - if there is a `current_type` field:
2872+
* - MUST consider the channel type to be `current_type`.
2873+
*/
2874+
/* Note: returns NULL on missing fields, aka NULL */
2875+
if (match_type(initr->desired_type,
2876+
ninitr->current_type, ninitr->upgradable))
2877+
type = initr->desired_type;
2878+
else if (ninitr->current_type)
2879+
type = ninitr->current_type;
2880+
else
2881+
type = NULL;
2882+
2883+
if (type)
2884+
set_channel_type(peer->channel, type);
2885+
}
2886+
tal_free(send_tlvs);
2887+
27782888
#endif /* EXPERIMENTAL_FEATURES */
27792889

27802890
/* Corner case: we didn't send shutdown before because update_add_htlc
@@ -3223,6 +3333,7 @@ static void req_in(struct peer *peer, const u8 *msg)
32233333
case WIRE_CHANNELD_DEV_MEMLEAK_REPLY:
32243334
case WIRE_CHANNELD_SEND_ERROR_REPLY:
32253335
case WIRE_CHANNELD_DEV_QUIESCE_REPLY:
3336+
case WIRE_CHANNELD_UPGRADED:
32263337
break;
32273338
}
32283339

channeld/channeld_wire.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,7 @@ msgtype,channeld_send_error_reply,1108
221221
# Ask channeld to quiesce.
222222
msgtype,channeld_dev_quiesce,1009
223223
msgtype,channeld_dev_quiesce_reply,1109
224+
225+
# Tell master we're upgrading the commitment tx.
226+
msgtype,channeld_upgraded,1011
227+
msgdata,channeld_upgraded,option_static_remotekey,bool,

channeld/channeld_wiregen.c

Lines changed: 25 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

channeld/channeld_wiregen.h

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/features.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,20 @@ u8 *featurebits_or(const tal_t *ctx, const u8 *f1 TAKES, const u8 *f2 TAKES)
478478
return result;
479479
}
480480

481+
bool featurebits_eq(const u8 *f1, const u8 *f2)
482+
{
483+
size_t len = tal_bytelen(f1);
484+
485+
if (tal_bytelen(f2) > len)
486+
len = tal_bytelen(f2);
487+
488+
for (size_t i = 0; i < len * 8; i++) {
489+
if (feature_is_set(f1, i) != feature_is_set(f2, i))
490+
return false;
491+
}
492+
return true;
493+
}
494+
481495
struct feature_set *fromwire_feature_set(const tal_t *ctx,
482496
const u8 **cursor, size_t *max)
483497
{

common/features.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ void set_feature_bit(u8 **ptr, u32 bit);
7171
/* Given two featurebit vectors, combine them by applying a logical OR. */
7272
u8 *featurebits_or(const tal_t *ctx, const u8 *f1 TAKES, const u8 *f2 TAKES);
7373

74+
/* Are these two feature bitsets functionally equal (one may have
75+
* trailing zeroes)? */
76+
bool featurebits_eq(const u8 *f1, const u8 *f2);
77+
7478
/* Good for debugging: returns comma-separated string of bits. */
7579
const char *fmt_featurebits(const tal_t *ctx, const u8 *featurebits);
7680

lightningd/channel_control.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,29 @@ void forget_channel(struct channel *channel, const char *why)
370370
forget(channel);
371371
}
372372

373+
#if EXPERIMENTAL_FEATURES
374+
static void handle_channel_upgrade(struct channel *channel,
375+
const u8 *msg)
376+
{
377+
bool option_static_remotekey;
378+
379+
if (!fromwire_channeld_upgraded(msg, &option_static_remotekey)) {
380+
channel_internal_error(channel, "bad handle_channel_upgrade: %s",
381+
tal_hex(tmpctx, msg));
382+
return;
383+
}
384+
385+
channel->static_remotekey_start[LOCAL] = channel->next_index[LOCAL];
386+
channel->static_remotekey_start[REMOTE] = channel->next_index[REMOTE];
387+
log_debug(channel->log,
388+
"option_static_remotekey enabled at %"PRIu64"/%"PRIu64,
389+
channel->static_remotekey_start[LOCAL],
390+
channel->static_remotekey_start[REMOTE]);
391+
392+
wallet_channel_save(channel->peer->ld->wallet, channel);
393+
}
394+
#endif /* EXPERIMENTAL_FEATURES */
395+
373396
static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
374397
{
375398
enum channeld_wire t = fromwire_peektype(msg);
@@ -405,6 +428,13 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
405428
case WIRE_CHANNELD_SEND_ERROR_REPLY:
406429
handle_error_channel(sd->channel, msg);
407430
break;
431+
#if EXPERIMENTAL_FEATURES
432+
case WIRE_CHANNELD_UPGRADED:
433+
handle_channel_upgrade(sd->channel, msg);
434+
break;
435+
#else
436+
case WIRE_CHANNELD_UPGRADED:
437+
#endif
408438
/* And we never get these from channeld. */
409439
case WIRE_CHANNELD_INIT:
410440
case WIRE_CHANNELD_FUNDING_DEPTH:

0 commit comments

Comments
 (0)