funding: add RPC arg to specify a 'close_to' address

Takes advantage of upfront-shutdown-script to permit users to
specify the close-to address for a channel at open, by adding
a `close_to` field to `fundchannel_start`.

Note that this only is in effect if `fundchannel_start` returns
with `close_to` set -- otherwise, peer doesn't
support `option_upfront_shutdown_script`.
This commit is contained in:
lisa neigut
2019-10-15 11:38:33 +10:30
committed by neil saitug
parent 624b76e32e
commit 422b4502d3
10 changed files with 141 additions and 118 deletions

View File

@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- JSON API: `fundchannel_start` now includes field `scriptpubkey` - JSON API: `fundchannel_start` now includes field `scriptpubkey`
- JSON API: New method `listtransactions` - JSON API: New method `listtransactions`
- JSON API: `signmessage` will now create a signature from your node on a message; `checkmessage` will verify it. - JSON API: `signmessage` will now create a signature from your node on a message; `checkmessage` will verify it.
- JSON API: `fundchannel_start` now accepts an optional parameter `close_to`, the address to which these channel funds should be sent to on close. Returns `using_close_to` if will use.
- Plugin: new notifications `sendpay_success` and `sendpay_failure`. - Plugin: new notifications `sendpay_success` and `sendpay_failure`.
- Protocol: nodes now announce features in `node_announcement` broadcasts. - Protocol: nodes now announce features in `node_announcement` broadcasts.
- Protocol: we now offer `option_gossip_queries_ex` for finegrained gossip control. - Protocol: we now offer `option_gossip_queries_ex` for finegrained gossip control.

View File

@@ -568,12 +568,13 @@ class LightningRpc(UnixDomainSocketRpc):
if 'satoshi' in kwargs: if 'satoshi' in kwargs:
return self._deprecated_fundchannel_start(node_id, *args, **kwargs) return self._deprecated_fundchannel_start(node_id, *args, **kwargs)
def _fundchannel_start(node_id, amount, feerate=None, announce=True): def _fundchannel_start(node_id, amount, feerate=None, announce=True, close_to=None):
payload = { payload = {
"id": node_id, "id": node_id,
"amount": amount, "amount": amount,
"feerate": feerate, "feerate": feerate,
"announce": announce "announce": announce,
"close_to": close_to,
} }
return self.call("fundchannel_start", payload) return self.call("fundchannel_start", payload)

View File

@@ -3,7 +3,7 @@
lightning-fundchannel_start - Command for initiating channel establishment for a lightning channel lightning-fundchannel_start - Command for initiating channel establishment for a lightning channel
.SH SYNOPSIS .SH SYNOPSIS
\fBfundchannel_start\fR \fIid\fR \fIamount\fR [\fIfeerate\fR \fIannounce\fR] \fBfundchannel_start\fR \fIid\fR \fIamount\fR [\fIfeerate\fR \fIannounce\fR \fIclose_to\fR]
.SH DESCRIPTION .SH DESCRIPTION
@@ -26,6 +26,11 @@ commitment transactions\.
\fIannounce\fR whether or not to announce this channel\. \fIannounce\fR whether or not to announce this channel\.
\fIclose_to\fR is a Bitcoin address to which the channel funds should be sent to
on close\. Only valid if both peers have negotiated \fBoption_upfront_shutdown_script\fR\.
Returns \fBclose_to\fR set to closing script iff is negotiated\.
Note that the funding transaction MUST NOT be broadcast until after Note that the funding transaction MUST NOT be broadcast until after
channel establishment has been successfully completed by running channel establishment has been successfully completed by running
\fBfundchannel_complete\fR, as the commitment transactions for this channel \fBfundchannel_complete\fR, as the commitment transactions for this channel
@@ -35,6 +40,8 @@ transaction before that can lead to unrecoverable loss of funds\.
.SH RETURN VALUE .SH RETURN VALUE
On success, returns the \fIfunding_address\fR and the \fIscriptpubkey\fR for the channel funding output\. On success, returns the \fIfunding_address\fR and the \fIscriptpubkey\fR for the channel funding output\.
If a \fBclose_to\fR address was provided, will close to this address iff the \fBclose_to\fR address is
returned in the response\. Otherwise, the peer does not support \fBoption_upfront_shutdownscript\fR\.
On failure, returns an error\. On failure, returns an error\.
@@ -52,7 +59,3 @@ lightning-fundchannel_\fBcomplete\fR(7), lightning-fundchannel_\fBcancel\fR(7)
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
.HL
Last updated 2019-06-12 11:16:20 CEST

View File

@@ -4,7 +4,7 @@ lightning-fundchannel\_start -- Command for initiating channel establishment for
SYNOPSIS SYNOPSIS
-------- --------
**fundchannel\_start** *id* *amount* \[*feerate* *announce*\] **fundchannel\_start** *id* *amount* \[*feerate* *announce* *close_to*\]
DESCRIPTION DESCRIPTION
----------- -----------
@@ -23,6 +23,10 @@ commitment transactions.
*announce* whether or not to announce this channel. *announce* whether or not to announce this channel.
*close_to* is a Bitcoin address to which the channel funds should be sent to
on close. Only valid if both peers have negotiated `option_upfront_shutdown_script`.
Returns `close_to` set to closing script iff is negotiated.
Note that the funding transaction MUST NOT be broadcast until after Note that the funding transaction MUST NOT be broadcast until after
channel establishment has been successfully completed by running channel establishment has been successfully completed by running
`fundchannel_complete`, as the commitment transactions for this channel `fundchannel_complete`, as the commitment transactions for this channel
@@ -33,6 +37,8 @@ RETURN VALUE
------------ ------------
On success, returns the *funding\_address* and the *scriptpubkey* for the channel funding output. On success, returns the *funding\_address* and the *scriptpubkey* for the channel funding output.
If a `close_to` address was provided, will close to this address iff the `close_to` address is
returned in the response. Otherwise, the peer does not support `option_upfront_shutdownscript`.
On failure, returns an error. On failure, returns an error.

View File

@@ -170,7 +170,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
const struct channel_info *channel_info, const struct channel_info *channel_info,
/* NULL or stolen */ /* NULL or stolen */
u8 *remote_shutdown_scriptpubkey, u8 *remote_shutdown_scriptpubkey,
u8 *local_shutdown_scriptpubkey, const u8 *local_shutdown_scriptpubkey,
u64 final_key_idx, u64 final_key_idx,
bool last_was_revoke, bool last_was_revoke,
/* NULL or stolen */ /* NULL or stolen */

View File

@@ -89,8 +89,8 @@ struct channel {
/* Our funding tx pubkey. */ /* Our funding tx pubkey. */
struct pubkey local_funding_pubkey; struct pubkey local_funding_pubkey;
/* Their scriptpubkey if they sent shutdown. */ /* scriptpubkey for shutdown, if applicable. */
u8 *shutdown_scriptpubkey[NUM_SIDES]; const u8 *shutdown_scriptpubkey[NUM_SIDES];
/* Address for any final outputs */ /* Address for any final outputs */
u64 final_key_idx; u64 final_key_idx;
@@ -157,7 +157,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
const struct channel_info *channel_info, const struct channel_info *channel_info,
/* NULL or stolen */ /* NULL or stolen */
u8 *remote_shutdown_scriptpubkey, u8 *remote_shutdown_scriptpubkey,
u8 *local_shutdown_scriptpubkey, const u8 *local_shutdown_scriptpubkey,
u64 final_key_idx, u64 final_key_idx,
bool last_was_revoke, bool last_was_revoke,
/* NULL or stolen */ /* NULL or stolen */

View File

@@ -77,6 +77,7 @@ struct funding_channel {
struct amount_msat push; struct amount_msat push;
struct amount_sat funding; struct amount_sat funding;
u8 channel_flags; u8 channel_flags;
const u8 *our_upfront_shutdown_script;
/* Variables we need to compose fields in cmd's response */ /* Variables we need to compose fields in cmd's response */
const char *hextx; const char *hextx;
@@ -165,6 +166,7 @@ wallet_commit_channel(struct lightningd *ld,
u8 channel_flags, u8 channel_flags,
struct channel_info *channel_info, struct channel_info *channel_info,
u32 feerate, u32 feerate,
const u8 *our_upfront_shutdown_script,
const u8 *remote_upfront_shutdown_script) const u8 *remote_upfront_shutdown_script)
{ {
struct channel *channel; struct channel *channel;
@@ -247,7 +249,7 @@ wallet_commit_channel(struct lightningd *ld,
NULL, /* No HTLC sigs yet */ NULL, /* No HTLC sigs yet */
channel_info, channel_info,
NULL, /* No shutdown_scriptpubkey[REMOTE] yet */ NULL, /* No shutdown_scriptpubkey[REMOTE] yet */
NULL, /* No shutdown_scriptpubkey[LOCAL] yet. Generate the default one. */ our_upfront_shutdown_script,
final_key_idx, false, final_key_idx, false,
NULL, /* No commit sent yet */ NULL, /* No commit sent yet */
/* If we're fundee, could be a little before this /* If we're fundee, could be a little before this
@@ -290,7 +292,8 @@ static void funding_success(struct channel *channel)
} }
static void funding_started_success(struct funding_channel *fc, static void funding_started_success(struct funding_channel *fc,
u8 *scriptPubkey) u8 *scriptPubkey,
bool supports_shutdown)
{ {
struct json_stream *response; struct json_stream *response;
struct command *cmd = fc->cmd; struct command *cmd = fc->cmd;
@@ -303,6 +306,8 @@ static void funding_started_success(struct funding_channel *fc,
if (out) { if (out) {
json_add_string(response, "funding_address", out); json_add_string(response, "funding_address", out);
json_add_hex_talarr(response, "scriptpubkey", scriptPubkey); json_add_hex_talarr(response, "scriptpubkey", scriptPubkey);
if (fc->our_upfront_shutdown_script)
json_add_hex_talarr(response, "close_to", fc->our_upfront_shutdown_script);
} }
/* Clear this so cancel doesn't think it's still in progress */ /* Clear this so cancel doesn't think it's still in progress */
@@ -315,9 +320,11 @@ static void opening_funder_start_replied(struct subd *openingd, const u8 *resp,
struct funding_channel *fc) struct funding_channel *fc)
{ {
u8 *funding_scriptPubkey; u8 *funding_scriptPubkey;
bool supports_shutdown_script;
if (!fromwire_opening_funder_start_reply(resp, resp, if (!fromwire_opening_funder_start_reply(resp, resp,
&funding_scriptPubkey)) { &funding_scriptPubkey,
&supports_shutdown_script)) {
log_broken(fc->uc->log, log_broken(fc->uc->log,
"bad OPENING_FUNDER_REPLY %s", "bad OPENING_FUNDER_REPLY %s",
tal_hex(resp, resp)); tal_hex(resp, resp));
@@ -327,7 +334,12 @@ static void opening_funder_start_replied(struct subd *openingd, const u8 *resp,
goto failed; goto failed;
} }
funding_started_success(fc, funding_scriptPubkey); /* If we're not using the upfront shutdown script, forget it */
if (!supports_shutdown_script)
fc->our_upfront_shutdown_script =
tal_free(fc->our_upfront_shutdown_script);
funding_started_success(fc, funding_scriptPubkey, supports_shutdown_script);
/* Mark that we're in-flight */ /* Mark that we're in-flight */
fc->inflight = true; fc->inflight = true;
@@ -401,6 +413,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
fc->channel_flags, fc->channel_flags,
&channel_info, &channel_info,
feerate, feerate,
fc->our_upfront_shutdown_script,
remote_upfront_shutdown_script); remote_upfront_shutdown_script);
if (!channel) { if (!channel) {
was_pending(command_fail(fc->cmd, LIGHTNINGD, was_pending(command_fail(fc->cmd, LIGHTNINGD,
@@ -496,6 +509,7 @@ static void opening_fundee_finished(struct subd *openingd,
channel_flags, channel_flags,
&channel_info, &channel_info,
feerate, feerate,
NULL,
remote_upfront_shutdown_script); remote_upfront_shutdown_script);
if (!channel) { if (!channel) {
uncommitted_channel_disconnect(uc, "Commit channel failed"); uncommitted_channel_disconnect(uc, "Commit channel failed");
@@ -1078,6 +1092,7 @@ static struct command_result *json_fund_channel_start(struct command *cmd,
p_req("amount", param_sat, &amount), p_req("amount", param_sat, &amount),
p_opt("feerate", param_feerate, &feerate_per_kw), p_opt("feerate", param_feerate, &feerate_per_kw),
p_opt_def("announce", param_bool, &announce_channel, true), p_opt_def("announce", param_bool, &announce_channel, true),
p_opt("close_to", param_bitcoin_address, &fc->our_upfront_shutdown_script),
NULL)) NULL))
return command_param_failed(); return command_param_failed();
} else { } else {
@@ -1101,6 +1116,9 @@ static struct command_result *json_fund_channel_start(struct command *cmd,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Need set 'amount' field"); "Need set 'amount' field");
} }
/* No upfront shutdown script option for deprecated API */
fc->our_upfront_shutdown_script = NULL;
} }
if (amount_sat_greater(*amount, max_funding_satoshi)) if (amount_sat_greater(*amount, max_funding_satoshi))
@@ -1161,9 +1179,15 @@ static struct command_result *json_fund_channel_start(struct command *cmd,
peer->uncommitted_channel->fc = tal_steal(peer->uncommitted_channel, fc); peer->uncommitted_channel->fc = tal_steal(peer->uncommitted_channel, fc);
fc->uc = peer->uncommitted_channel; 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_opening_funder_start(NULL, msg = towire_opening_funder_start(NULL,
*amount, *amount,
fc->push, fc->push,
fc->our_upfront_shutdown_script,
*feerate_per_kw, *feerate_per_kw,
fc->channel_flags); fc->channel_flags);

View File

@@ -1288,9 +1288,9 @@ static struct command_result *json_close(struct command *cmd,
unsigned int *timeout = NULL; unsigned int *timeout = NULL;
bool force = true; bool force = true;
bool do_timeout; bool do_timeout;
const u8 *local_shutdown_script = NULL; const u8 *close_to_script = NULL;
unsigned int *old_timeout; unsigned int *old_timeout;
bool *old_force; bool *old_force, close_script_set;
/* For generating help, give new-style. */ /* For generating help, give new-style. */
if (!params || !deprecated_apis) { if (!params || !deprecated_apis) {
@@ -1299,7 +1299,7 @@ static struct command_result *json_close(struct command *cmd,
p_opt_def("unilateraltimeout", param_number, p_opt_def("unilateraltimeout", param_number,
&timeout, 48 * 3600), &timeout, 48 * 3600),
p_opt("destination", param_bitcoin_address, p_opt("destination", param_bitcoin_address,
&local_shutdown_script), &close_to_script),
NULL)) NULL))
return command_param_failed(); return command_param_failed();
do_timeout = (*timeout != 0); do_timeout = (*timeout != 0);
@@ -1345,7 +1345,7 @@ static struct command_result *json_close(struct command *cmd,
res = json_to_address_scriptpubkey(cmd, res = json_to_address_scriptpubkey(cmd,
get_chainparams(cmd->ld), get_chainparams(cmd->ld),
buffer, secondtok, buffer, secondtok,
&local_shutdown_script); &close_to_script);
if (res == ADDRESS_PARSE_UNRECOGNIZED) if (res == ADDRESS_PARSE_UNRECOGNIZED)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Could not parse destination address"); "Could not parse destination address");
@@ -1368,7 +1368,7 @@ static struct command_result *json_close(struct command *cmd,
res = json_to_address_scriptpubkey(cmd, res = json_to_address_scriptpubkey(cmd,
get_chainparams(cmd->ld), get_chainparams(cmd->ld),
buffer, secondtok, buffer, secondtok,
&local_shutdown_script); &close_to_script);
if (res == ADDRESS_PARSE_UNRECOGNIZED) if (res == ADDRESS_PARSE_UNRECOGNIZED)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Could not parse destination address"); "Could not parse destination address");
@@ -1397,14 +1397,14 @@ static struct command_result *json_close(struct command *cmd,
p_opt_def("unilateraltimeout", param_number, p_opt_def("unilateraltimeout", param_number,
&timeout, 48 * 3600), &timeout, 48 * 3600),
p_opt("destination", param_bitcoin_address, p_opt("destination", param_bitcoin_address,
&local_shutdown_script), &close_to_script),
p_opt("force", param_bool, &old_force), p_opt("force", param_bool, &old_force),
p_opt("timeout", param_number, &old_timeout), p_opt("timeout", param_number, &old_timeout),
NULL)) NULL))
return command_param_failed(); return command_param_failed();
/* Old style has lower priority. */ /* Old style has lower priority. */
if (!local_shutdown_script) { if (!close_to_script) {
/* Old style. */ /* Old style. */
if (old_timeout) { if (old_timeout) {
*timeout = *old_timeout; *timeout = *old_timeout;
@@ -1446,6 +1446,45 @@ static struct command_result *json_close(struct command *cmd,
"Peer has no active channel"); "Peer has no active channel");
} }
/* If we've set a local shutdown script for this peer, and it's not the
* default upfront script, try to close to a different channel.
* Error is an operator error */
if (close_to_script && channel->shutdown_scriptpubkey[LOCAL]
&& !memeq(close_to_script,
tal_count(close_to_script),
channel->shutdown_scriptpubkey[LOCAL],
tal_count(channel->shutdown_scriptpubkey[LOCAL]))) {
u8 *default_close_to = p2wpkh_for_keyidx(tmpctx, cmd->ld,
channel->final_key_idx);
if (!memeq(default_close_to, tal_count(default_close_to),
channel->shutdown_scriptpubkey[LOCAL],
tal_count(channel->shutdown_scriptpubkey[LOCAL]))) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Destination address %s does not match "
"previous shutdown script %s",
tal_hex(tmpctx, channel->shutdown_scriptpubkey[LOCAL]),
tal_hex(tmpctx, close_to_script));
} else {
channel->shutdown_scriptpubkey[LOCAL] =
tal_free(channel->shutdown_scriptpubkey[LOCAL]);
channel->shutdown_scriptpubkey[LOCAL] =
tal_steal(channel, close_to_script);
close_script_set = true;
}
} else if (close_to_script && !channel->shutdown_scriptpubkey[LOCAL]) {
channel->shutdown_scriptpubkey[LOCAL]
= tal_steal(channel, cast_const(u8 *, close_to_script));
close_script_set = true;
} else if (!channel->shutdown_scriptpubkey[LOCAL]) {
channel->shutdown_scriptpubkey[LOCAL]
= p2wpkh_for_keyidx(channel, cmd->ld, channel->final_key_idx);
/* We don't save the default to disk */
close_script_set = false;
} else
close_script_set = false;
/* Normal case. /* Normal case.
* We allow states shutting down and sigexchange; a previous * We allow states shutting down and sigexchange; a previous
* close command may have timed out, and this current command * close command may have timed out, and this current command
@@ -1456,95 +1495,33 @@ static struct command_result *json_close(struct command *cmd,
* state. * state.
* (if already shutting down or sigexchange, just keep * (if already shutting down or sigexchange, just keep
* waiting) */ * waiting) */
if (channel->state == CHANNELD_NORMAL || channel->state == CHANNELD_AWAITING_LOCKIN) { switch (channel->state) {
/* Change the channel state first. */ case CHANNELD_NORMAL:
case CHANNELD_AWAITING_LOCKIN:
channel_set_state(channel, channel_set_state(channel,
channel->state, CHANNELD_SHUTTING_DOWN); channel->state, CHANNELD_SHUTTING_DOWN);
/* fallthrough */
/* FIXME: When we support local upfront_shutdown_script, local_shutdown_script case CHANNELD_SHUTTING_DOWN:
* must equal to the local upfront_shutdown_script. */
if (local_shutdown_script) {
tal_free(channel->shutdown_scriptpubkey[LOCAL]);
channel->shutdown_scriptpubkey[LOCAL]
= tal_steal(channel, cast_const(u8 *, local_shutdown_script));
}
if (channel->owner) if (channel->owner)
subd_send_msg(channel->owner, subd_send_msg(channel->owner,
take(towire_channel_send_shutdown(NULL, take(towire_channel_send_shutdown(NULL,
channel->shutdown_scriptpubkey[LOCAL]))); channel->shutdown_scriptpubkey[LOCAL])));
} else if (channel->state == CHANNELD_SHUTTING_DOWN) { break;
/* FIXME: Add to spec that we must allow repeated shutdown! */ case CLOSINGD_SIGEXCHANGE:
if (!local_shutdown_script) break;
local_shutdown_script = p2wpkh_for_keyidx(channel, default:
cmd->ld,
channel->final_key_idx);
bool change_script = !memeq(local_shutdown_script,
tal_count(local_shutdown_script),
channel->shutdown_scriptpubkey[LOCAL],
tal_count(channel->shutdown_scriptpubkey[LOCAL]));
if (change_script) {
log_debug(channel->log, "Repeated close command: "
"the new local scriptpubkey is %s, "
"and the old local scriptpubkey is %s",
local_shutdown_script,
channel->shutdown_scriptpubkey[LOCAL]);
if (!channel->owner)
return command_fail(cmd, LIGHTNINGD,
"The sub-daemon of channel is down(state %s), "
"can't change to-local destination "
"from %s to %s",
channel_state_name(channel),
channel->shutdown_scriptpubkey[LOCAL],
local_shutdown_script);
}
tal_free(channel->shutdown_scriptpubkey[LOCAL]);
channel->shutdown_scriptpubkey[LOCAL]
= tal_steal(channel, cast_const(u8 *, local_shutdown_script));
if (channel->owner)
subd_send_msg(channel->owner,
take(towire_channel_send_shutdown(NULL,
channel->shutdown_scriptpubkey[LOCAL])));
} else if (channel->state == CLOSINGD_SIGEXCHANGE) {
u8 *default_script = p2wpkh_for_keyidx(tmpctx, cmd->ld,
channel->final_key_idx);
bool is_default = memeq(default_script,
tal_count(default_script),
channel->shutdown_scriptpubkey[LOCAL],
tal_count(channel->shutdown_scriptpubkey[LOCAL]));
if (!local_shutdown_script) {
/* Means the user want to send to default address. */
local_shutdown_script = p2wpkh_for_keyidx(tmpctx, cmd->ld,
channel->final_key_idx);
}
if (!memeq(local_shutdown_script,
tal_count(local_shutdown_script),
channel->shutdown_scriptpubkey[LOCAL],
tal_count(channel->shutdown_scriptpubkey[LOCAL])))
return command_fail(cmd, LIGHTNINGD,
"Channel has already been closing now (in state %s) "
"with to-local destination %s",
channel_state_name(channel),
is_default ?
tal_fmt(tmpctx, "(default) %s",
channel->shutdown_scriptpubkey[LOCAL]) :
(char *)channel->shutdown_scriptpubkey[LOCAL]);
} else
return command_fail(cmd, LIGHTNINGD, "Channel is in state %s", return command_fail(cmd, LIGHTNINGD, "Channel is in state %s",
channel_state_name(channel)); channel_state_name(channel));
}
/* Register this command for later handling. */ /* Register this command for later handling. */
register_close_command(cmd->ld, cmd, channel, register_close_command(cmd->ld, cmd, channel,
do_timeout ? timeout : NULL, force); do_timeout ? timeout : NULL, force);
/* We may set new `channel->shutdown_scriptpubkey[LOCAL]` field. Save it. */ /* If we set `channel->shutdown_scriptpubkey[LOCAL]`, save it. */
if (close_script_set)
wallet_channel_save(cmd->ld->wallet, channel); wallet_channel_save(cmd->ld->wallet, channel);
/* Wait until close drops down to chain. */ /* Wait until close drops down to chain. */
return command_still_pending(cmd); return command_still_pending(cmd);
} }

View File

@@ -65,11 +65,12 @@ msgdata,opening_funder_reply,our_channel_reserve_satoshis,amount_sat,
msgdata,opening_funder_reply,shutdown_len,u16, msgdata,opening_funder_reply,shutdown_len,u16,
msgdata,opening_funder_reply,shutdown_scriptpubkey,u8,shutdown_len msgdata,opening_funder_reply,shutdown_scriptpubkey,u8,shutdown_len
# master->openingd: start channel establishment for a funding # master->openingd: start channel establishment for a funding tx
# tx that will be paid for by an external wallet
msgtype,opening_funder_start,6002 msgtype,opening_funder_start,6002
msgdata,opening_funder_start,funding_satoshis,amount_sat, msgdata,opening_funder_start,funding_satoshis,amount_sat,
msgdata,opening_funder_start,push_msat,amount_msat, msgdata,opening_funder_start,push_msat,amount_msat,
msgdata,opening_funder_start,len_upfront,u16,
msgdata,opening_funder_start,upfront_shutdown_script,u8,len_upfront
msgdata,opening_funder_start,feerate_per_kw,u32, msgdata,opening_funder_start,feerate_per_kw,u32,
msgdata,opening_funder_start,channel_flags,u8, msgdata,opening_funder_start,channel_flags,u8,
@@ -77,6 +78,7 @@ msgdata,opening_funder_start,channel_flags,u8,
msgtype,opening_funder_start_reply,6102 msgtype,opening_funder_start_reply,6102
msgdata,opening_funder_start_reply,script_len,u8, msgdata,opening_funder_start_reply,script_len,u8,
msgdata,opening_funder_start_reply,scriptpubkey,u8,script_len msgdata,opening_funder_start_reply,scriptpubkey,u8,script_len
msgdata,opening_funder_start_reply,upfront_shutdown_negotiated,bool,
# master->openingd: complete channel establishment for a funding # master->openingd: complete channel establishment for a funding
# tx that will be paid for by an external wallet # tx that will be paid for by an external wallet
1 #include <common/cryptomsg.h>
65 # tx that will be paid for by an external wallet msgtype,opening_funder_start,6002
66 msgtype,opening_funder_start,6002 msgdata,opening_funder_start,funding_satoshis,amount_sat,
67 msgdata,opening_funder_start,funding_satoshis,amount_sat, msgdata,opening_funder_start,push_msat,amount_msat,
68 msgdata,opening_funder_start,push_msat,amount_msat, msgdata,opening_funder_start,len_upfront,u16,
msgdata,opening_funder_start,feerate_per_kw,u32,
69 msgdata,opening_funder_start,channel_flags,u8, msgdata,opening_funder_start,upfront_shutdown_script,u8,len_upfront
70 # openingd->master: send back output script for 2-of-2 funding output msgdata,opening_funder_start,feerate_per_kw,u32,
71 msgtype,opening_funder_start_reply,6102 msgdata,opening_funder_start,channel_flags,u8,
72 # openingd->master: send back output script for 2-of-2 funding output
73 msgtype,opening_funder_start_reply,6102
74 msgdata,opening_funder_start_reply,script_len,u8,
75 msgdata,opening_funder_start_reply,scriptpubkey,u8,script_len
76 # master->openingd: complete channel establishment for a funding msgdata,opening_funder_start_reply,upfront_shutdown_negotiated,bool,
78 # response to this is a normal `opening_funder_reply` ?? # tx that will be paid for by an external wallet
79 msgtype,opening_funder_complete,6012 # response to this is a normal `opening_funder_reply` ??
80 msgdata,opening_funder_complete,funding_txid,bitcoin_txid, msgtype,opening_funder_complete,6012
81 msgdata,opening_funder_complete,funding_txid,bitcoin_txid,
82 msgdata,opening_funder_complete,funding_txout,u16,
83 #master->openingd: cancel channel establishment for a funding
84 msgtype,opening_funder_cancel,6013

View File

@@ -108,7 +108,7 @@ struct state {
bool option_static_remotekey; bool option_static_remotekey;
}; };
static const u8 *dev_upfront_shutdown_script(const tal_t *ctx) static u8 *dev_upfront_shutdown_script(const tal_t *ctx)
{ {
#if DEVELOPER #if DEVELOPER
/* This is a hack, for feature testing */ /* This is a hack, for feature testing */
@@ -485,6 +485,7 @@ static bool setup_channel_funder(struct state *state)
/* We start the 'fund a channel' negotation with the supplied peer, but /* We start the 'fund a channel' negotation with the supplied peer, but
* stop when we get to the part where we need the funding txid */ * stop when we get to the part where we need the funding txid */
static u8 *funder_channel_start(struct state *state, static u8 *funder_channel_start(struct state *state,
u8 *our_upfront_shutdown_script,
u8 channel_flags) u8 channel_flags)
{ {
u8 *msg; u8 *msg;
@@ -504,8 +505,9 @@ static u8 *funder_channel_start(struct state *state,
* - otherwise: * - otherwise:
* - MAY include a`shutdown_scriptpubkey`. * - MAY include a`shutdown_scriptpubkey`.
*/ */
/* We don't use shutdown_scriptpubkey (at least for now), so leave it if (!our_upfront_shutdown_script)
* NULL. */ our_upfront_shutdown_script = dev_upfront_shutdown_script(tmpctx);
msg = towire_open_channel_option_upfront_shutdown_script(NULL, msg = towire_open_channel_option_upfront_shutdown_script(NULL,
&state->chainparams->genesis_blockhash, &state->chainparams->genesis_blockhash,
&state->channel_id, &state->channel_id,
@@ -525,7 +527,7 @@ static u8 *funder_channel_start(struct state *state,
&state->our_points.htlc, &state->our_points.htlc,
&state->first_per_commitment_point[LOCAL], &state->first_per_commitment_point[LOCAL],
channel_flags, channel_flags,
dev_upfront_shutdown_script(tmpctx)); our_upfront_shutdown_script);
sync_crypto_write(state->pps, take(msg)); sync_crypto_write(state->pps, take(msg));
/* This is usually a very transient state... */ /* This is usually a very transient state... */
@@ -626,7 +628,12 @@ static u8 *funder_channel_start(struct state *state,
peer_billboard(false, peer_billboard(false,
"Funding channel start: awaiting funding_txid with output to %s", "Funding channel start: awaiting funding_txid with output to %s",
tal_hex(tmpctx, funding_output_script)); tal_hex(tmpctx, funding_output_script));
return towire_opening_funder_start_reply(state, funding_output_script);
return towire_opening_funder_start_reply(state,
funding_output_script,
feature_negotiated(
state->features,
OPT_UPFRONT_SHUTDOWN_SCRIPT));
} }
static bool funder_finalize_channel_setup(struct state *state, static bool funder_finalize_channel_setup(struct state *state,
@@ -1341,18 +1348,20 @@ static u8 *handle_master_in(struct state *state)
{ {
u8 *msg = wire_sync_read(tmpctx, REQ_FD); u8 *msg = wire_sync_read(tmpctx, REQ_FD);
enum opening_wire_type t = fromwire_peektype(msg); enum opening_wire_type t = fromwire_peektype(msg);
u8 channel_flags; u8 channel_flags, *upfront_shutdown_script;
struct bitcoin_txid funding_txid; struct bitcoin_txid funding_txid;
u16 funding_txout; u16 funding_txout;
switch (t) { switch (t) {
case WIRE_OPENING_FUNDER_START: case WIRE_OPENING_FUNDER_START:
if (!fromwire_opening_funder_start(msg, &state->funding, if (!fromwire_opening_funder_start(tmpctx, msg, &state->funding,
&state->push_msat, &state->push_msat,
&upfront_shutdown_script,
&state->feerate_per_kw, &state->feerate_per_kw,
&channel_flags)) &channel_flags))
master_badmsg(WIRE_OPENING_FUNDER_START, msg); master_badmsg(WIRE_OPENING_FUNDER_START, msg);
msg = funder_channel_start(state, channel_flags); msg = funder_channel_start(state, upfront_shutdown_script,
channel_flags);
/* We want to keep openingd alive, since we're not done yet */ /* We want to keep openingd alive, since we're not done yet */
if (msg) if (msg)