Skip to content

Commit 37281bc

Browse files
Lagrang3rustyrussell
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 5649984 commit 37281bc

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
@@ -911,6 +910,15 @@ REGISTER_PAYMENT_MODIFIER(checktimeout, checktimeout_cb);
911910
* we should return payment_success inmediately.
912911
*/
913912

913+
static int cmp_u64(const u64 *a, const u64 *b, void *unused)
914+
{
915+
if (*a < *b)
916+
return -1;
917+
if (*a > *b)
918+
return 1;
919+
return 0;
920+
}
921+
914922
static struct command_result *pendingsendpays_done(struct command *cmd,
915923
const char *method UNUSED,
916924
const char *buf,
@@ -920,11 +928,12 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
920928
size_t i;
921929
const char *err;
922930
const jsmntok_t *t, *arr;
923-
u64 max_group_id = 0;
924931

925932
/* Data for pending payments, this will be the one
926933
* who's result gets replayed if we end up suspending. */
927-
u64 pending_group_id = INVALID_ID;
934+
bool has_pending = false;
935+
u64 unused_groupid;
936+
u64 pending_group_id COMPILER_WANTS_INIT("12.3.0-17ubuntu1 -O3");
928937
u64 max_pending_partid = 0;
929938
struct amount_msat pending_sent = AMOUNT_MSAT(0),
930939
pending_msat = AMOUNT_MSAT(0);
@@ -954,6 +963,8 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
954963
return payment_success(payment, &success.preimage);
955964
}
956965

966+
u64 *groupid_arr = tal_arr(tmpctx, u64, 0);
967+
957968
// find if there is one pending group
958969
json_for_each_arr(i, t, arr)
959970
{
@@ -973,10 +984,13 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
973984
__func__, err);
974985

975986
if (streq(status, "pending")) {
987+
has_pending = true;
976988
pending_group_id = groupid;
977989
break;
978990
}
991+
tal_arr_expand(&groupid_arr, groupid);
979992
}
993+
assert(tal_count(groupid_arr) == arr->size);
980994

981995
/* We need two loops to get the highest partid for a groupid that has
982996
* pending sendpays. */
@@ -1007,12 +1021,8 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10071021
"following error: %s",
10081022
__func__, err);
10091023

1010-
/* If we decide to create a new group, we base it on
1011-
* max_group_id */
1012-
if (groupid > max_group_id)
1013-
max_group_id = groupid;
1014-
1015-
if (groupid == pending_group_id && partid > max_pending_partid)
1024+
if (has_pending && groupid == pending_group_id &&
1025+
partid > max_pending_partid)
10161026
max_pending_partid = partid;
10171027

10181028
/* status could be completed, pending or failed */
@@ -1036,7 +1046,17 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10361046
assert(!streq(status, "complete"));
10371047
}
10381048

1039-
if (pending_group_id != INVALID_ID) {
1049+
/* find the first unused groupid */
1050+
unused_groupid = 0;
1051+
asort(groupid_arr, tal_count(groupid_arr), cmp_u64, NULL);
1052+
for (i = 0; i < tal_count(groupid_arr); i++) {
1053+
if (unused_groupid < groupid_arr[i])
1054+
break;
1055+
if (unused_groupid == groupid_arr[i])
1056+
unused_groupid++;
1057+
}
1058+
1059+
if (has_pending) {
10401060
/* Continue where we left off? */
10411061
payment->groupid = pending_group_id;
10421062
payment->next_partid = max_pending_partid + 1;
@@ -1054,7 +1074,7 @@ static struct command_result *pendingsendpays_done(struct command *cmd,
10541074
} else {
10551075
/* There are no pending nor completed sendpays, get me the last
10561076
* sendpay group. */
1057-
payment->groupid = max_group_id + 1;
1077+
payment->groupid = unused_groupid;
10581078
payment->next_partid = 1;
10591079
payment->total_sent = AMOUNT_MSAT(0);
10601080
payment->total_delivering = AMOUNT_MSAT(0);

0 commit comments

Comments
 (0)