mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-05 07:14:36 +01:00
opening: wire up walking through open channel up thru accept
Fill in details to make fundchannel_start work.
This commit is contained in:
committed by
Rusty Russell
parent
685aa47b65
commit
5920e656cf
@@ -282,11 +282,50 @@ static void funding_broadcast_failed_or_success(struct channel *channel,
|
||||
}
|
||||
}
|
||||
|
||||
static void opening_funder_start_finished(struct subd *openingd, const u8 *resp,
|
||||
const int *fds,
|
||||
struct funding_channel *fc)
|
||||
static void funding_started_success(struct funding_channel *fc,
|
||||
u8 *scriptPubkey)
|
||||
{
|
||||
// todo: this.
|
||||
struct json_stream *response;
|
||||
struct command *cmd = fc->cmd;
|
||||
char *out;
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_object_start(response, NULL);
|
||||
out = encode_scriptpubkey_to_addr(cmd,
|
||||
get_chainparams(cmd->ld)->bip173_name,
|
||||
scriptPubkey);
|
||||
if (out)
|
||||
json_add_string(response, "funding_address", out);
|
||||
json_object_end(response);
|
||||
was_pending(command_success(cmd, response));
|
||||
}
|
||||
|
||||
static void opening_funder_start_replied(struct subd *openingd, const u8 *resp,
|
||||
const int *fds,
|
||||
struct funding_channel *fc)
|
||||
{
|
||||
u8 *funding_scriptPubkey;
|
||||
|
||||
if (!fromwire_opening_funder_start_reply(resp, resp,
|
||||
&funding_scriptPubkey)) {
|
||||
log_broken(fc->uc->log,
|
||||
"bad OPENING_FUNDER_REPLY %s",
|
||||
tal_hex(resp, resp));
|
||||
was_pending(command_fail(fc->cmd, LIGHTNINGD,
|
||||
"bad OPENING_FUNDER_REPLY %s",
|
||||
tal_hex(fc->cmd, resp)));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// FIXME: save the peer to the database?
|
||||
funding_started_success(fc, funding_scriptPubkey);
|
||||
return;
|
||||
|
||||
failed:
|
||||
subd_release_channel(openingd, fc->uc);
|
||||
fc->uc->openingd = NULL;
|
||||
/* Frees fc too, and tmpctx */
|
||||
tal_free(fc->uc);
|
||||
}
|
||||
|
||||
static void opening_funder_finished(struct subd *openingd, const u8 *resp,
|
||||
@@ -903,7 +942,7 @@ static unsigned int openingd_msg(struct subd *openingd,
|
||||
tal_free(openingd);
|
||||
return 0;
|
||||
}
|
||||
opening_funder_start_finished(openingd, msg, fds, uc->fc);
|
||||
opening_funder_start_replied(openingd, msg, fds, uc->fc);
|
||||
return 0;
|
||||
case WIRE_OPENING_FUNDER_FAILED:
|
||||
if (!uc->fc) {
|
||||
|
||||
@@ -472,7 +472,145 @@ static bool setup_channel_funder(struct state *state)
|
||||
static u8 *funder_channel_start(struct state *state,
|
||||
u8 channel_flags)
|
||||
{
|
||||
return towire_opening_funder_start_reply(state, NULL);
|
||||
struct channel_id id_in;
|
||||
u8 *msg;
|
||||
struct basepoints theirs;
|
||||
struct pubkey their_funding_pubkey;
|
||||
u32 minimum_depth;
|
||||
u8 *funding_output_script;
|
||||
|
||||
if (!setup_channel_funder(state))
|
||||
return NULL;
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* - if both nodes advertised the `option_upfront_shutdown_script`
|
||||
* feature:
|
||||
* - MUST include either a valid `shutdown_scriptpubkey` as required
|
||||
* by `shutdown` `scriptpubkey`, or a zero-length
|
||||
* `shutdown_scriptpubkey`.
|
||||
* - otherwise:
|
||||
* - MAY include a`shutdown_scriptpubkey`.
|
||||
*/
|
||||
/* We don't use shutdown_scriptpubkey (at least for now), so leave it
|
||||
* NULL. */
|
||||
msg = towire_open_channel_option_upfront_shutdown_script(NULL,
|
||||
&state->chainparams->genesis_blockhash,
|
||||
&state->channel_id,
|
||||
state->funding,
|
||||
state->push_msat,
|
||||
state->localconf.dust_limit,
|
||||
state->localconf.max_htlc_value_in_flight,
|
||||
state->localconf.channel_reserve,
|
||||
state->localconf.htlc_minimum,
|
||||
state->feerate_per_kw,
|
||||
state->localconf.to_self_delay,
|
||||
state->localconf.max_accepted_htlcs,
|
||||
&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,
|
||||
dev_upfront_shutdown_script(tmpctx));
|
||||
sync_crypto_write(state->pps, take(msg));
|
||||
|
||||
/* This is usually a very transient state... */
|
||||
peer_billboard(false,
|
||||
"Funding channel start: offered, now waiting for accept_channel");
|
||||
|
||||
/* ... since their reply should be immediate. */
|
||||
msg = opening_negotiate_msg(tmpctx, state, true);
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
/* Default is no shutdown_scriptpubkey: free any leftover one. */
|
||||
state->remote_upfront_shutdown_script
|
||||
= tal_free(state->remote_upfront_shutdown_script);
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The receiving node MUST fail the channel if:
|
||||
*...
|
||||
* - `funding_pubkey`, `revocation_basepoint`, `htlc_basepoint`,
|
||||
* `payment_basepoint`, or `delayed_payment_basepoint` are not
|
||||
* valid DER-encoded compressed secp256k1 pubkeys.
|
||||
*/
|
||||
if (local_feature_negotiated(state->localfeatures,
|
||||
LOCAL_UPFRONT_SHUTDOWN_SCRIPT)) {
|
||||
if (!fromwire_accept_channel_option_upfront_shutdown_script(state,
|
||||
msg, &id_in,
|
||||
&state->remoteconf.dust_limit,
|
||||
&state->remoteconf.max_htlc_value_in_flight,
|
||||
&state->remoteconf.channel_reserve,
|
||||
&state->remoteconf.htlc_minimum,
|
||||
&minimum_depth,
|
||||
&state->remoteconf.to_self_delay,
|
||||
&state->remoteconf.max_accepted_htlcs,
|
||||
&their_funding_pubkey,
|
||||
&theirs.revocation,
|
||||
&theirs.payment,
|
||||
&theirs.delayed_payment,
|
||||
&theirs.htlc,
|
||||
&state->first_per_commitment_point[REMOTE],
|
||||
&state->remote_upfront_shutdown_script))
|
||||
peer_failed(state->pps,
|
||||
&state->channel_id,
|
||||
"Parsing accept_channel with option_upfront_shutdown_script %s", tal_hex(msg, msg));
|
||||
} else if (!fromwire_accept_channel(msg, &id_in,
|
||||
&state->remoteconf.dust_limit,
|
||||
&state->remoteconf.max_htlc_value_in_flight,
|
||||
&state->remoteconf.channel_reserve,
|
||||
&state->remoteconf.htlc_minimum,
|
||||
&minimum_depth,
|
||||
&state->remoteconf.to_self_delay,
|
||||
&state->remoteconf.max_accepted_htlcs,
|
||||
&their_funding_pubkey,
|
||||
&theirs.revocation,
|
||||
&theirs.payment,
|
||||
&theirs.delayed_payment,
|
||||
&theirs.htlc,
|
||||
&state->first_per_commitment_point[REMOTE]))
|
||||
peer_failed(state->pps,
|
||||
&state->channel_id,
|
||||
"Parsing accept_channel %s", tal_hex(msg, msg));
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* The `temporary_channel_id` MUST be the same as the
|
||||
* `temporary_channel_id` in the `open_channel` message. */
|
||||
if (!channel_id_eq(&id_in, &state->channel_id))
|
||||
/* In this case we exit, since we don't know what's going on. */
|
||||
peer_failed(state->pps,
|
||||
&state->channel_id,
|
||||
"accept_channel ids don't match: sent %s got %s",
|
||||
type_to_string(msg, struct channel_id, &id_in),
|
||||
type_to_string(msg, struct channel_id,
|
||||
&state->channel_id));
|
||||
|
||||
if (amount_sat_greater(state->remoteconf.dust_limit,
|
||||
state->localconf.channel_reserve)) {
|
||||
negotiation_failed(state, true,
|
||||
"dust limit %s"
|
||||
" would be above our reserve %s",
|
||||
type_to_string(tmpctx, struct amount_sat,
|
||||
&state->remoteconf.dust_limit),
|
||||
type_to_string(tmpctx, struct amount_sat,
|
||||
&state->localconf.channel_reserve));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!check_config_bounds(state, &state->remoteconf, true))
|
||||
return NULL;
|
||||
|
||||
funding_output_script =
|
||||
scriptpubkey_p2wsh(tmpctx,
|
||||
bitcoin_redeem_2of2(tmpctx,
|
||||
&state->our_funding_pubkey,
|
||||
&their_funding_pubkey));
|
||||
|
||||
return towire_opening_funder_start_reply(state, funding_output_script);
|
||||
}
|
||||
|
||||
/*~ OK, let's fund a channel! Returns the reply for lightningd on success,
|
||||
|
||||
Reference in New Issue
Block a user