diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index b49c79da6..ad384cf6e 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -3,6 +3,7 @@ * saves and funding tx watching for a channel open */ #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -685,6 +687,106 @@ wallet_commit_channel(struct lightningd *ld, return channel; } +static void handle_peer_wants_to_close(struct subd *dualopend, + const u8 *msg) +{ + u8 *scriptpubkey; + struct lightningd *ld = dualopend->ld; + struct channel *channel; + char *errmsg; + + /* We shouldn't get this message while we're waiting to finish */ + if (dualopend->ctype == UNCOMMITTED) { + log_broken(dualopend->ld->log, "Channel in wrong state for" + " shutdown, still has uncommitted" + " channel pending."); + + errmsg = "Channel not established yet, shutdown invalid"; + subd_send_msg(dualopend, + take(towire_dualopend_fail(NULL, errmsg))); + return; + } + + channel = dualopend->channel; + + if (!fromwire_dualopend_got_shutdown(channel, msg, &scriptpubkey)) { + channel_internal_error(channel, "bad channel_got_shutdown %s", + tal_hex(msg, msg)); + return; + } + + + tal_free(channel->shutdown_scriptpubkey[REMOTE]); + channel->shutdown_scriptpubkey[REMOTE] = scriptpubkey; + + /* BOLT #2: + * + * 1. `OP_DUP` `OP_HASH160` `20` 20-bytes `OP_EQUALVERIFY` `OP_CHECKSIG` + * (pay to pubkey hash), OR + * 2. `OP_HASH160` `20` 20-bytes `OP_EQUAL` (pay to script hash), OR + * 3. `OP_0` `20` 20-bytes (version 0 pay to witness pubkey), OR + * 4. `OP_0` `32` 32-bytes (version 0 pay to witness script hash) + * + * A receiving node: + *... + * - if the `scriptpubkey` is not in one of the above forms: + * - SHOULD fail the connection. + */ + if (!is_p2pkh(scriptpubkey, NULL) && !is_p2sh(scriptpubkey, NULL) + && !is_p2wpkh(scriptpubkey, NULL) && !is_p2wsh(scriptpubkey, NULL)) { + channel_fail_permanent(channel, + REASON_PROTOCOL, + "Bad shutdown scriptpubkey %s", + tal_hex(channel, scriptpubkey)); + return; + } + + /* If we weren't already shutting down, we are now */ + if (channel->state != CHANNELD_SHUTTING_DOWN) + channel_set_state(channel, + channel->state, + CHANNELD_SHUTTING_DOWN, + REASON_REMOTE, + "Peer closes channel"); + + /* TODO(cdecker) Selectively save updated fields to DB */ + wallet_channel_save(ld->wallet, channel); + + /* Now we send back our scriptpubkey to close with */ + subd_send_msg(dualopend, take(towire_dualopend_send_shutdown(NULL, + channel->shutdown_scriptpubkey[LOCAL]))); + +} + +static void handle_channel_closed(struct subd *dualopend, + const int *fds, + const u8 *msg) +{ + struct per_peer_state *pps; + struct channel *channel; + + if (!fromwire_dualopend_shutdown_complete(tmpctx, msg, &pps)) { + channel_internal_error(dualopend->channel, + "bad shutdown_complete: %s", + tal_hex(msg, msg)); + close(fds[0]); + close(fds[1]); + close(fds[2]); + return; + } + + per_peer_state_set_fds_arr(pps, fds); + + assert(dualopend->ctype == CHANNEL); + channel = dualopend->channel; + peer_start_closingd(channel, pps, false, NULL); + channel_set_state(channel, + CHANNELD_SHUTTING_DOWN, + CLOSINGD_SIGEXCHANGE, + REASON_UNKNOWN, + "Start closingd"); +} + static void opener_psbt_changed(struct subd *dualopend, struct uncommitted_channel *uc, const u8 *msg) @@ -1661,6 +1763,14 @@ static unsigned int dual_opend_msg(struct subd *dualopend, return 3; handle_channel_locked(dualopend, fds, msg); return 0; + case WIRE_DUALOPEND_GOT_SHUTDOWN: + handle_peer_wants_to_close(dualopend, msg); + return 0; + case WIRE_DUALOPEND_SHUTDOWN_COMPLETE: + if (tal_count(fds) != 3) + return 3; + handle_channel_closed(dualopend, fds, msg); + return 0; case WIRE_DUALOPEND_FAILED: open_failed(dualopend, msg); return 0; @@ -1673,6 +1783,7 @@ static unsigned int dual_opend_msg(struct subd *dualopend, case WIRE_DUALOPEND_FAIL: case WIRE_DUALOPEND_PSBT_UPDATED: case WIRE_DUALOPEND_SEND_TX_SIGS: + case WIRE_DUALOPEND_SEND_SHUTDOWN: case WIRE_DUALOPEND_DEPTH_REACHED: case WIRE_DUALOPEND_DEV_MEMLEAK: break; diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index a91a83ce4..3be18e533 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -1496,16 +1497,26 @@ static struct command_result *json_close(struct command *cmd, switch (channel->state) { case CHANNELD_NORMAL: case CHANNELD_AWAITING_LOCKIN: + case DUALOPEND_AWAITING_LOCKIN: channel_set_state(channel, channel->state, CHANNELD_SHUTTING_DOWN, REASON_USER, "User or plugin invoked close command"); /* fallthrough */ case CHANNELD_SHUTTING_DOWN: - if (channel->owner) - subd_send_msg(channel->owner, - take(towire_channeld_send_shutdown(NULL, - channel->shutdown_scriptpubkey[LOCAL]))); + if (channel->owner) { + u8 *msg; + if (streq(channel->owner->name, "dualopend")) { + msg = towire_dualopend_send_shutdown( + NULL, + channel->shutdown_scriptpubkey[LOCAL]); + } else + msg = towire_channeld_send_shutdown( + NULL, + channel->shutdown_scriptpubkey[LOCAL]); + subd_send_msg(channel->owner, take(msg)); + } + break; case CLOSINGD_SIGEXCHANGE: break; diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index ff4347cba..1e15b9f7d 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -563,6 +563,9 @@ u8 *towire_channeld_specific_feerates(const tal_t *ctx UNNEEDED, u32 feerate_bas /* Generated stub for towire_connectd_connect_to_peer */ u8 *towire_connectd_connect_to_peer(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, u32 seconds_waited UNNEEDED, const struct wireaddr_internal *addrhint UNNEEDED) { fprintf(stderr, "towire_connectd_connect_to_peer called!\n"); abort(); } +/* Generated stub for towire_dualopend_send_shutdown */ +u8 *towire_dualopend_send_shutdown(const tal_t *ctx UNNEEDED, const u8 *shutdown_scriptpubkey UNNEEDED) +{ fprintf(stderr, "towire_dualopend_send_shutdown called!\n"); abort(); } /* Generated stub for towire_errorfmt */ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED, const struct channel_id *channel UNNEEDED, diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 8b7b50136..dcce958d4 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -246,7 +246,6 @@ static u8 *psbt_changeset_get_next(const tal_t *ctx, return NULL; } - /*~ If we can't agree on parameters, we fail to open the channel. If we're * the opener, we need to tell lightningd, otherwise it never really notices. */ static void negotiation_aborted(struct state *state, bool am_opener, @@ -308,6 +307,62 @@ static void billboard_update(struct state *state) peer_billboard(false, update); } +static void send_shutdown(struct state *state, const u8 *final_scriptpubkey) +{ + u8 *msg; + + msg = towire_shutdown(NULL, &state->channel_id, + final_scriptpubkey); + sync_crypto_write(state->pps, take(msg)); + state->shutdown_sent[LOCAL] = true; +} + +static void handle_peer_shutdown(struct state *state, u8 *msg) +{ + u8 *scriptpubkey; + struct channel_id cid; + + if (!fromwire_shutdown(tmpctx, msg, &cid, &scriptpubkey)) + peer_failed(state->pps, &state->channel_id, + "Bad shutdown %s", tal_hex(msg, msg)); + + if (tal_count(state->upfront_shutdown_script[REMOTE]) + && !memeq(scriptpubkey, tal_count(scriptpubkey), + state->upfront_shutdown_script[REMOTE], + tal_count(state->upfront_shutdown_script[REMOTE]))) + peer_failed(state->pps, &state->channel_id, + "scriptpubkey %s is not as agreed upfront (%s)", + tal_hex(state, scriptpubkey), + tal_hex(state, + state->upfront_shutdown_script[REMOTE])); + + wire_sync_write(REQ_FD, + take(towire_dualopend_got_shutdown(NULL, + scriptpubkey))); + msg = wire_sync_read(tmpctx, REQ_FD); + if (!fromwire_dualopend_send_shutdown(tmpctx, msg, &scriptpubkey)) + master_badmsg(fromwire_peektype(msg), msg); + + state->shutdown_sent[REMOTE] = true; + if (!state->shutdown_sent[LOCAL]) + send_shutdown(state, scriptpubkey); + + billboard_update(state); +} + +static void handle_our_shutdown(struct state *state, u8 *msg) +{ + u8 *scriptpubkey; + + if (!fromwire_dualopend_send_shutdown(tmpctx, msg, &scriptpubkey)) + master_badmsg(fromwire_peektype(msg), msg); + + if (!state->shutdown_sent[LOCAL]) + send_shutdown(state, scriptpubkey); + + billboard_update(state); +} + static void check_channel_id(struct state *state, struct channel_id *id_in, struct channel_id *orig_id) @@ -2316,19 +2371,27 @@ static u8 *handle_master_in(struct state *state) return NULL; case WIRE_DUALOPEND_DEPTH_REACHED: return handle_funding_depth(state, msg); - /* mostly handled inline */ - case WIRE_DUALOPEND_TX_SIGS_SENT: - case WIRE_DUALOPEND_CHANNEL_LOCKED: + case WIRE_DUALOPEND_SEND_SHUTDOWN: + handle_our_shutdown(state, msg); + return NULL; + + /* Handled inline */ case WIRE_DUALOPEND_INIT: - case WIRE_DUALOPEND_FUNDING_SIGS: case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY: - case WIRE_DUALOPEND_FAILED: case WIRE_DUALOPEND_FAIL: - case WIRE_DUALOPEND_GOT_OFFER: + case WIRE_DUALOPEND_PSBT_UPDATED: case WIRE_DUALOPEND_GOT_OFFER_REPLY: - case WIRE_DUALOPEND_COMMIT_RCVD: + + /* Messages we send */ + case WIRE_DUALOPEND_GOT_OFFER: case WIRE_DUALOPEND_PSBT_CHANGED: - case WIRE_DUALOPEND_PSBT_UPDATED: + case WIRE_DUALOPEND_COMMIT_RCVD: + case WIRE_DUALOPEND_FUNDING_SIGS: + case WIRE_DUALOPEND_TX_SIGS_SENT: + case WIRE_DUALOPEND_CHANNEL_LOCKED: + case WIRE_DUALOPEND_GOT_SHUTDOWN: + case WIRE_DUALOPEND_SHUTDOWN_COMPLETE: + case WIRE_DUALOPEND_FAILED: break; } @@ -2367,6 +2430,9 @@ static u8 *handle_peer_in(struct state *state) return NULL; } else if (t == WIRE_FUNDING_LOCKED) { return handle_funding_locked(state, msg); + } else if (t == WIRE_SHUTDOWN) { + handle_peer_shutdown(state, msg); + return NULL; } #if DEVELOPER @@ -2402,6 +2468,12 @@ static u8 *handle_peer_in(struct state *state) peer_failed_connection_lost(); } +static bool shutdown_complete(const struct state *state) +{ + return state->shutdown_sent[LOCAL] + && state->shutdown_sent[REMOTE]; +} + int main(int argc, char *argv[]) { common_setup(argv[0]); @@ -2518,6 +2590,10 @@ int main(int argc, char *argv[]) else try_read_gossip_store(state); + /* If we've shutdown, we're done */ + if (shutdown_complete(state)) + msg = towire_dualopend_shutdown_complete(state, + state->pps); /* Since we're the top-level event loop, we clean up */ clean_tmpctx(); } diff --git a/openingd/dualopend_wire.csv b/openingd/dualopend_wire.csv index 7a0f9c713..6b7be6992 100644 --- a/openingd/dualopend_wire.csv +++ b/openingd/dualopend_wire.csv @@ -130,6 +130,20 @@ msgdata,dualopend_channel_locked,remote_per_commit,pubkey, msgtype,dualopend_depth_reached,7020 msgdata,dualopend_depth_reached,depth,u32, +# Tell peer to shut down channel. +msgtype,dualopend_send_shutdown,7023 +msgdata,dualopend_send_shutdown,shutdown_scriptpubkey_len,u16, +msgdata,dualopend_send_shutdown,shutdown_scriptpubkey,u8,shutdown_scriptpubkey_len + +# Peer told us that channel is shutting down +msgtype,dualopend_got_shutdown,7024 +msgdata,dualopend_got_shutdown,scriptpubkey_len,u16, +msgdata,dualopend_got_shutdown,scriptpubkey,u8,scriptpubkey_len + +# Shutdown is complete, ready for closing negotiation. + peer_fd & gossip_fd. +msgtype,dualopend_shutdown_complete,7025 +msgdata,dualopend_shutdown_complete,per_peer_state,per_peer_state, + # master -> dualopend: do you have a memleak? msgtype,dualopend_dev_memleak,7033 diff --git a/openingd/dualopend_wiregen.c b/openingd/dualopend_wiregen.c index 4520d2c7a..75bbbc11f 100644 --- a/openingd/dualopend_wiregen.c +++ b/openingd/dualopend_wiregen.c @@ -34,6 +34,9 @@ const char *dualopend_wire_name(int e) case WIRE_DUALOPEND_TX_SIGS_SENT: return "WIRE_DUALOPEND_TX_SIGS_SENT"; case WIRE_DUALOPEND_CHANNEL_LOCKED: return "WIRE_DUALOPEND_CHANNEL_LOCKED"; case WIRE_DUALOPEND_DEPTH_REACHED: return "WIRE_DUALOPEND_DEPTH_REACHED"; + case WIRE_DUALOPEND_SEND_SHUTDOWN: return "WIRE_DUALOPEND_SEND_SHUTDOWN"; + case WIRE_DUALOPEND_GOT_SHUTDOWN: return "WIRE_DUALOPEND_GOT_SHUTDOWN"; + case WIRE_DUALOPEND_SHUTDOWN_COMPLETE: return "WIRE_DUALOPEND_SHUTDOWN_COMPLETE"; case WIRE_DUALOPEND_DEV_MEMLEAK: return "WIRE_DUALOPEND_DEV_MEMLEAK"; case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY: return "WIRE_DUALOPEND_DEV_MEMLEAK_REPLY"; } @@ -59,6 +62,9 @@ bool dualopend_wire_is_defined(u16 type) case WIRE_DUALOPEND_TX_SIGS_SENT:; case WIRE_DUALOPEND_CHANNEL_LOCKED:; case WIRE_DUALOPEND_DEPTH_REACHED:; + case WIRE_DUALOPEND_SEND_SHUTDOWN:; + case WIRE_DUALOPEND_GOT_SHUTDOWN:; + case WIRE_DUALOPEND_SHUTDOWN_COMPLETE:; case WIRE_DUALOPEND_DEV_MEMLEAK:; case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY:; return true; @@ -553,6 +559,86 @@ bool fromwire_dualopend_depth_reached(const void *p, u32 *depth) return cursor != NULL; } +/* WIRE: DUALOPEND_SEND_SHUTDOWN */ +/* Tell peer to shut down channel. */ +u8 *towire_dualopend_send_shutdown(const tal_t *ctx, const u8 *shutdown_scriptpubkey) +{ + u16 shutdown_scriptpubkey_len = tal_count(shutdown_scriptpubkey); + u8 *p = tal_arr(ctx, u8, 0); + + towire_u16(&p, WIRE_DUALOPEND_SEND_SHUTDOWN); + towire_u16(&p, shutdown_scriptpubkey_len); + towire_u8_array(&p, shutdown_scriptpubkey, shutdown_scriptpubkey_len); + + return memcheck(p, tal_count(p)); +} +bool fromwire_dualopend_send_shutdown(const tal_t *ctx, const void *p, u8 **shutdown_scriptpubkey) +{ + u16 shutdown_scriptpubkey_len; + + const u8 *cursor = p; + size_t plen = tal_count(p); + + if (fromwire_u16(&cursor, &plen) != WIRE_DUALOPEND_SEND_SHUTDOWN) + return false; + shutdown_scriptpubkey_len = fromwire_u16(&cursor, &plen); + // 2nd case shutdown_scriptpubkey + *shutdown_scriptpubkey = shutdown_scriptpubkey_len ? tal_arr(ctx, u8, shutdown_scriptpubkey_len) : NULL; + fromwire_u8_array(&cursor, &plen, *shutdown_scriptpubkey, shutdown_scriptpubkey_len); + return cursor != NULL; +} + +/* WIRE: DUALOPEND_GOT_SHUTDOWN */ +/* Peer told us that channel is shutting down */ +u8 *towire_dualopend_got_shutdown(const tal_t *ctx, const u8 *scriptpubkey) +{ + u16 scriptpubkey_len = tal_count(scriptpubkey); + u8 *p = tal_arr(ctx, u8, 0); + + towire_u16(&p, WIRE_DUALOPEND_GOT_SHUTDOWN); + towire_u16(&p, scriptpubkey_len); + towire_u8_array(&p, scriptpubkey, scriptpubkey_len); + + return memcheck(p, tal_count(p)); +} +bool fromwire_dualopend_got_shutdown(const tal_t *ctx, const void *p, u8 **scriptpubkey) +{ + u16 scriptpubkey_len; + + const u8 *cursor = p; + size_t plen = tal_count(p); + + if (fromwire_u16(&cursor, &plen) != WIRE_DUALOPEND_GOT_SHUTDOWN) + return false; + scriptpubkey_len = fromwire_u16(&cursor, &plen); + // 2nd case scriptpubkey + *scriptpubkey = scriptpubkey_len ? tal_arr(ctx, u8, scriptpubkey_len) : NULL; + fromwire_u8_array(&cursor, &plen, *scriptpubkey, scriptpubkey_len); + return cursor != NULL; +} + +/* WIRE: DUALOPEND_SHUTDOWN_COMPLETE */ +/* Shutdown is complete */ +u8 *towire_dualopend_shutdown_complete(const tal_t *ctx, const struct per_peer_state *per_peer_state) +{ + u8 *p = tal_arr(ctx, u8, 0); + + towire_u16(&p, WIRE_DUALOPEND_SHUTDOWN_COMPLETE); + towire_per_peer_state(&p, per_peer_state); + + return memcheck(p, tal_count(p)); +} +bool fromwire_dualopend_shutdown_complete(const tal_t *ctx, const void *p, struct per_peer_state **per_peer_state) +{ + const u8 *cursor = p; + size_t plen = tal_count(p); + + if (fromwire_u16(&cursor, &plen) != WIRE_DUALOPEND_SHUTDOWN_COMPLETE) + return false; + *per_peer_state = fromwire_per_peer_state(ctx, &cursor, &plen); + return cursor != NULL; +} + /* WIRE: DUALOPEND_DEV_MEMLEAK */ /* master -> dualopend: do you have a memleak? */ u8 *towire_dualopend_dev_memleak(const tal_t *ctx) @@ -593,4 +679,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak) *leak = fromwire_bool(&cursor, &plen); return cursor != NULL; } -// SHA256STAMP:420b9d30d0ecd89f962dee16c410c54f9ac7852dd5ab02c05730ab07ebc6bece +// SHA256STAMP:5b6ccfff2f6cc43eee53e4aed8767fc7ae539d548277bda1c628c51f3191dfe4 diff --git a/openingd/dualopend_wiregen.h b/openingd/dualopend_wiregen.h index cb6cbd17a..bed58c052 100644 --- a/openingd/dualopend_wiregen.h +++ b/openingd/dualopend_wiregen.h @@ -46,6 +46,12 @@ enum dualopend_wire { WIRE_DUALOPEND_CHANNEL_LOCKED = 7019, /* master->dualopend funding reached depth; tell peer */ WIRE_DUALOPEND_DEPTH_REACHED = 7020, + /* Tell peer to shut down channel. */ + WIRE_DUALOPEND_SEND_SHUTDOWN = 7023, + /* Peer told us that channel is shutting down */ + WIRE_DUALOPEND_GOT_SHUTDOWN = 7024, + /* Shutdown is complete */ + WIRE_DUALOPEND_SHUTDOWN_COMPLETE = 7025, /* master -> dualopend: do you have a memleak? */ WIRE_DUALOPEND_DEV_MEMLEAK = 7033, WIRE_DUALOPEND_DEV_MEMLEAK_REPLY = 7133, @@ -133,6 +139,21 @@ bool fromwire_dualopend_channel_locked(const tal_t *ctx, const void *p, struct p u8 *towire_dualopend_depth_reached(const tal_t *ctx, u32 depth); bool fromwire_dualopend_depth_reached(const void *p, u32 *depth); +/* WIRE: DUALOPEND_SEND_SHUTDOWN */ +/* Tell peer to shut down channel. */ +u8 *towire_dualopend_send_shutdown(const tal_t *ctx, const u8 *shutdown_scriptpubkey); +bool fromwire_dualopend_send_shutdown(const tal_t *ctx, const void *p, u8 **shutdown_scriptpubkey); + +/* WIRE: DUALOPEND_GOT_SHUTDOWN */ +/* Peer told us that channel is shutting down */ +u8 *towire_dualopend_got_shutdown(const tal_t *ctx, const u8 *scriptpubkey); +bool fromwire_dualopend_got_shutdown(const tal_t *ctx, const void *p, u8 **scriptpubkey); + +/* WIRE: DUALOPEND_SHUTDOWN_COMPLETE */ +/* Shutdown is complete */ +u8 *towire_dualopend_shutdown_complete(const tal_t *ctx, const struct per_peer_state *per_peer_state); +bool fromwire_dualopend_shutdown_complete(const tal_t *ctx, const void *p, struct per_peer_state **per_peer_state); + /* WIRE: DUALOPEND_DEV_MEMLEAK */ /* master -> dualopend: do you have a memleak? */ u8 *towire_dualopend_dev_memleak(const tal_t *ctx); @@ -144,4 +165,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak); #endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */ -// SHA256STAMP:420b9d30d0ecd89f962dee16c410c54f9ac7852dd5ab02c05730ab07ebc6bece +// SHA256STAMP:5b6ccfff2f6cc43eee53e4aed8767fc7ae539d548277bda1c628c51f3191dfe4 diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index faeff38f6..c5f4b6904 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -1774,4 +1774,4 @@ struct db_query db_postgres_queries[] = { #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ -// SHA256STAMP:3c65fc6d5dc492c13d1e7e91f7ca224e1a032237d3cf98b63d93d0e180665c3a +// SHA256STAMP:3b9fa7f4f741852169761dc4172ffbd3a61c877aa6ebd07ae24e1ddb10e49f7a diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index f1a5ee023..ebc1bf557 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -1774,4 +1774,4 @@ struct db_query db_sqlite3_queries[] = { #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ -// SHA256STAMP:3c65fc6d5dc492c13d1e7e91f7ca224e1a032237d3cf98b63d93d0e180665c3a +// SHA256STAMP:3b9fa7f4f741852169761dc4172ffbd3a61c877aa6ebd07ae24e1ddb10e49f7a diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index 372e90ed4..c13c3bae8 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -1166,7 +1166,7 @@ msgstr "" msgid "not a valid SQL statement" msgstr "" -#: wallet/test/run-wallet.c:1381 +#: wallet/test/run-wallet.c:1384 msgid "INSERT INTO channels (id) VALUES (1);" msgstr "" -# SHA256STAMP:0d3e9063d3a2e50eff73f42254c423cbbe75e3603a8f9a21aab99d1a56168736 +# SHA256STAMP:0d63ab43490ebe25d3e24ffbd0f1d837146e346443b6797cbc7976f10996a199 diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index bd8afe093..070c40189 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -715,6 +715,9 @@ u8 *towire_connectd_peer_disconnected(const tal_t *ctx UNNEEDED, const struct no /* Generated stub for towire_custommsg_out */ u8 *towire_custommsg_out(const tal_t *ctx UNNEEDED, const u8 *msg UNNEEDED) { fprintf(stderr, "towire_custommsg_out called!\n"); abort(); } +/* Generated stub for towire_dualopend_send_shutdown */ +u8 *towire_dualopend_send_shutdown(const tal_t *ctx UNNEEDED, const u8 *shutdown_scriptpubkey UNNEEDED) +{ fprintf(stderr, "towire_dualopend_send_shutdown called!\n"); abort(); } /* Generated stub for towire_errorfmt */ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED, const struct channel_id *channel UNNEEDED,