offers: make sure quantity limits are sane.

You could have quantity_min of 0, which makes no sense; spec has been
updated, so quote and enforce that.

Reported-by: @shesek
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2021-07-21 15:07:08 +09:30 committed by neil saitug
parent 7769903f1a
commit 0a0b2ce940
2 changed files with 42 additions and 0 deletions

View File

@ -319,6 +319,28 @@ struct command_result *json_offer(struct command *cmd,
NULL))
return command_param_failed();
/* BOLT-offers #12:
* - MUST NOT set `quantity_min` or `quantity_max` less than 1.
*/
if (offer->quantity_min && *offer->quantity_min < 1)
return command_fail_badparam(cmd, "quantity_min",
buffer, params,
"must be >= 1");
if (offer->quantity_max && *offer->quantity_max < 1)
return command_fail_badparam(cmd, "quantity_max",
buffer, params,
"must be >= 1");
/* BOLT-offers #12:
* - if both:
* - MUST set `quantity_min` less than or equal to `quantity_max`.
*/
if (offer->quantity_min && offer->quantity_max) {
if (*offer->quantity_min > *offer->quantity_max)
return command_fail_badparam(cmd, "quantity_min",
buffer, params,
"must be <= quantity_max");
}
/* BOLT-offers #12:
*
* - if the chain for the invoice is not solely bitcoin:

View File

@ -4006,6 +4006,26 @@ def test_offer(node_factory, bitcoind):
offer['bolt12']]).decode('UTF-8')
assert 'quantity_max: 2' in output
# BOLT-offers #12:
# * - MUST NOT set `quantity_min` or `quantity_max` less than 1.
with pytest.raises(RpcError, match='quantity_min: must be >= 1'):
ret = l1.rpc.call('offer', {'amount': '100000sat',
'description': 'quantity_min test',
'quantity_min': 0})
with pytest.raises(RpcError, match='quantity_max: must be >= 1'):
ret = l1.rpc.call('offer', {'amount': '100000sat',
'description': 'quantity_max test',
'quantity_max': 0})
# BOLT-offers #12:
# - if both:
# - MUST set `quantity_min` greater or equal to `quantity_max`.
with pytest.raises(RpcError, match='quantity_min: must be <= quantity_max'):
ret = l1.rpc.call('offer', {'amount': '100000sat',
'description': 'quantity_max test',
'quantity_min': 10,
'quantity_max': 9})
# Test absolute_expiry
exp = int(time.time() + 2)
ret = l1.rpc.call('offer', {'amount': '100000sat',