invoices: Make the invoice_details more idiomatic

This seems like a premature optimization: it tried to cut down the number of
allocations by reusing the same `struct invoice_details` while iterating through
a number of results. But this sidesteps the checks by `valgrind` and we'd miss a
missing field that was set by the previous iteration.

Reported-by: @rustyrussell
Signed-off-by: Christian Decker <@cdecker>
This commit is contained in:
Christian Decker
2018-07-27 12:57:02 +02:00
committed by Rusty Russell
parent 259a69994d
commit fbbc5899e4
7 changed files with 85 additions and 93 deletions

View File

@@ -60,11 +60,11 @@ static void json_add_invoice(struct json_result *response,
static void tell_waiter(struct command *cmd, const struct invoice *inv)
{
struct json_result *response = new_json_result(cmd);
struct invoice_details details;
const struct invoice_details *details;
wallet_invoice_details(cmd, cmd->ld->wallet, *inv, &details);
json_add_invoice(response, &details);
if (details.state == PAID)
details = wallet_invoice_details(cmd, cmd->ld->wallet, *inv);
json_add_invoice(response, details);
if (details->state == PAID)
command_success(cmd, response);
else {
/* FIXME: -2 should be a constant in jsonrpc_errors.h. */
@@ -153,7 +153,7 @@ static void json_invoice(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct invoice invoice;
struct invoice_details details;
const struct invoice_details *details;
const jsmntok_t *msatoshi, *label, *desctok, *fallbacks;
const jsmntok_t *preimagetok;
u64 *msatoshi_val;
@@ -320,23 +320,23 @@ static void json_invoice(struct command *cmd,
}
/* Get details */
wallet_invoice_details(cmd, cmd->ld->wallet, invoice, &details);
details = wallet_invoice_details(cmd, cmd->ld->wallet, invoice);
json_object_start(response, NULL);
json_add_hex(response, "payment_hash",
&details.rhash, sizeof(details.rhash));
json_add_u64(response, "expires_at", details.expiry_time);
json_add_string(response, "bolt11", details.bolt11);
json_add_hex(response, "payment_hash", details->rhash.u.u8,
sizeof(details->rhash));
json_add_u64(response, "expires_at", details->expiry_time);
json_add_string(response, "bolt11", details->bolt11);
json_object_end(response);
command_success(cmd, response);
}
static const struct json_command invoice_command = {
"invoice",
json_invoice,
"Create an invoice for {msatoshi} with {label} and {description} with optional {expiry} seconds (default 1 hour) and optional {preimage} (default autogenerated)"
};
"invoice", json_invoice, "Create an invoice for {msatoshi} with {label} "
"and {description} with optional {expiry} seconds "
"(default 1 hour) and optional {preimage} "
"(default autogenerated)"};
AUTODATA(json_command, &invoice_command);
static void json_add_invoices(struct json_result *response,
@@ -344,23 +344,22 @@ static void json_add_invoices(struct json_result *response,
const struct json_escaped *label)
{
struct invoice_iterator it;
struct invoice_details details;
const struct invoice_details *details;
/* Don't iterate entire db if we're just after one. */
if (label) {
struct invoice invoice;
if (wallet_invoice_find_by_label(wallet, &invoice, label)) {
wallet_invoice_details(response, wallet, invoice,
&details);
json_add_invoice(response, &details);
details = wallet_invoice_details(response, wallet, invoice);
json_add_invoice(response, details);
}
return;
}
memset(&it, 0, sizeof(it));
while (wallet_invoice_iterate(wallet, &it)) {
wallet_invoice_iterator_deref(response, wallet, &it, &details);
json_add_invoice(response, &details);
details = wallet_invoice_iterator_deref(response, wallet, &it);
json_add_invoice(response, details);
}
}
@@ -408,7 +407,7 @@ static void json_delinvoice(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct invoice i;
struct invoice_details details;
const struct invoice_details *details;
const jsmntok_t *labeltok, *statustok;
struct json_result *response = new_json_result(cmd);
const char *status, *actual_status;
@@ -433,13 +432,14 @@ static void json_delinvoice(struct command *cmd,
command_fail(cmd, LIGHTNINGD, "Unknown invoice");
return;
}
wallet_invoice_details(cmd, cmd->ld->wallet, i, &details);
details = wallet_invoice_details(cmd, cmd->ld->wallet, i);
status = tal_strndup(cmd, buffer + statustok->start,
statustok->end - statustok->start);
/* This is time-sensitive, so only call once; otherwise error msg
* might not make sense if it changed! */
actual_status = invoice_status_str(&details);
actual_status = invoice_status_str(details);
if (!streq(actual_status, status)) {
command_fail(cmd, LIGHTNINGD, "Invoice status is %s not %s",
actual_status, status);
@@ -448,7 +448,7 @@ static void json_delinvoice(struct command *cmd,
/* Get invoice details before attempting to delete, as
* otherwise the invoice will be freed. */
json_add_invoice(response, &details);
json_add_invoice(response, details);
if (!wallet_invoice_delete(wallet, i)) {
log_broken(cmd->ld->log,
@@ -562,7 +562,7 @@ static void json_waitinvoice(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct invoice i;
struct invoice_details details;
const struct invoice_details *details;
struct wallet *wallet = cmd->ld->wallet;
const jsmntok_t *labeltok;
struct json_escaped *label;
@@ -586,10 +586,10 @@ static void json_waitinvoice(struct command *cmd,
command_fail(cmd, LIGHTNINGD, "Label not found");
return;
}
wallet_invoice_details(cmd, cmd->ld->wallet, i, &details);
details = wallet_invoice_details(cmd, cmd->ld->wallet, i);
/* If paid or expired return immediately */
if (details.state == PAID || details.state == EXPIRED) {
if (details->state == PAID || details->state == EXPIRED) {
tell_waiter(cmd, &i);
return;
} else {

View File

@@ -249,7 +249,7 @@ static void handle_localpay(struct htlc_in *hin,
{
enum onion_type failcode;
struct invoice invoice;
struct invoice_details details;
const struct invoice_details *details;
struct lightningd *ld = hin->key.channel->peer->ld;
/* BOLT #4:
@@ -282,7 +282,7 @@ static void handle_localpay(struct htlc_in *hin,
failcode = WIRE_UNKNOWN_PAYMENT_HASH;
goto fail;
}
wallet_invoice_details(tmpctx, ld->wallet, invoice, &details);
details = wallet_invoice_details(tmpctx, ld->wallet, invoice);
/* BOLT #4:
*
@@ -298,10 +298,10 @@ static void handle_localpay(struct htlc_in *hin,
* leakage by altering the amount while not allowing for
* accidental gross overpayment.
*/
if (details.msatoshi != NULL && hin->msatoshi < *details.msatoshi) {
if (details->msatoshi != NULL && hin->msatoshi < *details->msatoshi) {
failcode = WIRE_INCORRECT_PAYMENT_AMOUNT;
goto fail;
} else if (details.msatoshi != NULL && hin->msatoshi > *details.msatoshi * 2) {
} else if (details->msatoshi != NULL && hin->msatoshi > *details->msatoshi * 2) {
failcode = WIRE_INCORRECT_PAYMENT_AMOUNT;
goto fail;
}
@@ -324,10 +324,10 @@ static void handle_localpay(struct htlc_in *hin,
}
log_info(ld->log, "Resolving invoice '%s' with HTLC %"PRIu64,
details.label->s, hin->key.id);
details->label->s, hin->key.id);
log_debug(ld->log, "%s: Actual amount %"PRIu64"msat, HTLC expiry %u",
details.label->s, hin->msatoshi, cltv_expiry);
fulfill_htlc(hin, &details.r);
details->label->s, hin->msatoshi, cltv_expiry);
fulfill_htlc(hin, &details->r);
wallet_invoice_resolve(ld->wallet, invoice, hin->msatoshi);
return;