mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
wallet: Adding primitives to save/load invoices to wallet
Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
048680d0f2
commit
a005bce155
@ -1096,12 +1096,99 @@ bool wallet_htlcs_reconnect(struct wallet *wallet,
|
|||||||
if (!hout->in) {
|
if (!hout->in) {
|
||||||
log_broken(
|
log_broken(
|
||||||
wallet->log,
|
wallet->log,
|
||||||
"Unable to find corresponding htlc_in %" PRIu64
|
"Unable to find corresponding htlc_in %"PRIu64" for htlc_out %"PRIu64,
|
||||||
" for htlc_out %" PRIu64,
|
|
||||||
hout->origin_htlc_id, hout->dbid);
|
hout->origin_htlc_id, hout->dbid);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wallet_invoice_save(struct wallet *wallet, struct invoice *inv)
|
||||||
|
{
|
||||||
|
/* Need to use the lower level API of sqlite3 to bind
|
||||||
|
* label. Otherwise we'd need to implement sanitization of
|
||||||
|
* that string for sql injections... */
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
if (!inv->id) {
|
||||||
|
stmt = db_prepare(wallet->db,
|
||||||
|
"INSERT INTO invoices (payment_hash, payment_key, state, msatoshi, label) VALUES (?, ?, ?, ?, ?);");
|
||||||
|
if (!stmt) {
|
||||||
|
log_broken(wallet->log, "Could not prepare statement: %s", wallet->db->err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_bind_blob(stmt, 1, &inv->rhash, sizeof(inv->rhash), SQLITE_TRANSIENT);
|
||||||
|
sqlite3_bind_blob(stmt, 2, &inv->r, sizeof(inv->r), SQLITE_TRANSIENT);
|
||||||
|
sqlite3_bind_int(stmt, 3, inv->state);
|
||||||
|
sqlite3_bind_int64(stmt, 4, inv->msatoshi);
|
||||||
|
sqlite3_bind_text(stmt, 5, inv->label, strlen(inv->label), SQLITE_TRANSIENT);
|
||||||
|
|
||||||
|
if (!db_exec_prepared(wallet->db, stmt)) {
|
||||||
|
log_broken(wallet->log, "Could not exec prepared statement: %s", wallet->db->err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inv->id = sqlite3_last_insert_rowid(wallet->db->sql);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
stmt = db_prepare(wallet->db, "UPDATE invoices SET state=? WHERE id=?;");
|
||||||
|
|
||||||
|
if (!stmt) {
|
||||||
|
log_broken(wallet->log, "Could not prepare statement: %s", wallet->db->err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_bind_int(stmt, 1, inv->state);
|
||||||
|
sqlite3_bind_int64(stmt, 2, inv->id);
|
||||||
|
|
||||||
|
if (!db_exec_prepared(wallet->db, stmt)) {
|
||||||
|
log_broken(wallet->log, "Could not exec prepared statement: %s", wallet->db->err);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool wallet_stmt2invoice(sqlite3_stmt *stmt, struct invoice *inv)
|
||||||
|
{
|
||||||
|
inv->id = sqlite3_column_int64(stmt, 0);
|
||||||
|
inv->state = sqlite3_column_int(stmt, 1);
|
||||||
|
|
||||||
|
assert(sqlite3_column_bytes(stmt, 2) == sizeof(struct preimage));
|
||||||
|
memcpy(&inv->r, sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
|
||||||
|
|
||||||
|
assert(sqlite3_column_bytes(stmt, 3) == sizeof(struct sha256));
|
||||||
|
memcpy(&inv->rhash, sqlite3_column_blob(stmt, 3), sqlite3_column_bytes(stmt, 3));
|
||||||
|
|
||||||
|
inv->label = tal_strndup(inv, sqlite3_column_blob(stmt, 4), sqlite3_column_bytes(stmt, 4));
|
||||||
|
inv->msatoshi = sqlite3_column_int64(stmt, 5);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wallet_invoices_load(struct wallet *wallet, struct invoices *invs)
|
||||||
|
{
|
||||||
|
struct invoice *i;
|
||||||
|
int count = 0;
|
||||||
|
sqlite3_stmt *stmt = db_query(__func__, wallet->db,
|
||||||
|
"SELECT id, state, payment_key, payment_hash, "
|
||||||
|
"label, msatoshi FROM invoices;");
|
||||||
|
if (!stmt) {
|
||||||
|
log_broken(wallet->log, "Could not load invoices: %s", wallet->db->err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
|
i = tal(invs, struct invoice);
|
||||||
|
if (!wallet_stmt2invoice(stmt, i)) {
|
||||||
|
log_broken(wallet->log, "Error deserializing invoice");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
invoice_add(invs, i);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug(wallet->log, "Loaded %d invoices from DB", count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <common/channel_config.h>
|
#include <common/channel_config.h>
|
||||||
#include <common/utxo.h>
|
#include <common/utxo.h>
|
||||||
#include <lightningd/htlc_end.h>
|
#include <lightningd/htlc_end.h>
|
||||||
|
#include <lightningd/invoice.h>
|
||||||
#include <wally_bip32.h>
|
#include <wally_bip32.h>
|
||||||
|
|
||||||
struct lightningd;
|
struct lightningd;
|
||||||
@ -300,4 +301,26 @@ bool wallet_htlcs_reconnect(struct wallet *wallet,
|
|||||||
struct htlc_in_map *htlcs_in,
|
struct htlc_in_map *htlcs_in,
|
||||||
struct htlc_out_map *htlcs_out);
|
struct htlc_out_map *htlcs_out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wallet_invoice_save -- Save/update an invoice to the wallet
|
||||||
|
*
|
||||||
|
* Save or update the invoice in the wallet. If `inv->id` is 0 this
|
||||||
|
* invoice will be considered a new invoice and result in an intert
|
||||||
|
* into the database, otherwise it'll be updated.
|
||||||
|
*
|
||||||
|
* @wallet: Wallet to store in
|
||||||
|
* @inv: Invoice to save
|
||||||
|
*/
|
||||||
|
bool wallet_invoice_save(struct wallet *wallet, struct invoice *inv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wallet_invoices_load -- Load all invoices into memory
|
||||||
|
*
|
||||||
|
* Load all invoices into the given `invoices` struct.
|
||||||
|
*
|
||||||
|
* @wallet: Wallet to load invoices from
|
||||||
|
* @invs: invoices container to load into
|
||||||
|
*/
|
||||||
|
bool wallet_invoices_load(struct wallet *wallet, struct invoices *invs);
|
||||||
|
|
||||||
#endif /* WALLET_WALLET_H */
|
#endif /* WALLET_WALLET_H */
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wallet/test_utils.h>
|
#include <wallet/test_utils.h>
|
||||||
|
|
||||||
|
void invoice_add(struct invoices *invs,
|
||||||
|
struct invoice *inv){}
|
||||||
|
|
||||||
static struct wallet *create_test_wallet(const tal_t *ctx)
|
static struct wallet *create_test_wallet(const tal_t *ctx)
|
||||||
{
|
{
|
||||||
char filename[] = "/tmp/ldb-XXXXXX";
|
char filename[] = "/tmp/ldb-XXXXXX";
|
||||||
|
Loading…
Reference in New Issue
Block a user