diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 823e697c0..c90424f44 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -178,21 +178,17 @@ static const char *find_my_path(const tal_t *ctx, const char *argv0) } void derive_peer_seed(struct lightningd *ld, struct privkey *peer_seed, - const struct pubkey *peer_id) + const struct pubkey *peer_id, const u64 channel_id) { - be64 counter = cpu_to_be64(ld->peer_counter); - u8 input[PUBKEY_DER_LEN + sizeof(counter)]; + u8 input[PUBKEY_DER_LEN + sizeof(channel_id)]; char *info = "per-peer seed"; - pubkey_to_der(input, peer_id); - memcpy(input + PUBKEY_DER_LEN, &counter, sizeof(counter)); + memcpy(input + PUBKEY_DER_LEN, &channel_id, sizeof(channel_id)); hkdf_sha256(peer_seed, sizeof(*peer_seed), input, sizeof(input), &ld->peer_seed, sizeof(ld->peer_seed), info, strlen(info)); - /* FIXME: This must be saved in db. */ - ld->peer_counter++; } static void shutdown_subdaemons(struct lightningd *ld) @@ -273,7 +269,7 @@ int main(int argc, char *argv[]) list_for_each(&ld->peers, peer, list) { populate_peer(ld, peer); peer->seed = tal(peer, struct privkey); - derive_peer_seed(ld, peer->seed, &peer->id); + derive_peer_seed(ld, peer->seed, &peer->id, peer->channel->id); } /* Create RPC socket (if any) */ diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index bc978749b..dc3322f9b 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -65,8 +65,23 @@ struct lightningd { const struct chainparams *chainparams; }; +/** + * derive_peer_seed - Generate a unique secret for this peer's channel + * + * @ld: the lightning daemon to get global secret from + * @peer_seed: where to store the generated secret + * @peer_id: the id node_id of the remote peer + * @chan_id: channel ID + * + * This method generates a unique secret from the given parameters. It + * is important that this secret be unique for each channel, but it + * must be reproducible for the same channel in case of + * reconnection. We use the DB channel ID to guarantee unique secrets + * per channel. + */ void derive_peer_seed(struct lightningd *ld, struct privkey *peer_seed, - const struct pubkey *peer_id); + const struct pubkey *peer_id, const u64 channel_id); + struct peer *find_peer_by_unique_id(struct lightningd *ld, u64 unique_id); /* FIXME */ static inline struct lightningd * diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index f8b8da969..26b53d995 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2042,8 +2042,16 @@ void peer_fundee_open(struct peer *peer, const u8 *from_peer, &max_to_self_delay, &max_minimum_depth, &min_effective_htlc_capacity_msat); + /* Store the channel in the database in order to get a channel + * ID that is unique and which we can base the peer_seed on */ + peer->channel = peer_channel_new(ld->wallet, peer); + if (!wallet_channel_save(peer->ld->wallet, peer->channel)) { + fatal("Could not save channel to database: %s", + peer->ld->wallet->db->err); + } peer->seed = tal(peer, struct privkey); - derive_peer_seed(ld, peer->seed, &peer->id); + derive_peer_seed(ld, peer->seed, &peer->id, peer->channel->id); + msg = towire_opening_init(peer, ld->chainparams->index, &peer->our_config, max_to_self_delay, @@ -2060,7 +2068,6 @@ void peer_fundee_open(struct peer *peer, const u8 *from_peer, peer_fail_permanent_str(peer, "Unacceptably long open_channel"); return; } - peer->channel = peer_channel_new(ld->wallet, peer); subd_req(peer, peer->owner, take(msg), -1, 2, opening_fundee_finished, peer); } @@ -2104,7 +2111,16 @@ static bool gossip_peer_released(struct subd *gossip, } fc->peer->owner = opening; + /* Store the channel in the database in order to get a channel + * ID that is unique and which we can base the peer_seed on */ fc->peer->channel = peer_channel_new(ld->wallet, fc->peer); + if (!wallet_channel_save(fc->peer->ld->wallet, fc->peer->channel)) { + fatal("Could not save channel to database: %s", + fc->peer->ld->wallet->db->err); + } + fc->peer->seed = tal(fc->peer, struct privkey); + derive_peer_seed(ld, fc->peer->seed, &fc->peer->id, + fc->peer->channel->id); /* We will fund channel */ fc->peer->funder = LOCAL; @@ -2114,8 +2130,6 @@ static bool gossip_peer_released(struct subd *gossip, fc->peer->channel_flags = OUR_CHANNEL_FLAGS; - fc->peer->seed = tal(fc->peer, struct privkey); - derive_peer_seed(ld, fc->peer->seed, &fc->peer->id); msg = towire_opening_init(fc, ld->chainparams->index, &fc->peer->our_config, max_to_self_delay, diff --git a/wallet/wallet.c b/wallet/wallet.c index 34e148119..8685819b8 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -550,6 +550,8 @@ static bool wallet_stmt2channel(struct wallet *w, sqlite3_stmt *stmt, assert(col == 34); + chan->peer->channel = chan; + return ok; }