From 633fd21e006f0892c5aaab1253227c6e5019c834 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 13 Nov 2025 16:02:39 +1030 Subject: [PATCH] lightningd: introduce some changes for dual open id randomness even with CLN_DEV_ENTROPY_SEED. Signed-off-by: Rusty Russell --- lightningd/dual_open_control.c | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index ad55ca866..cb7c28b47 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -30,6 +30,7 @@ #include #include #include +#include #include struct commit_rcvd { @@ -4087,6 +4088,35 @@ static void dualopen_errmsg(struct channel *channel, err_for_them ? "sent" : "received", desc); } +/* This is a hack for CLN_DEV_ENTROPY_SEED. We cannot actually use + * the same seed for each dualopend, or they choose the same ids, and we + * clash when combining the PSBTs (this is phenomenally unlikey normally). + * So we set it (for the child) to an incrementing value. */ +static const char *dev_setup_dualopend_seed(const tal_t *ctx, struct lightningd *ld) +{ + static u64 seed_incr = 0; + char seedstr[STR_MAX_CHARS(u64)]; + const char *old_seed; + + if (!ld->developer) + return NULL; + + old_seed = getenv("CLN_DEV_ENTROPY_SEED"); + if (!old_seed) + return NULL; + + old_seed = tal_strdup(tmpctx, old_seed); + seed_incr++; + snprintf(seedstr, sizeof(seedstr), "%"PRIu64, atol(old_seed) + seed_incr); + setenv("CLN_DEV_ENTROPY_SEED", seedstr, 1); + return old_seed; +} + +static void dev_restore_seed(const char *old_seed) +{ + if (old_seed) + setenv("CLN_DEV_ENTROPY_SEED", old_seed, 1); +} bool peer_start_dualopend(struct peer *peer, struct peer_fd *peer_fd, @@ -4096,6 +4126,7 @@ bool peer_start_dualopend(struct peer *peer, u32 max_to_self_delay; struct amount_msat min_effective_htlc_capacity; const u8 *msg; + const char *dev_old_seed; hsmfd = hsm_get_client_fd(peer->ld, &peer->id, channel->unsaved_dbid, HSM_PERM_COMMITMENT_POINT @@ -4109,6 +4140,7 @@ bool peer_start_dualopend(struct peer *peer, return false; } + dev_old_seed = dev_setup_dualopend_seed(tmpctx, peer->ld); channel->owner = new_channel_subd(channel, peer->ld, "lightning_dualopend", @@ -4121,6 +4153,7 @@ bool peer_start_dualopend(struct peer *peer, channel_set_billboard, take(&peer_fd->fd), take(&hsmfd), NULL); + dev_restore_seed(dev_old_seed); if (!channel->owner) { channel_internal_error(channel, @@ -4174,6 +4207,7 @@ bool peer_restart_dualopend(struct peer *peer, int hsmfd; u32 *local_shutdown_script_wallet_index; u8 *msg; + const char *dev_old_seed; if (channel_state_uncommitted(channel->state)) return peer_start_dualopend(peer, peer_fd, channel); @@ -4193,6 +4227,7 @@ bool peer_restart_dualopend(struct peer *peer, return false; } + dev_old_seed = dev_setup_dualopend_seed(tmpctx, peer->ld); channel_set_owner(channel, new_channel_subd(channel, peer->ld, "lightning_dualopend", @@ -4205,6 +4240,8 @@ bool peer_restart_dualopend(struct peer *peer, channel_set_billboard, take(&peer_fd->fd), take(&hsmfd), NULL)); + dev_restore_seed(dev_old_seed); + if (!channel->owner) { log_broken(channel->log, "Could not subdaemon channel: %s", strerror(errno));