Do preimage, hash and consequentially bolt11 generation before we store the invoice in db.

This way we store bolt11 to the table as well, in case a client needs it later
This commit is contained in:
Igor Cota 2018-02-28 17:26:58 +01:00 committed by Rusty Russell
parent 3371168d54
commit cb6820d445
6 changed files with 57 additions and 32 deletions

View file

@ -34,6 +34,7 @@ static void json_add_invoice(struct json_result *response,
{ {
json_object_start(response, NULL); json_object_start(response, NULL);
json_add_string(response, "label", inv->label); json_add_string(response, "label", inv->label);
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)
json_add_u64(response, "msatoshi", *inv->msatoshi); json_add_u64(response, "msatoshi", *inv->msatoshi);
@ -193,25 +194,18 @@ static void json_invoice(struct command *cmd,
} }
} }
struct preimage r;
struct sha256 rhash;
result = wallet_invoice_create(cmd->ld->wallet, /* Generate random secret preimage and hash. */
&invoice, randombytes_buf(r.r, sizeof(r.r));
take(msatoshi_val), sha256(&rhash, r.r, sizeof(r.r));
take(label_val),
expiry);
if (!result) {
command_fail(cmd, "Failed to create invoice on database");
return;
}
/* Get details */
wallet_invoice_details(cmd, cmd->ld->wallet, invoice, &details);
/* Construct bolt11 string. */ /* Construct bolt11 string. */
b11 = new_bolt11(cmd, details.msatoshi); b11 = new_bolt11(cmd, msatoshi_val);
b11->chain = get_chainparams(cmd->ld); b11->chain = get_chainparams(cmd->ld);
b11->timestamp = time_now().ts.tv_sec; b11->timestamp = time_now().ts.tv_sec;
b11->payment_hash = details.rhash; b11->payment_hash = rhash;
b11->receiver_id = cmd->ld->id; b11->receiver_id = cmd->ld->id;
b11->min_final_cltv_expiry = cmd->ld->config.cltv_final; b11->min_final_cltv_expiry = cmd->ld->config.cltv_final;
b11->expiry = expiry; b11->expiry = expiry;
@ -223,13 +217,30 @@ static void json_invoice(struct command *cmd,
/* FIXME: add private routes if necessary! */ /* FIXME: add private routes if necessary! */
b11enc = bolt11_encode(cmd, b11, false, hsm_sign_b11, cmd->ld); b11enc = bolt11_encode(cmd, b11, false, hsm_sign_b11, cmd->ld);
result = wallet_invoice_create(cmd->ld->wallet,
&invoice,
take(msatoshi_val),
take(label_val),
expiry,
b11enc,
&r,
&rhash);
if (!result) {
command_fail(cmd, "Failed to create invoice on database");
return;
}
/* Get details */
wallet_invoice_details(cmd, cmd->ld->wallet, invoice, &details);
json_object_start(response, NULL); json_object_start(response, NULL);
json_add_hex(response, "payment_hash", json_add_hex(response, "payment_hash",
&details.rhash, sizeof(details.rhash)); &details.rhash, sizeof(details.rhash));
if (deprecated_apis) if (deprecated_apis)
json_add_u64(response, "expiry_time", details.expiry_time); json_add_u64(response, "expiry_time", details.expiry_time);
json_add_u64(response, "expires_at", details.expiry_time); json_add_u64(response, "expires_at", details.expiry_time);
json_add_string(response, "bolt11", b11enc); json_add_string(response, "bolt11", details.bolt11);
json_object_end(response); json_object_end(response);
command_success(cmd, response); command_success(cmd, response);

View file

@ -117,6 +117,7 @@ static void wallet_stmt2invoice_details(const tal_t *ctx,
dtl->paid_timestamp = sqlite3_column_int64(stmt, 8); dtl->paid_timestamp = sqlite3_column_int64(stmt, 8);
} }
dtl->bolt11 = tal_strndup(ctx, sqlite3_column_blob(stmt, 9), sqlite3_column_bytes(stmt, 9));
return; return;
} }
@ -263,12 +264,13 @@ bool invoices_create(struct invoices *invoices,
struct invoice *pinvoice, struct invoice *pinvoice,
u64 *msatoshi TAKES, u64 *msatoshi TAKES,
const char *label TAKES, const char *label TAKES,
u64 expiry) u64 expiry,
const char *b11enc,
const struct preimage *r,
const struct sha256 *rhash)
{ {
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
struct invoice dummy; struct invoice dummy;
struct preimage r;
struct sha256 rhash;
u64 expiry_time; u64 expiry_time;
u64 now = time_now().ts.tv_sec; u64 now = time_now().ts.tv_sec;
@ -282,9 +284,6 @@ bool invoices_create(struct invoices *invoices,
/* Compute expiration. */ /* Compute expiration. */
expiry_time = now + expiry; expiry_time = now + expiry;
/* Generate random secret preimage and hash. */
randombytes_buf(r.r, sizeof(r.r));
sha256(&rhash, r.r, sizeof(r.r));
/* Save to database. */ /* Save to database. */
/* Need to use the lower level API of sqlite3 to bind /* Need to use the lower level API of sqlite3 to bind
@ -295,14 +294,14 @@ bool invoices_create(struct invoices *invoices,
" ( payment_hash, payment_key, state" " ( payment_hash, payment_key, state"
" , msatoshi, label, expiry_time" " , msatoshi, label, expiry_time"
" , pay_index, msatoshi_received" " , pay_index, msatoshi_received"
" , paid_timestamp)" " , paid_timestamp, bolt11)"
" VALUES ( ?, ?, ?" " VALUES ( ?, ?, ?"
" , ?, ?, ?" " , ?, ?, ?"
" , NULL, NULL" " , NULL, NULL"
" , NULL);"); " , NULL, ?);");
sqlite3_bind_blob(stmt, 1, &rhash, sizeof(rhash), SQLITE_TRANSIENT); sqlite3_bind_blob(stmt, 1, rhash, sizeof(struct sha256), SQLITE_TRANSIENT);
sqlite3_bind_blob(stmt, 2, &r, sizeof(r), SQLITE_TRANSIENT); sqlite3_bind_blob(stmt, 2, r, sizeof(struct preimage), SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 3, UNPAID); sqlite3_bind_int(stmt, 3, UNPAID);
if (msatoshi) if (msatoshi)
sqlite3_bind_int64(stmt, 4, *msatoshi); sqlite3_bind_int64(stmt, 4, *msatoshi);
@ -310,6 +309,7 @@ bool invoices_create(struct invoices *invoices,
sqlite3_bind_null(stmt, 4); sqlite3_bind_null(stmt, 4);
sqlite3_bind_text(stmt, 5, label, strlen(label), SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 5, label, strlen(label), SQLITE_TRANSIENT);
sqlite3_bind_int64(stmt, 6, expiry_time); sqlite3_bind_int64(stmt, 6, expiry_time);
sqlite3_bind_text(stmt, 7, b11enc, strlen(b11enc), SQLITE_TRANSIENT);
db_exec_prepared(invoices->db, stmt); db_exec_prepared(invoices->db, stmt);
@ -403,7 +403,7 @@ bool invoices_iterate(struct invoices *invoices,
stmt = db_prepare(invoices->db, stmt = db_prepare(invoices->db,
"SELECT state, payment_key, payment_hash" "SELECT state, payment_key, payment_hash"
" , label, msatoshi, expiry_time, pay_index" " , label, msatoshi, expiry_time, pay_index"
" , msatoshi_received, paid_timestamp" " , msatoshi_received, paid_timestamp, bolt11"
" FROM invoices;"); " FROM invoices;");
it->p = stmt; it->p = stmt;
} else } else
@ -580,7 +580,7 @@ void invoices_get_details(const tal_t *ctx,
stmt = db_prepare(invoices->db, stmt = db_prepare(invoices->db,
"SELECT state, payment_key, payment_hash" "SELECT state, payment_key, payment_hash"
" , label, msatoshi, expiry_time, pay_index" " , label, msatoshi, expiry_time, pay_index"
" , msatoshi_received, paid_timestamp" " , msatoshi_received, paid_timestamp, bolt11"
" FROM invoices" " FROM invoices"
" WHERE id = ?;"); " WHERE id = ?;");
sqlite3_bind_int64(stmt, 1, invoice.id); sqlite3_bind_int64(stmt, 1, invoice.id);

View file

@ -4,6 +4,7 @@
#include <ccan/short_types/short_types.h> #include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h> #include <ccan/tal/tal.h>
#include <ccan/take/take.h> #include <ccan/take/take.h>
#include <bitcoin/preimage.h>
struct db; struct db;
struct invoice; struct invoice;
@ -55,7 +56,10 @@ bool invoices_create(struct invoices *invoices,
struct invoice *pinvoice, struct invoice *pinvoice,
u64 *msatoshi TAKES, u64 *msatoshi TAKES,
const char *label TAKES, const char *label TAKES,
u64 expiry); u64 expiry,
const char *b11enc,
const struct preimage *r,
const struct sha256 *rhash);
/** /**
* invoices_find_by_label - Search for an invoice by label * invoices_find_by_label - Search for an invoice by label

View file

@ -99,7 +99,10 @@ 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 char *label TAKES UNNEEDED,
u64 expiry UNNEEDED) u64 expiry UNNEEDED,
const char *b11enc UNNEEDED,
const struct preimage *r UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "invoices_create called!\n"); abort(); } { fprintf(stderr, "invoices_create called!\n"); abort(); }
/* Generated stub for invoices_delete */ /* Generated stub for invoices_delete */
bool invoices_delete(struct invoices *invoices UNNEEDED, bool invoices_delete(struct invoices *invoices UNNEEDED,

View file

@ -1270,8 +1270,12 @@ bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice, struct invoice *pinvoice,
u64 *msatoshi TAKES, u64 *msatoshi TAKES,
const char *label TAKES, const char *label TAKES,
u64 expiry) { u64 expiry,
return invoices_create(wallet->invoices, pinvoice, msatoshi, label, expiry); const char *b11enc,
const struct preimage *r,
const struct sha256 *rhash)
{
return invoices_create(wallet->invoices, pinvoice, msatoshi, label, expiry, b11enc, r, rhash);
} }
bool wallet_invoice_find_by_label(struct wallet *wallet, bool wallet_invoice_find_by_label(struct wallet *wallet,
struct invoice *pinvoice, struct invoice *pinvoice,

View file

@ -441,7 +441,10 @@ bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice, struct invoice *pinvoice,
u64 *msatoshi TAKES, u64 *msatoshi TAKES,
const char *label TAKES, const char *label TAKES,
u64 expiry); u64 expiry,
const char *b11enc,
const struct preimage *r,
const struct sha256 *rhash);
/** /**
* wallet_invoice_find_by_label - Search for an invoice by label * wallet_invoice_find_by_label - Search for an invoice by label