Browse Source

wallet: use json_escaped for invoice label.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
76e8a11380
  1. 54
      lightningd/invoice.c
  2. 5
      lightningd/peer_htlcs.c
  3. 16
      wallet/db.c
  4. 5
      wallet/db.h
  5. 10
      wallet/invoices.c
  6. 9
      wallet/invoices.h
  7. 4
      wallet/test/run-db.c
  8. 11
      wallet/test/run-wallet.c
  9. 4
      wallet/wallet.c
  10. 10
      wallet/wallet.h

54
lightningd/invoice.c

@ -35,7 +35,7 @@ static void json_add_invoice(struct json_result *response,
bool modern) bool modern)
{ {
json_object_start(response, NULL); json_object_start(response, NULL);
json_add_string(response, "label", inv->label); json_add_escaped_string(response, "label", inv->label);
json_add_string(response, "bolt11", inv->bolt11); json_add_string(response, "bolt11", inv->bolt11);
json_add_hex(response, "payment_hash", &inv->rhash, sizeof(inv->rhash)); json_add_hex(response, "payment_hash", &inv->rhash, sizeof(inv->rhash));
if (inv->msatoshi) if (inv->msatoshi)
@ -154,7 +154,7 @@ static void json_invoice(struct command *cmd,
label->end - label->start, buffer + label->start); label->end - label->start, buffer + label->start);
return; return;
} }
if (wallet_invoice_find_by_label(wallet, &invoice, label_val->s)) { if (wallet_invoice_find_by_label(wallet, &invoice, label_val)) {
command_fail(cmd, "Duplicate label '%s'", label_val->s); command_fail(cmd, "Duplicate label '%s'", label_val->s);
return; return;
} }
@ -226,7 +226,7 @@ static void json_invoice(struct command *cmd,
result = wallet_invoice_create(cmd->ld->wallet, result = wallet_invoice_create(cmd->ld->wallet,
&invoice, &invoice,
take(msatoshi_val), take(msatoshi_val),
take((char *)label_val->s), take(label_val),
expiry, expiry,
b11enc, b11enc,
&r, &r,
@ -261,19 +261,16 @@ AUTODATA(json_command, &invoice_command);
static void json_add_invoices(struct json_result *response, static void json_add_invoices(struct json_result *response,
struct wallet *wallet, struct wallet *wallet,
const char *buffer, const jsmntok_t *label, const struct json_escaped *label,
bool modern) bool modern)
{ {
struct invoice_iterator it; struct invoice_iterator it;
struct invoice_details details; struct invoice_details details;
char *lbl = NULL;
if (label)
lbl = tal_strndup(response, &buffer[label->start], label->end - label->start);
memset(&it, 0, sizeof(it)); memset(&it, 0, sizeof(it));
while (wallet_invoice_iterate(wallet, &it)) { while (wallet_invoice_iterate(wallet, &it)) {
wallet_invoice_iterator_deref(response, wallet, &it, &details); wallet_invoice_iterator_deref(response, wallet, &it, &details);
if (lbl && !streq(details.label, lbl)) if (label && !json_escaped_eq(details.label, label))
continue; continue;
json_add_invoice(response, &details, modern); json_add_invoice(response, &details, modern);
} }
@ -284,22 +281,34 @@ static void json_listinvoice_internal(struct command *cmd,
const jsmntok_t *params, const jsmntok_t *params,
bool modern) bool modern)
{ {
jsmntok_t *label = NULL; jsmntok_t *labeltok = NULL;
struct json_escaped *label;
struct json_result *response = new_json_result(cmd); struct json_result *response = new_json_result(cmd);
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
if (!json_get_params(cmd, buffer, params, if (!json_get_params(cmd, buffer, params,
"?label", &label, "?label", &labeltok,
NULL)) { NULL)) {
return; return;
} }
if (labeltok) {
label = json_tok_escaped_string(cmd, buffer, labeltok);
if (!label) {
command_fail(cmd, "label '%.*s' is not a string",
labeltok->end - labeltok->start,
buffer + labeltok->start);
return;
}
} else
label = NULL;
if (modern) { if (modern) {
json_object_start(response, NULL); json_object_start(response, NULL);
json_array_start(response, "invoices"); json_array_start(response, "invoices");
} else } else
json_array_start(response, NULL); json_array_start(response, NULL);
json_add_invoices(response, wallet, buffer, label, modern); json_add_invoices(response, wallet, label, modern);
json_array_end(response); json_array_end(response);
if (modern) if (modern)
json_object_end(response); json_object_end(response);
@ -341,7 +350,8 @@ static void json_delinvoice(struct command *cmd,
struct invoice_details details; struct invoice_details details;
jsmntok_t *labeltok, *statustok; jsmntok_t *labeltok, *statustok;
struct json_result *response = new_json_result(cmd); struct json_result *response = new_json_result(cmd);
const char *label, *status, *actual_status; const char *status, *actual_status;
struct json_escaped *label;
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
if (!json_get_params(cmd, buffer, params, if (!json_get_params(cmd, buffer, params,
@ -351,8 +361,13 @@ static void json_delinvoice(struct command *cmd,
return; return;
} }
label = tal_strndup(cmd, buffer + labeltok->start, label = json_tok_escaped_string(cmd, buffer, labeltok);
labeltok->end - labeltok->start); if (!label) {
command_fail(cmd, "label '%.*s' not a string",
labeltok->end - labeltok->start,
buffer + labeltok->start);
return;
}
if (!wallet_invoice_find_by_label(wallet, &i, label)) { if (!wallet_invoice_find_by_label(wallet, &i, label)) {
command_fail(cmd, "Unknown invoice"); command_fail(cmd, "Unknown invoice");
return; return;
@ -532,14 +547,21 @@ static void json_waitinvoice(struct command *cmd,
struct invoice_details details; struct invoice_details details;
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
jsmntok_t *labeltok; jsmntok_t *labeltok;
const char *label = NULL; struct json_escaped *label;
if (!json_get_params(cmd, buffer, params, "label", &labeltok, NULL)) { if (!json_get_params(cmd, buffer, params, "label", &labeltok, NULL)) {
return; return;
} }
/* Search for invoice */ /* Search for invoice */
label = tal_strndup(cmd, buffer + labeltok->start, labeltok->end - labeltok->start); label = json_tok_escaped_string(cmd, buffer, labeltok);
if (!label) {
command_fail(cmd, "label '%.*s' is not a string",
labeltok->end - labeltok->start,
buffer + labeltok->start);
return;
}
if (!wallet_invoice_find_by_label(wallet, &i, label)) { if (!wallet_invoice_find_by_label(wallet, &i, label)) {
command_fail(cmd, "Label not found"); command_fail(cmd, "Label not found");
return; return;

5
lightningd/peer_htlcs.c

@ -4,6 +4,7 @@
#include <ccan/mem/mem.h> #include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <channeld/gen_channel_wire.h> #include <channeld/gen_channel_wire.h>
#include <common/json_escaped.h>
#include <common/overflows.h> #include <common/overflows.h>
#include <common/sphinx.h> #include <common/sphinx.h>
#include <gossipd/gen_gossip_wire.h> #include <gossipd/gen_gossip_wire.h>
@ -299,9 +300,9 @@ static void handle_localpay(struct htlc_in *hin,
} }
log_info(ld->log, "Resolving invoice '%s' with HTLC %"PRIu64, log_info(ld->log, "Resolving invoice '%s' with HTLC %"PRIu64,
details.label, hin->key.id); details.label->s, hin->key.id);
log_debug(ld->log, "%s: Actual amount %"PRIu64"msat, HTLC expiry %u", log_debug(ld->log, "%s: Actual amount %"PRIu64"msat, HTLC expiry %u",
details.label, hin->msatoshi, cltv_expiry); details.label->s, hin->msatoshi, cltv_expiry);
fulfill_htlc(hin, &details.r); fulfill_htlc(hin, &details.r);
wallet_invoice_resolve(ld->wallet, invoice, hin->msatoshi); wallet_invoice_resolve(ld->wallet, invoice, hin->msatoshi);

16
wallet/db.c

@ -1,6 +1,7 @@
#include "db.h" #include "db.h"
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <common/json_escaped.h>
#include <common/version.h> #include <common/version.h>
#include <inttypes.h> #include <inttypes.h>
#include <lightningd/lightningd.h> #include <lightningd/lightningd.h>
@ -759,3 +760,18 @@ bool sqlite3_bind_sha256_double(sqlite3_stmt *stmt, int col, const struct sha256
sqlite3_bind_blob(stmt, col, p, sizeof(struct sha256_double), SQLITE_TRANSIENT); sqlite3_bind_blob(stmt, col, p, sizeof(struct sha256_double), SQLITE_TRANSIENT);
return true; return true;
} }
struct json_escaped *sqlite3_column_json_escaped(const tal_t *ctx,
sqlite3_stmt *stmt, int col)
{
return json_escaped_string_(ctx,
sqlite3_column_blob(stmt, col),
sqlite3_column_bytes(stmt, col));
}
bool sqlite3_bind_json_escaped(sqlite3_stmt *stmt, int col,
const struct json_escaped *esc)
{
sqlite3_bind_text(stmt, col, esc->s, strlen(esc->s), SQLITE_TRANSIENT);
return true;
}

5
wallet/db.h

@ -156,4 +156,9 @@ bool sqlite3_column_sha256_double(sqlite3_stmt *stmt, int col, struct sha256_do
bool sqlite3_bind_sha256_double(sqlite3_stmt *stmt, int col, const struct sha256_double *p); bool sqlite3_bind_sha256_double(sqlite3_stmt *stmt, int col, const struct sha256_double *p);
struct secret *sqlite3_column_secrets(const tal_t *ctx, struct secret *sqlite3_column_secrets(const tal_t *ctx,
sqlite3_stmt *stmt, int col); sqlite3_stmt *stmt, int col);
struct json_escaped *sqlite3_column_json_escaped(const tal_t *ctx,
sqlite3_stmt *stmt, int col);
bool sqlite3_bind_json_escaped(sqlite3_stmt *stmt, int col,
const struct json_escaped *esc);
#endif /* LIGHTNING_WALLET_DB_H */ #endif /* LIGHTNING_WALLET_DB_H */

10
wallet/invoices.c

@ -98,7 +98,7 @@ static void wallet_stmt2invoice_details(const tal_t *ctx,
sqlite3_column_sha256(stmt, 2, &dtl->rhash); sqlite3_column_sha256(stmt, 2, &dtl->rhash);
dtl->label = tal_strndup(ctx, sqlite3_column_blob(stmt, 3), sqlite3_column_bytes(stmt, 3)); dtl->label = sqlite3_column_json_escaped(ctx, stmt, 3);
if (sqlite3_column_type(stmt, 4) != SQLITE_NULL) { if (sqlite3_column_type(stmt, 4) != SQLITE_NULL) {
dtl->msatoshi = tal(ctx, u64); dtl->msatoshi = tal(ctx, u64);
@ -258,7 +258,7 @@ bool invoices_load(struct invoices *invoices)
bool invoices_create(struct invoices *invoices, bool invoices_create(struct invoices *invoices,
struct invoice *pinvoice, struct invoice *pinvoice,
u64 *msatoshi TAKES, u64 *msatoshi TAKES,
const char *label TAKES, const struct json_escaped *label TAKES,
u64 expiry, u64 expiry,
const char *b11enc, const char *b11enc,
const struct preimage *r, const struct preimage *r,
@ -302,7 +302,7 @@ bool invoices_create(struct invoices *invoices,
sqlite3_bind_int64(stmt, 4, *msatoshi); sqlite3_bind_int64(stmt, 4, *msatoshi);
else else
sqlite3_bind_null(stmt, 4); sqlite3_bind_null(stmt, 4);
sqlite3_bind_text(stmt, 5, label, strlen(label), SQLITE_TRANSIENT); sqlite3_bind_json_escaped(stmt, 5, label);
sqlite3_bind_int64(stmt, 6, expiry_time); sqlite3_bind_int64(stmt, 6, expiry_time);
sqlite3_bind_text(stmt, 7, b11enc, strlen(b11enc), SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 7, b11enc, strlen(b11enc), SQLITE_TRANSIENT);
@ -328,7 +328,7 @@ bool invoices_create(struct invoices *invoices,
bool invoices_find_by_label(struct invoices *invoices, bool invoices_find_by_label(struct invoices *invoices,
struct invoice *pinvoice, struct invoice *pinvoice,
const char *label) const struct json_escaped *label)
{ {
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
@ -336,7 +336,7 @@ bool invoices_find_by_label(struct invoices *invoices,
"SELECT id" "SELECT id"
" FROM invoices" " FROM invoices"
" WHERE label = ?;"); " WHERE label = ?;");
sqlite3_bind_text(stmt, 1, label, strlen(label), SQLITE_TRANSIENT); sqlite3_bind_json_escaped(stmt, 1, label);
if (sqlite3_step(stmt) == SQLITE_ROW) { if (sqlite3_step(stmt) == SQLITE_ROW) {
pinvoice->id = sqlite3_column_int64(stmt, 0); pinvoice->id = sqlite3_column_int64(stmt, 0);
sqlite3_finalize(stmt); sqlite3_finalize(stmt);

9
wallet/invoices.h

@ -7,6 +7,7 @@
#include <ccan/tal/tal.h> #include <ccan/tal/tal.h>
struct db; struct db;
struct json_escaped;
struct invoice; struct invoice;
struct invoice_details; struct invoice_details;
struct invoice_iterator; struct invoice_iterator;
@ -44,7 +45,7 @@ bool invoices_load(struct invoices *invoices);
* @msatoshi - the amount the invoice should have, or * @msatoshi - the amount the invoice should have, or
* NULL for any-amount invoices. * NULL for any-amount invoices.
* @label - the unique label for this invoice. Must be * @label - the unique label for this invoice. Must be
* non-NULL. Must be null-terminated. * non-NULL.
* @expiry - the number of seconds before the invoice * @expiry - the number of seconds before the invoice
* expires * expires
* *
@ -55,7 +56,7 @@ bool invoices_load(struct invoices *invoices);
bool invoices_create(struct invoices *invoices, bool invoices_create(struct invoices *invoices,
struct invoice *pinvoice, struct invoice *pinvoice,
u64 *msatoshi TAKES, u64 *msatoshi TAKES,
const char *label TAKES, const struct json_escaped *label TAKES,
u64 expiry, u64 expiry,
const char *b11enc, const char *b11enc,
const struct preimage *r, const struct preimage *r,
@ -66,14 +67,14 @@ bool invoices_create(struct invoices *invoices,
* *
* @invoices - the invoice handler. * @invoices - the invoice handler.
* @pinvoice - pointer to location to load found invoice in. * @pinvoice - pointer to location to load found invoice in.
* @label - the label to search for. Must be null-terminated. * @label - the label to search for.
* *
* Returns false if no invoice with that label exists. * Returns false if no invoice with that label exists.
* Returns true if found. * Returns true if found.
*/ */
bool invoices_find_by_label(struct invoices *invoices, bool invoices_find_by_label(struct invoices *invoices,
struct invoice *pinvoice, struct invoice *pinvoice,
const char *label); const struct json_escaped *label);
/** /**
* invoices_find_unpaid - Search for an unpaid, unexpired invoice by * invoices_find_unpaid - Search for an unpaid, unexpired invoice by

4
wallet/test/run-db.c

@ -17,6 +17,10 @@ static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, const c
#include <unistd.h> #include <unistd.h>
/* AUTOGENERATED MOCKS START */ /* AUTOGENERATED MOCKS START */
/* Generated stub for json_escaped_string_ */
struct json_escaped *json_escaped_string_(const tal_t *ctx UNNEEDED,
const void *bytes UNNEEDED, size_t len UNNEEDED)
{ fprintf(stderr, "json_escaped_string_ called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */ /* AUTOGENERATED MOCKS END */
static char *db_err; static char *db_err;

11
wallet/test/run-wallet.c

@ -108,7 +108,7 @@ void invoices_autoclean_set(struct invoices *invoices UNNEEDED,
bool invoices_create(struct invoices *invoices UNNEEDED, bool invoices_create(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED, struct invoice *pinvoice UNNEEDED,
u64 *msatoshi TAKES UNNEEDED, u64 *msatoshi TAKES UNNEEDED,
const char *label TAKES UNNEEDED, const struct json_escaped *label TAKES UNNEEDED,
u64 expiry UNNEEDED, u64 expiry UNNEEDED,
const char *b11enc UNNEEDED, const char *b11enc UNNEEDED,
const struct preimage *r UNNEEDED, const struct preimage *r UNNEEDED,
@ -125,7 +125,7 @@ void invoices_delete_expired(struct invoices *invoices UNNEEDED,
/* Generated stub for invoices_find_by_label */ /* Generated stub for invoices_find_by_label */
bool invoices_find_by_label(struct invoices *invoices UNNEEDED, bool invoices_find_by_label(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED, struct invoice *pinvoice UNNEEDED,
const char *label UNNEEDED) const struct json_escaped *label UNNEEDED)
{ fprintf(stderr, "invoices_find_by_label called!\n"); abort(); } { fprintf(stderr, "invoices_find_by_label called!\n"); abort(); }
/* Generated stub for invoices_find_unpaid */ /* Generated stub for invoices_find_unpaid */
bool invoices_find_unpaid(struct invoices *invoices UNNEEDED, bool invoices_find_unpaid(struct invoices *invoices UNNEEDED,
@ -181,7 +181,8 @@ void json_add_bool(struct json_result *result UNNEEDED, const char *fieldname UN
bool value UNNEEDED) bool value UNNEEDED)
{ fprintf(stderr, "json_add_bool called!\n"); abort(); } { fprintf(stderr, "json_add_bool called!\n"); abort(); }
/* Generated stub for json_add_escaped_string */ /* Generated stub for json_add_escaped_string */
void json_add_escaped_string(struct json_result *result UNNEEDED, const char *fieldname UNNEEDED, void json_add_escaped_string(struct json_result *result UNNEEDED,
const char *fieldname UNNEEDED,
const struct json_escaped *esc TAKES UNNEEDED) const struct json_escaped *esc TAKES UNNEEDED)
{ fprintf(stderr, "json_add_escaped_string called!\n"); abort(); } { fprintf(stderr, "json_add_escaped_string called!\n"); abort(); }
/* Generated stub for json_add_hex */ /* Generated stub for json_add_hex */
@ -230,6 +231,10 @@ void json_array_start(struct json_result *ptr UNNEEDED, const char *fieldname UN
/* Generated stub for json_escape */ /* Generated stub for json_escape */
struct json_escaped *json_escape(const tal_t *ctx UNNEEDED, const char *str TAKES UNNEEDED) struct json_escaped *json_escape(const tal_t *ctx UNNEEDED, const char *str TAKES UNNEEDED)
{ fprintf(stderr, "json_escape called!\n"); abort(); } { fprintf(stderr, "json_escape called!\n"); abort(); }
/* Generated stub for json_escaped_string_ */
struct json_escaped *json_escaped_string_(const tal_t *ctx UNNEEDED,
const void *bytes UNNEEDED, size_t len UNNEEDED)
{ fprintf(stderr, "json_escaped_string_ called!\n"); abort(); }
/* Generated stub for json_get_params */ /* Generated stub for json_get_params */
bool json_get_params(struct command *cmd UNNEEDED, bool json_get_params(struct command *cmd UNNEEDED,
const char *buffer UNNEEDED, const jsmntok_t param[] UNNEEDED, ...) const char *buffer UNNEEDED, const jsmntok_t param[] UNNEEDED, ...)

4
wallet/wallet.c

@ -1369,7 +1369,7 @@ bool wallet_invoice_load(struct wallet *wallet)
bool wallet_invoice_create(struct wallet *wallet, bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice, struct invoice *pinvoice,
u64 *msatoshi TAKES, u64 *msatoshi TAKES,
const char *label TAKES, const struct json_escaped *label TAKES,
u64 expiry, u64 expiry,
const char *b11enc, const char *b11enc,
const struct preimage *r, const struct preimage *r,
@ -1379,7 +1379,7 @@ bool wallet_invoice_create(struct wallet *wallet,
} }
bool wallet_invoice_find_by_label(struct wallet *wallet, bool wallet_invoice_find_by_label(struct wallet *wallet,
struct invoice *pinvoice, struct invoice *pinvoice,
const char *label) const struct json_escaped *label)
{ {
return invoices_find_by_label(wallet->invoices, pinvoice, label); return invoices_find_by_label(wallet->invoices, pinvoice, label);
} }

10
wallet/wallet.h

@ -397,7 +397,7 @@ struct invoice_details {
/* Hash of preimage r */ /* Hash of preimage r */
struct sha256 rhash; struct sha256 rhash;
/* Label assigned by user */ /* Label assigned by user */
const char *label; const struct json_escaped *label;
/* NULL if they specified "any" */ /* NULL if they specified "any" */
u64 *msatoshi; u64 *msatoshi;
/* Absolute UNIX epoch time this will expire */ /* Absolute UNIX epoch time this will expire */
@ -449,7 +449,7 @@ bool wallet_invoice_load(struct wallet *wallet);
* @msatoshi - the amount the invoice should have, or * @msatoshi - the amount the invoice should have, or
* NULL for any-amount invoices. * NULL for any-amount invoices.
* @label - the unique label for this invoice. Must be * @label - the unique label for this invoice. Must be
* non-NULL. Must be null-terminated. * non-NULL.
* @expiry - the number of seconds before the invoice * @expiry - the number of seconds before the invoice
* expires * expires
* *
@ -460,7 +460,7 @@ bool wallet_invoice_load(struct wallet *wallet);
bool wallet_invoice_create(struct wallet *wallet, bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice, struct invoice *pinvoice,
u64 *msatoshi TAKES, u64 *msatoshi TAKES,
const char *label TAKES, const struct json_escaped *label TAKES,
u64 expiry, u64 expiry,
const char *b11enc, const char *b11enc,
const struct preimage *r, const struct preimage *r,
@ -471,14 +471,14 @@ bool wallet_invoice_create(struct wallet *wallet,
* *
* @wallet - the wallet to search. * @wallet - the wallet to search.
* @pinvoice - pointer to location to load found invoice in. * @pinvoice - pointer to location to load found invoice in.
* @label - the label to search for. Must be null-terminated. * @label - the label to search for.
* *
* Returns false if no invoice with that label exists. * Returns false if no invoice with that label exists.
* Returns true if found. * Returns true if found.
*/ */
bool wallet_invoice_find_by_label(struct wallet *wallet, bool wallet_invoice_find_by_label(struct wallet *wallet,
struct invoice *pinvoice, struct invoice *pinvoice,
const char *label); const struct json_escaped *label);
/** /**
* wallet_invoice_find_unpaid - Search for an unpaid, unexpired invoice by * wallet_invoice_find_unpaid - Search for an unpaid, unexpired invoice by

Loading…
Cancel
Save