Browse Source

df: handle shutdown (before lockedin) in dualopend

A channel can be closed before it locks in. This lets dualopend handle
shutdown messages from the peer before the channel is locked in.
ppa
niftynei 4 years ago
committed by Christian Decker
parent
commit
90d936bb60
  1. 111
      lightningd/dual_open_control.c
  2. 19
      lightningd/peer_control.c
  3. 3
      lightningd/test/run-invoice-select-inchan.c
  4. 94
      openingd/dualopend.c
  5. 14
      openingd/dualopend_wire.csv
  6. 88
      openingd/dualopend_wiregen.c
  7. 23
      openingd/dualopend_wiregen.h
  8. 2
      wallet/db_postgres_sqlgen.c
  9. 2
      wallet/db_sqlite3_sqlgen.c
  10. 4
      wallet/statements_gettextgen.po
  11. 3
      wallet/test/run-wallet.c

111
lightningd/dual_open_control.c

@ -3,6 +3,7 @@
* saves and funding tx watching for a channel open */
#include <bitcoin/psbt.h>
#include <bitcoin/script.h>
#include <ccan/ccan/take/take.h>
#include <ccan/short_types/short_types.h>
#include <common/amount.h>
@ -20,6 +21,7 @@
#include <hsmd/capabilities.h>
#include <lightningd/chaintopology.h>
#include <lightningd/channel_control.h>
#include <lightningd/closing_control.h>
#include <lightningd/dual_open_control.h>
#include <lightningd/hsm_control.h>
#include <lightningd/notification.h>
@ -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;

19
lightningd/peer_control.c

@ -56,6 +56,7 @@
#include <lightningd/peer_htlcs.h>
#include <lightningd/plugin_hook.h>
#include <limits.h>
#include <openingd/dualopend_wiregen.h>
#include <stdlib.h>
#include <unistd.h>
#include <wally_bip32.h>
@ -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;

3
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,

94
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();
}

14
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

Can't render this file because it has a wrong number of fields in line 11.

88
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

23
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

2
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

2
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

4
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

3
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,

Loading…
Cancel
Save