splicing: Add channel state AWAITING_SPLICE

Update gossip routiens and various other hecks on the channel state to consider AWAITING_SPLICE to be routable and treated similar to CHANNELD_NORMAL.

Small updates to psbt interface

Changelog-None
This commit is contained in:
Dusty Daemon 2023-07-27 13:17:33 -07:00 committed by Rusty Russell
parent 108658a539
commit 50fe819f47
17 changed files with 74 additions and 22 deletions

View File

@ -95,7 +95,7 @@ bool psbt_is_finalized(const struct wally_psbt *psbt)
}
struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt,
struct wally_tx_input *input,
const struct wally_tx_input *input,
size_t insert_at)
{
const u32 flags = WALLY_PSBT_FLAG_NON_FINAL; /* Skip script/witness */

View File

@ -108,7 +108,7 @@ struct wally_tx *psbt_final_tx(const tal_t *ctx, const struct wally_psbt *psbt);
u8 *psbt_make_key(const tal_t *ctx, u8 key_subtype, const u8 *key_data);
struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt,
struct wally_tx_input *input,
const struct wally_tx_input *input,
size_t insert_at);
/* One stop shop for adding an input + metadata to a PSBT */

View File

@ -65,6 +65,13 @@ enum jsonrpc_errcode {
FUNDING_STATE_INVALID = 312,
FUND_CANNOT_AFFORD_WITH_EMERGENCY = 313,
/* Splice errors */
SPLICE_BROADCAST_FAIL = 350,
SPLICE_WRONG_OWNER = 351,
SPLICE_UNKNOWN_CHANNEL = 352,
SPLICE_INVALID_CHANNEL_STATE = 353,
SPLICE_NOT_SUPPORTED = 354,
/* `connect` errors */
CONNECT_NO_KNOWN_ADDRESS = 400,
CONNECT_ALL_ADDRESSES_FAILED = 401,

View File

@ -116,7 +116,8 @@ void psbt_finalize_input(const tal_t *ctx,
const struct witness **
psbt_to_witnesses(const tal_t *ctx,
const struct wally_psbt *psbt,
enum tx_role side_to_stack)
enum tx_role side_to_stack,
int input_index_to_ignore)
{
u64 serial_id;
const struct witness **witnesses =
@ -128,6 +129,9 @@ psbt_to_witnesses(const tal_t *ctx,
/* FIXME: throw an error ? */
return tal_free(witnesses);
if (input_index_to_ignore == i)
continue;
/* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2:
* - if is the *initiator*:
* - MUST send even `serial_id`s

View File

@ -27,11 +27,13 @@ void psbt_finalize_input(const tal_t *ctx,
* @ctx - allocation context
* @psbt - PSBT to copy sigs from
* @side_to_stack - which side to stack witnesses of
* @input_index_to_ignore - which input to not include. Pass -1 to include all.
*/
const struct witness **
psbt_to_witnesses(const tal_t *ctx,
const struct wally_psbt *psbt,
enum tx_role side_to_stack);
enum tx_role side_to_stack,
int input_index_to_ignore);
/* psbt_input_weight - Calculate the tx weight for input index `in` */
size_t psbt_input_weight(struct wally_psbt *psbt,

View File

@ -505,7 +505,7 @@ static void remove_chan_from_node(struct routing_state *rstate,
/* Last channel? Simply delete node (and associated announce) */
if (num_chans == 0) {
if(node->rgraph.index != node->bcast.index)
if (node->rgraph.index != node->bcast.index)
gossip_store_delete(rstate->gs,
&node->rgraph,
WIRE_NODE_ANNOUNCEMENT);
@ -522,7 +522,7 @@ static void remove_chan_from_node(struct routing_state *rstate,
/* Removed only public channel? Remove node announcement. */
if (!node_has_broadcastable_channels(node)) {
if(node->rgraph.index != node->bcast.index)
if (node->rgraph.index != node->bcast.index)
gossip_store_delete(rstate->gs,
&node->rgraph,
WIRE_NODE_ANNOUNCEMENT);

View File

@ -152,8 +152,11 @@ new_inflight(struct channel *channel,
inflight->funding_psbt = tal_steal(inflight, psbt);
/* Make a 'clone' of this tx */
last_tx_psbt_clone = clone_psbt(inflight, last_tx->psbt);
inflight->last_tx = bitcoin_tx_with_psbt(inflight, last_tx_psbt_clone);
inflight->last_tx = NULL;
if (last_tx) {
last_tx_psbt_clone = clone_psbt(inflight, last_tx->psbt);
inflight->last_tx = bitcoin_tx_with_psbt(inflight, last_tx_psbt_clone);
}
inflight->last_sig = last_sig;
inflight->tx_broadcast = false;
@ -580,6 +583,18 @@ const char *channel_state_str(enum channel_state state)
return "unknown";
}
bool channel_state_normalish(const struct channel *channel)
{
return channel->state == CHANNELD_NORMAL
|| channel->state == CHANNELD_AWAITING_SPLICE;
}
bool channel_state_awaitish(const struct channel *channel)
{
return channel->state == CHANNELD_AWAITING_LOCKIN
|| channel->state == CHANNELD_AWAITING_SPLICE;
}
struct channel *peer_any_active_channel(struct peer *peer, bool *others)
{
struct channel *channel, *ret = NULL;
@ -793,7 +808,8 @@ void channel_set_state(struct channel *channel,
struct timeabs timestamp;
/* set closer, if known */
if (state > CHANNELD_NORMAL && channel->closer == NUM_SIDES) {
if (!(state == CHANNELD_AWAITING_SPLICE)
&& state > CHANNELD_NORMAL && channel->closer == NUM_SIDES) {
if (reason == REASON_LOCAL) channel->closer = LOCAL;
if (reason == REASON_USER) channel->closer = LOCAL;
if (reason == REASON_REMOTE) channel->closer = REMOTE;

View File

@ -384,6 +384,12 @@ void delete_channel(struct channel *channel STEALS);
const char *channel_state_name(const struct channel *channel);
const char *channel_state_str(enum channel_state state);
/* Is the channel in NORMAL or AWAITING_SPLICE state? */
bool channel_state_normalish(const struct channel *channel);
/* Is the channel in AWAITING_*? */
bool channel_state_awaitish(const struct channel *channel);
void channel_set_owner(struct channel *channel, struct subd *owner);
/* Channel has failed, but can try again. */
@ -454,12 +460,12 @@ void channel_set_last_tx(struct channel *channel,
static inline bool channel_can_add_htlc(const struct channel *channel)
{
return channel->state == CHANNELD_NORMAL;
return channel_state_normalish(channel);
}
static inline bool channel_fees_can_change(const struct channel *channel)
{
return channel->state == CHANNELD_NORMAL
return channel_state_normalish(channel)
|| channel->state == CHANNELD_SHUTTING_DOWN;
}

View File

@ -888,7 +888,8 @@ bool channel_tell_depth(struct lightningd *ld,
txid, depth);
return true;
} else if (channel->state != CHANNELD_AWAITING_LOCKIN
&& channel->state != CHANNELD_NORMAL) {
&& channel->state != CHANNELD_NORMAL
&& channel->state != CHANNELD_AWAITING_SPLICE) {
/* If not awaiting lockin/announce, it doesn't
* care any more */
log_debug(channel->log,
@ -1187,7 +1188,7 @@ static struct command_result *json_dev_feerate(struct command *cmd,
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
channel = peer_any_active_channel(peer, &more_than_one);
if (!channel || !channel->owner || channel->state != CHANNELD_NORMAL)
if (!channel || !channel->owner || !channel_state_normalish(channel))
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
/* This is a dev command: fix the api if you need this! */
if (more_than_one)
@ -1247,7 +1248,7 @@ static struct command_result *json_dev_quiesce(struct command *cmd,
/* FIXME: If this becomes a real API, check for OPT_QUIESCE! */
channel = peer_any_active_channel(peer, &more_than_one);
if (!channel || !channel->owner || channel->state != CHANNELD_NORMAL)
if (!channel || !channel->owner || !channel_state_normalish(channel))
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
/* This is a dev command: fix the api if you need this! */
if (more_than_one)

View File

@ -40,8 +40,11 @@ enum channel_state {
/* Dual-funded channel, waiting for lock-in */
DUALOPEND_AWAITING_LOCKIN,
/* Channel has started splice and is awaiting lock-in */
CHANNELD_AWAITING_SPLICE,
};
#define CHANNEL_STATE_MAX DUALOPEND_AWAITING_LOCKIN
#define CHANNEL_STATE_MAX CHANNELD_AWAITING_SPLICE
/* These are in the database, so don't renumber them! */
enum state_change {

View File

@ -836,6 +836,7 @@ static struct command_result *json_close(struct command *cmd,
* waiting) */
switch (channel->state) {
case CHANNELD_NORMAL:
case CHANNELD_AWAITING_SPLICE:
case CHANNELD_AWAITING_LOCKIN:
case DUALOPEND_AWAITING_LOCKIN:
channel_set_state(channel,

View File

@ -1170,6 +1170,7 @@ static void connect_activate_subd(struct lightningd *ld, struct channel *channel
case CHANNELD_AWAITING_LOCKIN:
case CHANNELD_NORMAL:
case CHANNELD_AWAITING_SPLICE:
case CHANNELD_SHUTTING_DOWN:
case CLOSINGD_SIGEXCHANGE:
assert(!channel->owner);
@ -1827,10 +1828,13 @@ static enum watch_result funding_depth_cb(struct lightningd *ld,
tal_free(txidstr);
bool min_depth_reached = depth >= channel->minimum_depth;
bool min_depth_no_scid = min_depth_reached && !channel->scid;
bool some_depth_has_scid = depth && channel->scid;
/* Reorg can change scid, so always update/save scid when possible (depth=0
* means the stale block with our funding tx was removed) */
if ((min_depth_reached && !channel->scid) || (depth && channel->scid)) {
if (channel->state != CHANNELD_AWAITING_SPLICE
&& (min_depth_no_scid || some_depth_has_scid)) {
struct txlocator *loc;
struct channel_inflight *inf;
@ -2632,6 +2636,7 @@ static struct command_result *param_channel_or_all(struct command *cmd,
*channels = tal_arr(cmd, struct channel *, 0);
list_for_each(&peer->channels, channel, list) {
if (channel->state != CHANNELD_NORMAL
&& channel->state != CHANNELD_AWAITING_SPLICE
&& channel->state != CHANNELD_AWAITING_LOCKIN
&& channel->state != DUALOPEND_AWAITING_LOCKIN)
continue;

View File

@ -582,7 +582,7 @@ static void htlc_offer_timeout(struct htlc_out *out)
assert(out->hstate == SENT_ADD_HTLC);
/* If owner died, we should already be taken care of. */
if (!channel->owner || channel->state != CHANNELD_NORMAL)
if (!channel->owner || !channel_state_normalish(channel))
return;
log_unusual(channel->owner->log,

View File

@ -993,7 +993,7 @@ static u8 *psbt_to_tx_sigs_msg(const tal_t *ctx,
const struct wally_psbt *psbt)
{
const struct witness **ws =
psbt_to_witnesses(tmpctx, psbt, state->our_role);
psbt_to_witnesses(tmpctx, psbt, state->our_role, -1);
return towire_tx_signatures(ctx, &state->channel_id,
&state->tx_state->funding.txid,

View File

@ -3291,7 +3291,8 @@ static struct command_result *direct_pay_listpeerchannels(struct command *cmd,
if (!chan->connected)
continue;
if (!streq(chan->state, "CHANNELD_NORMAL"))
if (!streq(chan->state, "CHANNELD_NORMAL")
&& !streq(chan->state, "CHANNELD_AWAITING_SPLICE"))
continue;
/* Must have either a local alias for zeroconf

View File

@ -255,8 +255,12 @@ static void update_connection(int store_fd,
bool disable)
{
secp256k1_ecdsa_signature dummy_sig;
u8 flags = node_id_idx(from, to);
u8 *msg;
if (disable)
flags |= ROUTING_FLAGS_DISABLED;
/* So valgrind doesn't complain */
memset(&dummy_sig, 0, sizeof(dummy_sig));
@ -265,8 +269,7 @@ static void update_connection(int store_fd,
&chainparams->genesis_blockhash,
scid, 0,
ROUTING_OPT_HTLC_MAX_MSAT,
node_id_idx(from, to)
+ (disable ? ROUTING_FLAGS_DISABLED : 0),
flags,
delay,
min,
base_fee,

View File

@ -317,7 +317,10 @@ static struct node_map *local_connected(const tal_t *ctx,
/* Must also have a channel in CHANNELD_NORMAL */
normal_chan = json_tok_streq(buf,
json_get_member(buf, channel, "state"),
"CHANNELD_NORMAL");
"CHANNELD_NORMAL")
|| json_tok_streq(buf,
json_get_member(buf, channel, "state"),
"CHANNELD_AWAITING_SPLICE");
if (normal_chan)
node_map_add(connected,