Browse Source

lightningd: struct uncommitted_channel for opening channels.

Each peer can have one 'uncommitted' channel, which is in the process
of opening.  This is used for openingd, and then on return we convert
it into a full-fledged struct channel and commit it into the database.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
8db8c51201
  1. 25
      lightningd/channel.c
  2. 13
      lightningd/channel.h
  3. 2
      lightningd/pay.c
  4. 811
      lightningd/peer_control.c
  5. 3
      lightningd/peer_control.h
  6. 2
      lightningd/peer_htlcs.c
  7. 2
      tests/test_lightningd.py

25
lightningd/channel.c

@ -53,19 +53,15 @@ static void destroy_channel(struct channel *channel)
list_del_from(&channel->peer->channels, &channel->list); list_del_from(&channel->peer->channels, &channel->list);
} }
/* This lets us give a more detailed error than just a destructor. */ /* FIXME: remove why */
void delete_channel(struct channel *channel, const char *why) void delete_channel(struct channel *channel, const char *why)
{ {
struct peer *peer = channel->peer; struct peer *peer = channel->peer;
if (channel->opening_cmd) {
command_fail(channel->opening_cmd, "%s", why);
channel->opening_cmd = NULL;
}
wallet_channel_delete(channel->peer->ld->wallet, channel->dbid); wallet_channel_delete(channel->peer->ld->wallet, channel->dbid);
tal_free(channel); tal_free(channel);
/* Last one out frees the peer */ /* Last one out frees the peer */
if (list_empty(&peer->channels)) if (list_empty(&peer->channels) && !peer->uncommitted_channel)
delete_peer(peer); delete_peer(peer);
} }
@ -84,9 +80,9 @@ void delete_channel(struct channel *channel, const char *why)
* reconnection. We use the DB channel ID to guarantee unique secrets * reconnection. We use the DB channel ID to guarantee unique secrets
* per channel. * per channel.
*/ */
static void derive_channel_seed(struct lightningd *ld, struct privkey *seed, void derive_channel_seed(struct lightningd *ld, struct privkey *seed,
const struct pubkey *peer_id, const struct pubkey *peer_id,
const u64 dbid) const u64 dbid)
{ {
u8 input[PUBKEY_DER_LEN + sizeof(dbid)]; u8 input[PUBKEY_DER_LEN + sizeof(dbid)];
char *info = "per-peer seed"; char *info = "per-peer seed";
@ -143,11 +139,18 @@ struct channel *peer_active_channel(struct peer *peer)
} }
struct channel *active_channel_by_id(struct lightningd *ld, struct channel *active_channel_by_id(struct lightningd *ld,
const struct pubkey *id) const struct pubkey *id,
struct uncommitted_channel **uc)
{ {
struct peer *peer = peer_by_id(ld, id); struct peer *peer = peer_by_id(ld, id);
if (!peer) if (!peer) {
if (uc)
*uc = NULL;
return NULL; return NULL;
}
if (uc)
*uc = peer->uncommitted_channel;
return peer_active_channel(peer); return peer_active_channel(peer);
} }

13
lightningd/channel.h

@ -5,6 +5,8 @@
#include <lightningd/peer_state.h> #include <lightningd/peer_state.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
struct uncommitted_channel;
struct channel { struct channel {
/* Inside peer->channels. */ /* Inside peer->channels. */
struct list_node list; struct list_node list;
@ -27,9 +29,6 @@ struct channel {
/* Which side offered channel? */ /* Which side offered channel? */
enum side funder; enum side funder;
/* Command which ordered us to open channel, if any. */
struct command *opening_cmd;
/* Is there a single subdaemon responsible for us? */ /* Is there a single subdaemon responsible for us? */
struct subd *owner; struct subd *owner;
@ -110,8 +109,10 @@ void channel_set_state(struct channel *channel,
/* Find a channel which is not onchain, if any */ /* Find a channel which is not onchain, if any */
struct channel *peer_active_channel(struct peer *peer); struct channel *peer_active_channel(struct peer *peer);
/* Get active channel for peer, optionally any uncommitted_channel. */
struct channel *active_channel_by_id(struct lightningd *ld, struct channel *active_channel_by_id(struct lightningd *ld,
const struct pubkey *id); const struct pubkey *id,
struct uncommitted_channel **uc);
void channel_set_last_tx(struct channel *channel, void channel_set_last_tx(struct channel *channel,
struct bitcoin_tx *tx, struct bitcoin_tx *tx,
@ -176,4 +177,8 @@ static inline bool channel_persists(const struct channel *channel)
{ {
return channel->state >= CHANNELD_AWAITING_LOCKIN; return channel->state >= CHANNELD_AWAITING_LOCKIN;
} }
void derive_channel_seed(struct lightningd *ld, struct privkey *seed,
const struct pubkey *peer_id,
const u64 dbid);
#endif /* LIGHTNING_LIGHTNINGD_CHANNEL_H */ #endif /* LIGHTNING_LIGHTNINGD_CHANNEL_H */

2
lightningd/pay.c

@ -547,7 +547,7 @@ bool send_payment(const tal_t *ctx,
* context, not our temporary context. */ * context, not our temporary context. */
new_sendpay_command(ctx, rhash, ld, cb, cbarg); new_sendpay_command(ctx, rhash, ld, cb, cbarg);
channel = active_channel_by_id(ld, &ids[0]); channel = active_channel_by_id(ld, &ids[0], NULL);
if (!channel) { if (!channel) {
/* Report routing failure to gossipd */ /* Report routing failure to gossipd */
fail = immediate_routing_failure(tmpctx, ld, fail = immediate_routing_failure(tmpctx, ld,

811
lightningd/peer_control.c

File diff suppressed because it is too large

3
lightningd/peer_control.h

@ -34,6 +34,9 @@ struct peer {
/* Our channels */ /* Our channels */
struct list_head channels; struct list_head channels;
/* Our (only) uncommitted channel, still opening. */
struct uncommitted_channel *uncommitted_channel;
/* History */ /* History */
struct log_book *log_book; struct log_book *log_book;

2
lightningd/peer_htlcs.c

@ -422,7 +422,7 @@ static void forward_htlc(struct htlc_in *hin,
enum onion_type failcode; enum onion_type failcode;
u64 fee; u64 fee;
struct lightningd *ld = hin->key.channel->peer->ld; struct lightningd *ld = hin->key.channel->peer->ld;
struct channel *next = active_channel_by_id(ld, next_hop); struct channel *next = active_channel_by_id(ld, next_hop, NULL);
/* Unknown peer, or peer not ready. */ /* Unknown peer, or peer not ready. */
if (!next || !next->scid) { if (!next || !next->scid) {

2
tests/test_lightningd.py

@ -2406,7 +2406,7 @@ class LightningDTests(BaseLightningDTests):
l1.rpc.connect(l2.info['id'], 'localhost', l2.info['port']) l1.rpc.connect(l2.info['id'], 'localhost', l2.info['port'])
# We should get a message about reconnecting. # We should get a message about reconnecting.
l2.daemon.wait_for_log('Peer has reconnected, state OPENINGD') l2.daemon.wait_for_log('Peer reconnected, killing openingd')
# Should work fine. # Should work fine.
l1.rpc.fundchannel(l2.info['id'], 20000) l1.rpc.fundchannel(l2.info['id'], 20000)

Loading…
Cancel
Save