mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-21 16:14:23 +01:00
invoice: don't allow zero-value invoices.
You can't pay them anyway, and at least one person used 0 instead of "any". Closes: #3808 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Changed: JSON-RPC: `invoice` no longer accepts zero amounts (did you mean "any"?)
This commit is contained in:
2
doc/lightning-invoice.7
generated
2
doc/lightning-invoice.7
generated
@@ -16,7 +16,7 @@ invoice, if any exists\.
|
||||
|
||||
|
||||
The \fImsatoshi\fR parameter can be the string "any", which creates an
|
||||
invoice that can be paid with any amount\. Otherwise it is in
|
||||
invoice that can be paid with any amount\. Otherwise it is a positive value in
|
||||
millisatoshi precision; it can be a whole number, or a whole number
|
||||
ending in \fImsat\fR or \fIsat\fR, or a number with three decimal places ending
|
||||
in \fIsat\fR, or a number with 1 to 11 decimal places ending in \fIbtc\fR\.
|
||||
|
||||
@@ -17,7 +17,7 @@ lightning daemon can use to pay this invoice. This token includes a
|
||||
invoice, if any exists.
|
||||
|
||||
The *msatoshi* parameter can be the string "any", which creates an
|
||||
invoice that can be paid with any amount. Otherwise it is in
|
||||
invoice that can be paid with any amount. Otherwise it is a positive value in
|
||||
millisatoshi precision; it can be a whole number, or a whole number
|
||||
ending in *msat* or *sat*, or a number with three decimal places ending
|
||||
in *sat*, or a number with 1 to 11 decimal places ending in *btc*.
|
||||
|
||||
@@ -826,7 +826,7 @@ static struct route_info **unpack_routes(const tal_t *ctx,
|
||||
}
|
||||
#endif /* DEVELOPER */
|
||||
|
||||
static struct command_result *param_msat_or_any(struct command *cmd,
|
||||
static struct command_result *param_positive_msat_or_any(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
@@ -837,11 +837,13 @@ static struct command_result *param_msat_or_any(struct command *cmd,
|
||||
return NULL;
|
||||
}
|
||||
*msat = tal(cmd, struct amount_msat);
|
||||
if (parse_amount_msat(*msat, buffer + tok->start, tok->end - tok->start))
|
||||
if (parse_amount_msat(*msat, buffer + tok->start, tok->end - tok->start)
|
||||
&& !amount_msat_eq(**msat, AMOUNT_MSAT(0)))
|
||||
return NULL;
|
||||
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"'%s' should be millisatoshis or 'any', not '%.*s'",
|
||||
"'%s' should be positive millisatoshis or 'any',"
|
||||
" not '%.*s'",
|
||||
name,
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
@@ -963,7 +965,7 @@ static struct command_result *json_invoice(struct command *cmd,
|
||||
info->cmd = cmd;
|
||||
|
||||
if (!param(cmd, buffer, params,
|
||||
p_req("msatoshi", param_msat_or_any, &msatoshi_val),
|
||||
p_req("msatoshi", param_positive_msat_or_any, &msatoshi_val),
|
||||
p_req("label", param_label, &info->label),
|
||||
p_req("description", param_escaped_string, &desc_val),
|
||||
p_opt_def("expiry", param_time, &expiry, 3600*24*7),
|
||||
|
||||
@@ -59,6 +59,26 @@ def test_invoice(node_factory, chainparams):
|
||||
l2.rpc.invoice(4294967295, 'inv3', '?')
|
||||
|
||||
|
||||
def test_invoice_zeroval(node_factory):
|
||||
"""A zero value invoice is unpayable, did you mean 'any'?"""
|
||||
l1 = node_factory.get_node()
|
||||
|
||||
with pytest.raises(RpcError, match=r"positive .* not '0'"):
|
||||
l1.rpc.invoice(0, 'inv', '?')
|
||||
|
||||
with pytest.raises(RpcError, match=r"positive .* not '0msat'"):
|
||||
l1.rpc.invoice('0msat', 'inv', '?')
|
||||
|
||||
with pytest.raises(RpcError, match=r"positive .* not '0sat'"):
|
||||
l1.rpc.invoice('0sat', 'inv', '?')
|
||||
|
||||
with pytest.raises(RpcError, match=r"positive .* not '0.00000000btc'"):
|
||||
l1.rpc.invoice('0.00000000btc', 'inv', '?')
|
||||
|
||||
with pytest.raises(RpcError, match=r"positive .* not '0.00000000000btc'"):
|
||||
l1.rpc.invoice('0.00000000000btc', 'inv', '?')
|
||||
|
||||
|
||||
def test_invoice_weirdstring(node_factory):
|
||||
l1 = node_factory.get_node()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user