From cb6820d44504430d971ae604c3d02b81862c4c1f Mon Sep 17 00:00:00 2001 From: Igor Cota Date: Wed, 28 Feb 2018 17:26:58 +0100 Subject: [PATCH] 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 --- lightningd/invoice.c | 41 +++++++++++++++++++++++++--------------- wallet/invoices.c | 24 +++++++++++------------ wallet/invoices.h | 6 +++++- wallet/test/run-wallet.c | 5 ++++- wallet/wallet.c | 8 ++++++-- wallet/wallet.h | 5 ++++- 6 files changed, 57 insertions(+), 32 deletions(-) diff --git a/lightningd/invoice.c b/lightningd/invoice.c index e516802e7..45b8e5499 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -34,6 +34,7 @@ static void json_add_invoice(struct json_result *response, { json_object_start(response, NULL); 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)); if (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, - &invoice, - take(msatoshi_val), - 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); + /* Generate random secret preimage and hash. */ + randombytes_buf(r.r, sizeof(r.r)); + sha256(&rhash, r.r, sizeof(r.r)); /* Construct bolt11 string. */ - b11 = new_bolt11(cmd, details.msatoshi); + b11 = new_bolt11(cmd, msatoshi_val); b11->chain = get_chainparams(cmd->ld); b11->timestamp = time_now().ts.tv_sec; - b11->payment_hash = details.rhash; + b11->payment_hash = rhash; b11->receiver_id = cmd->ld->id; b11->min_final_cltv_expiry = cmd->ld->config.cltv_final; b11->expiry = expiry; @@ -223,13 +217,30 @@ static void json_invoice(struct command *cmd, /* FIXME: add private routes if necessary! */ 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_add_hex(response, "payment_hash", &details.rhash, sizeof(details.rhash)); if (deprecated_apis) json_add_u64(response, "expiry_time", 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); command_success(cmd, response); diff --git a/wallet/invoices.c b/wallet/invoices.c index 22b642aa9..8cc43e477 100644 --- a/wallet/invoices.c +++ b/wallet/invoices.c @@ -117,6 +117,7 @@ static void wallet_stmt2invoice_details(const tal_t *ctx, dtl->paid_timestamp = sqlite3_column_int64(stmt, 8); } + dtl->bolt11 = tal_strndup(ctx, sqlite3_column_blob(stmt, 9), sqlite3_column_bytes(stmt, 9)); return; } @@ -263,12 +264,13 @@ bool invoices_create(struct invoices *invoices, struct invoice *pinvoice, u64 *msatoshi TAKES, const char *label TAKES, - u64 expiry) + u64 expiry, + const char *b11enc, + const struct preimage *r, + const struct sha256 *rhash) { sqlite3_stmt *stmt; struct invoice dummy; - struct preimage r; - struct sha256 rhash; u64 expiry_time; u64 now = time_now().ts.tv_sec; @@ -282,9 +284,6 @@ bool invoices_create(struct invoices *invoices, /* Compute expiration. */ 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. */ /* 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" " , msatoshi, label, expiry_time" " , pay_index, msatoshi_received" - " , paid_timestamp)" + " , paid_timestamp, bolt11)" " VALUES ( ?, ?, ?" " , ?, ?, ?" " , NULL, NULL" - " , NULL);"); + " , NULL, ?);"); - sqlite3_bind_blob(stmt, 1, &rhash, sizeof(rhash), SQLITE_TRANSIENT); - sqlite3_bind_blob(stmt, 2, &r, sizeof(r), SQLITE_TRANSIENT); + sqlite3_bind_blob(stmt, 1, rhash, sizeof(struct sha256), SQLITE_TRANSIENT); + sqlite3_bind_blob(stmt, 2, r, sizeof(struct preimage), SQLITE_TRANSIENT); sqlite3_bind_int(stmt, 3, UNPAID); if (msatoshi) sqlite3_bind_int64(stmt, 4, *msatoshi); @@ -310,6 +309,7 @@ bool invoices_create(struct invoices *invoices, sqlite3_bind_null(stmt, 4); sqlite3_bind_text(stmt, 5, label, strlen(label), SQLITE_TRANSIENT); sqlite3_bind_int64(stmt, 6, expiry_time); + sqlite3_bind_text(stmt, 7, b11enc, strlen(b11enc), SQLITE_TRANSIENT); db_exec_prepared(invoices->db, stmt); @@ -403,7 +403,7 @@ bool invoices_iterate(struct invoices *invoices, stmt = db_prepare(invoices->db, "SELECT state, payment_key, payment_hash" " , label, msatoshi, expiry_time, pay_index" - " , msatoshi_received, paid_timestamp" + " , msatoshi_received, paid_timestamp, bolt11" " FROM invoices;"); it->p = stmt; } else @@ -580,7 +580,7 @@ void invoices_get_details(const tal_t *ctx, stmt = db_prepare(invoices->db, "SELECT state, payment_key, payment_hash" " , label, msatoshi, expiry_time, pay_index" - " , msatoshi_received, paid_timestamp" + " , msatoshi_received, paid_timestamp, bolt11" " FROM invoices" " WHERE id = ?;"); sqlite3_bind_int64(stmt, 1, invoice.id); diff --git a/wallet/invoices.h b/wallet/invoices.h index fce9d0fe8..05ccba482 100644 --- a/wallet/invoices.h +++ b/wallet/invoices.h @@ -4,6 +4,7 @@ #include #include #include +#include struct db; struct invoice; @@ -55,7 +56,10 @@ bool invoices_create(struct invoices *invoices, struct invoice *pinvoice, u64 *msatoshi 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 diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index d1cc1d65a..a828fed32 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -99,7 +99,10 @@ bool invoices_create(struct invoices *invoices UNNEEDED, struct invoice *pinvoice UNNEEDED, u64 *msatoshi 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(); } /* Generated stub for invoices_delete */ bool invoices_delete(struct invoices *invoices UNNEEDED, diff --git a/wallet/wallet.c b/wallet/wallet.c index e350d3e2a..bc562e224 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1270,8 +1270,12 @@ bool wallet_invoice_create(struct wallet *wallet, struct invoice *pinvoice, u64 *msatoshi TAKES, const char *label TAKES, - u64 expiry) { - return invoices_create(wallet->invoices, pinvoice, msatoshi, label, expiry); + u64 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, struct invoice *pinvoice, diff --git a/wallet/wallet.h b/wallet/wallet.h index 38076a55e..68f2090be 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -441,7 +441,10 @@ bool wallet_invoice_create(struct wallet *wallet, struct invoice *pinvoice, u64 *msatoshi 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