opening: add entry point for `funding_start rpc command

Beginnings of wiring up the funding_start rpc command. missing
the part that actually starts the funding channel dance.
This commit is contained in:
lisa neigut 2019-05-21 16:51:52 -07:00 committed by Rusty Russell
parent 846bc9cbc4
commit 8103acd9b3
3 changed files with 145 additions and 1 deletions

View File

@ -282,6 +282,13 @@ 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)
{
// todo: this.
}
static void opening_funder_finished(struct subd *openingd, const u8 *resp, static void opening_funder_finished(struct subd *openingd, const u8 *resp,
const int *fds, const int *fds,
struct funding_channel *fc) struct funding_channel *fc)
@ -889,7 +896,15 @@ static unsigned int openingd_msg(struct subd *openingd,
return 3; return 3;
opening_funder_finished(openingd, msg, fds, uc->fc); opening_funder_finished(openingd, msg, fds, uc->fc);
return 0; return 0;
case WIRE_OPENING_FUNDER_START_REPLY:
if (!uc->fc) {
log_broken(openingd->log, "Unexpected FUNDER_START_REPLY %s",
tal_hex(tmpctx, msg));
tal_free(openingd);
return 0;
}
opening_funder_start_finished(openingd, msg, fds, uc->fc);
return 0;
case WIRE_OPENING_FUNDER_FAILED: case WIRE_OPENING_FUNDER_FAILED:
if (!uc->fc) { if (!uc->fc) {
log_broken(openingd->log, "Unexpected FUNDER_FAILED %s", log_broken(openingd->log, "Unexpected FUNDER_FAILED %s",
@ -913,6 +928,7 @@ static unsigned int openingd_msg(struct subd *openingd,
/* We send these! */ /* We send these! */
case WIRE_OPENING_INIT: case WIRE_OPENING_INIT:
case WIRE_OPENING_FUNDER: case WIRE_OPENING_FUNDER:
case WIRE_OPENING_FUNDER_START:
case WIRE_OPENING_GOT_OFFER_REPLY: case WIRE_OPENING_GOT_OFFER_REPLY:
case WIRE_OPENING_DEV_MEMLEAK: case WIRE_OPENING_DEV_MEMLEAK:
/* Replies never get here */ /* Replies never get here */
@ -989,6 +1005,93 @@ void peer_start_openingd(struct peer *peer,
subd_send_msg(uc->openingd, take(msg)); subd_send_msg(uc->openingd, take(msg));
} }
static struct command_result *json_fund_channel_start(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;
u8 *msg = NULL;
struct amount_sat max_funding_satoshi, *amount;
max_funding_satoshi = get_chainparams(cmd->ld)->max_funding;
fc->cmd = cmd;
fc->uc = NULL;
if (!param(fc->cmd, buffer, params,
p_req("id", param_node_id, &id),
p_req("satoshi", param_sat, &amount),
p_opt("feerate", param_feerate, &feerate_per_kw),
p_opt_def("announce", param_bool, &announce_channel, true),
NULL))
return command_param_failed();
if (amount_sat_greater(*amount, max_funding_satoshi))
return command_fail(cmd, FUND_MAX_EXCEEDED,
"Amount exceeded %s",
type_to_string(tmpctx, struct amount_sat,
&max_funding_satoshi));
if (!feerate_per_kw) {
feerate_per_kw = tal(cmd, u32);
*feerate_per_kw = opening_feerate(cmd->ld->topology);
if (!*feerate_per_kw) {
return command_fail(cmd, LIGHTNINGD,
"Cannot estimate fees");
}
}
if (*feerate_per_kw < feerate_floor()) {
return command_fail(cmd, LIGHTNINGD,
"Feerate below feerate floor");
}
peer = peer_by_id(cmd->ld, id);
if (!peer) {
return command_fail(cmd, LIGHTNINGD, "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, LIGHTNINGD, "Peer not connected");
}
if (peer->uncommitted_channel->fc) {
return command_fail(cmd, LIGHTNINGD, "Already funding channel");
}
fc->push = AMOUNT_MSAT(0);
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));
}
assert(!amount_sat_greater(*amount, max_funding_satoshi));
peer->uncommitted_channel->fc = tal_steal(peer->uncommitted_channel, fc);
fc->uc = peer->uncommitted_channel;
msg = towire_opening_funder_start(NULL,
*amount,
fc->push,
*feerate_per_kw,
fc->channel_flags);
subd_send_msg(peer->uncommitted_channel->openingd, take(msg));
return command_still_pending(cmd);
}
/** /**
* json_fund_channel - Entrypoint for funding a channel * json_fund_channel - Entrypoint for funding a channel
*/ */
@ -1106,6 +1209,15 @@ static const struct json_command fund_channel_command = {
}; };
AUTODATA(json_command, &fund_channel_command); AUTODATA(json_command, &fund_channel_command);
static const struct json_command fund_channel_start_command = {
"fundchannel_start",
"channels",
json_fund_channel_start,
"Start fund channel with {id} using {amount} satoshis. "
"Returns a bech32 address to use as an output for a funding transaction."
};
AUTODATA(json_command, &fund_channel_start_command);
#if DEVELOPER #if DEVELOPER
/* Indented to avoid include ordering check */ /* Indented to avoid include ordering check */
#include <lightningd/memdump.h> #include <lightningd/memdump.h>

View File

@ -77,6 +77,19 @@ opening_funder_reply,,our_channel_reserve_satoshis,struct amount_sat
opening_funder_reply,,shutdown_len,u16 opening_funder_reply,,shutdown_len,u16
opening_funder_reply,,shutdown_scriptpubkey,shutdown_len*u8 opening_funder_reply,,shutdown_scriptpubkey,shutdown_len*u8
# master->openingd: start channel establishment for a funding
# tx that will be paid for by an external wallet
opening_funder_start,6002
opening_funder_start,,funding_satoshis,struct amount_sat
opening_funder_start,,push_msat,struct amount_msat
opening_funder_start,,feerate_per_kw,u32
opening_funder_start,,channel_flags,u8
# openingd->master: send back output script for 2-of-2 funding output
opening_funder_start_reply,6102
opening_funder_start_reply,,script_len,u8
opening_funder_start_reply,,scriptpubkey,script_len*u8
# Openingd->master: we failed to negotiation channel # Openingd->master: we failed to negotiation channel
opening_funder_failed,6004 opening_funder_failed,6004
opening_funder_failed,,reason,wirestring opening_funder_failed,,reason,wirestring

1 #include <common/cryptomsg.h>
77 opening_funder_failed,,reason,wirestring opening_funder_start,6002
78 opening_funder_failed,,is_err,bool opening_funder_start,,funding_satoshis,struct amount_sat
79 # Openingd->master: they offered channel. opening_funder_start,,push_msat,struct amount_msat
80 opening_funder_start,,feerate_per_kw,u32
81 opening_funder_start,,channel_flags,u8
82 # openingd->master: send back output script for 2-of-2 funding output
83 opening_funder_start_reply,6102
84 opening_funder_start_reply,,script_len,u8
85 opening_funder_start_reply,,scriptpubkey,script_len*u8
86 # Openingd->master: we failed to negotiation channel
87 opening_funder_failed,6004
88 opening_funder_failed,,reason,wirestring
89 opening_funder_failed,,is_err,bool
90 # Openingd->master: they offered channel.
91 # This gives their txid and info, means we can send funding_signed: we're done.
92 opening_fundee,6003
93 # This gives their txid and info, means we can send funding_signed: we're done. opening_fundee,,their_config,struct channel_config
94 opening_fundee,6003 opening_fundee,,first_commit,struct bitcoin_tx
95 opening_fundee,,their_config,struct channel_config opening_fundee,,first_commit_sig,struct bitcoin_signature

View File

@ -438,6 +438,14 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state,
} }
} }
/* 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 */
static u8 *funder_channel_start(struct state *state,
u8 channel_flags)
{
return towire_opening_funder_start_reply(state, NULL);
}
/*~ OK, let's fund a channel! Returns the reply for lightningd on success, /*~ OK, let's fund a channel! Returns the reply for lightningd on success,
* or NULL if something goes wrong. */ * or NULL if something goes wrong. */
static u8 *funder_channel(struct state *state, static u8 *funder_channel(struct state *state,
@ -1425,7 +1433,17 @@ static u8 *handle_master_in(struct state *state)
change_keyindex, channel_flags, change_keyindex, channel_flags,
take(utxos), &bip32_base); take(utxos), &bip32_base);
return msg; return msg;
case WIRE_OPENING_FUNDER_START:
if (!fromwire_opening_funder_start(msg, &state->funding,
&state->push_msat,
&state->feerate_per_kw,
&channel_flags))
master_badmsg(WIRE_OPENING_FUNDER_START, msg);
msg = funder_channel_start(state, channel_flags);
/* We want to keep openingd alive, since we're not done yet */
wire_sync_write(REQ_FD, take(msg));
return NULL;
case WIRE_OPENING_DEV_MEMLEAK: case WIRE_OPENING_DEV_MEMLEAK:
#if DEVELOPER #if DEVELOPER
handle_dev_memleak(state, msg); handle_dev_memleak(state, msg);
@ -1434,6 +1452,7 @@ static u8 *handle_master_in(struct state *state)
case WIRE_OPENING_DEV_MEMLEAK_REPLY: case WIRE_OPENING_DEV_MEMLEAK_REPLY:
case WIRE_OPENING_INIT: case WIRE_OPENING_INIT:
case WIRE_OPENING_FUNDER_REPLY: case WIRE_OPENING_FUNDER_REPLY:
case WIRE_OPENING_FUNDER_START_REPLY:
case WIRE_OPENING_FUNDEE: case WIRE_OPENING_FUNDEE:
case WIRE_OPENING_FUNDER_FAILED: case WIRE_OPENING_FUNDER_FAILED:
case WIRE_OPENING_GOT_OFFER: case WIRE_OPENING_GOT_OFFER: