mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
pay: Do not clobber error messages if we fail decoding a bolt11
We were automatically falling back to bolt12 decoding, clobbering the fail message. Ultimately resulting in confusing error messages (expected prefix lni but got lnbtrc). Now we first determine which decoding we're trying to do, and then only decode accordingly. Changelog-Fixed: pay: Report the correct decoding error if bolt11 parsing fails.
This commit is contained in:
parent
ea92466025
commit
40e9d60ce0
1 changed files with 37 additions and 22 deletions
|
@ -1973,6 +1973,7 @@ static struct command_result *json_paymod(struct command *cmd,
|
|||
u64 invexpiry;
|
||||
struct sha256 *local_offer_id;
|
||||
const struct tlv_invoice *b12;
|
||||
bool is_b12;
|
||||
#if DEVELOPER
|
||||
bool *use_shadow;
|
||||
#endif
|
||||
|
@ -2003,31 +2004,45 @@ static struct command_result *json_paymod(struct command *cmd,
|
|||
p = payment_new(cmd, cmd, NULL /* No parent */, paymod_mods);
|
||||
p->invstring = tal_steal(p, b11str);
|
||||
|
||||
b11 = bolt11_decode(cmd, b11str, plugin_feature_set(cmd->plugin),
|
||||
NULL, chainparams, &fail);
|
||||
if (b11) {
|
||||
is_b12 = strlen(b11str) > 3 &&
|
||||
(strstarts(b11str, "lni") || strstarts(b11str, "lno") ||
|
||||
strstarts(b11str, "lnr"));
|
||||
|
||||
b11 = bolt11_decode(cmd, b11str, plugin_feature_set(cmd->plugin), NULL,
|
||||
chainparams, &fail);
|
||||
if (!is_b12) {
|
||||
if (b11 == NULL)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Invalid bolt11: %s", fail);
|
||||
invmsat = b11->msat;
|
||||
invexpiry = b11->timestamp + b11->expiry;
|
||||
|
||||
p->destination = tal_dup(p, struct node_id, &b11->receiver_id);
|
||||
p->destination_has_tlv = feature_offered(b11->features,
|
||||
OPT_VAR_ONION);
|
||||
p->destination_has_tlv =
|
||||
feature_offered(b11->features, OPT_VAR_ONION);
|
||||
p->payment_hash = tal_dup(p, struct sha256, &b11->payment_hash);
|
||||
p->payment_secret = b11->payment_secret
|
||||
p->payment_secret =
|
||||
b11->payment_secret
|
||||
? tal_dup(p, struct secret, b11->payment_secret)
|
||||
: NULL;
|
||||
p->routes = tal_steal(p, b11->routes);
|
||||
p->min_final_cltv_expiry = b11->min_final_cltv_expiry;
|
||||
p->features = tal_steal(p, b11->features);
|
||||
/* Sanity check */
|
||||
if (feature_offered(b11->features, OPT_VAR_ONION)
|
||||
&& !b11->payment_secret)
|
||||
if (feature_offered(b11->features, OPT_VAR_ONION) &&
|
||||
!b11->payment_secret)
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Invalid bolt11:"
|
||||
" sets feature var_onion with no secret");
|
||||
} else {
|
||||
b12 = invoice_decode(cmd, b11str, strlen(b11str),
|
||||
plugin_feature_set(cmd->plugin),
|
||||
chainparams, &fail);
|
||||
if (b12 == NULL)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Invalid bolt11:"
|
||||
" sets feature var_onion with no secret");
|
||||
} else if ((b12 = invoice_decode(cmd, b11str, strlen(b11str),
|
||||
plugin_feature_set(cmd->plugin),
|
||||
chainparams, &fail)) != NULL) {
|
||||
"Invalid bolt12: %s", fail);
|
||||
|
||||
if (!exp_offers)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"experimental-offers disabled");
|
||||
|
@ -2051,14 +2066,14 @@ static struct command_result *json_paymod(struct command *cmd,
|
|||
|
||||
/* FIXME: gossmap should store as pubkey32 */
|
||||
p->destination = tal(p, struct node_id);
|
||||
gossmap_guess_node_id(get_gossmap(cmd->plugin),
|
||||
b12->node_id,
|
||||
gossmap_guess_node_id(get_gossmap(cmd->plugin), b12->node_id,
|
||||
p->destination);
|
||||
p->destination_has_tlv = true;
|
||||
p->payment_hash = tal_dup(p, struct sha256, b12->payment_hash);
|
||||
if (b12->recurrence_counter && !label)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"recurring invoice requires a label");
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"recurring invoice requires a label");
|
||||
/* FIXME payment_secret should be signature! */
|
||||
{
|
||||
struct sha256 merkle;
|
||||
|
@ -2066,7 +2081,8 @@ static struct command_result *json_paymod(struct command *cmd,
|
|||
p->payment_secret = tal(p, struct secret);
|
||||
merkle_tlv(b12->fields, &merkle);
|
||||
memcpy(p->payment_secret, &merkle, sizeof(merkle));
|
||||
BUILD_ASSERT(sizeof(*p->payment_secret) == sizeof(merkle));
|
||||
BUILD_ASSERT(sizeof(*p->payment_secret) ==
|
||||
sizeof(merkle));
|
||||
}
|
||||
p->routes = NULL;
|
||||
/* FIXME: paths! */
|
||||
|
@ -2081,16 +2097,15 @@ static struct command_result *json_paymod(struct command *cmd,
|
|||
* `seconds_from_timestamp`.
|
||||
* - otherwise:
|
||||
* - MUST reject the invoice if the current time since
|
||||
* 1970-01-01 UTC is greater than `timestamp` plus 7200.
|
||||
* 1970-01-01 UTC is greater than `timestamp` plus
|
||||
* 7200.
|
||||
*/
|
||||
if (b12->relative_expiry)
|
||||
invexpiry = *b12->timestamp + *b12->relative_expiry;
|
||||
else
|
||||
invexpiry = *b12->timestamp + BOLT12_DEFAULT_REL_EXPIRY;
|
||||
p->local_offer_id = tal_steal(p, local_offer_id);
|
||||
} else
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Invalid bolt11: %s", fail);
|
||||
}
|
||||
|
||||
if (time_now().ts.tv_sec > invexpiry)
|
||||
return command_fail(cmd, PAY_INVOICE_EXPIRED, "Invoice expired");
|
||||
|
|
Loading…
Add table
Reference in a new issue