Skip to content

Commit

Permalink
lightningd: don't force state if gossipd gives us an unexpected chann…
Browse files Browse the repository at this point in the history
…el_update.

This was triggered by the recover plugin tests (not yet merged!) and causes a crash
because we don't have signatures yet.  It can only happen if we lost our database,
but at least don't crash!

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Feb 14, 2024
1 parent 3f4306e commit a1377c8
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 7 deletions.
76 changes: 73 additions & 3 deletions contrib/msggen/msggen/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2583,7 +2583,7 @@
"description": "period starts at this UNIX timestamp"
},
"start_any_period": {
"type": "u64",
"type": "boolean",
"description": "you can start at any period (only if `basetime` present)"
},
"limit": {
Expand Down Expand Up @@ -2878,7 +2878,7 @@
"description": "period starts at this UNIX timestamp"
},
"start_any_period": {
"type": "u64",
"type": "boolean",
"description": "you can start at any period (only if `basetime` present)"
},
"limit": {
Expand Down Expand Up @@ -3242,7 +3242,7 @@
"description": "period starts at this UNIX timestamp"
},
"start_any_period": {
"type": "u64",
"type": "boolean",
"description": "you can start at any period (only if `basetime` present)"
},
"limit": {
Expand Down Expand Up @@ -10163,6 +10163,22 @@
}
}
},
"listoffers.request.json": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [],
"additionalProperties": false,
"properties": {
"offer_id": {
"type": "hash",
"description": "Only return offers matching this ID"
},
"active_only": {
"type": "boolean",
"description": "f active_only is set and is true, only offers with active true are returned."
}
}
},
"listoffers.schema.json": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
Expand Down Expand Up @@ -13412,6 +13428,60 @@
"additionalProperties": false,
"properties": {}
},
"offer.request.json": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"amount",
"description"
],
"properties": {
"amount": {
"type": "string",
"description": "The amount parameter can be the string \"any\", which creates an offer that can be paid with any amount (e.g. a donation). Otherwise it can be a positive value in millisatoshi precision; it can be a whole number, or a whole number ending in msat or sat, or a number with three decimal places ending in sat, or a number with 1 to 11 decimal places ending in btc. `amount` can also have an ISO 4217 postfix (i.e. USD), in which case currency conversion will need to be done for the invoice itself. A plugin is needed which provides the \"currencyconvert\" API for this currency, otherwise the offer creation will fail."
},
"description": {
"type": "string",
"description": "a short description of purpose of the offer"
},
"issuer": {
"type": "string",
"description": "who is issuing this offer"
},
"label": {
"type": "string",
"description": "an internal-use name for the offer"
},
"quantity_max": {
"type": "u64",
"description": "specifies the number of items up (and including) this maximum"
},
"absolute_expiry": {
"type": "u64",
"description": "the time the offer is valid until, in seconds since the first day of 1970 UTC"
},
"recurrence": {
"type": "string",
"description": "A recurrence period with unit (matches '[0-9]+(seconds|minutes|hours|days|weeks|months|years)' "
},
"recurrence_base": {
"type": "string",
"description": "Time in seconds since the first day of 1970 UTC. If not prefixed with an '@' the offer will start in any period (no missed payments will be performed)"
},
"recurrence_paywindow": {
"type": "string",
"description": "an optional argument of form '-time+time[%]'. The first time is the number of seconds before the start of a period in which an invoice and payment is valid, the second time is the number of seconds after the start of the period. For example -604800+86400 means you can fetch an pay the invoice 4 weeks before the given period starts, and up to 1 day afterwards. The optional % indicates that the amount of the invoice will be scaled by the time remaining in the period. If this is not specified, the default is that payment is allowed during the current and previous periods. This is encoded in the offer."
},
"recurrence_limit": {
"type": "u64",
"description": "the maximum recurrence period which exists"
},
"single_use": {
"type": "boolean",
"description": "indicates that the offer is only valid once"
}
}
},
"offer.schema.json": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
Expand Down
35 changes: 31 additions & 4 deletions lightningd/channel_gossip.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ enum channel_gossip_state {
CGOSSIP_ANNOUNCED,
};

static const char *channel_gossip_state_str(enum channel_gossip_state s)
{
switch (s) {
case CGOSSIP_PRIVATE:
return "CGOSSIP_PRIVATE";
case CGOSSIP_NOT_USABLE:
return "CGOSSIP_NOT_USABLE";
case CGOSSIP_NOT_DEEP_ENOUGH:
return "CGOSSIP_NOT_DEEP_ENOUGH";
case CGOSSIP_NEED_PEER_SIGS:
return "CGOSSIP_NEED_PEER_SIGS";
case CGOSSIP_ANNOUNCED:
return "CGOSSIP_ANNOUNCED";
}
return "***INVALID***";
}

struct remote_announce_sigs {
struct short_channel_id scid;
secp256k1_ecdsa_signature node_sig;
Expand Down Expand Up @@ -774,18 +791,28 @@ void channel_gossip_update_from_gossipd(struct channel *channel,
return;
}

/* If we didn't think it was announced already, it is now! */
/* We might still want signatures from peer (we lost state?) */
switch (channel->channel_gossip->state) {
case CGOSSIP_PRIVATE:
log_broken(channel->log,
"gossipd gave channel_update for private channel? update=%s",
tal_hex(tmpctx, channel_update));
return;
case CGOSSIP_NOT_USABLE:
/* This happens: we step back a block when restarting. We can
* fast-forward in this case. */
case CGOSSIP_NOT_DEEP_ENOUGH:
case CGOSSIP_NEED_PEER_SIGS:
set_gossip_state(channel, CGOSSIP_ANNOUNCED);
set_gossip_state(channel, CGOSSIP_NEED_PEER_SIGS);
check_channel_gossip(channel);
break;

case CGOSSIP_NOT_USABLE:
case CGOSSIP_NEED_PEER_SIGS:
if (taken(channel_update))
tal_free(channel_update);
log_broken(channel->log,
"gossipd gave us channel_update for channel in gossip_state %s",
channel_gossip_state_str(channel->channel_gossip->state));
return;
case CGOSSIP_ANNOUNCED:
break;
}
Expand Down

0 comments on commit a1377c8

Please sign in to comment.