mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
lightningd: Base peer->seed off of the channel ID
The peer->seed needs to be unique for each channel, since bitcoin pubkeys and the shachain are generated from it. However we also need to guarantee that the same seed is generated for a given channel every time, e.g., upon a restart. The DB channel ID is guaranteed to be unique, and will not change throughout the lifetime of a channel, so we simply mix it in, instead of a separate increasing counter. We also needed to make sure to store in the DB before deriving the seed, in order to get an ID assigned by the DB. Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
e51d261f51
commit
def3d77a70
@ -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) */
|
||||
|
@ -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 *
|
||||
|
@ -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,
|
||||
|
@ -550,6 +550,8 @@ static bool wallet_stmt2channel(struct wallet *w, sqlite3_stmt *stmt,
|
||||
|
||||
assert(col == 34);
|
||||
|
||||
chan->peer->channel = chan;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user