Browse Source

dualfund: opener, openchannel_init command (1/3)

There are 3 commands for opening a channel with dualfunding.
`openchannel_init` is the first of these.

It initializes the open-channel dialog, and stops once we've run out of
updates (input/outputs) to send to the peer.
travis-experimental
niftynei 4 years ago
committed by Rusty Russell
parent
commit
06c41a0547
  1. 2
      common/jsonrpc_errors.h
  2. 1
      doc/Makefile
  3. 1
      doc/index.rst
  4. 97
      doc/lightning-openchannel_init.7
  5. 82
      doc/lightning-openchannel_init.7.md
  6. 200
      lightningd/dual_open_control.c
  7. 184
      openingd/dualopend.c
  8. 12
      openingd/dualopend_wire.csv
  9. 45
      openingd/dualopend_wiregen.c
  10. 13
      openingd/dualopend_wiregen.h

2
common/jsonrpc_errors.h

@ -52,6 +52,8 @@ static const errcode_t FUNDING_PEER_NOT_CONNECTED = 305;
static const errcode_t FUNDING_UNKNOWN_PEER = 306;
static const errcode_t FUNDING_NOTHING_TO_CANCEL = 307;
static const errcode_t FUNDING_CANCEL_NOT_SAFE = 308;
static const errcode_t FUNDING_PSBT_INVALID = 309;
static const errcode_t FUNDING_V2_NOT_SUPPORTED = 310;
/* `connect` errors */
static const errcode_t CONNECT_NO_KNOWN_ADDRESS = 400;

1
doc/Makefile

@ -40,6 +40,7 @@ MANPAGES := doc/lightning-cli.1 \
doc/lightning-multifundchannel.7 \
doc/lightning-multiwithdraw.7 \
doc/lightning-newaddr.7 \
doc/lightning-openchannel_init.7 \
doc/lightning-pay.7 \
doc/lightning-plugin.7 \
doc/lightning-reserveinputs.7 \

1
doc/index.rst

@ -68,6 +68,7 @@ c-lightning Documentation
lightning-multifundchannel <lightning-multifundchannel.7.md>
lightning-multiwithdraw <lightning-multiwithdraw.7.md>
lightning-newaddr <lightning-newaddr.7.md>
lightning-openchannel_init <lightning-openchannel_init.7.md>
lightning-pay <lightning-pay.7.md>
lightning-ping <lightning-ping.7.md>
lightning-plugin <lightning-plugin.7.md>

97
doc/lightning-openchannel_init.7

@ -0,0 +1,97 @@
.TH "LIGHTNING-OPENCHANNEL_INIT" "7" "" "" "lightning-openchannel_init"
.SH NAME
lightning-openchannel_init - Command to initiate a channel to a peer
.SH SYNOPSIS
\fBopenchannel_init\fR \fIid\fR \fIamount\fR \fIinitalpsbt\fR [\fIcommitment_feerate\fR] [\fIfunding_feerate\fR] [\fIannounce\fR] [\fIclose_to\fR]
.SH DESCRIPTION
\fBopenchannel_init\fR is a low level RPC command which initiates a channel
open with a specified peer\. It uses the openchannel protocol
which allows for interactive transaction construction\.
\fIid\fR is the node id of the remote peer\.
\fIamount\fR is the satoshi value that we will contribute to the channel\.
This value will be \fIadded\fR to the provided PSBT in the output which is
encumbered by the 2-of-2 script for this channel\.
\fIinitialpsbt\fR is the funded, incomplete PSBT that specifies the UTXOs and
change output for our channel contribution\. It can be updated,
see \fBopenchannel_update\fR; \fIinitialpsbt\fR must have at least one input to
provide a PoDLE to the peer\. Must have the Non-Witness UTXO
(PSBT_IN_NON_WITNESS_UTXO) set for every input\. An error
(code 309) will be returned if this requirement is not met\.
\fIcommitment_feerate\fR is an optional field\. Sets the feerate for
commitment transactions: see \fBfundchannel\fR\.
\fIfunding_feerate\fR is an optional field\. Sets the feerate for the
funding transaction\. Defaults to 'opening' feerate\.
\fIannounce\fR is an optional field\. Whether or not to announce this channel\.
\fIclose_to\fR is a Bitcoin address to which the channel funds should be
sent on close\. Only valid if both peers have negotiated
\fBoption_upfront_shutdown_script\fR\.
.SH RETURN VALUE
On success, returns the \fIchannel_id\fR for this channel; an updated
incomplete \fIinitialpsbt\fR for this funding transaction; and the flag
\fIcommitments_secured\fR, which indiciates the completeness of the
passed back \fIpsbt\fR\. (Will always be false)\.
If the peer does not support \fBoption_dual_fund\fR, this command
will return an error\.
On error the returned object will contain \fBcode\fR and \fBmessage\fR properties,
with \fBcode\fR being one of the following:
.RS
.IP \[bu]
-32602: If the given parameters are wrong\.
.IP \[bu]
-1: Catchall nonspecific error\.
.IP \[bu]
300: The amount exceeded the maximum configured funding amount\.
.IP \[bu]
301: The provided PSBT cannot afford the funding amount\.
.IP \[bu]
304: Still syncing with bitcoin network
.IP \[bu]
305: Peer is not connected\.
.IP \[bu]
306: Unknown peer id\.
.IP \[bu]
309: PSBT missing required fields
.IP \[bu]
310: v2 channel open protocol not supported by peer
.RE
.SH SEE ALSO
lightning-openchannel_\fBupdate\fR(7), lightning-openchannel_\fBsigned\fR(7),
lightning-fundchannel_\fBstart\fR(7), lightning-fundchannel_\fBcomplete\fR(7),
\fBlightning-fundchannel\fR(7), \fBlightning-fundpsbt\fR(7), \fBlightning-utxopsbt\fR(7),
\fBlightning-multifundchannel\fR(7)
.SH AUTHOR
@niftynei \fI<niftynei@gmail.com\fR> is mainly responsible\.
.SH RESOURCES
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
\" SHA256STAMP:a06dc67176c3c9863e4fc3048de7d0172eb79d091479415eb639335b3d096860

82
doc/lightning-openchannel_init.7.md

@ -0,0 +1,82 @@
lightning-openchannel\_init -- Command to initiate a channel to a peer
=====================================================================
SYNOPSIS
--------
**openchannel_init** *id* *amount* *initalpsbt* \[*commitment_feerate*\] \[*funding_feerate*\] \[*announce*\] \[*close_to*\]
DESCRIPTION
-----------
`openchannel_init` is a low level RPC command which initiates a channel
open with a specified peer. It uses the openchannel protocol
which allows for interactive transaction construction.
*id* is the node id of the remote peer.
*amount* is the satoshi value that we will contribute to the channel.
This value will be _added_ to the provided PSBT in the output which is
encumbered by the 2-of-2 script for this channel.
*initialpsbt* is the funded, incomplete PSBT that specifies the UTXOs and
change output for our channel contribution. It can be updated,
see `openchannel_update`; *initialpsbt* must have at least one input to
provide a PoDLE to the peer. Must have the Non-Witness UTXO
(PSBT\_IN\_NON\_WITNESS\_UTXO) set for every input. An error
(code 309) will be returned if this requirement is not met.
*commitment_feerate* is an optional field. Sets the feerate for
commitment transactions: see **fundchannel**.
*funding_feerate* is an optional field. Sets the feerate for the
funding transaction. Defaults to 'opening' feerate.
*announce* is an optional field. Whether or not to announce this channel.
*close_to* is a Bitcoin address to which the channel funds should be
sent on close. Only valid if both peers have negotiated
`option_upfront_shutdown_script`.
RETURN VALUE
------------
On success, returns the *channel_id* for this channel; an updated
incomplete *initialpsbt* for this funding transaction; and the flag
*commitments_secured*, which indiciates the completeness of the
passed back *psbt*. (Will always be false).
If the peer does not support `option_dual_fund`, this command
will return an error.
On error the returned object will contain `code` and `message` properties,
with `code` being one of the following:
- -32602: If the given parameters are wrong.
- -1: Catchall nonspecific error.
- 300: The amount exceeded the maximum configured funding amount.
- 301: The provided PSBT cannot afford the funding amount.
- 304: Still syncing with bitcoin network
- 305: Peer is not connected.
- 306: Unknown peer id.
- 309: PSBT missing required fields
- 310: v2 channel open protocol not supported by peer
SEE ALSO
--------
lightning-openchannel\_update(7), lightning-openchannel\_signed(7),
lightning-fundchannel\_start(7), lightning-fundchannel\_complete(7),
lightning-fundchannel(7), lightning-fundpsbt(7), lightning-utxopsbt(7),
lightning-multifundchannel(7)
AUTHOR
------
@niftynei <<niftynei@gmail.com>> is mainly responsible.
RESOURCES
---------
Main web site: <https://github.com/ElementsProject/lightning>

200
lightningd/dual_open_control.c

@ -741,6 +741,35 @@ wallet_commit_channel(struct lightningd *ld,
return channel;
}
static void opener_psbt_changed(struct subd *dualopend,
struct uncommitted_channel *uc,
const u8 *msg)
{
struct channel_id cid;
struct wally_psbt *psbt;
struct json_stream *response;
struct command *cmd = uc->fc->cmd;
if (!fromwire_dual_open_psbt_changed(cmd, msg,
&cid,
&psbt)) {
log_broken(dualopend->log,
"Malformed dual_open_psbt_changed %s",
tal_hex(tmpctx, msg));
tal_free(dualopend);
return;
}
response = json_stream_success(cmd);
json_add_string(response, "channel_id",
type_to_string(tmpctx, struct channel_id, &cid));
json_add_psbt(response, "psbt", psbt);
json_add_bool(response, "commitments_secured", false);
uc->fc->inflight = true;
was_pending(command_success(cmd, response));
}
static void accepter_commit_received(struct subd *dualopend,
struct uncommitted_channel *uc,
const int *fds,
@ -923,6 +952,155 @@ static void accepter_got_offer(struct subd *dualopend,
plugin_hook_call_openchannel2(dualopend->ld, payload);
}
static struct command_result *json_open_channel_init(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
struct funding_channel *fc = tal(cmd, struct funding_channel);
struct node_id *id;
struct peer *peer;
struct channel *channel;
bool *announce_channel;
u32 *feerate_per_kw_funding;
u32 *feerate_per_kw;
struct amount_sat *amount, psbt_val;
struct wally_psbt *psbt;
u8 *msg = NULL;
fc->cmd = cmd;
fc->cancels = tal_arr(fc, struct command *, 0);
fc->uc = NULL;
fc->inflight = false;
if (!param(fc->cmd, buffer, params,
p_req("id", param_node_id, &id),
p_req("amount", param_sat, &amount),
p_req("initialpsbt", param_psbt, &psbt),
p_opt("commitment_feerate", param_feerate, &feerate_per_kw),
p_opt("funding_feerate", param_feerate, &feerate_per_kw_funding),
p_opt_def("announce", param_bool, &announce_channel, true),
p_opt("close_to", param_bitcoin_address, &fc->our_upfront_shutdown_script),
NULL))
return command_param_failed();
psbt_val = AMOUNT_SAT(0);
for (size_t i = 0; i < psbt->num_inputs; i++) {
struct amount_sat in_amt = psbt_input_get_amount(psbt, i);
if (!amount_sat_add(&psbt_val, psbt_val, in_amt))
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Overflow in adding PSBT input values. %s",
type_to_string(tmpctx, struct wally_psbt, psbt));
}
/* If they don't pass in at least enough in the PSBT to cover
* their amount, nope */
if (!amount_sat_greater(psbt_val, *amount))
return command_fail(cmd, FUND_CANNOT_AFFORD,
"Provided PSBT cannot afford funding of "
"amount %s. %s",
type_to_string(tmpctx, struct amount_sat, amount),
type_to_string(tmpctx, struct wally_psbt, psbt));
fc->funding = *amount;
if (!feerate_per_kw) {
feerate_per_kw = tal(cmd, u32);
/* Anchors exist, set the commitment feerate to min */
*feerate_per_kw = feerate_min(cmd->ld, NULL);
}
if (!feerate_per_kw_funding) {
feerate_per_kw_funding = tal(cmd, u32);
*feerate_per_kw_funding = opening_feerate(cmd->ld->topology);
if (!*feerate_per_kw_funding)
return command_fail(cmd, LIGHTNINGD,
"`funding_feerate` not specified and fee "
"estimation failed");
}
if (!topology_synced(cmd->ld->topology)) {
return command_fail(cmd, FUNDING_STILL_SYNCING_BITCOIN,
"Still syncing with bitcoin network");
}
peer = peer_by_id(cmd->ld, id);
if (!peer) {
return command_fail(cmd, FUNDING_UNKNOWN_PEER, "Unknown peer");
}
channel = peer_active_channel(peer);
if (channel) {
return command_fail(cmd, LIGHTNINGD, "Peer already %s",
channel_state_name(channel));
}
if (!peer->uncommitted_channel) {
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
"Peer not connected");
}
if (peer->uncommitted_channel->fc) {
return command_fail(cmd, LIGHTNINGD, "Already funding channel");
}
#if EXPERIMENTAL_FEATURES
if (!feature_negotiated(cmd->ld->our_features,
peer->their_features,
OPT_DUAL_FUND)) {
return command_fail(cmd, FUNDING_V2_NOT_SUPPORTED,
"v2 openchannel not supported "
"by peer");
}
#endif /* EXPERIMENTAL_FEATURES */
/* BOLT #2:
* - if both nodes advertised `option_support_large_channel`:
* - MAY set `funding_satoshis` greater than or equal to 2^24 satoshi.
* - otherwise:
* - MUST set `funding_satoshis` to less than 2^24 satoshi.
*/
if (!feature_negotiated(cmd->ld->our_features,
peer->their_features, OPT_LARGE_CHANNELS)
&& amount_sat_greater(*amount, chainparams->max_funding))
return command_fail(cmd, FUND_MAX_EXCEEDED,
"Amount exceeded %s",
type_to_string(tmpctx, struct amount_sat,
&chainparams->max_funding));
fc->channel_flags = OUR_CHANNEL_FLAGS;
if (!*announce_channel) {
fc->channel_flags &= ~CHANNEL_FLAGS_ANNOUNCE_CHANNEL;
log_info(peer->ld->log, "Will open private channel with node %s",
type_to_string(fc, struct node_id, id));
}
/* Add serials to any input that's missing them */
psbt_add_serials(psbt, LOCAL);
if (!psbt_has_required_fields(psbt))
return command_fail(cmd, FUNDING_PSBT_INVALID,
"PSBT is missing required fields %s",
type_to_string(tmpctx, struct wally_psbt,
psbt));
peer->uncommitted_channel->fc = tal_steal(peer->uncommitted_channel, fc);
fc->uc = peer->uncommitted_channel;
/* Needs to be stolen away from cmd */
if (fc->our_upfront_shutdown_script)
fc->our_upfront_shutdown_script
= tal_steal(fc, fc->our_upfront_shutdown_script);
msg = towire_dual_open_opener_init(NULL,
psbt, *amount,
fc->our_upfront_shutdown_script,
*feerate_per_kw,
*feerate_per_kw_funding,
fc->channel_flags);
subd_send_msg(peer->uncommitted_channel->open_daemon, take(msg));
return command_still_pending(cmd);
}
static unsigned int dual_opend_msg(struct subd *dualopend,
const u8 *msg, const int *fds)
{
@ -934,7 +1112,17 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
accepter_got_offer(dualopend, uc, msg);
return 0;
case WIRE_DUAL_OPEN_PSBT_CHANGED:
accepter_psbt_changed(dualopend, msg);
if (uc->fc) {
if (!uc->fc->cmd) {
log_unusual(dualopend->log,
"Unexpected PSBT_CHANGED %s",
tal_hex(tmpctx, msg));
tal_free(dualopend);
return 0;
}
opener_psbt_changed(dualopend, uc, msg);
} else
accepter_psbt_changed(dualopend, msg);
return 0;
case WIRE_DUAL_OPEN_COMMIT_RCVD:
if (tal_count(fds) != 3)
@ -946,6 +1134,7 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
/* Messages we send */
case WIRE_DUAL_OPEN_INIT:
case WIRE_DUAL_OPEN_OPENER_INIT:
case WIRE_DUAL_OPEN_GOT_OFFER_REPLY:
case WIRE_DUAL_OPEN_FAIL:
case WIRE_DUAL_OPEN_DEV_MEMLEAK:
@ -971,6 +1160,15 @@ static unsigned int dual_opend_msg(struct subd *dualopend,
return 0;
}
static const struct json_command open_channel_init_command = {
"openchannel_init",
"channels",
json_open_channel_init,
"Init an open channel to {id} with {initialpsbt} for {amount} satoshis. "
"Returns updated {psbt} with (partial) contributions from peer"
};
AUTODATA(json_command, &open_channel_init_command);
void peer_start_dualopend(struct peer *peer,
struct per_peer_state *pps,
const u8 *send_msg)

184
openingd/dualopend.c

@ -1236,6 +1236,186 @@ static u8 *accepter_start(struct state *state, const u8 *oc2_msg)
}
#endif /* EXPERIMENTAL_FEATURES */
static u8 *opener_start(struct state *state, u8 *msg)
{
struct tlv_opening_tlvs *open_tlv;
struct tlv_accept_tlvs *a_tlv;
struct channel_id cid;
char *err_reason;
struct amount_sat total;
struct wally_psbt *psbt;
struct wally_psbt_output *funding_out;
u8 channel_flags;
const u8 *wscript;
u16 serial_id;
struct sha256 podle;
if (!fromwire_dual_open_opener_init(state, msg,
&psbt,
&state->opener_funding,
&state->upfront_shutdown_script[LOCAL],
&state->feerate_per_kw,
&state->feerate_per_kw_funding,
&channel_flags))
master_badmsg(WIRE_DUAL_OPEN_OPENER_INIT, msg);
state->our_role = TX_INITIATOR;
state->tx_locktime = psbt->tx->locktime;
open_tlv = tlv_opening_tlvs_new(tmpctx);
if (state->upfront_shutdown_script[LOCAL]) {
open_tlv->option_upfront_shutdown_script =
tal(open_tlv,
struct tlv_opening_tlvs_option_upfront_shutdown_script);
open_tlv->option_upfront_shutdown_script->shutdown_scriptpubkey =
state->upfront_shutdown_script[LOCAL];
}
/* FIXME: actually set the podle */
memset(&podle, 0, sizeof(podle));
msg = towire_open_channel2(NULL,
&chainparams->genesis_blockhash,
&podle, /* FIXME: podle H2! */
state->feerate_per_kw_funding,
state->opener_funding,
state->localconf.dust_limit,
state->localconf.max_htlc_value_in_flight,
state->localconf.htlc_minimum,
state->feerate_per_kw,
state->localconf.to_self_delay,
state->localconf.max_accepted_htlcs,
state->tx_locktime,
&state->our_funding_pubkey,
&state->our_points.revocation,
&state->our_points.payment,
&state->our_points.delayed_payment,
&state->our_points.htlc,
&state->first_per_commitment_point[LOCAL],
channel_flags,
open_tlv);
sync_crypto_write(state->pps, take(msg));
/* This is usually a very transient state... */
peer_billboard(false, "channel open: offered, waiting for accept_channel2");
/* ... since their reply should be immediate. */
msg = opening_negotiate_msg(tmpctx, state, true);
if (!msg)
return NULL;
/* Set a cid default value, so on failure it's populated */
memset(&cid, 0xFF, sizeof(cid));
a_tlv = tlv_accept_tlvs_new(state);
if (!fromwire_accept_channel2(msg, &cid,
&state->accepter_funding,
&state->remoteconf.dust_limit,
&state->remoteconf.max_htlc_value_in_flight,
&state->remoteconf.htlc_minimum,
&state->minimum_depth,
&state->remoteconf.to_self_delay,
&state->remoteconf.max_accepted_htlcs,
&state->their_funding_pubkey,
&state->their_points.revocation,
&state->their_points.payment,
&state->their_points.delayed_payment,
&state->their_points.htlc,
&state->first_per_commitment_point[REMOTE],
a_tlv))
peer_failed(state->pps, &cid,
"Parsing accept_channel2 %s", tal_hex(msg, msg));
if (a_tlv->option_upfront_shutdown_script) {
state->upfront_shutdown_script[REMOTE] = tal_steal(state,
a_tlv->option_upfront_shutdown_script->shutdown_scriptpubkey);
} else
state->upfront_shutdown_script[REMOTE] = NULL;
derive_channel_id_v2(&state->channel_id,
&state->our_points.revocation,
&state->their_points.revocation);
if (!channel_id_eq(&cid, &state->channel_id))
peer_failed(state->pps, &state->channel_id,
"accept_channel2 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));
/* Check that total funding doesn't overflow */
if (!amount_sat_add(&total, state->opener_funding,
state->accepter_funding))
peer_failed(state->pps, &state->channel_id,
"Amount overflow. Local sats %s. "
"Remote sats %s",
type_to_string(tmpctx, struct amount_sat,
&state->opener_funding),
type_to_string(tmpctx, struct amount_sat,
&state->accepter_funding));
/* Check that total funding doesn't exceed allowed channel capacity */
/* BOLT #2:
*
* The receiving node MUST fail the channel if:
*...
* - `funding_satoshis` is greater than or equal to 2^24 and the receiver does not support
* `option_support_large_channel`. */
/* We choose to require *negotiation*, not just support! */
if (!feature_negotiated(state->our_features, state->their_features,
OPT_LARGE_CHANNELS)
&& amount_sat_greater(total, chainparams->max_funding)) {
negotiation_failed(state, false,
"total funding_satoshis %s too large",
type_to_string(tmpctx, struct amount_sat,
&total));
return NULL;
}
/* BOLT-78de9a79b491ae9fb84b1fdb4546bacf642dce87 #2:
* The sending node:
* - if is the `opener`:
* - MUST send at least one `tx_add_output`, the channel funding output.
*/
wscript = bitcoin_redeem_2of2(state,
&state->our_funding_pubkey,
&state->their_funding_pubkey);
funding_out = psbt_append_output(psbt,
scriptpubkey_p2wsh(tmpctx, wscript),
total);
/* Add a serial_id for this output */
serial_id = 0; /* FIXME: generate new serial */
psbt_output_add_serial_id(psbt, funding_out, serial_id);
/* Add all of our inputs/outputs to the changeset */
init_changeset(state, psbt);
/* Now that we know the total of the channel, we can set the reserve */
set_reserve(state, total);
if (!check_config_bounds(tmpctx, total, state->feerate_per_kw,
state->max_to_self_delay,
state->min_effective_htlc_capacity,
&state->remoteconf,
&state->localconf,
true, true, /* v2 means we use anchor outputs */
&err_reason)) {
negotiation_failed(state, false, "%s", err_reason);
return NULL;
}
/* Send our first message, we're opener we initiate here */
if (send_next(state, &psbt))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Must have at least one update to send");
/* Figure out what the funding transaction looks like! */
if (!run_tx_interactive(state, &psbt))
return NULL;
/* FIXME! */
return NULL;
}
/* Memory leak detection is DEVELOPER-only because we go to great lengths to
* record the backtrace when allocations occur: without that, the leak
* detection tends to be useless for diagnosing where the leak came from, but
@ -1321,9 +1501,11 @@ static u8 *handle_master_in(struct state *state)
handle_dev_memleak(state, msg);
return NULL;
#endif
case WIRE_DUAL_OPEN_OPENER_INIT:
return opener_start(state, msg);
/* mostly handled inline */
case WIRE_DUAL_OPEN_DEV_MEMLEAK_REPLY:
case WIRE_DUAL_OPEN_INIT:
case WIRE_DUAL_OPEN_DEV_MEMLEAK_REPLY:
case WIRE_DUAL_OPEN_FAILED:
case WIRE_DUAL_OPEN_FAIL:
case WIRE_DUAL_OPEN_GOT_OFFER:

12
openingd/dualopend_wire.csv

@ -93,10 +93,20 @@ msgdata,dual_open_psbt_changed,psbt,wally_psbt,
msgtype,dual_open_fail,7003
msgdata,dual_open_fail,reason,wirestring,
# dualopend->master: we failed to negotiation channel
# dualopend->master: we failed to negotiate channel
msgtype,dual_open_failed,7004
msgdata,dual_open_failed,reason,wirestring,
# master->dualopend: hello, I'd like to start a channel open
msgtype,dual_open_opener_init,7200
msgdata,dual_open_opener_init,psbt,wally_psbt,
msgdata,dual_open_opener_init,funding_amount,amount_sat,
msgdata,dual_open_opener_init,local_shutdown_len,u16,
msgdata,dual_open_opener_init,local_shutdown_scriptpubkey,u8,local_shutdown_len
msgdata,dual_open_opener_init,feerate_per_kw,u32,
msgdata,dual_open_opener_init,feerate_per_kw_funding,u32,
msgdata,dual_open_opener_init,channel_flags,u8,
# master -> dualopend: do you have a memleak?
msgtype,dual_open_dev_memleak,7033

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

45
openingd/dualopend_wiregen.c

@ -27,6 +27,7 @@ const char *dualopend_wire_name(int e)
case WIRE_DUAL_OPEN_PSBT_CHANGED: return "WIRE_DUAL_OPEN_PSBT_CHANGED";
case WIRE_DUAL_OPEN_FAIL: return "WIRE_DUAL_OPEN_FAIL";
case WIRE_DUAL_OPEN_FAILED: return "WIRE_DUAL_OPEN_FAILED";
case WIRE_DUAL_OPEN_OPENER_INIT: return "WIRE_DUAL_OPEN_OPENER_INIT";
case WIRE_DUAL_OPEN_DEV_MEMLEAK: return "WIRE_DUAL_OPEN_DEV_MEMLEAK";
case WIRE_DUAL_OPEN_DEV_MEMLEAK_REPLY: return "WIRE_DUAL_OPEN_DEV_MEMLEAK_REPLY";
}
@ -45,6 +46,7 @@ bool dualopend_wire_is_defined(u16 type)
case WIRE_DUAL_OPEN_PSBT_CHANGED:;
case WIRE_DUAL_OPEN_FAIL:;
case WIRE_DUAL_OPEN_FAILED:;
case WIRE_DUAL_OPEN_OPENER_INIT:;
case WIRE_DUAL_OPEN_DEV_MEMLEAK:;
case WIRE_DUAL_OPEN_DEV_MEMLEAK_REPLY:;
return true;
@ -352,7 +354,7 @@ bool fromwire_dual_open_fail(const tal_t *ctx, const void *p, wirestring **reaso
}
/* WIRE: DUAL_OPEN_FAILED */
/* dualopend->master: we failed to negotiation channel */
/* dualopend->master: we failed to negotiate channel */
u8 *towire_dual_open_failed(const tal_t *ctx, const wirestring *reason)
{
u8 *p = tal_arr(ctx, u8, 0);
@ -373,6 +375,45 @@ bool fromwire_dual_open_failed(const tal_t *ctx, const void *p, wirestring **rea
return cursor != NULL;
}
/* WIRE: DUAL_OPEN_OPENER_INIT */
/* master->dualopend: hello */
u8 *towire_dual_open_opener_init(const tal_t *ctx, const struct wally_psbt *psbt, struct amount_sat funding_amount, const u8 *local_shutdown_scriptpubkey, u32 feerate_per_kw, u32 feerate_per_kw_funding, u8 channel_flags)
{
u16 local_shutdown_len = tal_count(local_shutdown_scriptpubkey);
u8 *p = tal_arr(ctx, u8, 0);
towire_u16(&p, WIRE_DUAL_OPEN_OPENER_INIT);
towire_wally_psbt(&p, psbt);
towire_amount_sat(&p, funding_amount);
towire_u16(&p, local_shutdown_len);
towire_u8_array(&p, local_shutdown_scriptpubkey, local_shutdown_len);
towire_u32(&p, feerate_per_kw);
towire_u32(&p, feerate_per_kw_funding);
towire_u8(&p, channel_flags);
return memcheck(p, tal_count(p));
}
bool fromwire_dual_open_opener_init(const tal_t *ctx, const void *p, struct wally_psbt **psbt, struct amount_sat *funding_amount, u8 **local_shutdown_scriptpubkey, u32 *feerate_per_kw, u32 *feerate_per_kw_funding, u8 *channel_flags)
{
u16 local_shutdown_len;
const u8 *cursor = p;
size_t plen = tal_count(p);
if (fromwire_u16(&cursor, &plen) != WIRE_DUAL_OPEN_OPENER_INIT)
return false;
*psbt = fromwire_wally_psbt(ctx, &cursor, &plen);
*funding_amount = fromwire_amount_sat(&cursor, &plen);
local_shutdown_len = fromwire_u16(&cursor, &plen);
// 2nd case local_shutdown_scriptpubkey
*local_shutdown_scriptpubkey = local_shutdown_len ? tal_arr(ctx, u8, local_shutdown_len) : NULL;
fromwire_u8_array(&cursor, &plen, *local_shutdown_scriptpubkey, local_shutdown_len);
*feerate_per_kw = fromwire_u32(&cursor, &plen);
*feerate_per_kw_funding = fromwire_u32(&cursor, &plen);
*channel_flags = fromwire_u8(&cursor, &plen);
return cursor != NULL;
}
/* WIRE: DUAL_OPEN_DEV_MEMLEAK */
/* master -> dualopend: do you have a memleak? */
u8 *towire_dual_open_dev_memleak(const tal_t *ctx)
@ -413,4 +454,4 @@ bool fromwire_dual_open_dev_memleak_reply(const void *p, bool *leak)
*leak = fromwire_bool(&cursor, &plen);
return cursor != NULL;
}
// SHA256STAMP:45ac65939acab987dfb71715f3a03db62863aa2048923666845e2adf45387eba
// SHA256STAMP:4d357681ca9bea1ad36f3fe4d3482a0a12f808dfe20b71f0b9bee78beed0950e

13
openingd/dualopend_wiregen.h

@ -31,8 +31,10 @@ enum dualopend_wire {
WIRE_DUAL_OPEN_PSBT_CHANGED = 7107,
/* master->dualopend: fail this channel open */
WIRE_DUAL_OPEN_FAIL = 7003,
/* dualopend->master: we failed to negotiation channel */
/* dualopend->master: we failed to negotiate channel */
WIRE_DUAL_OPEN_FAILED = 7004,
/* master->dualopend: hello */
WIRE_DUAL_OPEN_OPENER_INIT = 7200,
/* master -> dualopend: do you have a memleak? */
WIRE_DUAL_OPEN_DEV_MEMLEAK = 7033,
WIRE_DUAL_OPEN_DEV_MEMLEAK_REPLY = 7133,
@ -82,10 +84,15 @@ u8 *towire_dual_open_fail(const tal_t *ctx, const wirestring *reason);
bool fromwire_dual_open_fail(const tal_t *ctx, const void *p, wirestring **reason);
/* WIRE: DUAL_OPEN_FAILED */
/* dualopend->master: we failed to negotiation channel */
/* dualopend->master: we failed to negotiate channel */
u8 *towire_dual_open_failed(const tal_t *ctx, const wirestring *reason);
bool fromwire_dual_open_failed(const tal_t *ctx, const void *p, wirestring **reason);
/* WIRE: DUAL_OPEN_OPENER_INIT */
/* master->dualopend: hello */
u8 *towire_dual_open_opener_init(const tal_t *ctx, const struct wally_psbt *psbt, struct amount_sat funding_amount, const u8 *local_shutdown_scriptpubkey, u32 feerate_per_kw, u32 feerate_per_kw_funding, u8 channel_flags);
bool fromwire_dual_open_opener_init(const tal_t *ctx, const void *p, struct wally_psbt **psbt, struct amount_sat *funding_amount, u8 **local_shutdown_scriptpubkey, u32 *feerate_per_kw, u32 *feerate_per_kw_funding, u8 *channel_flags);
/* WIRE: DUAL_OPEN_DEV_MEMLEAK */
/* master -> dualopend: do you have a memleak? */
u8 *towire_dual_open_dev_memleak(const tal_t *ctx);
@ -97,4 +104,4 @@ bool fromwire_dual_open_dev_memleak_reply(const void *p, bool *leak);
#endif /* LIGHTNING_OPENINGD_DUALOPEND_WIREGEN_H */
// SHA256STAMP:45ac65939acab987dfb71715f3a03db62863aa2048923666845e2adf45387eba
// SHA256STAMP:4d357681ca9bea1ad36f3fe4d3482a0a12f808dfe20b71f0b9bee78beed0950e

Loading…
Cancel
Save