Skip to content

Commit a2a186f

Browse files
Lagrang3endothermicdev
authored andcommitted
renepay: change the groupid selection
Searches the first unused groupid and uses that number for the current payment attempt. We previously used the highest value of used groupid + 1, which breaks in a few corner cases. Changelog-None Signed-off-by: Lagrang3 <[email protected]>
1 parent 0e98426 commit a2a186f

File tree

1 file changed

+32
-13
lines changed

1 file changed

+32
-13
lines changed

plugins/renepay/mods.c

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "config.h"
2+
#include <ccan/asort/asort.h>
23
#include <ccan/bitmap/bitmap.h>
34
#include <common/amount.h>
45
#include <common/bolt11.h>
@@ -15,8 +16,6 @@
1516
#include <unistd.h>
1617
#include <wire/bolt12_wiregen.h>
1718

18-
#define INVALID_ID UINT64_MAX
19-
2019
#define OP_NULL NULL
2120
#define OP_CALL (void *)1
2221
#define OP_IF (void *)2
@@ -932,6 +931,15 @@ REGISTER_PAYMENT_MODIFIER(checktimeout, checktimeout_cb);
932931
* we should return payment_success inmediately.
933932
*/
934933

934+
static int cmp_u64(const u64 *a, const u64 *b, void *unused)
935+
{
936+
if (*a < *b)
937+
return -1;
938+
if (*a > *b)
939+
return 1;
940+
return 0;
941+
}
942+
935943
static struct command_result *pendingsendpays_done(struct command *cmd,
936944
const char *method UNUSED,
937945
const char *buf,
@@ -941,11 +949,12 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
941949
size_t i;
942950
const char *err;
943951
const jsmntok_t *t, *arr;
944-
u64 max_group_id = 0;
945952

946953
/* Data for pending payments, this will be the one
947954
* who's result gets replayed if we end up suspending. */
948-
u64 pending_group_id = INVALID_ID;
955+
bool has_pending = false;
956+
u64 unused_groupid;
957+
u64 pending_group_id COMPILER_WANTS_INIT("12.3.0-17ubuntu1 -O3");
949958
u64 max_pending_partid = 0;
950959
struct amount_msat pending_sent = AMOUNT_MSAT(0),
951960
pending_msat = AMOUNT_MSAT(0);
@@ -975,6 +984,8 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
975984
return payment_success(payment, &success.preimage);
976985
}
977986

987+
u64 *groupid_arr = tal_arr(tmpctx, u64, 0);
988+
978989
// find if there is one pending group
979990
json_for_each_arr(i, t, arr)
980991
{
@@ -994,10 +1005,12 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
9941005
__func__, err);
9951006

9961007
if (streq(status, "pending")) {
1008+
has_pending = true;
9971009
pending_group_id = groupid;
998-
break;
9991010
}
1011+
tal_arr_expand(&groupid_arr, groupid);
10001012
}
1013+
assert(tal_count(groupid_arr) == arr->size);
10011014

10021015
/* We need two loops to get the highest partid for a groupid that has
10031016
* pending sendpays. */
@@ -1028,12 +1041,8 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10281041
"following error: %s",
10291042
__func__, err);
10301043

1031-
/* If we decide to create a new group, we base it on
1032-
* max_group_id */
1033-
if (groupid > max_group_id)
1034-
max_group_id = groupid;
1035-
1036-
if (groupid == pending_group_id && partid > max_pending_partid)
1044+
if (has_pending && groupid == pending_group_id &&
1045+
partid > max_pending_partid)
10371046
max_pending_partid = partid;
10381047

10391048
/* status could be completed, pending or failed */
@@ -1057,7 +1066,17 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10571066
assert(!streq(status, "complete"));
10581067
}
10591068

1060-
if (pending_group_id != INVALID_ID) {
1069+
/* find the first unused groupid */
1070+
unused_groupid = 1;
1071+
asort(groupid_arr, tal_count(groupid_arr), cmp_u64, NULL);
1072+
for (i = 0; i < tal_count(groupid_arr); i++) {
1073+
if (unused_groupid < groupid_arr[i])
1074+
break;
1075+
if (unused_groupid == groupid_arr[i])
1076+
unused_groupid++;
1077+
}
1078+
1079+
if (has_pending) {
10611080
/* Continue where we left off? */
10621081
payment->groupid = pending_group_id;
10631082
payment->next_partid = max_pending_partid + 1;
@@ -1075,7 +1094,7 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10751094
} else {
10761095
/* There are no pending nor completed sendpays, get me the last
10771096
* sendpay group. */
1078-
payment->groupid = max_group_id + 1;
1097+
payment->groupid = unused_groupid;
10791098
payment->next_partid = 1;
10801099
payment->total_sent = AMOUNT_MSAT(0);
10811100
payment->total_delivering = AMOUNT_MSAT(0);

0 commit comments

Comments
 (0)