Browse Source

openingd: check with lightningd when we receive an offer.

Instead of lightningd telling us when it's ready, we ask it.
This also provides an opportunity to have a plugin hook at this point.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
htlc_accepted_hook
Rusty Russell 6 years ago
committed by neil saitug
parent
commit
f3d30f1267
  1. 7
      lightningd/channel.c
  2. 30
      lightningd/opening_control.c
  3. 2
      lightningd/opening_control.h
  4. 3
      lightningd/test/run-invoice-select-inchan.c
  5. 20
      openingd/opening_wire.csv
  6. 55
      openingd/openingd.c
  7. 3
      wallet/test/run-wallet.c

7
lightningd/channel.c

@ -332,8 +332,6 @@ void channel_set_state(struct channel *channel,
enum channel_state old_state, enum channel_state old_state,
enum channel_state state) enum channel_state state)
{ {
bool was_active = channel_active(channel);
log_info(channel->log, "State changed from %s to %s", log_info(channel->log, "State changed from %s to %s",
channel_state_name(channel), channel_state_str(state)); channel_state_name(channel), channel_state_str(state));
if (channel->state != old_state) if (channel->state != old_state)
@ -344,11 +342,6 @@ void channel_set_state(struct channel *channel,
/* TODO(cdecker) Selectively save updated fields to DB */ /* TODO(cdecker) Selectively save updated fields to DB */
wallet_channel_save(channel->peer->ld->wallet, channel); wallet_channel_save(channel->peer->ld->wallet, channel);
/* If openingd is running, it might want to know we're no longer
* active */
if (was_active && !channel_active(channel))
opening_peer_no_active_channels(channel->peer);
} }
void channel_fail_permanent(struct channel *channel, const char *fmt, ...) void channel_fail_permanent(struct channel *channel, const char *fmt, ...)

30
lightningd/opening_control.c

@ -725,6 +725,20 @@ static void channel_config(struct lightningd *ld,
ours->channel_reserve = AMOUNT_SAT(UINT64_MAX); ours->channel_reserve = AMOUNT_SAT(UINT64_MAX);
} }
static void opening_got_offer(struct subd *openingd,
const u8 *msg,
struct uncommitted_channel *uc)
{
const char *reason = NULL;
/* Tell them they can't open, if we already have open channel. */
if (peer_active_channel(uc->peer))
reason = "Already have active channel";
subd_send_msg(openingd,
take(towire_opening_got_offer_reply(NULL, reason)));
}
static unsigned int openingd_msg(struct subd *openingd, static unsigned int openingd_msg(struct subd *openingd,
const u8 *msg, const int *fds) const u8 *msg, const int *fds)
{ {
@ -760,10 +774,14 @@ static unsigned int openingd_msg(struct subd *openingd,
opening_fundee_finished(openingd, msg, fds, uc); opening_fundee_finished(openingd, msg, fds, uc);
return 0; return 0;
case WIRE_OPENING_GOT_OFFER:
opening_got_offer(openingd, msg, uc);
return 0;
/* 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_CAN_ACCEPT_CHANNEL: case WIRE_OPENING_GOT_OFFER_REPLY:
case WIRE_OPENING_DEV_MEMLEAK: case WIRE_OPENING_DEV_MEMLEAK:
/* Replies never get here */ /* Replies never get here */
case WIRE_OPENING_DEV_MEMLEAK_REPLY: case WIRE_OPENING_DEV_MEMLEAK_REPLY:
@ -834,21 +852,11 @@ void peer_start_openingd(struct peer *peer,
uc->minimum_depth, uc->minimum_depth,
feerate_min(peer->ld, NULL), feerate_min(peer->ld, NULL),
feerate_max(peer->ld, NULL), feerate_max(peer->ld, NULL),
!peer_active_channel(peer),
peer->localfeatures, peer->localfeatures,
send_msg); send_msg);
subd_send_msg(uc->openingd, take(msg)); subd_send_msg(uc->openingd, take(msg));
} }
void opening_peer_no_active_channels(struct peer *peer)
{
assert(!peer_active_channel(peer));
if (peer->uncommitted_channel) {
subd_send_msg(peer->uncommitted_channel->openingd,
take(towire_opening_can_accept_channel(NULL)));
}
}
/** /**
* json_fund_channel - Entrypoint for funding a channel * json_fund_channel - Entrypoint for funding a channel
*/ */

2
lightningd/opening_control.h

@ -17,8 +17,6 @@ void peer_start_openingd(struct peer *peer,
struct peer_comms *pcomms, struct peer_comms *pcomms,
const u8 *msg); const u8 *msg);
void opening_peer_no_active_channels(struct peer *peer);
void kill_uncommitted_channel(struct uncommitted_channel *uc, void kill_uncommitted_channel(struct uncommitted_channel *uc,
const char *why); const char *why);

3
lightningd/test/run-invoice-select-inchan.c

@ -290,9 +290,6 @@ enum watch_result onchaind_funding_spent(struct channel *channel UNNEEDED,
const struct bitcoin_tx *tx UNNEEDED, const struct bitcoin_tx *tx UNNEEDED,
u32 blockheight UNNEEDED) u32 blockheight UNNEEDED)
{ fprintf(stderr, "onchaind_funding_spent called!\n"); abort(); } { fprintf(stderr, "onchaind_funding_spent called!\n"); abort(); }
/* Generated stub for opening_peer_no_active_channels */
void opening_peer_no_active_channels(struct peer *peer UNNEEDED)
{ fprintf(stderr, "opening_peer_no_active_channels called!\n"); abort(); }
/* Generated stub for param */ /* Generated stub for param */
bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED, bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED,
const jsmntok_t params[] UNNEEDED, ...) const jsmntok_t params[] UNNEEDED, ...)

20
openingd/opening_wire.csv

@ -17,15 +17,29 @@ opening_init,,our_funding_pubkey,struct pubkey
opening_init,,minimum_depth,u32 opening_init,,minimum_depth,u32
opening_init,,min_feerate,u32 opening_init,,min_feerate,u32
opening_init,,max_feerate,u32 opening_init,,max_feerate,u32
opening_init,,can_open_channel,bool
opening_init,,lfeatures_len,u16 opening_init,,lfeatures_len,u16
opening_init,,lfeatures,lfeatures_len*u8 opening_init,,lfeatures,lfeatures_len*u8
# Optional msg to send. # Optional msg to send.
opening_init,,len,u16 opening_init,,len,u16
opening_init,,msg,len*u8 opening_init,,msg,len*u8
# Master->openingd: they can now open a channel if they want. # Openingd->master: they offered channel, should we continue?
opening_can_accept_channel,6002 opening_got_offer,6005
opening_got_offer,,funding_satoshis,struct amount_sat
opening_got_offer,,push_msat,struct amount_msat
opening_got_offer,,dust_limit_satoshis,struct amount_sat
opening_got_offer,,max_htlc_value_in_flight_msat,struct amount_msat
opening_got_offer,,channel_reserve_satoshis,struct amount_sat
opening_got_offer,,htlc_minimum_msat,struct amount_msat
opening_got_offer,,feerate_per_kw,u32
opening_got_offer,,to_self_delay,u16
opening_got_offer,,max_accepted_htlcs,u16
opening_got_offer,,channel_flags,u8
opening_got_offer,,shutdown_len,u16
opening_got_offer,,shutdown_scriptpubkey,shutdown_len*u8
# master->openingd: optional rejection message
opening_got_offer_reply,6105
opening_got_offer_reply,,rejection,?wirestring
#include <common/bip32.h> #include <common/bip32.h>
#include <common/htlc_wire.h> #include <common/htlc_wire.h>

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

55
openingd/openingd.c

@ -102,12 +102,6 @@ struct state {
* as initial channels never have HTLCs. */ * as initial channels never have HTLCs. */
struct channel *channel; struct channel *channel;
/*~ We only allow one active channel at a time per peer. Otherwise
* all our per-peer daemons would have to handle multiple channels,
* or we would need some other daemon to demux the messages.
* Thus, lightningd tells is if/when there's no active channel. */
bool can_accept_channel;
/* Which chain we're on, so we can check/set `chain_hash` fields */ /* Which chain we're on, so we can check/set `chain_hash` fields */
const struct chainparams *chainparams; const struct chainparams *chainparams;
}; };
@ -971,16 +965,6 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
"Bad open_channel %s", "Bad open_channel %s",
tal_hex(open_channel_msg, open_channel_msg)); tal_hex(open_channel_msg, open_channel_msg));
/* We can't handle talking about more than one channel at once. */
if (!state->can_accept_channel) {
u8 *errmsg;
errmsg = towire_errorfmt(NULL, &state->channel_id,
"Already have active channel");
sync_crypto_write(&state->cs, PEER_FD, take(errmsg));
return NULL;
}
/* BOLT #2: /* BOLT #2:
* *
* The receiving node MUST fail the channel if: * The receiving node MUST fail the channel if:
@ -1018,7 +1002,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
if (amount_msat_greater_sat(state->push_msat, state->funding)) { if (amount_msat_greater_sat(state->push_msat, state->funding)) {
peer_failed(&state->cs, peer_failed(&state->cs,
&state->channel_id, &state->channel_id,
"Our push_msat %s" "Their push_msat %s"
" would be too large for funding_satoshis %s", " would be too large for funding_satoshis %s",
type_to_string(tmpctx, struct amount_msat, type_to_string(tmpctx, struct amount_msat,
&state->push_msat), &state->push_msat),
@ -1087,6 +1071,34 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
if (!check_config_bounds(state, &state->remoteconf, false)) if (!check_config_bounds(state, &state->remoteconf, false))
return NULL; return NULL;
/* Check with lightningd that we can accept this? In particular,
* if we have an existing channel, we don't support it. */
msg = towire_opening_got_offer(NULL,
state->funding,
state->push_msat,
state->remoteconf.dust_limit,
state->remoteconf.max_htlc_value_in_flight,
state->remoteconf.channel_reserve,
state->remoteconf.htlc_minimum,
state->feerate_per_kw,
state->remoteconf.to_self_delay,
state->remoteconf.max_accepted_htlcs,
channel_flags,
state->remote_upfront_shutdown_script);
wire_sync_write(REQ_FD, take(msg));
msg = wire_sync_read(tmpctx, REQ_FD);
if (!fromwire_opening_got_offer_reply(tmpctx, msg, &err_reason))
master_badmsg(WIRE_OPENING_GOT_OFFER_REPLY, msg);
/* If they give us a reason to reject, do so. */
if (err_reason) {
u8 *errmsg = towire_errorfmt(NULL, &state->channel_id,
"%s", err_reason);
sync_crypto_write(&state->cs, PEER_FD, take(errmsg));
return NULL;
}
/* OK, we accept! */ /* OK, we accept! */
msg = towire_accept_channel_option_upfront_shutdown_script(NULL, &state->channel_id, msg = towire_accept_channel_option_upfront_shutdown_script(NULL, &state->channel_id,
state->localconf.dust_limit, state->localconf.dust_limit,
@ -1429,12 +1441,6 @@ static u8 *handle_master_in(struct state *state)
take(utxos), &bip32_base); take(utxos), &bip32_base);
return msg; return msg;
case WIRE_OPENING_CAN_ACCEPT_CHANNEL:
if (!fromwire_opening_can_accept_channel(msg))
master_badmsg(WIRE_OPENING_CAN_ACCEPT_CHANNEL, msg);
state->can_accept_channel = true;
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);
@ -1445,6 +1451,8 @@ static u8 *handle_master_in(struct state *state)
case WIRE_OPENING_FUNDER_REPLY: case WIRE_OPENING_FUNDER_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_REPLY:
break; break;
} }
@ -1480,7 +1488,6 @@ int main(int argc, char *argv[])
&state->our_funding_pubkey, &state->our_funding_pubkey,
&state->minimum_depth, &state->minimum_depth,
&state->min_feerate, &state->max_feerate, &state->min_feerate, &state->max_feerate,
&state->can_accept_channel,
&state->localfeatures, &state->localfeatures,
&inner)) &inner))
master_badmsg(WIRE_OPENING_INIT, msg); master_badmsg(WIRE_OPENING_INIT, msg);

3
wallet/test/run-wallet.c

@ -350,9 +350,6 @@ enum watch_result onchaind_funding_spent(struct channel *channel UNNEEDED,
/* Generated stub for onion_type_name */ /* Generated stub for onion_type_name */
const char *onion_type_name(int e UNNEEDED) const char *onion_type_name(int e UNNEEDED)
{ fprintf(stderr, "onion_type_name called!\n"); abort(); } { fprintf(stderr, "onion_type_name called!\n"); abort(); }
/* Generated stub for opening_peer_no_active_channels */
void opening_peer_no_active_channels(struct peer *peer UNNEEDED)
{ fprintf(stderr, "opening_peer_no_active_channels called!\n"); abort(); }
/* Generated stub for outpointfilter_add */ /* Generated stub for outpointfilter_add */
void outpointfilter_add(struct outpointfilter *of UNNEEDED, void outpointfilter_add(struct outpointfilter *of UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED) const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED)

Loading…
Cancel
Save