mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
delinvoice: allow desconly arg to only remove the description.
Means that field is now optional in JSON output. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: JSON-RPC: `delinvoice` has a new parameter `desconly` to remove description.
This commit is contained in:
@@ -77,6 +77,7 @@ static const errcode_t INVOICE_WAIT_TIMED_OUT = 904;
|
|||||||
static const errcode_t INVOICE_NOT_FOUND = 905;
|
static const errcode_t INVOICE_NOT_FOUND = 905;
|
||||||
static const errcode_t INVOICE_STATUS_UNEXPECTED = 906;
|
static const errcode_t INVOICE_STATUS_UNEXPECTED = 906;
|
||||||
static const errcode_t INVOICE_OFFER_INACTIVE = 907;
|
static const errcode_t INVOICE_OFFER_INACTIVE = 907;
|
||||||
|
static const errcode_t INVOICE_NO_DESCRIPTION = 908;
|
||||||
|
|
||||||
/* Errors from HSM crypto operations. */
|
/* Errors from HSM crypto operations. */
|
||||||
static const errcode_t HSM_ECDH_FAILED = 800;
|
static const errcode_t HSM_ECDH_FAILED = 800;
|
||||||
|
|||||||
@@ -566,13 +566,14 @@ class LightningRpc(UnixDomainSocketRpc):
|
|||||||
}
|
}
|
||||||
return self.call("delexpiredinvoice", payload)
|
return self.call("delexpiredinvoice", payload)
|
||||||
|
|
||||||
def delinvoice(self, label, status):
|
def delinvoice(self, label, status, desconly=None):
|
||||||
"""
|
"""
|
||||||
Delete unpaid invoice {label} with {status}.
|
Delete unpaid invoice {label} with {status} (or, with {desconly} true, remove its description).
|
||||||
"""
|
"""
|
||||||
payload = {
|
payload = {
|
||||||
"label": label,
|
"label": label,
|
||||||
"status": status
|
"status": status,
|
||||||
|
"desconly": desconly,
|
||||||
}
|
}
|
||||||
return self.call("delinvoice", payload)
|
return self.call("delinvoice", payload)
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
lightning-delinvoice -- Command for removing an invoice
|
lightning-delinvoice -- Command for removing an invoice (or just its description)
|
||||||
=======================================================
|
=================================================================================
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
|
|
||||||
**delinvoice** *label* *status*
|
**delinvoice** *label* *status* [*desconly*]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
The **delinvoice** RPC command removes an invoice with *status* as given
|
The **delinvoice** RPC command removes an invoice with *status* as given
|
||||||
in **listinvoices**.
|
in **listinvoices**, or with *desconly* set, removes its description.
|
||||||
|
|
||||||
The caller should be particularly aware of the error case caused by the
|
The caller should be particularly aware of the error case caused by the
|
||||||
*status* changing just before this command is invoked!
|
*status* changing just before this command is invoked!
|
||||||
|
|
||||||
|
If *desconly* is set, the invoice is not deleted, but has its
|
||||||
|
description removed (this can save space with very large descriptions,
|
||||||
|
as would be used with lightning-invoice(7) *deschashonly*.
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@@ -55,6 +59,7 @@ The following errors may be reported:
|
|||||||
*current_status* and *expected_status* fields.
|
*current_status* and *expected_status* fields.
|
||||||
This is most likely due to the *status* of the invoice
|
This is most likely due to the *status* of the invoice
|
||||||
changing just before this command is invoked.
|
changing just before this command is invoked.
|
||||||
|
- 908: The invoice already has no description, and *desconly* was set.
|
||||||
|
|
||||||
AUTHOR
|
AUTHOR
|
||||||
------
|
------
|
||||||
@@ -73,4 +78,4 @@ RESOURCES
|
|||||||
|
|
||||||
Main web site: <https://github.com/ElementsProject/lightning>
|
Main web site: <https://github.com/ElementsProject/lightning>
|
||||||
|
|
||||||
[comment]: # ( SHA256STAMP:cd3b009a6ef0c220ca21c6d8e3a5716ca2080997016cf00a2e26defc03cfac73)
|
[comment]: # ( SHA256STAMP:73d9097734e85d438de90844ab78bdd737e6df53620542887170c7564a86b90b)
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ RETURN VALUE
|
|||||||
[comment]: # (GENERATE-FROM-SCHEMA-START)
|
[comment]: # (GENERATE-FROM-SCHEMA-START)
|
||||||
On success, an object containing **invoices** is returned. It is an array of objects, where each object contains:
|
On success, an object containing **invoices** is returned. It is an array of objects, where each object contains:
|
||||||
- **label** (string): unique label supplied at invoice creation
|
- **label** (string): unique label supplied at invoice creation
|
||||||
- **description** (string): description used in the invoice
|
|
||||||
- **payment_hash** (hex): the hash of the *payment_preimage* which will prove payment (always 64 characters)
|
- **payment_hash** (hex): the hash of the *payment_preimage* which will prove payment (always 64 characters)
|
||||||
- **status** (string): Whether it's paid, unpaid or unpayable (one of "unpaid", "paid", "expired")
|
- **status** (string): Whether it's paid, unpaid or unpayable (one of "unpaid", "paid", "expired")
|
||||||
- **expires_at** (u64): UNIX timestamp of when it will become / became unpayable
|
- **expires_at** (u64): UNIX timestamp of when it will become / became unpayable
|
||||||
|
- **description** (string, optional): description used in the invoice
|
||||||
- **amount_msat** (msat, optional): the amount required to pay this invoice
|
- **amount_msat** (msat, optional): the amount required to pay this invoice
|
||||||
- **bolt11** (string, optional): the BOLT11 string (always present unless *bolt12* is)
|
- **bolt11** (string, optional): the BOLT11 string (always present unless *bolt12* is)
|
||||||
- **bolt12** (string, optional): the BOLT12 string (always present unless *bolt11* is)
|
- **bolt12** (string, optional): the BOLT12 string (always present unless *bolt11* is)
|
||||||
@@ -56,4 +56,4 @@ RESOURCES
|
|||||||
|
|
||||||
Main web site: <https://github.com/ElementsProject/lightning>
|
Main web site: <https://github.com/ElementsProject/lightning>
|
||||||
|
|
||||||
[comment]: # ( SHA256STAMP:3dc5d5b8f7796d29e0d174d96e93915cbc7131b173a1547de022e021c55e8db6)
|
[comment]: # ( SHA256STAMP:d1328ecc2a4e76ede8c9adc3a63d18ce36be305ddcee7cf717039f79642cfd41)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
"additionalProperties": true,
|
"additionalProperties": true,
|
||||||
"required": [
|
"required": [
|
||||||
"label",
|
"label",
|
||||||
"description",
|
|
||||||
"payment_hash",
|
"payment_hash",
|
||||||
"status",
|
"status",
|
||||||
"expires_at"
|
"expires_at"
|
||||||
|
|||||||
@@ -1382,15 +1382,17 @@ static struct command_result *json_delinvoice(struct command *cmd,
|
|||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
struct invoice i;
|
struct invoice i;
|
||||||
const struct invoice_details *details;
|
struct invoice_details *details;
|
||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
const char *status, *actual_status;
|
const char *status, *actual_status;
|
||||||
struct json_escape *label;
|
struct json_escape *label;
|
||||||
struct wallet *wallet = cmd->ld->wallet;
|
struct wallet *wallet = cmd->ld->wallet;
|
||||||
|
bool *deldesc;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("label", param_label, &label),
|
p_req("label", param_label, &label),
|
||||||
p_req("status", param_string, &status),
|
p_req("status", param_string, &status),
|
||||||
|
p_opt_def("desconly", param_bool, &deldesc, false),
|
||||||
NULL))
|
NULL))
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
@@ -1415,12 +1417,27 @@ static struct command_result *json_delinvoice(struct command *cmd,
|
|||||||
return command_failed(cmd, js);
|
return command_failed(cmd, js);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wallet_invoice_delete(wallet, i)) {
|
if (*deldesc) {
|
||||||
log_broken(cmd->ld->log,
|
if (!details->description)
|
||||||
"Error attempting to remove invoice %"PRIu64,
|
return command_fail(cmd, INVOICE_NO_DESCRIPTION,
|
||||||
i.id);
|
"Invoice description already removed");
|
||||||
/* FIXME: allocate a generic DATABASE_ERROR code. */
|
|
||||||
return command_fail(cmd, LIGHTNINGD, "Database error");
|
if (!wallet_invoice_delete_description(wallet, i)) {
|
||||||
|
log_broken(cmd->ld->log,
|
||||||
|
"Error attempting to delete description of invoice %"PRIu64,
|
||||||
|
i.id);
|
||||||
|
/* FIXME: allocate a generic DATABASE_ERROR code. */
|
||||||
|
return command_fail(cmd, LIGHTNINGD, "Database error");
|
||||||
|
}
|
||||||
|
details->description = tal_free(details->description);
|
||||||
|
} else {
|
||||||
|
if (!wallet_invoice_delete(wallet, i)) {
|
||||||
|
log_broken(cmd->ld->log,
|
||||||
|
"Error attempting to remove invoice %"PRIu64,
|
||||||
|
i.id);
|
||||||
|
/* FIXME: allocate a generic DATABASE_ERROR code. */
|
||||||
|
return command_fail(cmd, LIGHTNINGD, "Database error");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
|
|||||||
@@ -753,14 +753,18 @@ bool wallet_invoice_create(struct wallet *wallet UNNEEDED,
|
|||||||
bool wallet_invoice_delete(struct wallet *wallet UNNEEDED,
|
bool wallet_invoice_delete(struct wallet *wallet UNNEEDED,
|
||||||
struct invoice invoice UNNEEDED)
|
struct invoice invoice UNNEEDED)
|
||||||
{ fprintf(stderr, "wallet_invoice_delete called!\n"); abort(); }
|
{ fprintf(stderr, "wallet_invoice_delete called!\n"); abort(); }
|
||||||
|
/* Generated stub for wallet_invoice_delete_description */
|
||||||
|
bool wallet_invoice_delete_description(struct wallet *wallet UNNEEDED,
|
||||||
|
struct invoice invoice UNNEEDED)
|
||||||
|
{ fprintf(stderr, "wallet_invoice_delete_description called!\n"); abort(); }
|
||||||
/* Generated stub for wallet_invoice_delete_expired */
|
/* Generated stub for wallet_invoice_delete_expired */
|
||||||
void wallet_invoice_delete_expired(struct wallet *wallet UNNEEDED,
|
void wallet_invoice_delete_expired(struct wallet *wallet UNNEEDED,
|
||||||
u64 max_expiry_time UNNEEDED)
|
u64 max_expiry_time UNNEEDED)
|
||||||
{ fprintf(stderr, "wallet_invoice_delete_expired called!\n"); abort(); }
|
{ fprintf(stderr, "wallet_invoice_delete_expired called!\n"); abort(); }
|
||||||
/* Generated stub for wallet_invoice_details */
|
/* Generated stub for wallet_invoice_details */
|
||||||
const struct invoice_details *wallet_invoice_details(const tal_t *ctx UNNEEDED,
|
struct invoice_details *wallet_invoice_details(const tal_t *ctx UNNEEDED,
|
||||||
struct wallet *wallet UNNEEDED,
|
struct wallet *wallet UNNEEDED,
|
||||||
struct invoice invoice UNNEEDED)
|
struct invoice invoice UNNEEDED)
|
||||||
{ fprintf(stderr, "wallet_invoice_details called!\n"); abort(); }
|
{ fprintf(stderr, "wallet_invoice_details called!\n"); abort(); }
|
||||||
/* Generated stub for wallet_invoice_find_by_label */
|
/* Generated stub for wallet_invoice_find_by_label */
|
||||||
bool wallet_invoice_find_by_label(struct wallet *wallet UNNEEDED,
|
bool wallet_invoice_find_by_label(struct wallet *wallet UNNEEDED,
|
||||||
|
|||||||
@@ -733,3 +733,10 @@ def test_invoice_deschash(node_factory, chainparams):
|
|||||||
|
|
||||||
# Make sure we can pay it!
|
# Make sure we can pay it!
|
||||||
l1.rpc.pay(inv['bolt11'])
|
l1.rpc.pay(inv['bolt11'])
|
||||||
|
|
||||||
|
# Try removing description.
|
||||||
|
l2.rpc.delinvoice('label', "paid", desconly=True)
|
||||||
|
assert 'description' not in only_one(l2.rpc.listinvoices()['invoices'])
|
||||||
|
|
||||||
|
with pytest.raises(RpcError, match=r'description already removed'):
|
||||||
|
l2.rpc.delinvoice('label', "paid", desconly=True)
|
||||||
|
|||||||
@@ -421,6 +421,23 @@ bool invoices_delete(struct invoices *invoices, struct invoice invoice)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool invoices_delete_description(struct invoices *invoices, struct invoice invoice)
|
||||||
|
{
|
||||||
|
struct db_stmt *stmt;
|
||||||
|
int changes;
|
||||||
|
|
||||||
|
stmt = db_prepare_v2(invoices->db, SQL("UPDATE invoices"
|
||||||
|
" SET description = NULL"
|
||||||
|
" WHERE ID = ?;"));
|
||||||
|
db_bind_u64(stmt, 0, invoice.id);
|
||||||
|
db_exec_prepared_v2(stmt);
|
||||||
|
|
||||||
|
changes = db_count_changes(stmt);
|
||||||
|
tal_free(stmt);
|
||||||
|
|
||||||
|
return changes == 1;
|
||||||
|
}
|
||||||
|
|
||||||
void invoices_delete_expired(struct invoices *invoices,
|
void invoices_delete_expired(struct invoices *invoices,
|
||||||
u64 max_expiry_time)
|
u64 max_expiry_time)
|
||||||
{
|
{
|
||||||
@@ -648,9 +665,9 @@ void invoices_waitone(const tal_t *ctx,
|
|||||||
false, invoice.id, cb, cbarg);
|
false, invoice.id, cb, cbarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct invoice_details *invoices_get_details(const tal_t *ctx,
|
struct invoice_details *invoices_get_details(const tal_t *ctx,
|
||||||
struct invoices *invoices,
|
struct invoices *invoices,
|
||||||
struct invoice invoice)
|
struct invoice invoice)
|
||||||
{
|
{
|
||||||
struct db_stmt *stmt;
|
struct db_stmt *stmt;
|
||||||
bool res;
|
bool res;
|
||||||
|
|||||||
@@ -108,6 +108,17 @@ bool invoices_find_unpaid(struct invoices *invoices,
|
|||||||
bool invoices_delete(struct invoices *invoices,
|
bool invoices_delete(struct invoices *invoices,
|
||||||
struct invoice invoice);
|
struct invoice invoice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* invoices_delete_description - Remove description from an invoice
|
||||||
|
*
|
||||||
|
* @invoices - the invoice handler.
|
||||||
|
* @invoice - the invoice to remove description from.
|
||||||
|
*
|
||||||
|
* Return false on failure.
|
||||||
|
*/
|
||||||
|
bool invoices_delete_description(struct invoices *invoices,
|
||||||
|
struct invoice invoice);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* invoices_delete_expired - Delete all expired invoices
|
* invoices_delete_expired - Delete all expired invoices
|
||||||
* with expiration time less than or equal to the given.
|
* with expiration time less than or equal to the given.
|
||||||
@@ -213,8 +224,8 @@ void invoices_waitone(const tal_t *ctx,
|
|||||||
* @invoice - the invoice to get details on.
|
* @invoice - the invoice to get details on.
|
||||||
* @return pointer to the invoice details allocated off of `ctx`.
|
* @return pointer to the invoice details allocated off of `ctx`.
|
||||||
*/
|
*/
|
||||||
const struct invoice_details *invoices_get_details(const tal_t *ctx,
|
struct invoice_details *invoices_get_details(const tal_t *ctx,
|
||||||
struct invoices *invoices,
|
struct invoices *invoices,
|
||||||
struct invoice invoice);
|
struct invoice invoice);
|
||||||
|
|
||||||
#endif /* LIGHTNING_WALLET_INVOICES_H */
|
#endif /* LIGHTNING_WALLET_INVOICES_H */
|
||||||
|
|||||||
@@ -212,6 +212,10 @@ bool invoices_create(struct invoices *invoices UNNEEDED,
|
|||||||
bool invoices_delete(struct invoices *invoices UNNEEDED,
|
bool invoices_delete(struct invoices *invoices UNNEEDED,
|
||||||
struct invoice invoice UNNEEDED)
|
struct invoice invoice UNNEEDED)
|
||||||
{ fprintf(stderr, "invoices_delete called!\n"); abort(); }
|
{ fprintf(stderr, "invoices_delete called!\n"); abort(); }
|
||||||
|
/* Generated stub for invoices_delete_description */
|
||||||
|
bool invoices_delete_description(struct invoices *invoices UNNEEDED,
|
||||||
|
struct invoice invoice UNNEEDED)
|
||||||
|
{ fprintf(stderr, "invoices_delete_description called!\n"); abort(); }
|
||||||
/* Generated stub for invoices_delete_expired */
|
/* Generated stub for invoices_delete_expired */
|
||||||
void invoices_delete_expired(struct invoices *invoices UNNEEDED,
|
void invoices_delete_expired(struct invoices *invoices UNNEEDED,
|
||||||
u64 max_expiry_time UNNEEDED)
|
u64 max_expiry_time UNNEEDED)
|
||||||
@@ -232,9 +236,9 @@ bool invoices_find_unpaid(struct invoices *invoices UNNEEDED,
|
|||||||
const struct sha256 *rhash UNNEEDED)
|
const struct sha256 *rhash UNNEEDED)
|
||||||
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
|
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
|
||||||
/* Generated stub for invoices_get_details */
|
/* Generated stub for invoices_get_details */
|
||||||
const struct invoice_details *invoices_get_details(const tal_t *ctx UNNEEDED,
|
struct invoice_details *invoices_get_details(const tal_t *ctx UNNEEDED,
|
||||||
struct invoices *invoices UNNEEDED,
|
struct invoices *invoices UNNEEDED,
|
||||||
struct invoice invoice UNNEEDED)
|
struct invoice invoice UNNEEDED)
|
||||||
{ fprintf(stderr, "invoices_get_details called!\n"); abort(); }
|
{ fprintf(stderr, "invoices_get_details called!\n"); abort(); }
|
||||||
/* Generated stub for invoices_iterate */
|
/* Generated stub for invoices_iterate */
|
||||||
bool invoices_iterate(struct invoices *invoices UNNEEDED,
|
bool invoices_iterate(struct invoices *invoices UNNEEDED,
|
||||||
|
|||||||
@@ -2850,6 +2850,11 @@ bool wallet_invoice_delete(struct wallet *wallet,
|
|||||||
{
|
{
|
||||||
return invoices_delete(wallet->invoices, invoice);
|
return invoices_delete(wallet->invoices, invoice);
|
||||||
}
|
}
|
||||||
|
bool wallet_invoice_delete_description(struct wallet *wallet,
|
||||||
|
struct invoice invoice)
|
||||||
|
{
|
||||||
|
return invoices_delete_description(wallet->invoices, invoice);
|
||||||
|
}
|
||||||
void wallet_invoice_delete_expired(struct wallet *wallet, u64 e)
|
void wallet_invoice_delete_expired(struct wallet *wallet, u64 e)
|
||||||
{
|
{
|
||||||
invoices_delete_expired(wallet->invoices, e);
|
invoices_delete_expired(wallet->invoices, e);
|
||||||
@@ -2888,9 +2893,9 @@ void wallet_invoice_waitone(const tal_t *ctx,
|
|||||||
invoices_waitone(ctx, wallet->invoices, invoice, cb, cbarg);
|
invoices_waitone(ctx, wallet->invoices, invoice, cb, cbarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct invoice_details *wallet_invoice_details(const tal_t *ctx,
|
struct invoice_details *wallet_invoice_details(const tal_t *ctx,
|
||||||
struct wallet *wallet,
|
struct wallet *wallet,
|
||||||
struct invoice invoice)
|
struct invoice invoice)
|
||||||
{
|
{
|
||||||
return invoices_get_details(ctx, wallet->invoices, invoice);
|
return invoices_get_details(ctx, wallet->invoices, invoice);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -893,6 +893,9 @@ bool wallet_invoice_find_unpaid(struct wallet *wallet,
|
|||||||
bool wallet_invoice_delete(struct wallet *wallet,
|
bool wallet_invoice_delete(struct wallet *wallet,
|
||||||
struct invoice invoice);
|
struct invoice invoice);
|
||||||
|
|
||||||
|
bool wallet_invoice_delete_description(struct wallet *wallet,
|
||||||
|
struct invoice invoice);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wallet_invoice_delete_expired - Delete all expired invoices
|
* wallet_invoice_delete_expired - Delete all expired invoices
|
||||||
* with expiration time less than or equal to the given.
|
* with expiration time less than or equal to the given.
|
||||||
@@ -999,9 +1002,9 @@ void wallet_invoice_waitone(const tal_t *ctx,
|
|||||||
* @invoice - the invoice to get details on.
|
* @invoice - the invoice to get details on.
|
||||||
* @return pointer to the invoice details allocated off of `ctx`.
|
* @return pointer to the invoice details allocated off of `ctx`.
|
||||||
*/
|
*/
|
||||||
const struct invoice_details *wallet_invoice_details(const tal_t *ctx,
|
struct invoice_details *wallet_invoice_details(const tal_t *ctx,
|
||||||
struct wallet *wallet,
|
struct wallet *wallet,
|
||||||
struct invoice invoice);
|
struct invoice invoice);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wallet_htlc_stubs - Retrieve HTLC stubs for the given channel
|
* wallet_htlc_stubs - Retrieve HTLC stubs for the given channel
|
||||||
|
|||||||
Reference in New Issue
Block a user