Browse Source

dual-open: handle sigs and channel lockin in dualopend, not channeld

This will make it possible to do RBF, since we can re-start the opening
process in dualopend while waiting for lock-in.

Note the new channel states are being used, DUALOPEND_INIT and
DUALOPEND_AWAITING_LOCKIN, to differentiate from openingd/channeld opens
ppa
niftynei 4 years ago
committed by Christian Decker
parent
commit
1ea4e63331
  1. 6
      lightningd/channel_control.c
  2. 172
      lightningd/dual_open_control.c
  3. 5
      lightningd/dual_open_control.h
  4. 110
      openingd/dualopend.c
  5. 12
      openingd/dualopend_wire.csv
  6. 74
      openingd/dualopend_wiregen.c
  7. 23
      openingd/dualopend_wiregen.h

6
lightningd/channel_control.c

@ -631,7 +631,11 @@ bool channel_tell_depth(struct lightningd *ld,
return true;
}
// FIXME: pass to dualopend here!
#if EXPERIMENTAL_FEATURES
dualopen_tell_depth(channel->owner, channel, depth);
// FIXME: lockin complete?
return true;
#endif /* EXPERIMENTAL_FEATURES */
} else if (channel->state != CHANNELD_AWAITING_LOCKIN
&& channel->state != CHANNELD_NORMAL) {
/* If not awaiting lockin/announce, it doesn't

172
lightningd/dual_open_control.c

@ -26,7 +26,6 @@
#include <lightningd/opening_common.h>
#include <lightningd/peer_control.h>
#include <lightningd/plugin_hook.h>
#include <lightningd/subd.h>
#include <openingd/dualopend_wiregen.h>
#include <wire/common_wiregen.h>
#include <wire/peer_wire.h>
@ -34,12 +33,11 @@
struct commit_rcvd {
struct channel *channel;
struct channel_id cid;
struct per_peer_state *pps;
u8 *commitment_msg;
struct uncommitted_channel *uc;
};
static void handle_signed_psbt(struct lightningd *ld,
struct subd *dualopend,
const struct wally_psbt *psbt,
struct commit_rcvd *rcvd)
{
@ -51,10 +49,9 @@ static void handle_signed_psbt(struct lightningd *ld,
channel_watch_funding(ld, rcvd->channel);
peer_start_channeld(rcvd->channel,
rcvd->pps,
rcvd->commitment_msg,
false);
/* Send peer our signatures */
subd_send_msg(dualopend,
take(towire_dualopend_send_tx_sigs(NULL, psbt)));
}
/* ~Map of the Territory~
@ -534,6 +531,7 @@ openchannel2_signed_deserialize(struct openchannel2_psbt_payload *payload,
if (payload->psbt)
tal_free(payload->psbt);
payload->psbt = tal_steal(payload, psbt);
return true;
}
@ -541,9 +539,19 @@ openchannel2_signed_deserialize(struct openchannel2_psbt_payload *payload,
static void
openchannel2_sign_hook_cb(struct openchannel2_psbt_payload *payload STEALS)
{
/* Free payload regardless of what happens next */
/* Whatever happens, we free the payload */
tal_steal(tmpctx, payload);
if (!payload->dualopend) {
log_broken(payload->ld->log, "dualopend daemon died"
" before signed PSBT returned");
channel_internal_error(payload->rcvd->channel, "daemon died");
return;
}
tal_del_destructor2(payload->dualopend,
openchannel2_psbt_remove_dualopend,
payload);
/* Finalize it, if not already. It shouldn't work entirely */
psbt_finalize(payload->psbt);
@ -552,7 +560,8 @@ openchannel2_sign_hook_cb(struct openchannel2_psbt_payload *payload STEALS)
"for their inputs %s",
type_to_string(tmpctx, struct wally_psbt, payload->psbt));
handle_signed_psbt(payload->ld, payload->psbt, payload->rcvd);
handle_signed_psbt(payload->ld, payload->dualopend,
payload->psbt, payload->rcvd);
}
REGISTER_PLUGIN_HOOK(openchannel2,
@ -620,7 +629,7 @@ wallet_commit_channel(struct lightningd *ld,
channel = new_channel(uc->peer, uc->dbid,
NULL, /* No shachain yet */
CHANNELD_AWAITING_LOCKIN,
DUALOPEND_OPEN_INIT,
opener,
uc->log,
take(uc->transient_billboard),
@ -1040,6 +1049,110 @@ static void send_funding_tx(struct channel *channel,
sendfunding_done, cs);
}
static void handle_peer_tx_sigs_sent(struct subd *dualopend,
const int *fds,
const u8 *msg)
{
struct channel *channel = dualopend->channel;
const struct wally_tx *wtx;
if (!fromwire_dualopend_tx_sigs_sent(msg)) {
channel_internal_error(channel,
"bad WIRE_DUALOPEND_TX_SIGS_SENT %s",
tal_hex(tmpctx, msg));
return;
}
if (psbt_finalize(cast_const(struct wally_psbt *, channel->psbt))) {
wtx = psbt_final_tx(NULL, channel->psbt);
if (!wtx) {
channel_internal_error(channel,
"Unable to extract final tx"
" from PSBT %s",
type_to_string(tmpctx,
struct wally_psbt,
channel->psbt));
return;
}
send_funding_tx(channel, take(wtx));
channel_set_state(channel, DUALOPEND_OPEN_INIT,
DUALOPEND_AWAITING_LOCKIN,
REASON_UNKNOWN,
"Sigs exchanged, waiting for lock-in");
}
}
static void handle_channel_locked(struct subd *dualopend,
const int *fds,
const u8 *msg)
{
struct channel *channel = dualopend->channel;
struct pubkey remote_per_commit;
struct per_peer_state *pps;
if (!fromwire_dualopend_channel_locked(tmpctx, msg, &pps,
&remote_per_commit)) {
log_broken(dualopend->log,
"bad WIRE_DUALOPEND_CHANNEL_LOCKED %s",
tal_hex(msg, msg));
close(fds[0]);
close(fds[1]);
close(fds[2]);
goto cleanup;
}
per_peer_state_set_fds_arr(pps, fds);
/* Updates channel with the next per-commit point etc */
if (!channel_on_funding_locked(channel, &remote_per_commit))
goto cleanup;
assert(channel->scid);
assert(channel->remote_funding_locked);
if (channel->state != DUALOPEND_AWAITING_LOCKIN) {
log_debug(channel->log, "Lockin complete, but state %s",
channel_state_name(channel));
} else {
channel_set_state(channel,
DUALOPEND_AWAITING_LOCKIN,
CHANNELD_NORMAL,
REASON_UNKNOWN,
"Lockin complete");
channel_record_open(channel);
}
/* FIXME: LND sigs/update_fee msgs? */
peer_start_channeld(channel, pps, NULL, false);
return;
cleanup:
subd_release_channel(dualopend, channel);
}
void dualopen_tell_depth(struct subd *dualopend,
struct channel *channel,
u32 depth)
{
const u8 *msg;
u32 to_go;
if (depth < channel->minimum_depth)
to_go = channel->minimum_depth - depth;
else
to_go = 0;
/* Are we there yet? */
if (to_go == 0) {
assert(channel->scid);
msg = towire_dualopend_depth_reached(NULL, depth);
subd_send_msg(dualopend, take(msg));
}
// FIXME: update billboard. needs to_go counter!
}
static void accepter_psbt_changed(struct subd *dualopend,
const u8 *msg)
{
@ -1118,8 +1231,8 @@ static void accepter_got_offer(struct subd *dualopend,
plugin_hook_call_openchannel2(dualopend->ld, payload);
}
static void peer_tx_sigs_msg(struct subd *dualopend,
const u8 *msg)
static void handle_peer_tx_sigs_msg(struct subd *dualopend,
const u8 *msg)
{
struct wally_psbt *psbt;
const struct wally_tx *wtx;
@ -1150,8 +1263,21 @@ static void peer_tx_sigs_msg(struct subd *dualopend,
if (psbt_finalize(cast_const(struct wally_psbt *, channel->psbt))) {
wtx = psbt_final_tx(NULL, channel->psbt);
if (wtx)
send_funding_tx(channel, take(wtx));
if (!wtx) {
channel_internal_error(channel,
"Unable to extract final tx"
" from PSBT %s",
type_to_string(tmpctx,
struct wally_psbt,
channel->psbt));
return;
}
send_funding_tx(channel, take(wtx));
channel_set_state(channel, DUALOPEND_OPEN_INIT,
DUALOPEND_AWAITING_LOCKIN,
REASON_UNKNOWN,
"Sigs exchanged, waiting for lock-in");
}
wallet_channel_save(ld->wallet, channel);
@ -1169,7 +1295,6 @@ json_openchannel_signed(struct command *cmd,
const jsmntok_t *params)
{
struct wally_psbt *psbt;
const struct wally_tx *wtx;
struct uncommitted_channel *uc;
struct channel_id *cid;
struct channel *channel;
@ -1237,12 +1362,6 @@ json_openchannel_signed(struct command *cmd,
subd_send_msg(channel->owner,
take(towire_dualopend_send_tx_sigs(NULL, channel->psbt)));
if (psbt_finalize(cast_const(struct wally_psbt *, channel->psbt))) {
wtx = psbt_final_tx(NULL, channel->psbt);
if (wtx)
send_funding_tx(channel, take(wtx));
}
channel->openchannel_signed_cmd = tal_steal(channel, cmd);
return command_still_pending(cmd);
}
@ -1491,7 +1610,15 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
uc, fds, msg);
return 0;
case WIRE_DUALOPEND_FUNDING_SIGS:
peer_tx_sigs_msg(dualopend, msg);
handle_peer_tx_sigs_msg(dualopend, msg);
return 0;
case WIRE_DUALOPEND_TX_SIGS_SENT:
handle_peer_tx_sigs_sent(dualopend, fds, msg);
return 0;
case WIRE_DUALOPEND_CHANNEL_LOCKED:
if (tal_count(fds) != 3)
return 3;
handle_channel_locked(dualopend, fds, msg);
return 0;
case WIRE_DUALOPEND_FAILED:
case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY:
@ -1503,6 +1630,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_DEPTH_REACHED:
case WIRE_DUALOPEND_DEV_MEMLEAK:
break;
}

5
lightningd/dual_open_control.h

@ -2,10 +2,15 @@
#define LIGHTNING_LIGHTNINGD_DUAL_OPEN_CONTROL_H
#include "config.h"
#include <lightningd/subd.h>
struct per_peer_state;
void peer_start_dualopend(struct peer *peer,
struct per_peer_state *pps,
const u8 *send_msg);
void dualopen_tell_depth(struct subd *dualopend,
struct channel *channel,
u32 depth);
#endif /* LIGHTNING_LIGHTNINGD_DUAL_OPEN_CONTROL_H */

110
openingd/dualopend.c

@ -144,10 +144,17 @@ struct state {
/* Track how many of each tx collab msg we receive */
u16 tx_msg_count[NUM_TX_MSGS];
/* Tally of which sides are locked, or not */
bool funding_locked[NUM_SIDES];
/* PSBT of the funding tx */
struct wally_psbt *psbt;
/* Peer sends this to us in the funding_locked msg */
struct pubkey remote_per_commit;
/* Are we shutting this channel down? */
bool shutting_down;
};
/* psbt_changeset_get_next - Get next message to send
@ -750,7 +757,7 @@ static void handle_tx_sigs(struct state *state, const u8 *msg)
take(towire_dualopend_funding_sigs(NULL, state->psbt)));
}
static u8 *handle_send_tx_sigs(struct state *state, const u8 *msg)
static void handle_send_tx_sigs(struct state *state, const u8 *msg)
{
struct wally_psbt *psbt;
struct bitcoin_txid txid;
@ -774,10 +781,21 @@ static u8 *handle_send_tx_sigs(struct state *state, const u8 *msg)
if (wally_psbt_combine(state->psbt, psbt) != WALLY_OK) {
tal_wally_end(tal_free(state->psbt));
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Unable to combine PSBTs");
"Unable to combine PSBTs. received %s\n"
"local %s",
type_to_string(tmpctx, struct wally_psbt,
psbt),
type_to_string(tmpctx, struct wally_psbt,
state->psbt));
}
tal_wally_end(tal_steal(state, state->psbt));
return psbt_to_tx_sigs_msg(tmpctx, state, psbt);
tal_wally_end(state->psbt);
/* Send our sigs to peer */
msg = psbt_to_tx_sigs_msg(tmpctx, state, state->psbt);
sync_crypto_write(state->pps, take(msg));
/* Notify lightningd that we've sent sigs */
wire_sync_write(REQ_FD, take(towire_dualopend_tx_sigs_sent(NULL)));
}
static struct wally_psbt *
@ -2151,6 +2169,81 @@ static void opener_start(struct state *state, u8 *msg)
wire_sync_write(REQ_FD, take(msg));
}
static u8 *handle_funding_locked(struct state *state, u8 *msg)
{
struct channel_id cid;
if (!fromwire_funding_locked(msg, &cid,
&state->remote_per_commit))
peer_failed(state->pps, &state->channel_id,
"Bad funding_locked %s", tal_hex(msg, msg));
if (!channel_id_eq(&cid, &state->channel_id))
peer_failed(state->pps, &state->channel_id,
"funding_locked ids don't match: "
"expected %s, got %s",
type_to_string(msg, struct channel_id,
&state->channel_id),
type_to_string(msg, struct channel_id, &cid));
state->funding_locked[REMOTE] = true;
// FIXME: update billboard!
if (state->funding_locked[LOCAL])
return towire_dualopend_channel_locked(state, state->pps,
&state->remote_per_commit);
return NULL;
}
static void hsm_per_commitment_point(u64 index, struct pubkey *point)
{
struct secret *s;
const u8 *msg;
msg = towire_hsmd_get_per_commitment_point(NULL, index);
wire_sync_write(HSM_FD, take(msg));
msg = wire_sync_read(tmpctx, HSM_FD);
if (!fromwire_hsmd_get_per_commitment_point_reply(tmpctx, msg,
point, &s))
status_failed(STATUS_FAIL_HSM_IO,
"Bad per_commitment_point reply %s",
tal_hex(tmpctx, msg));
}
static u8 *handle_funding_depth(struct state *state, u8 *msg)
{
u32 depth;
struct pubkey next_local_per_commit;
if (!fromwire_dualopend_depth_reached(msg, &depth))
master_badmsg(WIRE_DUALOPEND_DEPTH_REACHED, msg);
/* Too late, shutting down already */
if (state->shutting_down)
return NULL;
/* We check this before we arrive here, but for sanity */
assert(state->minimum_depth <= depth);
/* Figure out the next local commit */
hsm_per_commitment_point(1, &next_local_per_commit);
msg = towire_funding_locked(NULL,
&state->channel_id,
&next_local_per_commit);
sync_crypto_write(state->pps, take(msg));
state->funding_locked[LOCAL] = true;
// FIXME: update billboard!
if (state->funding_locked[REMOTE])
return towire_dualopend_channel_locked(state,
state->pps,
&state->remote_per_commit);
return NULL;
}
/*~ If we see the gossip_fd readable, we read a whole message. Sure, we might
* block, but we trust gossipd. */
static void handle_gossip_in(struct state *state)
@ -2209,7 +2302,11 @@ static u8 *handle_master_in(struct state *state)
case WIRE_DUALOPEND_SEND_TX_SIGS:
handle_send_tx_sigs(state, msg);
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_INIT:
case WIRE_DUALOPEND_FUNDING_SIGS:
case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY:
@ -2256,6 +2353,8 @@ static u8 *handle_peer_in(struct state *state)
} else if (t == WIRE_TX_SIGNATURES) {
handle_tx_sigs(state, msg);
return NULL;
} else if (t == WIRE_FUNDING_LOCKED) {
return handle_funding_locked(state, msg);
}
#if DEVELOPER
@ -2338,6 +2437,9 @@ int main(int argc, char *argv[])
* handle_peer_gossip_or_error compares this. */
memset(&state->channel_id, 0, sizeof(state->channel_id));
state->channel = NULL;
state->funding_locked[LOCAL] = state->funding_locked[REMOTE] = false;
state->shutting_down = false;
for (size_t i = 0; i < NUM_TX_MSGS; i++)
state->tx_msg_count[i] = 0;

12
openingd/dualopend_wire.csv

@ -118,6 +118,18 @@ msgdata,dualopend_funding_sigs,signed_psbt,wally_psbt,
msgtype,dualopend_send_tx_sigs,7011
msgdata,dualopend_send_tx_sigs,signed_psbt,wally_psbt,
# dualopend->master tx sigs transmitted to peer
msgtype,dualopend_tx_sigs_sent,7012
# dualopend->master this channel has been locked
msgtype,dualopend_channel_locked,7019
msgdata,dualopend_channel_locked,pps,per_peer_state,
msgdata,dualopend_channel_locked,remote_per_commit,pubkey,
# master->dualopend funding reached depth; tell peer
msgtype,dualopend_depth_reached,7020
msgdata,dualopend_depth_reached,depth,u32,
# 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.

74
openingd/dualopend_wiregen.c

@ -31,6 +31,9 @@ const char *dualopend_wire_name(int e)
case WIRE_DUALOPEND_OPENER_INIT: return "WIRE_DUALOPEND_OPENER_INIT";
case WIRE_DUALOPEND_FUNDING_SIGS: return "WIRE_DUALOPEND_FUNDING_SIGS";
case WIRE_DUALOPEND_SEND_TX_SIGS: return "WIRE_DUALOPEND_SEND_TX_SIGS";
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_DEV_MEMLEAK: return "WIRE_DUALOPEND_DEV_MEMLEAK";
case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY: return "WIRE_DUALOPEND_DEV_MEMLEAK_REPLY";
}
@ -53,6 +56,9 @@ bool dualopend_wire_is_defined(u16 type)
case WIRE_DUALOPEND_OPENER_INIT:;
case WIRE_DUALOPEND_FUNDING_SIGS:;
case WIRE_DUALOPEND_SEND_TX_SIGS:;
case WIRE_DUALOPEND_TX_SIGS_SENT:;
case WIRE_DUALOPEND_CHANNEL_LOCKED:;
case WIRE_DUALOPEND_DEPTH_REACHED:;
case WIRE_DUALOPEND_DEV_MEMLEAK:;
case WIRE_DUALOPEND_DEV_MEMLEAK_REPLY:;
return true;
@ -481,6 +487,72 @@ bool fromwire_dualopend_send_tx_sigs(const tal_t *ctx, const void *p, struct wal
return cursor != NULL;
}
/* WIRE: DUALOPEND_TX_SIGS_SENT */
/* dualopend->master tx sigs transmitted to peer */
u8 *towire_dualopend_tx_sigs_sent(const tal_t *ctx)
{
u8 *p = tal_arr(ctx, u8, 0);
towire_u16(&p, WIRE_DUALOPEND_TX_SIGS_SENT);
return memcheck(p, tal_count(p));
}
bool fromwire_dualopend_tx_sigs_sent(const void *p)
{
const u8 *cursor = p;
size_t plen = tal_count(p);
if (fromwire_u16(&cursor, &plen) != WIRE_DUALOPEND_TX_SIGS_SENT)
return false;
return cursor != NULL;
}
/* WIRE: DUALOPEND_CHANNEL_LOCKED */
/* dualopend->master this channel has been locked */
u8 *towire_dualopend_channel_locked(const tal_t *ctx, const struct per_peer_state *pps, const struct pubkey *remote_per_commit)
{
u8 *p = tal_arr(ctx, u8, 0);
towire_u16(&p, WIRE_DUALOPEND_CHANNEL_LOCKED);
towire_per_peer_state(&p, pps);
towire_pubkey(&p, remote_per_commit);
return memcheck(p, tal_count(p));
}
bool fromwire_dualopend_channel_locked(const tal_t *ctx, const void *p, struct per_peer_state **pps, struct pubkey *remote_per_commit)
{
const u8 *cursor = p;
size_t plen = tal_count(p);
if (fromwire_u16(&cursor, &plen) != WIRE_DUALOPEND_CHANNEL_LOCKED)
return false;
*pps = fromwire_per_peer_state(ctx, &cursor, &plen);
fromwire_pubkey(&cursor, &plen, remote_per_commit);
return cursor != NULL;
}
/* WIRE: DUALOPEND_DEPTH_REACHED */
/* master->dualopend funding reached depth; tell peer */
u8 *towire_dualopend_depth_reached(const tal_t *ctx, u32 depth)
{
u8 *p = tal_arr(ctx, u8, 0);
towire_u16(&p, WIRE_DUALOPEND_DEPTH_REACHED);
towire_u32(&p, depth);
return memcheck(p, tal_count(p));
}
bool fromwire_dualopend_depth_reached(const void *p, u32 *depth)
{
const u8 *cursor = p;
size_t plen = tal_count(p);
if (fromwire_u16(&cursor, &plen) != WIRE_DUALOPEND_DEPTH_REACHED)
return false;
*depth = fromwire_u32(&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)
@ -521,4 +593,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak)
*leak = fromwire_bool(&cursor, &plen);
return cursor != NULL;
}
// SHA256STAMP:b209a8683f1e9cbdc9f64302b70b86b2d66ac8fa917e3f1e482fda64f92c20a2
// SHA256STAMP:420b9d30d0ecd89f962dee16c410c54f9ac7852dd5ab02c05730ab07ebc6bece

23
openingd/dualopend_wiregen.h

@ -40,6 +40,12 @@ enum dualopend_wire {
WIRE_DUALOPEND_FUNDING_SIGS = 7010,
/* master->dualopend send our tx_sigs to peer */
WIRE_DUALOPEND_SEND_TX_SIGS = 7011,
/* dualopend->master tx sigs transmitted to peer */
WIRE_DUALOPEND_TX_SIGS_SENT = 7012,
/* dualopend->master this channel has been locked */
WIRE_DUALOPEND_CHANNEL_LOCKED = 7019,
/* master->dualopend funding reached depth; tell peer */
WIRE_DUALOPEND_DEPTH_REACHED = 7020,
/* master -> dualopend: do you have a memleak? */
WIRE_DUALOPEND_DEV_MEMLEAK = 7033,
WIRE_DUALOPEND_DEV_MEMLEAK_REPLY = 7133,
@ -112,6 +118,21 @@ bool fromwire_dualopend_funding_sigs(const tal_t *ctx, const void *p, struct wal
u8 *towire_dualopend_send_tx_sigs(const tal_t *ctx, const struct wally_psbt *signed_psbt);
bool fromwire_dualopend_send_tx_sigs(const tal_t *ctx, const void *p, struct wally_psbt **signed_psbt);
/* WIRE: DUALOPEND_TX_SIGS_SENT */
/* dualopend->master tx sigs transmitted to peer */
u8 *towire_dualopend_tx_sigs_sent(const tal_t *ctx);
bool fromwire_dualopend_tx_sigs_sent(const void *p);
/* WIRE: DUALOPEND_CHANNEL_LOCKED */
/* dualopend->master this channel has been locked */
u8 *towire_dualopend_channel_locked(const tal_t *ctx, const struct per_peer_state *pps, const struct pubkey *remote_per_commit);
bool fromwire_dualopend_channel_locked(const tal_t *ctx, const void *p, struct per_peer_state **pps, struct pubkey *remote_per_commit);
/* WIRE: DUALOPEND_DEPTH_REACHED */
/* master->dualopend funding reached depth; tell peer */
u8 *towire_dualopend_depth_reached(const tal_t *ctx, u32 depth);
bool fromwire_dualopend_depth_reached(const void *p, u32 *depth);
/* WIRE: DUALOPEND_DEV_MEMLEAK */
/* master -> dualopend: do you have a memleak? */
u8 *towire_dualopend_dev_memleak(const tal_t *ctx);
@ -123,4 +144,4 @@ bool fromwire_dualopend_dev_memleak_reply(const void *p, bool *leak);
#endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */
// SHA256STAMP:b209a8683f1e9cbdc9f64302b70b86b2d66ac8fa917e3f1e482fda64f92c20a2
// SHA256STAMP:420b9d30d0ecd89f962dee16c410c54f9ac7852dd5ab02c05730ab07ebc6bece

Loading…
Cancel
Save