mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-21 14:24:09 +01:00
channeld: import updated channel_upgrade spec.
It now uses raw bitfields instead of a subtype, and only allows a single option for any upgrade. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
55dbe82162
commit
7157a92ea6
7 changed files with 93 additions and 81 deletions
|
@ -332,37 +332,32 @@ static bool handle_master_request_later(struct peer *peer, const u8 *msg)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool match_type(const struct channel_type *desired,
|
||||
const struct channel_type *current,
|
||||
struct channel_type **upgradable)
|
||||
/* Compare, with false if either is NULL */
|
||||
static bool match_type(const u8 *t1, const u8 *t2)
|
||||
{
|
||||
/* Missing fields are possible. */
|
||||
if (!desired || !current)
|
||||
if (!t1 || !t2)
|
||||
return false;
|
||||
|
||||
if (channel_type_eq(desired, current))
|
||||
return true;
|
||||
|
||||
return channel_type_eq_any(desired, upgradable);
|
||||
return featurebits_eq(t1, t2);
|
||||
}
|
||||
|
||||
static void set_channel_type(struct channel *channel,
|
||||
const struct channel_type *type)
|
||||
static void set_channel_type(struct channel *channel, const u8 *type)
|
||||
{
|
||||
const struct channel_type *cur = channel->type;
|
||||
|
||||
if (channel_type_eq(cur, type))
|
||||
if (featurebits_eq(cur->features, type))
|
||||
return;
|
||||
|
||||
/* We only allow one upgrade at the moment, so that's it. */
|
||||
assert(!channel_has(channel, OPT_STATIC_REMOTEKEY));
|
||||
assert(feature_offered(type->features, OPT_STATIC_REMOTEKEY));
|
||||
assert(feature_offered(type, OPT_STATIC_REMOTEKEY));
|
||||
|
||||
/* Do upgrade, tell master. */
|
||||
tal_free(channel->type);
|
||||
channel->type = channel_type_dup(channel, type);
|
||||
channel->type = channel_type_from(channel, type);
|
||||
status_unusual("Upgraded channel to [%s]",
|
||||
fmt_featurebits(tmpctx, type->features));
|
||||
fmt_featurebits(tmpctx, type));
|
||||
wire_sync_write(MASTER_FD,
|
||||
take(towire_channeld_upgraded(NULL, channel->type)));
|
||||
}
|
||||
|
@ -2650,6 +2645,27 @@ static bool capture_premature_msg(const u8 ***shit_lnd_says, const u8 *msg)
|
|||
return true;
|
||||
}
|
||||
|
||||
#if EXPERIMENTAL_FEATURES
|
||||
/* Unwrap a channel_type into a raw byte array for the wire: can be NULL */
|
||||
static u8 *to_bytearr(const tal_t *ctx,
|
||||
const struct channel_type *channel_type TAKES)
|
||||
{
|
||||
u8 *ret;
|
||||
bool steal;
|
||||
|
||||
steal = taken(channel_type);
|
||||
if (!channel_type)
|
||||
return NULL;
|
||||
|
||||
if (steal) {
|
||||
ret = tal_steal(ctx, channel_type->features);
|
||||
tal_free(channel_type);
|
||||
} else
|
||||
ret = tal_dup_talarr(ctx, u8, channel_type->features);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void peer_reconnect(struct peer *peer,
|
||||
const struct secret *last_remote_per_commit_secret,
|
||||
u8 *reestablish_only)
|
||||
|
@ -2699,8 +2715,10 @@ static void peer_reconnect(struct peer *peer,
|
|||
* channel.
|
||||
*/
|
||||
if (peer->channel->opener == LOCAL)
|
||||
send_tlvs->desired_type = channel_desired_type(send_tlvs,
|
||||
peer->channel);
|
||||
send_tlvs->desired_channel_type =
|
||||
to_bytearr(send_tlvs,
|
||||
take(channel_desired_type(NULL,
|
||||
peer->channel)));
|
||||
else {
|
||||
/* BOLT-upgrade_protocol #2:
|
||||
* - otherwise:
|
||||
|
@ -2710,10 +2728,12 @@ static void peer_reconnect(struct peer *peer,
|
|||
* to.
|
||||
* - MAY not set `upgradable` if it would be empty.
|
||||
*/
|
||||
send_tlvs->current_type = tal_dup(send_tlvs, struct channel_type,
|
||||
peer->channel->type);
|
||||
send_tlvs->upgradable = channel_upgradable_types(send_tlvs,
|
||||
peer->channel);
|
||||
send_tlvs->current_channel_type
|
||||
= to_bytearr(send_tlvs, peer->channel->type);
|
||||
send_tlvs->upgradable_channel_type
|
||||
= to_bytearr(send_tlvs,
|
||||
take(channel_upgradable_type(NULL,
|
||||
peer->channel)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2991,20 +3011,19 @@ got_reestablish:
|
|||
maybe_send_shutdown(peer);
|
||||
|
||||
#if EXPERIMENTAL_FEATURES
|
||||
if (recv_tlvs->desired_type)
|
||||
status_debug("They sent desired_type [%s]",
|
||||
if (recv_tlvs->desired_channel_type)
|
||||
status_debug("They sent desired_channel_type [%s]",
|
||||
fmt_featurebits(tmpctx,
|
||||
recv_tlvs->desired_type->features));
|
||||
if (recv_tlvs->current_type)
|
||||
status_debug("They sent current_type [%s]",
|
||||
recv_tlvs->desired_channel_type));
|
||||
if (recv_tlvs->current_channel_type)
|
||||
status_debug("They sent current_channel_type [%s]",
|
||||
fmt_featurebits(tmpctx,
|
||||
recv_tlvs->current_type->features));
|
||||
recv_tlvs->current_channel_type));
|
||||
|
||||
for (size_t i = 0; i < tal_count(recv_tlvs->upgradable); i++) {
|
||||
if (recv_tlvs->upgradable_channel_type)
|
||||
status_debug("They offered upgrade to [%s]",
|
||||
fmt_featurebits(tmpctx,
|
||||
recv_tlvs->upgradable[i]->features));
|
||||
}
|
||||
recv_tlvs->upgradable_channel_type));
|
||||
|
||||
/* BOLT-upgrade_protocol #2:
|
||||
*
|
||||
|
@ -3036,7 +3055,7 @@ got_reestablish:
|
|||
status_debug("No upgrade: pending changes");
|
||||
} else {
|
||||
const struct tlv_channel_reestablish_tlvs *initr, *ninitr;
|
||||
const struct channel_type *type;
|
||||
const u8 *type;
|
||||
|
||||
if (peer->channel->opener == LOCAL) {
|
||||
initr = send_tlvs;
|
||||
|
@ -3048,20 +3067,21 @@ got_reestablish:
|
|||
|
||||
/* BOLT-upgrade_protocol #2:
|
||||
*
|
||||
* - if `desired_type` matches `current_type` or any
|
||||
* `upgradable` `upgrades`:
|
||||
* - MUST consider the channel type to be `desired_type`.
|
||||
* - if `desired_channel_type` matches `current_channel_type` or any
|
||||
* `upgradable_channel_type`:
|
||||
* - MUST consider the channel type to be `desired_channel_type`.
|
||||
* - otherwise:
|
||||
* - MUST consider the channel feature change failed.
|
||||
* - if there is a `current_type` field:
|
||||
* - MUST consider the channel type to be `current_type`.
|
||||
* - MUST consider the channel type change failed.
|
||||
* - if there is a `current_channel_type` field:
|
||||
* - MUST consider the channel type to be `current_channel_type`.
|
||||
*/
|
||||
/* Note: returns NULL on missing fields, aka NULL */
|
||||
if (match_type(initr->desired_type,
|
||||
ninitr->current_type, ninitr->upgradable))
|
||||
type = initr->desired_type;
|
||||
else if (ninitr->current_type)
|
||||
type = ninitr->current_type;
|
||||
if (match_type(initr->desired_channel_type,
|
||||
ninitr->current_channel_type)
|
||||
|| match_type(initr->desired_channel_type,
|
||||
ninitr->upgradable_channel_type))
|
||||
type = initr->desired_channel_type;
|
||||
else if (ninitr->current_channel_type)
|
||||
type = ninitr->current_channel_type;
|
||||
else
|
||||
type = NULL;
|
||||
|
||||
|
|
|
@ -86,16 +86,6 @@ bool channel_type_eq(const struct channel_type *a,
|
|||
return featurebits_eq(a->features, b->features);
|
||||
}
|
||||
|
||||
bool channel_type_eq_any(const struct channel_type *t,
|
||||
struct channel_type **arr)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(arr); i++) {
|
||||
if (channel_type_eq(t, arr[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct channel_type *channel_type_dup(const tal_t *ctx,
|
||||
const struct channel_type *t)
|
||||
{
|
||||
|
@ -104,6 +94,14 @@ struct channel_type *channel_type_dup(const tal_t *ctx,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct channel_type *channel_type_from(const tal_t *ctx,
|
||||
const u8 *features TAKES)
|
||||
{
|
||||
struct channel_type *ret = tal(ctx, struct channel_type);
|
||||
ret->features = tal_dup_talarr(ret, u8, features);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct channel_type *channel_type_accept(const tal_t *ctx,
|
||||
const u8 *t,
|
||||
const struct feature_set *our_features,
|
||||
|
|
|
@ -14,6 +14,10 @@ struct channel_type *channel_type_anchor_outputs(const tal_t *ctx);
|
|||
struct channel_type *channel_type_dup(const tal_t *ctx,
|
||||
const struct channel_type *t);
|
||||
|
||||
/* Convert feature bits to channel_type */
|
||||
struct channel_type *channel_type_from(const tal_t *ctx,
|
||||
const u8 *features TAKES);
|
||||
|
||||
/* Derive channel type from feature negotiation */
|
||||
struct channel_type *default_channel_type(const tal_t *ctx,
|
||||
const struct feature_set *our_features,
|
||||
|
@ -26,10 +30,6 @@ bool channel_type_has(const struct channel_type *type, int feature);
|
|||
bool channel_type_eq(const struct channel_type *a,
|
||||
const struct channel_type *b);
|
||||
|
||||
/* Is channel_type_eq() for any type in this array? */
|
||||
bool channel_type_eq_any(const struct channel_type *t,
|
||||
struct channel_type **arr);
|
||||
|
||||
/* Return channel_type if this is acceptable, otherwise NULL */
|
||||
struct channel_type *channel_type_accept(const tal_t *ctx,
|
||||
const u8 *t,
|
||||
|
|
|
@ -160,15 +160,13 @@ u32 channel_blockheight(const struct channel *channel, enum side side)
|
|||
channel->opener, side);
|
||||
}
|
||||
|
||||
struct channel_type **channel_upgradable_types(const tal_t *ctx,
|
||||
const struct channel *channel)
|
||||
struct channel_type *channel_upgradable_type(const tal_t *ctx,
|
||||
const struct channel *channel)
|
||||
{
|
||||
struct channel_type **arr = tal_arr(ctx, struct channel_type *, 0);
|
||||
|
||||
if (!channel_has(channel, OPT_STATIC_REMOTEKEY))
|
||||
tal_arr_expand(&arr, channel_type_static_remotekey(arr));
|
||||
return channel_type_static_remotekey(ctx);
|
||||
|
||||
return arr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct channel_type *channel_desired_type(const tal_t *ctx,
|
||||
|
|
|
@ -152,15 +152,11 @@ u32 channel_feerate(const struct channel *channel, enum side side);
|
|||
*/
|
||||
u32 channel_blockheight(const struct channel *channel, enum side side);
|
||||
|
||||
/* BOLT-upgrade_protocol #2:
|
||||
* Channel features are explicitly enumerated as `channel_type` bitfields,
|
||||
* using odd features bits.
|
||||
*/
|
||||
/* What features can we upgrade? (Returns NULL if none). */
|
||||
struct channel_type **channel_upgradable_types(const tal_t *ctx,
|
||||
const struct channel *channel);
|
||||
/* What can we upgrade to? (Returns NULL if none). */
|
||||
struct channel_type *channel_upgradable_type(const tal_t *ctx,
|
||||
const struct channel *channel);
|
||||
|
||||
/* What features do we want? */
|
||||
/* What channel type do we want? */
|
||||
struct channel_type *channel_desired_type(const tal_t *ctx,
|
||||
const struct channel *channel);
|
||||
|
||||
|
|
|
@ -3499,9 +3499,9 @@ def test_upgrade_statickey(node_factory, executor):
|
|||
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 \[\]",
|
||||
l1.daemon.wait_for_logs([r"They sent current_channel_type \[\]",
|
||||
r"They offered upgrade to \[12\]"])
|
||||
l2.daemon.wait_for_log(r"They sent desired_type \[12\]")
|
||||
l2.daemon.wait_for_log(r"They sent desired_channel_type \[12\]")
|
||||
|
||||
l1.daemon.wait_for_log('option_static_remotekey enabled at 1/1')
|
||||
l2.daemon.wait_for_log('option_static_remotekey enabled at 1/1')
|
||||
|
@ -3514,8 +3514,8 @@ def test_upgrade_statickey(node_factory, executor):
|
|||
# They won't offer upgrade!
|
||||
assert not l1.daemon.is_in_log("They offered upgrade",
|
||||
start=l1.daemon.logsearch_start)
|
||||
l1.daemon.wait_for_log(r"They sent current_type \[12\]")
|
||||
l2.daemon.wait_for_log(r"They sent desired_type \[12\]")
|
||||
l1.daemon.wait_for_log(r"They sent current_channel_type \[12\]")
|
||||
l2.daemon.wait_for_log(r"They sent desired_channel_type \[12\]")
|
||||
|
||||
|
||||
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "upgrade protocol not available")
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
--- wire/peer_wire.csv 2021-05-09 15:44:59.166135652 +0930
|
||||
+++ wire/peer_wire.csv.raw 2021-05-11 09:59:31.695459756 +0930
|
||||
@@ -221,6 +131,15 @@
|
||||
@@ -244,6 +140,15 @@
|
||||
msgdata,channel_reestablish,next_revocation_number,u64,
|
||||
msgdata,channel_reestablish,your_last_per_commitment_secret,byte,32
|
||||
msgdata,channel_reestablish,my_current_per_commitment_point,point,
|
||||
+msgdata,channel_reestablish,tlvs,channel_reestablish_tlvs,
|
||||
+tlvtype,channel_reestablish_tlvs,next_to_send,1
|
||||
+tlvdata,channel_reestablish_tlvs,next_to_send,commitment_number,tu64,
|
||||
+tlvtype,channel_reestablish_tlvs,desired_type,3
|
||||
+tlvdata,channel_reestablish_tlvs,desired_type,type,channel_type,
|
||||
+tlvtype,channel_reestablish_tlvs,current_type,5
|
||||
+tlvdata,channel_reestablish_tlvs,current_type,type,channel_type,
|
||||
+tlvtype,channel_reestablish_tlvs,upgradable,7
|
||||
+tlvdata,channel_reestablish_tlvs,upgradable,upgrades,channel_type,...
|
||||
+tlvtype,channel_reestablish_tlvs,desired_channel_type,3
|
||||
+tlvdata,channel_reestablish_tlvs,desired_channel_type,type,byte,...
|
||||
+tlvtype,channel_reestablish_tlvs,current_channel_type,5
|
||||
+tlvdata,channel_reestablish_tlvs,current_channel_type,type,byte,...
|
||||
+tlvtype,channel_reestablish_tlvs,upgradable_channel_type,7
|
||||
+tlvdata,channel_reestablish_tlvs,upgradable_channel_type,type,byte,...
|
||||
msgtype,announcement_signatures,259
|
||||
msgdata,announcement_signatures,channel_id,channel_id,
|
||||
msgdata,announcement_signatures,short_channel_id,short_channel_id,
|
||||
|
|
Loading…
Add table
Reference in a new issue