diff --git a/common/jsonrpc_errors.h b/common/jsonrpc_errors.h index d3fe80d53997..a2ea1bf1b2e1 100644 --- a/common/jsonrpc_errors.h +++ b/common/jsonrpc_errors.h @@ -116,6 +116,7 @@ enum jsonrpc_errcode { OFFER_BAD_INVREQ_REPLY = 1004, OFFER_TIMEOUT = 1005, OFFER_ALREADY_ENABLED = 1006, + OFFER_USED_SINGLE_USE = 1007, /* Errors from datastore command */ DATASTORE_DEL_DOES_NOT_EXIST = 1200, diff --git a/lightningd/offer.c b/lightningd/offer.c index bd4357eb33af..50edd4d4f9b6 100644 --- a/lightningd/offer.c +++ b/lightningd/offer.c @@ -282,6 +282,10 @@ static struct command_result *json_enableoffer(struct command *cmd, return command_fail(cmd, OFFER_ALREADY_ENABLED, "offer already active"); + if (offer_status_single(status) && offer_status_used(status)) + return command_fail(cmd, OFFER_USED_SINGLE_USE, + "cannot activate an used single use offer"); + if (command_check_only(cmd)) return command_check_done(cmd); diff --git a/tests/test_pay.py b/tests/test_pay.py index 48abcb3142ab..cf016f58ef5d 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -4591,9 +4591,11 @@ def test_fetchinvoice(node_factory, bitcoind): assert 'msat' not in inv1['changes'] # Single-use invoice can be fetched multiple times, only paid once. - offer2 = l3.rpc.call('offer', {'amount': '1msat', - 'description': 'single-use test', - 'single_use': True})['bolt12'] + offer2_ret = l3.rpc.call('offer', {'amount': '1msat', + 'description': 'single-use test', + 'single_use': True}) + offer2 = offer2_ret['bolt12'] + offer2_id = offer2_ret['offer_id'] # We've done 3 onion calls: sleep now to avoid hitting ratelimit! time.sleep(1) @@ -4614,6 +4616,12 @@ def test_fetchinvoice(node_factory, bitcoind): with pytest.raises(RpcError, match='Offer no longer available'): l1.rpc.call('fetchinvoice', {'offer': offer2}) + # Can't enable it either! + OFFER_USED_SINGLE_USE = 1007 + with pytest.raises(RpcError) as excinfo: + l3.rpc.enableoffer(offer_id=offer2_id) + assert excinfo.value.error['code'] == OFFER_USED_SINGLE_USE + # Now, test amount in different currency! plugin = os.path.join(os.path.dirname(__file__), 'plugins/currencyUSDAUD5000.py') l3.rpc.plugin_start(plugin)