From dea0aef52fc0d4465769362457b8ba55d685bb2a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 18 Jan 2018 06:52:22 +1030 Subject: [PATCH] wallet: use wallet_payment only for *outgoing* payments. Incoming payment information is completely covered by invoices. Signed-off-by: Rusty Russell --- lightningd/invoice.c | 18 ------------------ lightningd/pay.c | 15 +++++---------- wallet/db.c | 1 + wallet/test/run-wallet.c | 26 +++++++++++++++----------- wallet/wallet.c | 35 ++++++----------------------------- wallet/wallet.h | 16 ++++++---------- 6 files changed, 33 insertions(+), 78 deletions(-) diff --git a/lightningd/invoice.c b/lightningd/invoice.c index d68e43a82..01e1b34db 100644 --- a/lightningd/invoice.c +++ b/lightningd/invoice.c @@ -85,7 +85,6 @@ static void json_invoice(struct command *cmd, struct wallet *wallet = cmd->ld->wallet; struct bolt11 *b11; char *b11enc; - struct wallet_payment payment; u64 expiry = 3600; if (!json_get_params(buffer, params, @@ -160,23 +159,6 @@ static void json_invoice(struct command *cmd, /* FIXME: add private routes if necessary! */ b11enc = bolt11_encode(cmd, b11, false, hsm_sign_b11, cmd->ld); - /* Store the payment so we can later show it in the history */ - payment.id = 0; - payment.incoming = true; - payment.payment_hash = invoice->rhash; - payment.destination = NULL; - payment.status = PAYMENT_PENDING; - if (invoice->msatoshi) - payment.msatoshi = tal_dup(cmd, u64, invoice->msatoshi); - else - payment.msatoshi = NULL; - payment.timestamp = b11->timestamp; - - if (!wallet_payment_add(cmd->ld->wallet, &payment)) { - command_fail(cmd, "Unable to record payment in the database."); - return; - } - json_object_start(response, NULL); json_add_hex(response, "payment_hash", &invoice->rhash, sizeof(invoice->rhash)); diff --git a/lightningd/pay.c b/lightningd/pay.c index 2a194b6d6..09a95a7b8 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -243,12 +243,10 @@ static bool send_payment(struct command *cmd, payment = tal(tmpctx, struct wallet_payment); payment->id = 0; - payment->incoming = false; payment->payment_hash = *rhash; - payment->destination = &ids[n_hops - 1]; + payment->destination = ids[n_hops - 1]; payment->status = PAYMENT_PENDING; - payment->msatoshi = tal(payment, u64); - *payment->msatoshi = route[n_hops-1].amount; + payment->msatoshi = route[n_hops-1].amount; payment->timestamp = time_now().ts.tv_sec; } pc->cmd = cmd; @@ -500,12 +498,9 @@ static void json_listpayments(struct command *cmd, const char *buffer, const struct wallet_payment *t = payments[i]; json_object_start(response, NULL); json_add_u64(response, "id", t->id); - json_add_bool(response, "incoming", t->incoming); json_add_hex(response, "payment_hash", &t->payment_hash, sizeof(t->payment_hash)); - if (!t->incoming) - json_add_pubkey(response, "destination", t->destination); - if (t->msatoshi) - json_add_u64(response, "msatoshi", *t->msatoshi); + json_add_pubkey(response, "destination", &t->destination); + json_add_u64(response, "msatoshi", t->msatoshi); json_add_u64(response, "timestamp", t->timestamp); switch (t->status) { @@ -530,6 +525,6 @@ static const struct json_command listpayments_command = { "listpayments", json_listpayments, "Get a list of incoming and outgoing payments", - "Returns a list of payments with {direction}, {payment_hash}, {destination} if outgoing and {msatoshi}" + "Returns a list of payments with {payment_hash}, {destination}, {msatoshi}, {timestamp} and {status}" }; AUTODATA(json_command, &listpayments_command); diff --git a/wallet/db.c b/wallet/db.c index e8c1245ed..d3cf01b19 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -126,6 +126,7 @@ char *dbmigrations[] = { " timestamp INTEGER," " status INTEGER," " payment_hash BLOB," + /* FIXME: Direction is now always 1 (OUTGOING), can be removed */ " direction INTEGER," " destination BLOB," " msatoshi INTEGER," diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 4a65a00ea..f24867b0c 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -550,29 +550,33 @@ static bool test_payment_crud(const tal_t *ctx) { struct wallet_payment t, *t2; struct wallet *w = create_test_wallet(ctx); - struct pubkey destination; mempat(&t, sizeof(t)); - memset(&destination, 1, sizeof(destination)); + memset(&t.destination, 1, sizeof(t.destination)); t.id = 0; - t.destination = NULL; - t.msatoshi = NULL; + t.msatoshi = 100; + t.status = PAYMENT_PENDING; + memset(&t.payment_hash, 1, sizeof(t.payment_hash)); db_begin_transaction(w->db); CHECK(wallet_payment_add(w, &t)); CHECK(t.id != 0); t2 = wallet_payment_by_hash(ctx, w, &t.payment_hash); CHECK(t2 != NULL); - CHECK(t2->id == t.id && t2->destination == NULL); + CHECK(t2->id == t.id); + CHECK(t2->status == t.status); + CHECK(pubkey_cmp(&t2->destination, &t.destination) == 0); + CHECK(t2->msatoshi == t.msatoshi); - t.destination = &destination; - t.id = 0; - memset(&t.payment_hash, 1, sizeof(t.payment_hash)); - - CHECK(wallet_payment_add(w, &t)); + t.status = PAYMENT_COMPLETE; + wallet_payment_set_status(w, &t.payment_hash, t.status); t2 = wallet_payment_by_hash(ctx, w, &t.payment_hash); - CHECK(t2->destination && pubkey_cmp(t2->destination, &destination) == 0); + CHECK(t2 != NULL); + CHECK(t2->id == t.id); + CHECK(t2->status == t.status); + CHECK(pubkey_cmp(&t2->destination, &t.destination) == 0); + CHECK(t2->msatoshi == t.msatoshi); db_commit_transaction(w->db); return true; diff --git a/wallet/wallet.c b/wallet/wallet.c index d4d32c721..8717610fc 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1190,8 +1190,6 @@ void wallet_invoice_resolve(struct wallet *wallet, u64 msatoshi_received) { invoices_resolve(wallet->invoices, invoice, msatoshi_received); - /* FIXME: consider payment recording. */ - wallet_payment_set_status(wallet, &invoice->rhash, PAYMENT_COMPLETE); } void wallet_invoice_waitany(const tal_t *ctx, struct wallet *wallet, @@ -1263,18 +1261,9 @@ bool wallet_payment_add(struct wallet *wallet, sqlite3_bind_int(stmt, 1, payment->status); sqlite3_bind_sha256(stmt, 2, &payment->payment_hash); - sqlite3_bind_int(stmt, 3, payment->incoming?DIRECTION_INCOMING:DIRECTION_OUTGOING); - - if (payment->destination) - sqlite3_bind_pubkey(stmt, 4, payment->destination); - else - sqlite3_bind_null(stmt, 4); - - if (payment->msatoshi) - sqlite3_bind_int64(stmt, 5, *payment->msatoshi); - else - sqlite3_bind_null(stmt, 5); - + sqlite3_bind_int(stmt, 3, DIRECTION_OUTGOING); + sqlite3_bind_pubkey(stmt, 4, &payment->destination); + sqlite3_bind_int64(stmt, 5, payment->msatoshi); sqlite3_bind_int(stmt, 6, payment->timestamp); db_exec_prepared(wallet->db, stmt); @@ -1288,21 +1277,9 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx, struct wallet_payment *payment = tal(ctx, struct wallet_payment); payment->id = sqlite3_column_int64(stmt, 0); payment->status = sqlite3_column_int(stmt, 1); - payment->incoming = sqlite3_column_int(stmt, 2) == DIRECTION_INCOMING; - if (sqlite3_column_type(stmt, 3) != SQLITE_NULL) { - payment->destination = tal(payment, struct pubkey); - sqlite3_column_pubkey(stmt, 3, payment->destination); - } else { - payment->destination = NULL; - } - - if (sqlite3_column_type(stmt, 4) != SQLITE_NULL) { - payment->msatoshi = tal(payment, u64); - *payment->msatoshi = sqlite3_column_int64(stmt, 4); - } else { - payment->msatoshi = NULL; - } + sqlite3_column_pubkey(stmt, 3, &payment->destination); + payment->msatoshi = sqlite3_column_int64(stmt, 4); sqlite3_column_sha256(stmt, 5, &payment->payment_hash); payment->timestamp = sqlite3_column_int(stmt, 6); @@ -1320,7 +1297,7 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet, "SELECT id, status, direction, destination," "msatoshi , payment_hash, timestamp " "FROM payments " - "WHERE payment_hash = ?"); + "WHERE payment_hash = ? AND direction = 1"); sqlite3_bind_sha256(stmt, 1, payment_hash); if (sqlite3_step(stmt) == SQLITE_ROW) { diff --git a/wallet/wallet.h b/wallet/wallet.h index bd3eacf4f..f05beca9d 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -68,9 +68,7 @@ struct wallet_channel { /* Possible states for a wallet_payment. Payments start in * `PENDING`. Outgoing payments are set to `PAYMENT_COMPLETE` once we * get the preimage matching the rhash, or to - * `PAYMENT_FAILED`. Incoming payments are set to `PAYMENT_COMPLETE` - * once the matching invoice is marked as complete, or `FAILED` - * otherwise. */ + * `PAYMENT_FAILED`. */ /* /!\ This is a DB ENUM, please do not change the numbering of any * already defined elements (adding is ok) /!\ */ enum wallet_payment_status { @@ -79,19 +77,17 @@ enum wallet_payment_status { PAYMENT_FAILED = 2 }; -/* Incoming and outgoing payments. A simple persisted representation - * of a payment we either initiated or received. This can be used by - * a UI to display the balance history. We explicitly exclude - * forwarded payments. +/* Outgoing payments. A simple persisted representation + * of a payment we initiated. This can be used by + * a UI (alongside invoices) to display the balance history. */ struct wallet_payment { u64 id; u32 timestamp; - bool incoming; struct sha256 payment_hash; enum wallet_payment_status status; - struct pubkey *destination; - u64 *msatoshi; + struct pubkey destination; + u64 msatoshi; }; /**