channeld: send upgradable types, add logging (EXPERIMENTAL_FEATURES)

For now the only upgrade possible is to enable option_static_remotekey.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2021-06-04 14:43:47 +09:30
parent d2814a957f
commit d305b8ada6
4 changed files with 50 additions and 0 deletions

View File

@@ -2524,6 +2524,8 @@ static void peer_reconnect(struct peer *peer,
* - MAY not set `upgradable` if it would be empty. * - MAY not set `upgradable` if it would be empty.
*/ */
send_tlvs->current_type = channel_type(send_tlvs, peer->channel); send_tlvs->current_type = channel_type(send_tlvs, peer->channel);
send_tlvs->upgradable = channel_upgradable_types(send_tlvs,
peer->channel);
} }
#endif #endif
@@ -2780,6 +2782,23 @@ static void peer_reconnect(struct peer *peer,
/* (If we had sent `closing_signed`, we'd be in closingd). */ /* (If we had sent `closing_signed`, we'd be in closingd). */
maybe_send_shutdown(peer); maybe_send_shutdown(peer);
#if EXPERIMENTAL_FEATURES
if (recv_tlvs->desired_type)
status_debug("They sent desired_type [%s]",
fmt_featurebits(tmpctx,
recv_tlvs->desired_type->features));
if (recv_tlvs->current_type)
status_debug("They sent current_type [%s]",
fmt_featurebits(tmpctx,
recv_tlvs->current_type->features));
for (size_t i = 0; i < tal_count(recv_tlvs->upgradable); i++) {
status_debug("They offered upgrade to [%s]",
fmt_featurebits(tmpctx,
recv_tlvs->upgradable[i]->features));
}
#endif /* EXPERIMENTAL_FEATURES */
/* Corner case: we didn't send shutdown before because update_add_htlc /* Corner case: we didn't send shutdown before because update_add_htlc
* pending, but now they're cleared by restart, and we're actually * pending, but now they're cleared by restart, and we're actually
* complete. In that case, their `shutdown` will trigger us. */ * complete. In that case, their `shutdown` will trigger us. */

View File

@@ -186,6 +186,17 @@ struct channel_type *channel_type(const tal_t *ctx,
return new_channel_type(ctx); return new_channel_type(ctx);
} }
struct channel_type **channel_upgradable_types(const tal_t *ctx,
const struct channel *channel)
{
struct channel_type **arr = tal_arr(ctx, struct channel_type *, 0);
if (!channel->option_static_remotekey)
tal_arr_expand(&arr, type_static_remotekey(arr));
return arr;
}
#endif /* EXPERIMENTAL_FEATURES */ #endif /* EXPERIMENTAL_FEATURES */
static char *fmt_channel_view(const tal_t *ctx, const struct channel_view *view) static char *fmt_channel_view(const tal_t *ctx, const struct channel_view *view)

View File

@@ -147,6 +147,10 @@ u32 channel_feerate(const struct channel *channel, enum side side);
*/ */
struct channel_type *channel_type(const tal_t *ctx, struct channel_type *channel_type(const tal_t *ctx,
const struct channel *channel); const struct channel *channel);
/* What features can we upgrade? (Returns NULL if none). */
struct channel_type **channel_upgradable_types(const tal_t *ctx,
const struct channel *channel);
#endif /* EXPERIMENTAL_FEATURES */ #endif /* EXPERIMENTAL_FEATURES */
#endif /* LIGHTNING_COMMON_INITIAL_CHANNEL_H */ #endif /* LIGHTNING_COMMON_INITIAL_CHANNEL_H */

View File

@@ -3478,6 +3478,22 @@ def test_openchannel_init_alternate(node_factory, executor):
print("nothing to do") print("nothing to do")
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "upgrade protocol not available")
@pytest.mark.developer("dev-force-features required")
def test_upgrade_statickey(node_factory, executor):
"""l1 doesn't have option_static_remotekey, l2 offers it."""
l1, l2 = node_factory.line_graph(2, opts=[{'may_reconnect': True,
'dev-force-features': ["-13", "-21"]},
{'may_reconnect': True}])
l1.rpc.disconnect(l2.info['id'], force=True)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.daemon.wait_for_logs([r"They sent current_type \[\]",
r"They offered upgrade to \[13\]"])
l2.daemon.wait_for_log(r"They sent desired_type \[\]")
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "quiescence is experimental") @unittest.skipIf(not EXPERIMENTAL_FEATURES, "quiescence is experimental")
@pytest.mark.developer("quiescence triggering is dev only") @pytest.mark.developer("quiescence triggering is dev only")
def test_quiescence(node_factory, executor): def test_quiescence(node_factory, executor):