diff --git a/common/jsonrpc_errors.h b/common/jsonrpc_errors.h index f56584544..c87f2630b 100644 --- a/common/jsonrpc_errors.h +++ b/common/jsonrpc_errors.h @@ -72,6 +72,7 @@ static const errcode_t INVOICE_EXPIRED_DURING_WAIT = 903; static const errcode_t INVOICE_WAIT_TIMED_OUT = 904; static const errcode_t INVOICE_NOT_FOUND = 905; static const errcode_t INVOICE_STATUS_UNEXPECTED = 906; +static const errcode_t INVOICE_OFFER_INACTIVE = 907; /* Errors from HSM crypto operations. */ static const errcode_t HSM_ECDH_FAILED = 800; diff --git a/doc/Makefile b/doc/Makefile index d89389d58..5f1455b85 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -13,6 +13,7 @@ MANPAGES := doc/lightning-cli.1 \ doc/lightning-close.7 \ doc/lightning-connect.7 \ doc/lightning-createonion.7 \ + doc/lightning-createinvoice.7 \ doc/lightning-decodepay.7 \ doc/lightning-delexpiredinvoice.7 \ doc/lightning-delinvoice.7 \ diff --git a/doc/index.rst b/doc/index.rst index 83c2744ed..d2e1ffc32 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -34,6 +34,7 @@ c-lightning Documentation lightning-cli lightning-close lightning-connect + lightning-createinvoice lightning-createonion lightning-decodepay lightning-delexpiredinvoice diff --git a/doc/lightning-createinvoice.7 b/doc/lightning-createinvoice.7 new file mode 100644 index 000000000..4b53482ad --- /dev/null +++ b/doc/lightning-createinvoice.7 @@ -0,0 +1,60 @@ +.TH "LIGHTNING-CREATEINVOICE" "7" "" "" "lightning-createinvoice" +.SH NAME +lightning-createinvoice - Low-level invoice creation +.SH SYNOPSIS + +\fBcreateinvoice\fR \fIinvstring\fR \fIpreimage\fR \fIlabel\fR + +.SH DESCRIPTION + +The \fBcreateinvoice\fR RPC command signs and saves an invoice into the +database\. + + +The \fIinvstring\fR parameter is of bolt11 form, but without the final +signature appended\. Minimal sanity checks are done\. + + +The \fIpreimage\fR is the preimage to supply upon successful payment of +the invoice\. + + +The \fIlabel\fR must be a unique string or number (which is treated as a +string, so "01" is different from "1"); it is never revealed to other +nodes on the lightning network, but it can be used to query the status +of this invoice\. + +.SH RETURN VALUE + +On success, an invoice object is returned, as per \fBlistinvoices\fR(7)\. + + +On failure, an error is returned and no invoice is created\. If the +lightning process fails before responding, the caller should use +\fBlightning-listinvoices\fR(7) to query whether this invoice was created or +not\. + + +The following error codes may occur: + +.RS +.IP \[bu] +-1: Catchall nonspecific error\. +.IP \[bu] +900: An invoice with the given \fIlabel\fR already exists\. + +.RE +.SH AUTHOR + +Rusty Russell \fI is mainly responsible\. + +.SH SEE ALSO + +\fBlightning-invoice\fR(7), \fBlightning-listinvoices\fR(7), \fBlightning-delinvoice\fR(7), +\fBlightning-getroute\fR(7), \fBlightning-sendpay\fR(7)\. + +.SH RESOURCES + +Main web site: \fIhttps://github.com/ElementsProject/lightning\fR + +\" SHA256STAMP:1b6598e430d416615867dc09604574c62a8ecb47c51a370711da75359ff80ef3 diff --git a/doc/lightning-createinvoice.7.md b/doc/lightning-createinvoice.7.md new file mode 100644 index 000000000..a3c9d1f59 --- /dev/null +++ b/doc/lightning-createinvoice.7.md @@ -0,0 +1,56 @@ +lightning-createinvoice -- Low-level invoice creation +===================================================== + +SYNOPSIS +-------- + +**createinvoice** *invstring* *preimage* *label* + +DESCRIPTION +----------- + +The **createinvoice** RPC command signs and saves an invoice into the +database. + +The *invstring* parameter is of bolt11 form, but without the final +signature appended. Minimal sanity checks are done. + +The *preimage* is the preimage to supply upon successful payment of +the invoice. + +The *label* must be a unique string or number (which is treated as a +string, so "01" is different from "1"); it is never revealed to other +nodes on the lightning network, but it can be used to query the status +of this invoice. + + +RETURN VALUE +------------ + +On success, an invoice object is returned, as per listinvoices(7). + +On failure, an error is returned and no invoice is created. If the +lightning process fails before responding, the caller should use +lightning-listinvoices(7) to query whether this invoice was created or +not. + +The following error codes may occur: +- -1: Catchall nonspecific error. +- 900: An invoice with the given *label* already exists. + +AUTHOR +------ + +Rusty Russell <> is mainly responsible. + +SEE ALSO +-------- + +lightning-invoice(7), lightning-listinvoices(7), lightning-delinvoice(7), +lightning-getroute(7), lightning-sendpay(7). + +RESOURCES +--------- + +Main web site: + diff --git a/lightningd/invoice.c b/lightningd/invoice.c index ce05b9fb8..df63e9d90 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -10,6 +10,10 @@ #include #include #include +#if EXPERIMENTAL_FEATURES +#include +#include +#endif #include #include #include @@ -428,6 +432,29 @@ static bool hsm_sign_b11(const u5 *u5bytes, return true; } +#if EXPERIMENTAL_FEATURES +static void hsm_sign_b12_invoice(struct lightningd *ld, + struct tlv_invoice *invoice) +{ + struct sha256 merkle; + u8 *msg; + + assert(!invoice->signature); + + merkle_tlv(invoice->fields, &merkle); + msg = towire_hsmd_sign_bolt12(NULL, "invoice", "signature", &merkle); + + if (!wire_sync_write(ld->hsm_fd, take(msg))) + fatal("Could not write to HSM: %s", strerror(errno)); + + msg = wire_sync_read(tmpctx, ld->hsm_fd); + invoice->signature = tal(invoice, struct bip340sig); + if (!fromwire_hsmd_sign_bolt12_reply(msg, invoice->signature)) + fatal("HSM gave bad sign_invoice_reply %s", + tal_hex(msg, msg)); +} +#endif /* EXPERIMENTAL_FEATURES */ + static struct command_result *parse_fallback(struct command *cmd, const char *buffer, const jsmntok_t *fallback, @@ -920,13 +947,27 @@ static struct command_result *param_chanhints(struct command *cmd, &(*chanhints)->hints); } +static struct command_result *param_preimage(struct command *cmd, + const char *name, + const char *buffer, + const jsmntok_t *tok, + struct preimage **preimage) +{ + *preimage = tal(cmd, struct preimage); + if (!hex_decode(buffer + tok->start, tok->end - tok->start, + *preimage, sizeof(**preimage))) + return command_fail_badparam(cmd, "preimage", + buffer, tok, + "should be 64 hex digits"); + return NULL; +} + static struct command_result *json_invoice(struct command *cmd, const char *buffer, const jsmntok_t *obj UNNEEDED, const jsmntok_t *params) { const jsmntok_t *fallbacks; - const jsmntok_t *preimagetok; struct amount_msat *msatoshi_val; struct invoice_info *info; const char *desc_val; @@ -934,6 +975,7 @@ static struct command_result *json_invoice(struct command *cmd, u64 *expiry; struct sha256 rhash; struct secret payment_secret; + struct preimage *preimage; #if DEVELOPER const jsmntok_t *routes; #endif @@ -947,7 +989,7 @@ static struct command_result *json_invoice(struct command *cmd, p_req("description", param_escaped_string, &desc_val), p_opt_def("expiry", param_time, &expiry, 3600*24*7), p_opt("fallbacks", param_array, &fallbacks), - p_opt("preimage", param_tok, &preimagetok), + p_opt("preimage", param_preimage, &preimage), p_opt("exposeprivatechannels", param_chanhints, &info->chanhints), #if DEVELOPER @@ -993,17 +1035,9 @@ static struct command_result *json_invoice(struct command *cmd, } } - if (preimagetok) { - /* Get secret preimage from user. */ - if (!hex_decode(buffer + preimagetok->start, - preimagetok->end - preimagetok->start, - &info->payment_preimage, - sizeof(info->payment_preimage))) { - return command_fail_badparam(cmd, "preimage", - buffer, preimagetok, - "should be 64 hex digits"); - } - } else + if (preimage) + info->payment_preimage = *preimage; + else /* Generate random secret preimage. */ randombytes_buf(&info->payment_preimage, sizeof(info->payment_preimage)); @@ -1441,3 +1475,162 @@ static const struct json_command decodepay_command = { "Decode {bolt11}, using {description} if necessary" }; AUTODATA(json_command, &decodepay_command); + +/* If we fail because it exists, we also return the clashing invoice */ +static struct command_result *fail_exists(struct command *cmd, + const struct json_escape *label) +{ + struct json_stream *data; + struct invoice invoice; + struct wallet *wallet = cmd->ld->wallet; + + data = json_stream_fail(cmd, INVOICE_LABEL_ALREADY_EXISTS, + "Duplicate label"); + if (!wallet_invoice_find_by_label(wallet, &invoice, label)) + fatal("Duplicate invoice %s not found any more?", + label->s); + + json_add_invoice(data, wallet_invoice_details(cmd, wallet, invoice)); + json_object_end(data); + + return command_failed(cmd, data); +} + +static struct command_result *json_createinvoice(struct command *cmd, + const char *buffer, + const jsmntok_t *obj UNNEEDED, + const jsmntok_t *params) +{ + const char *invstring; + struct json_escape *label; + struct preimage *preimage; + struct invoice invoice; + struct sha256 payment_hash; + struct json_stream *response; + struct bolt11 *b11; + struct sha256 hash; + u5 *sig; + bool have_n; + char *fail; + + if (!param(cmd, buffer, params, + p_req("invstring", param_string, &invstring), + p_req("preimage", param_preimage, &preimage), + p_req("label", param_label, &label), + NULL)) + return command_param_failed(); + + sha256(&payment_hash, preimage, sizeof(*preimage)); + b11 = bolt11_decode_nosig(cmd, invstring, cmd->ld->our_features, + NULL, chainparams, &hash, &sig, &have_n, + &fail); + if (b11) { + /* This adds the signature */ + char *b11enc = bolt11_encode(cmd, b11, have_n, + hsm_sign_b11, cmd->ld); + + if (!b11->description) + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "Missing description in invoice"); + + if (!b11->expiry) + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "Missing expiry in invoice"); + + if (!wallet_invoice_create(cmd->ld->wallet, + &invoice, + b11->msat, + label, + b11->expiry, + b11enc, + b11->description, + b11->features, + preimage, + &payment_hash, + NULL)) + return fail_exists(cmd, label); + + notify_invoice_creation(cmd->ld, b11->msat, *preimage, label); + } else { +#if EXPERIMENTAL_FEATURES + struct tlv_invoice *inv; + struct sha256 *local_offer_id; + + inv = invoice_decode_nosig(cmd, invstring, strlen(invstring), + cmd->ld->our_features, chainparams, + &fail); + if (inv) { + char *b12enc; + struct amount_msat msat; + const char *desc; + u32 expiry; + enum offer_status status; + + if (inv->signature) + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "invoice already signed"); + hsm_sign_b12_invoice(cmd->ld, inv); + b12enc = invoice_encode(cmd, inv); + + if (inv->offer_id + && wallet_offer_find(tmpctx, cmd->ld->wallet, + inv->offer_id, NULL, &status)) { + if (!offer_status_active(status)) + return command_fail(cmd, INVOICE_OFFER_INACTIVE, + "offer not active"); + local_offer_id = inv->offer_id; + } else + local_offer_id = NULL; + + if (inv->amount) + msat = amount_msat(*inv->amount); + + if (inv->relative_expiry) + expiry = *inv->relative_expiry; + else + expiry = 7200; + + if (!inv->description) + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "Missing description in invoice"); + desc = tal_strndup(cmd, + cast_signed(char *, inv->description), + tal_bytelen(inv->description)); + + if (!wallet_invoice_create(cmd->ld->wallet, + &invoice, + inv->amount ? &msat : NULL, + label, + expiry, + b12enc, + desc, + inv->features, + preimage, + &payment_hash, + local_offer_id)) + return fail_exists(cmd, label); + + notify_invoice_creation(cmd->ld, + inv->amount ? &msat : NULL, + *preimage, label); + } else +#endif /* EXPERIMENTAL_FEATURES */ + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "Unparsable invoice '%s': %s", + invstring, fail); + } + + response = json_stream_success(cmd); + json_add_invoice(response, + wallet_invoice_details(cmd, cmd->ld->wallet, invoice)); + return command_success(cmd, response); +} + +static const struct json_command createinvoice_command = { + "createinvoice", + "payment", + json_createinvoice, + "Lowlevel command to sign and create invoice {invstring}, resolved with {preimage}, using unique {label}." +}; +AUTODATA(json_command, &createinvoice_command); + diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 0a4439070..8c127e734 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -27,6 +27,16 @@ struct bolt11 *bolt11_decode(const tal_t *ctx UNNEEDED, const char *str UNNEEDED const struct chainparams *must_be_chain UNNEEDED, char **fail UNNEEDED) { fprintf(stderr, "bolt11_decode called!\n"); abort(); } +/* Generated stub for bolt11_decode_nosig */ +struct bolt11 *bolt11_decode_nosig(const tal_t *ctx UNNEEDED, const char *str UNNEEDED, + const struct feature_set *our_features UNNEEDED, + const char *description UNNEEDED, + const struct chainparams *must_be_chain UNNEEDED, + struct sha256 *hash UNNEEDED, + u5 **sig UNNEEDED, + bool *have_n UNNEEDED, + char **fail UNNEEDED) +{ fprintf(stderr, "bolt11_decode_nosig called!\n"); abort(); } /* Generated stub for bolt11_encode_ */ char *bolt11_encode_(const tal_t *ctx UNNEEDED, const struct bolt11 *b11 UNNEEDED, bool n_field UNNEEDED, @@ -171,6 +181,9 @@ bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p U /* Generated stub for fromwire_gossipd_get_incoming_channels_reply */ bool fromwire_gossipd_get_incoming_channels_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct route_info **public_route_info UNNEEDED, bool **public_deadends UNNEEDED, struct route_info **private_route_info UNNEEDED, bool **private_deadends UNNEEDED) { fprintf(stderr, "fromwire_gossipd_get_incoming_channels_reply called!\n"); abort(); } +/* Generated stub for fromwire_hsmd_sign_bolt12_reply */ +bool fromwire_hsmd_sign_bolt12_reply(const void *p UNNEEDED, struct bip340sig *sig UNNEEDED) +{ fprintf(stderr, "fromwire_hsmd_sign_bolt12_reply called!\n"); abort(); } /* Generated stub for fromwire_hsmd_sign_commitment_tx_reply */ bool fromwire_hsmd_sign_commitment_tx_reply(const void *p UNNEEDED, struct bitcoin_signature *sig UNNEEDED) { fprintf(stderr, "fromwire_hsmd_sign_commitment_tx_reply called!\n"); abort(); } @@ -555,6 +568,9 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED, /* Generated stub for towire_gossipd_get_incoming_channels */ u8 *towire_gossipd_get_incoming_channels(const tal_t *ctx UNNEEDED) { fprintf(stderr, "towire_gossipd_get_incoming_channels called!\n"); abort(); } +/* Generated stub for towire_hsmd_sign_bolt12 */ +u8 *towire_hsmd_sign_bolt12(const tal_t *ctx UNNEEDED, const wirestring *messagename UNNEEDED, const wirestring *fieldname UNNEEDED, const struct sha256 *merkleroot UNNEEDED) +{ fprintf(stderr, "towire_hsmd_sign_bolt12 called!\n"); abort(); } /* Generated stub for towire_hsmd_sign_commitment_tx */ u8 *towire_hsmd_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct node_id *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED) { fprintf(stderr, "towire_hsmd_sign_commitment_tx called!\n"); abort(); } @@ -668,6 +684,14 @@ void wallet_invoice_waitone(const tal_t *ctx UNNEEDED, void (*cb)(const struct invoice * UNNEEDED, void*) UNNEEDED, void *cbarg UNNEEDED) { fprintf(stderr, "wallet_invoice_waitone called!\n"); abort(); } +/* Generated stub for wallet_offer_find */ +char *wallet_offer_find(const tal_t *ctx UNNEEDED, + struct wallet *w UNNEEDED, + const struct sha256 *offer_id UNNEEDED, + const struct json_escape **label UNNEEDED, + enum offer_status *status) + +{ fprintf(stderr, "wallet_offer_find called!\n"); abort(); } /* Generated stub for wallet_peer_delete */ void wallet_peer_delete(struct wallet *w UNNEEDED, u64 peer_dbid UNNEEDED) { fprintf(stderr, "wallet_peer_delete called!\n"); abort(); } @@ -722,6 +746,22 @@ bool dev_disconnect_permanent(struct lightningd *ld UNNEEDED) { fprintf(stderr, "dev_disconnect_permanent called!\n"); abort(); } #endif +#if EXPERIMENTAL_FEATURES +/* Generated stub for merkle_tlv */ +void merkle_tlv(const struct tlv_field *fields UNNEEDED, struct sha256 *merkle UNNEEDED) +{ fprintf(stderr, "merkle_tlv called!\n"); abort(); } +/* Generated stub for invoice_decode_nosig */ +struct tlv_invoice *invoice_decode_nosig(const tal_t *ctx UNNEEDED, + const char *b12 UNNEEDED, size_t b12len UNNEEDED, + const struct feature_set *our_features UNNEEDED, + const struct chainparams *must_be_chain UNNEEDED, + char **fail UNNEEDED) +{ fprintf(stderr, "invoice_decode_nosig called!\n"); abort(); } +/* Generated stub for invoice_encode */ +char *invoice_encode(const tal_t *ctx UNNEEDED, const struct tlv_invoice *bolt12_tlv UNNEEDED) +{ fprintf(stderr, "invoice_encode called!\n"); abort(); } +#endif + static void add_candidate(struct routehint_candidate **candidates, int n, struct channel *c) { diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index ca8f1e9db..120434eac 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -860,6 +860,12 @@ struct db_query db_postgres_queries[] = { .placeholders = 0, .readonly = false, }, + { + .name = "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL;", + .query = "ALTER TABLE payments ADD COLUMN local_offer_id BYTEA DEFAULT NULL;", + .placeholders = 0, + .readonly = false, + }, { .name = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?", .query = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = $1", @@ -1401,9 +1407,9 @@ struct db_query db_postgres_queries[] = { .readonly = true, }, { - .name = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", - .query = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);", - .placeholders = 13, + .name = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + .query = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);", + .placeholders = 14, .readonly = false, }, { @@ -1419,8 +1425,8 @@ struct db_query db_postgres_queries[] = { .readonly = false, }, { - .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?", - .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = $1 AND partid = $2", + .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?", + .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = $1 AND partid = $2", .placeholders = 2, .readonly = true, }, @@ -1455,17 +1461,23 @@ struct db_query db_postgres_queries[] = { .readonly = false, }, { - .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;", - .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = $1;", + .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ?;", + .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = $1;", .placeholders = 1, .readonly = true, }, { - .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;", - .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;", + .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;", + .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;", .placeholders = 0, .readonly = true, }, + { + .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;", + .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = $1;", + .placeholders = 1, + .readonly = true, + }, { .name = "DELETE FROM htlc_sigs WHERE channelid = ?", .query = "DELETE FROM htlc_sigs WHERE channelid = $1", @@ -1744,10 +1756,10 @@ struct db_query db_postgres_queries[] = { }, }; -#define DB_POSTGRES_QUERY_COUNT 289 +#define DB_POSTGRES_QUERY_COUNT 291 #endif /* HAVE_POSTGRES */ #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ -// SHA256STAMP:83a4b63d1c5566db35ab00e9da60f6c98c04f8bd30800e51cce294dfcb49c9ec +// SHA256STAMP:682d4f3ac081ef003be6eba257a5e5e023fee5169592c760c8878288ee12f212 diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index 6686c5ae3..83b083949 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -860,6 +860,12 @@ struct db_query db_sqlite3_queries[] = { .placeholders = 0, .readonly = false, }, + { + .name = "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL;", + .query = "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL;", + .placeholders = 0, + .readonly = false, + }, { .name = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?", .query = "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?", @@ -1401,9 +1407,9 @@ struct db_query db_sqlite3_queries[] = { .readonly = true, }, { - .name = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", - .query = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", - .placeholders = 13, + .name = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + .query = "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + .placeholders = 14, .readonly = false, }, { @@ -1419,8 +1425,8 @@ struct db_query db_sqlite3_queries[] = { .readonly = false, }, { - .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?", - .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?", + .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?", + .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?", .placeholders = 2, .readonly = true, }, @@ -1455,17 +1461,23 @@ struct db_query db_sqlite3_queries[] = { .readonly = false, }, { - .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;", - .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;", + .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ?;", + .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ?;", .placeholders = 1, .readonly = true, }, { - .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;", - .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;", + .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;", + .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;", .placeholders = 0, .readonly = true, }, + { + .name = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;", + .query = "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;", + .placeholders = 1, + .readonly = true, + }, { .name = "DELETE FROM htlc_sigs WHERE channelid = ?", .query = "DELETE FROM htlc_sigs WHERE channelid = ?", @@ -1744,10 +1756,10 @@ struct db_query db_sqlite3_queries[] = { }, }; -#define DB_SQLITE3_QUERY_COUNT 289 +#define DB_SQLITE3_QUERY_COUNT 291 #endif /* HAVE_SQLITE3 */ #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ -// SHA256STAMP:83a4b63d1c5566db35ab00e9da60f6c98c04f8bd30800e51cce294dfcb49c9ec +// SHA256STAMP:682d4f3ac081ef003be6eba257a5e5e023fee5169592c760c8878288ee12f212 diff --git a/wallet/invoices.c b/wallet/invoices.c index 8f5072ee5..9e9db1f50 100644 --- a/wallet/invoices.c +++ b/wallet/invoices.c @@ -306,7 +306,10 @@ bool invoices_create(struct invoices *invoices, db_bind_json_escape(stmt, 4, label); db_bind_u64(stmt, 5, expiry_time); db_bind_text(stmt, 6, b11enc); - db_bind_text(stmt, 7, description); + if (!description) + db_bind_null(stmt, 7); + else + db_bind_text(stmt, 7, description); db_bind_talarr(stmt, 8, features); if (local_offer_id) db_bind_sha256(stmt, 9, local_offer_id); diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index faab3e85a..e673e2b45 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -566,67 +566,71 @@ msgstr "" msgid "ALTER TABLE invoices ADD COLUMN local_offer_id BLOB DEFAULT NULL;" msgstr "" -#: wallet/db.c:895 +#: wallet/db.c:670 +msgid "ALTER TABLE payments ADD COLUMN local_offer_id BLOB DEFAULT NULL;" +msgstr "" + +#: wallet/db.c:897 msgid "UPDATE vars SET intval = intval + 1 WHERE name = 'data_version' AND intval = ?" msgstr "" -#: wallet/db.c:995 +#: wallet/db.c:997 msgid "SELECT version FROM version LIMIT 1" msgstr "" -#: wallet/db.c:1053 +#: wallet/db.c:1055 msgid "UPDATE version SET version=?;" msgstr "" -#: wallet/db.c:1061 +#: wallet/db.c:1063 msgid "INSERT INTO db_upgrades VALUES (?, ?);" msgstr "" -#: wallet/db.c:1073 +#: wallet/db.c:1075 msgid "SELECT intval FROM vars WHERE name = 'data_version'" msgstr "" -#: wallet/db.c:1100 +#: wallet/db.c:1102 msgid "SELECT intval FROM vars WHERE name= ? LIMIT 1" msgstr "" -#: wallet/db.c:1116 +#: wallet/db.c:1118 msgid "UPDATE vars SET intval=? WHERE name=?;" msgstr "" -#: wallet/db.c:1125 +#: wallet/db.c:1127 msgid "INSERT INTO vars (name, intval) VALUES (?, ?);" msgstr "" -#: wallet/db.c:1139 +#: wallet/db.c:1141 msgid "UPDATE channels SET feerate_base = ?, feerate_ppm = ?;" msgstr "" -#: wallet/db.c:1160 +#: wallet/db.c:1162 msgid "UPDATE channels SET our_funding_satoshi = funding_satoshi WHERE funder = 0;" msgstr "" -#: wallet/db.c:1176 +#: wallet/db.c:1178 msgid "SELECT type, keyindex, prev_out_tx, prev_out_index, channel_id, peer_id, commitment_point FROM outputs WHERE scriptpubkey IS NULL;" msgstr "" -#: wallet/db.c:1238 +#: wallet/db.c:1240 msgid "UPDATE outputs SET scriptpubkey = ? WHERE prev_out_tx = ? AND prev_out_index = ?" msgstr "" -#: wallet/db.c:1263 +#: wallet/db.c:1265 msgid "SELECT id, funding_tx_id, funding_tx_outnum FROM channels;" msgstr "" -#: wallet/db.c:1282 +#: wallet/db.c:1284 msgid "UPDATE channels SET full_channel_id = ? WHERE id = ?;" msgstr "" -#: wallet/db.c:1305 +#: wallet/db.c:1307 msgid "SELECT c.id, p.node_id, c.last_tx, c.funding_satoshi, c.fundingkey_remote, c.last_sig FROM channels c LEFT OUTER JOIN peers p ON p.id = c.peer_id;" msgstr "" -#: wallet/db.c:1372 +#: wallet/db.c:1374 msgid "UPDATE channels SET last_tx = ? WHERE id = ?;" msgstr "" @@ -646,47 +650,47 @@ msgstr "" msgid "INSERT INTO invoices ( payment_hash, payment_key, state , msatoshi, label, expiry_time , pay_index, msatoshi_received , paid_timestamp, bolt11, description, features, local_offer_id) VALUES ( ?, ?, ? , ?, ?, ? , NULL, NULL , NULL, ?, ?, ?, ?);" msgstr "" -#: wallet/invoices.c:341 +#: wallet/invoices.c:344 msgid "SELECT id FROM invoices WHERE label = ?;" msgstr "" -#: wallet/invoices.c:363 +#: wallet/invoices.c:366 msgid "SELECT id FROM invoices WHERE payment_hash = ?;" msgstr "" -#: wallet/invoices.c:384 +#: wallet/invoices.c:387 msgid "SELECT id FROM invoices WHERE payment_hash = ? AND state = ?;" msgstr "" -#: wallet/invoices.c:408 +#: wallet/invoices.c:411 msgid "DELETE FROM invoices WHERE id=?;" msgstr "" -#: wallet/invoices.c:428 +#: wallet/invoices.c:431 msgid "DELETE FROM invoices WHERE state = ? AND expiry_time <= ?;" msgstr "" -#: wallet/invoices.c:442 +#: wallet/invoices.c:445 msgid "SELECT state, payment_key, payment_hash, label, msatoshi, expiry_time, pay_index, msatoshi_received, paid_timestamp, bolt11, description, features FROM invoices ORDER BY id;" msgstr "" -#: wallet/invoices.c:499 +#: wallet/invoices.c:502 msgid "SELECT state FROM invoices WHERE id = ?;" msgstr "" -#: wallet/invoices.c:517 +#: wallet/invoices.c:520 msgid "SELECT local_offer_id FROM invoices WHERE id = ?;" msgstr "" -#: wallet/invoices.c:549 +#: wallet/invoices.c:552 msgid "UPDATE invoices SET state=? , pay_index=? , msatoshi_received=? , paid_timestamp=? WHERE id=?;" msgstr "" -#: wallet/invoices.c:608 +#: wallet/invoices.c:611 msgid "SELECT id FROM invoices WHERE pay_index IS NOT NULL AND pay_index > ? ORDER BY pay_index ASC LIMIT 1;" msgstr "" -#: wallet/invoices.c:657 +#: wallet/invoices.c:660 msgid "SELECT state, payment_key, payment_hash, label, msatoshi, expiry_time, pay_index, msatoshi_received, paid_timestamp, bolt11, description, features, local_offer_id FROM invoices WHERE id = ?;" msgstr "" @@ -927,218 +931,222 @@ msgid "SELECT status FROM payments WHERE payment_hash=? AND partid = ?;" msgstr "" #: wallet/wallet.c:2484 -msgid "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" +msgid "INSERT INTO payments ( status, payment_hash, destination, msatoshi, timestamp, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, total_msat, partid, local_offer_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:2567 +#: wallet/wallet.c:2573 msgid "DELETE FROM payments WHERE payment_hash = ? AND partid = ?" msgstr "" -#: wallet/wallet.c:2581 +#: wallet/wallet.c:2587 msgid "DELETE FROM payments WHERE payment_hash = ?" msgstr "" -#: wallet/wallet.c:2676 -msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ? AND partid = ?" +#: wallet/wallet.c:2688 +msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ? AND partid = ?" msgstr "" -#: wallet/wallet.c:2725 +#: wallet/wallet.c:2738 msgid "UPDATE payments SET status=? WHERE payment_hash=? AND partid=?" msgstr "" -#: wallet/wallet.c:2735 +#: wallet/wallet.c:2748 msgid "UPDATE payments SET payment_preimage=? WHERE payment_hash=? AND partid=?" msgstr "" -#: wallet/wallet.c:2745 +#: wallet/wallet.c:2758 msgid "UPDATE payments SET path_secrets = NULL , route_nodes = NULL , route_channels = NULL WHERE payment_hash = ? AND partid = ?;" msgstr "" -#: wallet/wallet.c:2777 +#: wallet/wallet.c:2790 msgid "SELECT failonionreply, faildestperm, failindex, failcode, failnode, failchannel, failupdate, faildetail, faildirection FROM payments WHERE payment_hash=? AND partid=?;" msgstr "" -#: wallet/wallet.c:2844 +#: wallet/wallet.c:2857 msgid "UPDATE payments SET failonionreply=? , faildestperm=? , failindex=? , failcode=? , failnode=? , failchannel=? , failupdate=? , faildetail=? , faildirection=? WHERE payment_hash=? AND partid=?;" msgstr "" -#: wallet/wallet.c:2903 -msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments WHERE payment_hash = ?;" +#: wallet/wallet.c:2916 +msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE payment_hash = ?;" msgstr "" -#: wallet/wallet.c:2924 -msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid FROM payments ORDER BY id;" +#: wallet/wallet.c:2938 +msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments ORDER BY id;" msgstr "" -#: wallet/wallet.c:2968 +#: wallet/wallet.c:2989 +msgid "SELECT id, status, destination, msatoshi, payment_hash, timestamp, payment_preimage, path_secrets, route_nodes, route_channels, msatoshi_sent, description, bolt11, failonionreply, total_msat, partid, local_offer_id FROM payments WHERE local_offer_id = ?;" +msgstr "" + +#: wallet/wallet.c:3034 msgid "DELETE FROM htlc_sigs WHERE channelid = ?" msgstr "" -#: wallet/wallet.c:2975 +#: wallet/wallet.c:3041 msgid "INSERT INTO htlc_sigs (channelid, signature) VALUES (?, ?)" msgstr "" -#: wallet/wallet.c:2987 +#: wallet/wallet.c:3053 msgid "SELECT blobval FROM vars WHERE name='genesis_hash'" msgstr "" -#: wallet/wallet.c:3011 +#: wallet/wallet.c:3077 msgid "INSERT INTO vars (name, blobval) VALUES ('genesis_hash', ?);" msgstr "" -#: wallet/wallet.c:3027 +#: wallet/wallet.c:3093 msgid "DELETE FROM utxoset WHERE spendheight < ?" msgstr "" -#: wallet/wallet.c:3035 wallet/wallet.c:3145 +#: wallet/wallet.c:3101 wallet/wallet.c:3211 msgid "INSERT INTO blocks (height, hash, prev_hash) VALUES (?, ?, ?);" msgstr "" -#: wallet/wallet.c:3054 +#: wallet/wallet.c:3120 msgid "DELETE FROM blocks WHERE hash = ?" msgstr "" -#: wallet/wallet.c:3060 +#: wallet/wallet.c:3126 msgid "SELECT * FROM blocks WHERE height >= ?;" msgstr "" -#: wallet/wallet.c:3069 +#: wallet/wallet.c:3135 msgid "DELETE FROM blocks WHERE height > ?" msgstr "" -#: wallet/wallet.c:3081 +#: wallet/wallet.c:3147 msgid "UPDATE outputs SET spend_height = ?, status = ? WHERE prev_out_tx = ? AND prev_out_index = ?" msgstr "" -#: wallet/wallet.c:3098 +#: wallet/wallet.c:3164 msgid "UPDATE utxoset SET spendheight = ? WHERE txid = ? AND outnum = ?" msgstr "" -#: wallet/wallet.c:3120 wallet/wallet.c:3156 +#: wallet/wallet.c:3186 wallet/wallet.c:3222 msgid "INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3180 +#: wallet/wallet.c:3246 msgid "SELECT height FROM blocks WHERE height = ?" msgstr "" -#: wallet/wallet.c:3193 +#: wallet/wallet.c:3259 msgid "SELECT txid, spendheight, scriptpubkey, satoshis FROM utxoset WHERE blockheight = ? AND txindex = ? AND outnum = ? AND spendheight IS NULL" msgstr "" -#: wallet/wallet.c:3235 +#: wallet/wallet.c:3301 msgid "SELECT blockheight, txindex, outnum FROM utxoset WHERE spendheight = ?" msgstr "" -#: wallet/wallet.c:3266 wallet/wallet.c:3426 +#: wallet/wallet.c:3332 wallet/wallet.c:3492 msgid "SELECT blockheight FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3276 +#: wallet/wallet.c:3342 msgid "INSERT INTO transactions ( id, blockheight, txindex, rawtx) VALUES (?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3297 +#: wallet/wallet.c:3363 msgid "UPDATE transactions SET blockheight = ?, txindex = ? WHERE id = ?" msgstr "" -#: wallet/wallet.c:3314 +#: wallet/wallet.c:3380 msgid "INSERT INTO transaction_annotations (txid, idx, location, type, channel) VALUES (?, ?, ?, ?, ?) ON CONFLICT(txid,idx) DO NOTHING;" msgstr "" -#: wallet/wallet.c:3346 +#: wallet/wallet.c:3412 msgid "SELECT type, channel_id FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3362 +#: wallet/wallet.c:3428 msgid "UPDATE transactions SET type = ?, channel_id = ? WHERE id = ?" msgstr "" -#: wallet/wallet.c:3381 +#: wallet/wallet.c:3447 msgid "SELECT type FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3404 +#: wallet/wallet.c:3470 msgid "SELECT rawtx FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3450 +#: wallet/wallet.c:3516 msgid "SELECT blockheight, txindex FROM transactions WHERE id=?" msgstr "" -#: wallet/wallet.c:3478 +#: wallet/wallet.c:3544 msgid "SELECT id FROM transactions WHERE blockheight=?" msgstr "" -#: wallet/wallet.c:3497 +#: wallet/wallet.c:3563 msgid "INSERT INTO channeltxs ( channel_id, type, transaction_id, input_num, blockheight) VALUES (?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3521 +#: wallet/wallet.c:3587 msgid "SELECT DISTINCT(channel_id) FROM channeltxs WHERE type = ?;" msgstr "" -#: wallet/wallet.c:3542 +#: wallet/wallet.c:3608 msgid "SELECT c.type, c.blockheight, t.rawtx, c.input_num, c.blockheight - t.blockheight + 1 AS depth, t.id as txid FROM channeltxs c JOIN transactions t ON t.id = c.transaction_id WHERE c.channel_id = ? ORDER BY c.id ASC;" msgstr "" -#: wallet/wallet.c:3587 +#: wallet/wallet.c:3653 msgid "UPDATE forwarded_payments SET in_msatoshi=?, out_msatoshi=?, state=?, resolved_time=?, failcode=? WHERE in_htlc_id=?" msgstr "" -#: wallet/wallet.c:3645 +#: wallet/wallet.c:3711 msgid "INSERT INTO forwarded_payments ( in_htlc_id, out_htlc_id, in_channel_scid, out_channel_scid, in_msatoshi, out_msatoshi, state, received_time, resolved_time, failcode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3704 +#: wallet/wallet.c:3770 msgid "SELECT CAST(COALESCE(SUM(in_msatoshi - out_msatoshi), 0) AS BIGINT)FROM forwarded_payments WHERE state = ?;" msgstr "" -#: wallet/wallet.c:3728 +#: wallet/wallet.c:3794 msgid "SELECT f.state, in_msatoshi, out_msatoshi, hin.payment_hash as payment_hash, in_channel_scid, out_channel_scid, f.received_time, f.resolved_time, f.failcode FROM forwarded_payments f LEFT JOIN channel_htlcs hin ON (f.in_htlc_id = hin.id)" msgstr "" -#: wallet/wallet.c:3816 +#: wallet/wallet.c:3882 msgid "SELECT t.id, t.rawtx, t.blockheight, t.txindex, t.type as txtype, c2.short_channel_id as txchan, a.location, a.idx as ann_idx, a.type as annotation_type, c.short_channel_id FROM transactions t LEFT JOIN transaction_annotations a ON (a.txid = t.id) LEFT JOIN channels c ON (a.channel = c.id) LEFT JOIN channels c2 ON (t.channel_id = c2.id) ORDER BY t.blockheight, t.txindex ASC" msgstr "" -#: wallet/wallet.c:3910 +#: wallet/wallet.c:3976 msgid "INSERT INTO penalty_bases ( channel_id, commitnum, txid, outnum, amount) VALUES (?, ?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:3935 +#: wallet/wallet.c:4001 msgid "SELECT commitnum, txid, outnum, amount FROM penalty_bases WHERE channel_id = ?" msgstr "" -#: wallet/wallet.c:3959 +#: wallet/wallet.c:4025 msgid "DELETE FROM penalty_bases WHERE channel_id = ? AND commitnum = ?" msgstr "" -#: wallet/wallet.c:3977 +#: wallet/wallet.c:4043 msgid "SELECT 1 FROM offers WHERE offer_id = ?;" msgstr "" -#: wallet/wallet.c:3990 +#: wallet/wallet.c:4056 msgid "INSERT INTO offers ( offer_id, bolt12, label, status) VALUES (?, ?, ?, ?);" msgstr "" -#: wallet/wallet.c:4018 +#: wallet/wallet.c:4084 msgid "SELECT bolt12, label, status FROM offers WHERE offer_id = ?;" msgstr "" -#: wallet/wallet.c:4046 +#: wallet/wallet.c:4112 msgid "SELECT offer_id FROM offers;" msgstr "" -#: wallet/wallet.c:4072 +#: wallet/wallet.c:4138 msgid "UPDATE offers SET status=? WHERE offer_id = ?;" msgstr "" -#: wallet/wallet.c:4083 +#: wallet/wallet.c:4149 msgid "UPDATE invoices SET state=? WHERE state=? AND local_offer_id = ?;" msgstr "" -#: wallet/wallet.c:4111 +#: wallet/wallet.c:4177 msgid "SELECT status FROM offers WHERE offer_id = ?;" msgstr "" @@ -1153,4 +1161,4 @@ msgstr "" #: wallet/test/run-wallet.c:1378 msgid "INSERT INTO channels (id) VALUES (1);" msgstr "" -# SHA256STAMP:f7e6df1a958f5eeb00dd1ffb0221fab28816a4807908fe904ae913a248b0f98c +# SHA256STAMP:edc18cc0be69eb519707d9442372246c466d08ec7ed12f24584be19ae9032d9b