mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
invoice: turn assert failure into more informative log_broken message.
We had this assertion fail, and I can't see a clear reason why. Remove it (i.e. don't crash because we're having trouble with creating invoice routehints) and add logging. ``` Assertion failed: a->c->rr_number < b->c->rr_number (lightningd/invoice.c: cmp_rr_number: 623) lightningd: FATAL SIGNAL 6 (version v0.10.2-modded) 0x5654f1c40061 send_backtrace common/daemon.c:33 0x5654f1c400e9 crashdump common/daemon.c:46 0x7efd87da6c8a ??? ???:0 ``` There are several possible causes for this: 1. We have two channels with the same rr_number. A quick audit shows we always set that rr_number to a unique value (and 64 bits, so wrap is not possible between the release and now!). 2. It's theoretically possible that sort() could compare a value with itself, but that would be really dumb: it doesn't that I've ever seen, but then, we've never seen this assert() hit, either. 3. listincoming has given us the same channel twice. I don't see how that is possible: we had a race where channels could momentarily vanish, but never be duplicated (emailed crash.log shows no duplicates!). 4. General corruption/freed memory access. If a channel we've just looked up is gone but still in the hash table, this is possible but would cause lots of random behavior and crashes. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
9d1b5a654e
commit
3a61e0e181
@ -617,13 +617,17 @@ static struct route_info **select_inchan(const tal_t *ctx,
|
||||
|
||||
static int cmp_rr_number(const struct routehint_candidate *a,
|
||||
const struct routehint_candidate *b,
|
||||
void *unused)
|
||||
struct lightningd *ld)
|
||||
{
|
||||
/* They're unique, so can't be equal */
|
||||
if (a->c->rr_number > b->c->rr_number)
|
||||
return 1;
|
||||
assert(a->c->rr_number < b->c->rr_number);
|
||||
return -1;
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** select_inchan_mpp
|
||||
@ -650,7 +654,7 @@ static struct route_info **select_inchan_mpp(const tal_t *ctx,
|
||||
routehints = tal_arr(ctx, struct route_info *, 0);
|
||||
|
||||
/* Sort by rr_number, so we get fresh channels. */
|
||||
asort(candidates, tal_count(candidates), cmp_rr_number, NULL);
|
||||
asort(candidates, tal_count(candidates), cmp_rr_number, ld);
|
||||
for (size_t i = 0; i < tal_count(candidates); i++) {
|
||||
if (amount_msat_greater_eq(gathered, amount_needed))
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user