Skip to content

Commit 381bc9b

Browse files
committed
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 f85adac commit 381bc9b

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

plugins/renepay/mods.c

Lines changed: 32 additions & 12 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>
@@ -14,8 +15,6 @@
1415
#include <plugins/renepay/routetracker.h>
1516
#include <unistd.h>
1617

17-
#define INVALID_ID UINT64_MAX
18-
1918
#define OP_NULL NULL
2019
#define OP_CALL (void *)1
2120
#define OP_IF (void *)2
@@ -918,6 +917,15 @@ REGISTER_PAYMENT_MODIFIER(checktimeout, checktimeout_cb);
918917
* we should return payment_success inmediately.
919918
*/
920919

920+
static int cmp_u64(const u64 *a, const u64 *b, void *unused)
921+
{
922+
if (*a < *b)
923+
return -1;
924+
if (*a > *b)
925+
return 1;
926+
return 0;
927+
}
928+
921929
static struct command_result *pendingsendpays_done(struct command *cmd,
922930
const char *method UNUSED,
923931
const char *buf,
@@ -927,11 +935,12 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
927935
size_t i;
928936
const char *err;
929937
const jsmntok_t *t, *arr;
930-
u64 max_group_id = 0;
931938

932939
/* Data for pending payments, this will be the one
933940
* who's result gets replayed if we end up suspending. */
934-
u64 pending_group_id = INVALID_ID;
941+
bool has_pending = false;
942+
u64 unused_groupid;
943+
u64 pending_group_id;
935944
u64 max_pending_partid = 0;
936945
struct amount_msat pending_sent = AMOUNT_MSAT(0),
937946
pending_msat = AMOUNT_MSAT(0);
@@ -961,6 +970,8 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
961970
return payment_success(payment, &success.preimage);
962971
}
963972

973+
u64 *groupid_arr = tal_arr(tmpctx, u64, 0);
974+
964975
// find if there is one pending group
965976
json_for_each_arr(i, t, arr)
966977
{
@@ -980,10 +991,13 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
980991
__func__, err);
981992

982993
if (streq(status, "pending")) {
994+
has_pending = true;
983995
pending_group_id = groupid;
984996
break;
985997
}
998+
tal_arr_expand(&groupid_arr, groupid);
986999
}
1000+
assert(tal_count(groupid_arr) == arr->size);
9871001

9881002
/* We need two loops to get the highest partid for a groupid that has
9891003
* pending sendpays. */
@@ -1014,12 +1028,8 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10141028
"following error: %s",
10151029
__func__, err);
10161030

1017-
/* If we decide to create a new group, we base it on
1018-
* max_group_id */
1019-
if (groupid > max_group_id)
1020-
max_group_id = groupid;
1021-
1022-
if (groupid == pending_group_id && partid > max_pending_partid)
1031+
if (has_pending && groupid == pending_group_id &&
1032+
partid > max_pending_partid)
10231033
max_pending_partid = partid;
10241034

10251035
/* status could be completed, pending or failed */
@@ -1043,7 +1053,17 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10431053
assert(!streq(status, "complete"));
10441054
}
10451055

1046-
if (pending_group_id != INVALID_ID) {
1056+
/* find the first unused groupid */
1057+
unused_groupid = 0;
1058+
asort(groupid_arr, tal_count(groupid_arr), cmp_u64, NULL);
1059+
for (i = 0; i < tal_count(groupid_arr); i++) {
1060+
if (unused_groupid < groupid_arr[i])
1061+
break;
1062+
if (unused_groupid == groupid_arr[i])
1063+
unused_groupid++;
1064+
}
1065+
1066+
if (has_pending) {
10471067
/* Continue where we left off? */
10481068
payment->groupid = pending_group_id;
10491069
payment->next_partid = max_pending_partid + 1;
@@ -1061,7 +1081,7 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10611081
} else {
10621082
/* There are no pending nor completed sendpays, get me the last
10631083
* sendpay group. */
1064-
payment->groupid = max_group_id + 1;
1084+
payment->groupid = unused_groupid;
10651085
payment->next_partid = 1;
10661086
payment->total_sent = AMOUNT_MSAT(0);
10671087
payment->total_delivering = AMOUNT_MSAT(0);

0 commit comments

Comments
 (0)