From cc460095cae982efaa09e1be5150af9c5f6d0798 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 19 Feb 2018 11:36:14 +1030 Subject: [PATCH] lightningd: make new_channel a proper constructor. It's giant, but it's encapsulating at least. It is called from the wallet code when loading channels, or from the opening code when converting an uncommitted_channel. Signed-off-by: Rusty Russell --- lightningd/channel.c | 96 +++++++++++++++++++++---- lightningd/channel.h | 36 +++++++++- lightningd/peer_control.c | 67 +++++++++--------- wallet/wallet.c | 143 ++++++++++++++++++++------------------ 4 files changed, 224 insertions(+), 118 deletions(-) diff --git a/lightningd/channel.c b/lightningd/channel.c index 31fc203de..76922564f 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -96,28 +96,94 @@ void derive_channel_seed(struct lightningd *ld, struct privkey *seed, info, strlen(info)); } -struct channel *new_channel(struct peer *peer, u64 dbid, u32 first_blocknum) +struct channel *new_channel(struct peer *peer, u64 dbid, + /* NULL or stolen */ + struct wallet_shachain *their_shachain, + enum peer_state state, + enum side funder, + /* NULL or stolen */ + struct log *log, + u8 channel_flags, + const struct channel_config *our_config, + u32 minimum_depth, + u64 next_index_local, + u64 next_index_remote, + u64 next_htlc_id, + const struct bitcoin_txid *funding_txid, + u16 funding_outnum, + u64 funding_satoshi, + u64 push_msat, + bool remote_funding_locked, + /* NULL or stolen */ + struct short_channel_id *scid, + u64 our_msatoshi, + /* Stolen */ + struct bitcoin_tx *last_tx, + const secp256k1_ecdsa_signature *last_sig, + /* NULL or stolen */ + secp256k1_ecdsa_signature *last_htlc_sigs, + const struct channel_info *channel_info, + /* NULL or stolen */ + u8 *remote_shutdown_scriptpubkey, + /* (-1 if not chosen yet) */ + s64 local_shutdown_idx, + bool last_was_revoke, + /* NULL or stolen */ + struct changed_htlc *last_sent_commit, + u32 first_blocknum) { - /* FIXME: We currently rely on it being all zero/NULL */ - struct channel *channel = talz(peer->ld, struct channel); - char *idname; + struct channel *channel = tal(peer->ld, struct channel); assert(dbid != 0); - channel->dbid = dbid; channel->peer = peer; + channel->dbid = dbid; + channel->error = NULL; + if (their_shachain) + channel->their_shachain = *their_shachain; + else { + channel->their_shachain.id = 0; + shachain_init(&channel->their_shachain.chain); + } + channel->state = state; + channel->funder = funder; + channel->owner = NULL; + if (!log) { + /* FIXME: update log prefix when we get scid */ + /* FIXME: Use minimal unique pubkey prefix for logs! */ + char *idname = type_to_string(peer, struct pubkey, &peer->id); + channel->log = new_log(channel, + peer->log_book, "%s chan #%"PRIu64":", + idname, dbid); + tal_free(idname); + } else + channel->log = tal_steal(channel, log); + channel->channel_flags = channel_flags; + channel->our_config = *our_config; + channel->minimum_depth = minimum_depth; + channel->next_index[LOCAL] = next_index_local; + channel->next_index[REMOTE] = next_index_remote; + channel->next_htlc_id = next_htlc_id; + channel->funding_txid = *funding_txid; + channel->funding_outnum = funding_outnum; + channel->funding_satoshi = funding_satoshi; + channel->push_msat = push_msat; + channel->remote_funding_locked = remote_funding_locked; + channel->scid = tal_steal(channel, scid); + channel->our_msatoshi = our_msatoshi; + channel->last_tx = tal_steal(channel, last_tx); + channel->last_sig = *last_sig; + channel->last_htlc_sigs = tal_steal(channel, last_htlc_sigs); + channel->channel_info = *channel_info; + channel->remote_shutdown_scriptpubkey + = tal_steal(channel, remote_shutdown_scriptpubkey); + channel->local_shutdown_idx = local_shutdown_idx; + channel->last_was_revoke = last_was_revoke; + channel->last_sent_commit = tal_steal(channel, last_sent_commit); channel->first_blocknum = first_blocknum; - channel->state = UNINITIALIZED; - channel->local_shutdown_idx = -1; - - /* FIXME: update log prefix when we get scid */ - /* FIXME: Use minimal unique pubkey prefix for logs! */ - idname = type_to_string(peer, struct pubkey, &peer->id); - channel->log = new_log(channel, peer->log_book, "%s chan #%"PRIu64":", - idname, dbid); - tal_free(idname); + derive_channel_seed(peer->ld, &channel->seed, &peer->id, channel->dbid); + list_add_tail(&peer->channels, &channel->list); tal_add_destructor(channel, destroy_channel); - derive_channel_seed(peer->ld, &channel->seed, &peer->id, channel->dbid); return channel; } diff --git a/lightningd/channel.h b/lightningd/channel.h index 589d5c3e3..b82b5aa42 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -85,7 +85,41 @@ struct channel { u64 first_blocknum; }; -struct channel *new_channel(struct peer *peer, u64 dbid, u32 first_blocknum); +struct channel *new_channel(struct peer *peer, u64 dbid, + /* NULL or stolen */ + struct wallet_shachain *their_shachain, + enum peer_state state, + enum side funder, + /* NULL or stolen */ + struct log *log, + u8 channel_flags, + const struct channel_config *our_config, + u32 minimum_depth, + u64 next_index_local, + u64 next_index_remote, + u64 next_htlc_id, + const struct bitcoin_txid *funding_txid, + u16 funding_outnum, + u64 funding_satoshi, + u64 push_msat, + bool remote_funding_locked, + /* NULL or stolen */ + struct short_channel_id *scid, + u64 our_msatoshi, + /* Stolen */ + struct bitcoin_tx *last_tx, + const secp256k1_ecdsa_signature *last_sig, + /* NULL or stolen */ + secp256k1_ecdsa_signature *last_htlc_sigs, + const struct channel_info *channel_info, + /* NULL or stolen */ + u8 *remote_shutdown_scriptpubkey, + /* (-1 if not chosen yet) */ + s64 local_shutdown_idx, + bool last_was_revoke, + /* NULL or stolen */ + struct changed_htlc *last_sent_commit, + u32 first_blocknum); /* This lets us give a more detailed error than just a destructor, and * deletes from db. */ diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index c02a62c5d..4215c688f 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2158,7 +2158,7 @@ static bool peer_start_channeld(struct channel *channel, return true; } -/* FIXME: Unify with new_channel */ +/* Steals fields from uncommitted_channel */ static struct channel * wallet_commit_channel(struct lightningd *ld, struct uncommitted_channel *uc, @@ -2169,48 +2169,49 @@ wallet_commit_channel(struct lightningd *ld, u64 funding_satoshi, u64 push_msat, u8 channel_flags, - const struct channel_info *channel_info, + struct channel_info *channel_info, u32 feerate) { struct channel *channel; + u64 our_msatoshi; - channel = new_channel(uc->peer, uc->dbid, uc->first_blocknum); - channel->state = CHANNELD_AWAITING_LOCKIN; - channel->funder = uc->fc ? LOCAL : REMOTE; - tal_free(channel->log); - channel->log = tal_steal(channel, uc->log); - channel->channel_flags = channel_flags; - channel->our_config = uc->our_config; - channel->minimum_depth = uc->minimum_depth; - channel->next_index[LOCAL] = channel->next_index[REMOTE] = 1; - channel->next_htlc_id = 0; - channel->funding_txid = *funding_txid; - channel->funding_outnum = funding_outnum; - channel->funding_satoshi = funding_satoshi; - channel->push_msat = push_msat; - channel->remote_funding_locked = false; - channel->scid = NULL; - - if (channel->funder == LOCAL) - channel->our_msatoshi - = channel->funding_satoshi * 1000 - channel->push_msat; + if (uc->fc) + our_msatoshi = funding_satoshi * 1000 - push_msat; else - channel->our_msatoshi = channel->push_msat; - - channel->last_tx = tal_steal(channel, remote_commit); - channel->last_sig = *remote_commit_sig; - channel->last_htlc_sigs = NULL; - - channel->channel_info = *channel_info; + our_msatoshi = push_msat; /* Feerates begin identical. */ - channel->channel_info.feerate_per_kw[LOCAL] - = channel->channel_info.feerate_per_kw[REMOTE] + channel_info->feerate_per_kw[LOCAL] + = channel_info->feerate_per_kw[REMOTE] = feerate; /* old_remote_per_commit not valid yet, copy valid one. */ - channel->channel_info.old_remote_per_commit - = channel->channel_info.remote_per_commit; + channel_info->old_remote_per_commit = channel_info->remote_per_commit; + + channel = new_channel(uc->peer, uc->dbid, + NULL, /* No shachain yet */ + CHANNELD_AWAITING_LOCKIN, + uc->fc ? LOCAL : REMOTE, + uc->log, + channel_flags, + &uc->our_config, + uc->minimum_depth, + 1, 1, 0, + funding_txid, + funding_outnum, + funding_satoshi, + push_msat, + false, /* !remote_funding_locked */ + NULL, /* no scid yet */ + our_msatoshi, + remote_commit, + remote_commit_sig, + NULL, /* No HTLC sigs yet */ + channel_info, + NULL, /* No remote_shutdown_scriptpubkey yet */ + -1, false, + NULL, /* No commit sent yet */ + uc->first_blocknum); /* Now we finally put it in the database. */ wallet_channel_insert(ld->wallet, channel); diff --git a/wallet/wallet.c b/wallet/wallet.c index 0c34e8c55..fa33ef96f 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -501,100 +501,105 @@ wallet_htlc_sigs_load(const tal_t *ctx, struct wallet *w, u64 channelid) static struct channel *wallet_stmt2channel(const tal_t *ctx, struct wallet *w, sqlite3_stmt *stmt) { bool ok = true; - struct channel_info *channel_info; - u64 remote_config_id; + struct channel_info channel_info; + struct short_channel_id *scid; struct channel *chan; u64 peer_dbid; struct peer *peer; + struct wallet_shachain wshachain; + struct channel_config our_config; + struct bitcoin_txid funding_txid; + secp256k1_ecdsa_signature last_sig; + u8 *remote_shutdown_scriptpubkey; + struct changed_htlc *last_sent_commit; + const tal_t *tmpctx = tal_tmpctx(ctx); peer_dbid = sqlite3_column_int64(stmt, 1); peer = find_peer_by_dbid(w->ld, peer_dbid); if (!peer) { peer = wallet_peer_load(ctx, w, peer_dbid); - if (!peer) + if (!peer) { + tal_free(tmpctx); return NULL; + } } - chan = new_channel(peer, sqlite3_column_int64(stmt, 0), - sqlite3_column_int64(stmt, 35)); if (sqlite3_column_type(stmt, 2) != SQLITE_NULL) { - chan->scid = tal(chan->peer, struct short_channel_id); - sqlite3_column_short_channel_id(stmt, 2, chan->scid); + scid = tal(tmpctx, struct short_channel_id); + sqlite3_column_short_channel_id(stmt, 2, scid); } else { - chan->scid = NULL; + scid = NULL; } - chan->our_config.id = sqlite3_column_int64(stmt, 3); - wallet_channel_config_load(w, chan->our_config.id, &chan->our_config); - remote_config_id = sqlite3_column_int64(stmt, 4); - - chan->state = sqlite3_column_int(stmt, 5); - assert(chan->state > OPENINGD && chan->state <= CHANNEL_STATE_MAX); - chan->funder = sqlite3_column_int(stmt, 6); - chan->channel_flags = sqlite3_column_int(stmt, 7); - chan->minimum_depth = sqlite3_column_int(stmt, 8); - chan->next_index[LOCAL] = sqlite3_column_int64(stmt, 9); - chan->next_index[REMOTE] = sqlite3_column_int64(stmt, 10); - chan->next_htlc_id = sqlite3_column_int64(stmt, 11); - - sqlite3_column_sha256_double(stmt, 12, &chan->funding_txid.shad); + ok &= wallet_shachain_load(w, sqlite3_column_int64(stmt, 27), + &wshachain); - chan->funding_outnum = sqlite3_column_int(stmt, 13); - chan->funding_satoshi = sqlite3_column_int64(stmt, 14); - chan->remote_funding_locked = - sqlite3_column_int(stmt, 15) != 0; - chan->push_msat = sqlite3_column_int64(stmt, 16); - chan->our_msatoshi = sqlite3_column_int64(stmt, 17); - - channel_info = &chan->channel_info; - - /* Populate channel_info */ - ok &= sqlite3_column_pubkey(stmt, 18, &channel_info->remote_fundingkey); - ok &= sqlite3_column_pubkey(stmt, 19, &channel_info->theirbase.revocation); - ok &= sqlite3_column_pubkey(stmt, 20, &channel_info->theirbase.payment); - ok &= sqlite3_column_pubkey(stmt, 21, &channel_info->theirbase.htlc); - ok &= sqlite3_column_pubkey(stmt, 22, &channel_info->theirbase.delayed_payment); - ok &= sqlite3_column_pubkey(stmt, 23, &channel_info->remote_per_commit); - ok &= sqlite3_column_pubkey(stmt, 24, &channel_info->old_remote_per_commit); - channel_info->feerate_per_kw[LOCAL] = sqlite3_column_int(stmt, 25); - channel_info->feerate_per_kw[REMOTE] = sqlite3_column_int(stmt, 26); - wallet_channel_config_load(w, remote_config_id, &channel_info->their_config); - - /* Load shachain */ - u64 shachain_id = sqlite3_column_int64(stmt, 27); - ok &= wallet_shachain_load(w, shachain_id, &chan->their_shachain); - - /* Do we have a non-null remote_shutdown_scriptpubkey? */ - if (sqlite3_column_type(stmt, 28) != SQLITE_NULL) { - chan->remote_shutdown_scriptpubkey = tal_arr(chan, u8, sqlite3_column_bytes(stmt, 28)); - memcpy(chan->remote_shutdown_scriptpubkey, sqlite3_column_blob(stmt, 28), sqlite3_column_bytes(stmt, 28)); - chan->local_shutdown_idx = sqlite3_column_int64(stmt, 29); - } else { - chan->remote_shutdown_scriptpubkey = tal_free(chan->remote_shutdown_scriptpubkey); - chan->local_shutdown_idx = -1; - } + remote_shutdown_scriptpubkey = sqlite3_column_arr(tmpctx, stmt, 28, u8); /* Do we have a last_sent_commit, if yes, populate */ if (sqlite3_column_type(stmt, 30) != SQLITE_NULL) { - if (!chan->last_sent_commit) { - chan->last_sent_commit = tal(chan, struct changed_htlc); - } - chan->last_sent_commit->newstate = sqlite3_column_int64(stmt, 30); - chan->last_sent_commit->id = sqlite3_column_int64(stmt, 31); + last_sent_commit = tal(tmpctx, struct changed_htlc); + last_sent_commit->newstate = sqlite3_column_int64(stmt, 30); + last_sent_commit->id = sqlite3_column_int64(stmt, 31); } else { - chan->last_sent_commit = tal_free(chan->last_sent_commit); + last_sent_commit = NULL; } - chan->last_tx = sqlite3_column_tx(chan, stmt, 32); - sqlite3_column_signature(stmt, 33, &chan->last_sig); + ok &= wallet_channel_config_load(w, sqlite3_column_int64(stmt, 3), + &our_config); + ok &= sqlite3_column_sha256_double(stmt, 12, &funding_txid.shad); - chan->last_was_revoke = sqlite3_column_int(stmt, 34) != 0; + ok &= sqlite3_column_signature(stmt, 33, &last_sig); - /* Load any htlc_sigs */ - chan->last_htlc_sigs = wallet_htlc_sigs_load(chan, w, chan->dbid); + /* Populate channel_info */ + ok &= sqlite3_column_pubkey(stmt, 18, &channel_info.remote_fundingkey); + ok &= sqlite3_column_pubkey(stmt, 19, &channel_info.theirbase.revocation); + ok &= sqlite3_column_pubkey(stmt, 20, &channel_info.theirbase.payment); + ok &= sqlite3_column_pubkey(stmt, 21, &channel_info.theirbase.htlc); + ok &= sqlite3_column_pubkey(stmt, 22, &channel_info.theirbase.delayed_payment); + ok &= sqlite3_column_pubkey(stmt, 23, &channel_info.remote_per_commit); + ok &= sqlite3_column_pubkey(stmt, 24, &channel_info.old_remote_per_commit); + channel_info.feerate_per_kw[LOCAL] = sqlite3_column_int(stmt, 25); + channel_info.feerate_per_kw[REMOTE] = sqlite3_column_int(stmt, 26); + wallet_channel_config_load(w, sqlite3_column_int64(stmt, 4), + &channel_info.their_config); + + if (!ok) { + tal_free(tmpctx); + return NULL; + } - if (!ok) - return tal_free(chan); + chan = new_channel(peer, sqlite3_column_int64(stmt, 0), + &wshachain, + sqlite3_column_int(stmt, 5), + sqlite3_column_int(stmt, 6), + NULL, /* Set up fresh log */ + sqlite3_column_int(stmt, 7), + &our_config, + sqlite3_column_int(stmt, 8), + sqlite3_column_int64(stmt, 9), + sqlite3_column_int64(stmt, 10), + sqlite3_column_int64(stmt, 11), + &funding_txid, + sqlite3_column_int(stmt, 13), + sqlite3_column_int64(stmt, 14), + sqlite3_column_int64(stmt, 16), + sqlite3_column_int(stmt, 15) != 0, + scid, + sqlite3_column_int64(stmt, 17), + sqlite3_column_tx(tmpctx, stmt, 32), + &last_sig, + wallet_htlc_sigs_load(tmpctx, w, + sqlite3_column_int64(stmt, 0)), + &channel_info, + remote_shutdown_scriptpubkey, + remote_shutdown_scriptpubkey + ? sqlite3_column_int64(stmt, 29) : -1, + sqlite3_column_int(stmt, 34) != 0, + last_sent_commit, + sqlite3_column_int64(stmt, 35)); + + tal_free(tmpctx); return chan; }