diff --git a/plugins/offers.c b/plugins/offers.c index 735ba87b6..2cefc1ff7 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -1,6 +1,7 @@ /* This plugin covers both sending and receiving offers */ #include "config.h" #include +#include #include #include #include @@ -314,7 +315,7 @@ struct find_best_peer_data { struct command_result *(*cb)(struct command *, const struct chaninfo *, void *); - int needed_feature; + u64 needed_features; void *arg; }; @@ -333,6 +334,7 @@ static struct command_result *listincoming_done(struct command *cmd, struct chaninfo ci; const jsmntok_t *pftok; u8 *features; + u64 feature_bits; const char *err; struct amount_msat feebase; bool enabled; @@ -373,11 +375,20 @@ static struct command_result *listincoming_done(struct command *cmd, if (!pftok) continue; features = json_tok_bin_from_hex(tmpctx, buf, pftok); - if (!feature_offered(features, data->needed_feature)) - continue; + + /* It must have all the features we need */ + feature_bits = data->needed_features; + while (feature_bits) { + int feature = bitops_ls64(feature_bits); + if (!feature_offered(features, feature)) + goto next; + feature_bits &= ~(1ULL << feature); + } if (!best || amount_msat_greater(ci.capacity, best->capacity)) best = tal_dup(tmpctx, struct chaninfo, &ci); + + next:; } /* Free data if they don't */ @@ -386,7 +397,7 @@ static struct command_result *listincoming_done(struct command *cmd, } struct command_result *find_best_peer_(struct command *cmd, - int needed_feature, + u64 needed_features, struct command_result *(*cb)(struct command *, const struct chaninfo *, void *), @@ -396,7 +407,7 @@ struct command_result *find_best_peer_(struct command *cmd, struct find_best_peer_data *data = tal(cmd, struct find_best_peer_data); data->cb = cb; data->arg = arg; - data->needed_feature = needed_feature; + data->needed_features = needed_features; req = jsonrpc_request_start(cmd, "listincoming", listincoming_done, forward_error, data); return send_outreq(req); diff --git a/plugins/offers.h b/plugins/offers.h index e59796a9f..b7be946fb 100644 --- a/plugins/offers.h +++ b/plugins/offers.h @@ -78,14 +78,14 @@ struct chaninfo { /* Calls listpeerchannels, then cb with best peer (if any!) which has needed_feature */ struct command_result *find_best_peer_(struct command *cmd, - int needed_feature, + u64 needed_features, struct command_result *(*cb)(struct command *, const struct chaninfo *, void *), void *arg); -#define find_best_peer(cmd, needed_feature, cb, arg) \ - find_best_peer_((cmd), (needed_feature), \ +#define find_best_peer(cmd, needed_features, cb, arg) \ + find_best_peer_((cmd), (needed_features), \ typesafe_cb_preargs(struct command_result *, void *, \ (cb), (arg), \ struct command *, \ diff --git a/plugins/offers_invreq_hook.c b/plugins/offers_invreq_hook.c index 6f8bcc103..d57b7f953 100644 --- a/plugins/offers_invreq_hook.c +++ b/plugins/offers_invreq_hook.c @@ -381,7 +381,7 @@ static struct command_result *add_blindedpaths(struct command *cmd, if (!we_want_blinded_path(cmd->plugin, true)) return create_invoicereq(cmd, ir); - return find_best_peer(cmd, OPT_ROUTE_BLINDING, + return find_best_peer(cmd, 1ULL << OPT_ROUTE_BLINDING, found_best_peer, ir); } diff --git a/plugins/offers_offer.c b/plugins/offers_offer.c index 53c88f05a..8bad82496 100644 --- a/plugins/offers_offer.c +++ b/plugins/offers_offer.c @@ -303,7 +303,7 @@ static struct command_result *maybe_add_path(struct command *cmd, */ if (!offinfo->offer->offer_paths) { if (we_want_blinded_path(cmd->plugin, false)) - return find_best_peer(cmd, OPT_ONION_MESSAGES, + return find_best_peer(cmd, 1ULL << OPT_ONION_MESSAGES, found_best_peer, offinfo); } return create_offer(cmd, offinfo); @@ -729,7 +729,7 @@ struct command_result *json_invoicerequest(struct command *cmd, idata->invreq = invreq; idata->single_use = *single_use; idata->label = label; - return find_best_peer(cmd, OPT_ONION_MESSAGES, + return find_best_peer(cmd, 1ULL << OPT_ONION_MESSAGES, found_best_peer_invrequest, idata); }