From a465fb9ad23b9bfdbb2c52336940b26d95339388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADckolas=20Goline?= Date: Wed, 20 May 2026 08:42:07 -0300 Subject: [PATCH] invoice: fix false BROKEN log in cmp_rr_number when sort self-compares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some qsort implementations (notably macOS) call the comparator with the same element against itself (a == b). cmp_rr_number assumed rr_numbers are unique across distinct channels and logged BROKEN on any tie, but when a == b then a->c == b->c and the tie is trivially expected — not a data corruption. Guard the BROKEN log with `if (a->c != b->c)`: equal channel pointers mean the same channel entry; only different channels sharing an rr_number is genuinely broken. This silences the spurious BROKEN log on macOS that caused test_xpay_limited_max_accepted_htlcs to fail with "had BROKEN or That's weird messages". Changelog-Fixed: invoice: no longer spuriously logs BROKEN when macOS qsort compares a routehint candidate to itself. Co-Authored-By: Claude Sonnet 4.6 --- lightningd/invoice.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lightningd/invoice.c b/lightningd/invoice.c index 28173383d23d..af922d46fa28 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -606,9 +606,12 @@ static int cmp_rr_number(const struct routehint_candidate *a, if (a->c->rr_number < b->c->rr_number) return -1; - /* They're unique, so can't be equal */ - log_broken(ld->log, "Two equal candidates %p and %p, channels %p and %p, rr_number %"PRIu64" and %"PRIu64, - a, b, a->c, b->c, a->c->rr_number, b->c->rr_number); + /* rr_numbers are unique per channel; equal means same channel. + * Some qsort implementations (notably macOS) compare an element + * with itself, so a->c == b->c is expected and not a bug. */ + if (a->c != b->c) + log_broken(ld->log, "Two equal candidates %p and %p, channels %p and %p, rr_number %"PRIu64" and %"PRIu64, + a, b, a->c, b->c, a->c->rr_number, b->c->rr_number); return 0; }