Browse Source

wallet: add preimage to db.

We should be saving this, as it's our proof of payment.  Also, we return
it if they try to pay again.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
2cbe5b65c7
  1. 11
      lightningd/pay.c
  2. 2
      wallet/db.c
  3. 9
      wallet/test/run-wallet.c
  4. 22
      wallet/wallet.c
  5. 5
      wallet/wallet.h

11
lightningd/pay.c

@ -68,7 +68,8 @@ void payment_succeeded(struct lightningd *ld, struct htlc_out *hout,
const struct preimage *rval) const struct preimage *rval)
{ {
assert(!hout->pay_command->rval); assert(!hout->pay_command->rval);
wallet_payment_set_status(ld->wallet, &hout->payment_hash, PAYMENT_COMPLETE); wallet_payment_set_status(ld->wallet, &hout->payment_hash,
PAYMENT_COMPLETE, rval);
hout->pay_command->rval = tal_dup(hout->pay_command, hout->pay_command->rval = tal_dup(hout->pay_command,
struct preimage, rval); struct preimage, rval);
json_pay_success(hout->pay_command->cmd, rval); json_pay_success(hout->pay_command->cmd, rval);
@ -82,7 +83,8 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
struct onionreply *reply; struct onionreply *reply;
enum onion_type failcode; enum onion_type failcode;
wallet_payment_set_status(ld->wallet, &hout->payment_hash, PAYMENT_FAILED); wallet_payment_set_status(ld->wallet, &hout->payment_hash,
PAYMENT_FAILED, NULL);
/* This gives more details than a generic failure message */ /* This gives more details than a generic failure message */
if (localfail) { if (localfail) {
@ -248,6 +250,7 @@ static bool send_payment(struct command *cmd,
payment->status = PAYMENT_PENDING; payment->status = PAYMENT_PENDING;
payment->msatoshi = route[n_hops-1].amount; payment->msatoshi = route[n_hops-1].amount;
payment->timestamp = time_now().ts.tv_sec; payment->timestamp = time_now().ts.tv_sec;
payment->payment_preimage = NULL;
} }
pc->cmd = cmd; pc->cmd = cmd;
pc->rhash = *rhash; pc->rhash = *rhash;
@ -514,6 +517,10 @@ static void json_listpayments(struct command *cmd, const char *buffer,
json_add_string(response, "status", "failed"); json_add_string(response, "status", "failed");
break; break;
} }
if (t->payment_preimage)
json_add_hex(response, "payment_preimage",
t->payment_preimage,
sizeof(*t->payment_preimage));
json_object_end(response); json_object_end(response);
} }

2
wallet/db.c

@ -173,6 +173,8 @@ char *dbmigrations[] = {
");", ");",
"INSERT INTO payments SELECT id, timestamp, status, payment_hash, destination, msatoshi FROM temp_payments WHERE direction=1;", "INSERT INTO payments SELECT id, timestamp, status, payment_hash, destination, msatoshi FROM temp_payments WHERE direction=1;",
"DROP TABLE temp_payments;", "DROP TABLE temp_payments;",
/* We need to keep the preimage in case they ask to pay again. */
"ALTER TABLE payments ADD COLUMN payment_preimage BLOB;",
NULL, NULL,
}; };

9
wallet/test/run-wallet.c

@ -15,6 +15,7 @@ static void db_log_(struct log *log, enum log_level level, const char *fmt, ...)
#include <ccan/mem/mem.h> #include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <ccan/structeq/structeq.h>
#include <common/memleak.h> #include <common/memleak.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>
@ -557,6 +558,7 @@ static bool test_payment_crud(const tal_t *ctx)
t.id = 0; t.id = 0;
t.msatoshi = 100; t.msatoshi = 100;
t.status = PAYMENT_PENDING; t.status = PAYMENT_PENDING;
t.payment_preimage = NULL;
memset(&t.payment_hash, 1, sizeof(t.payment_hash)); memset(&t.payment_hash, 1, sizeof(t.payment_hash));
db_begin_transaction(w->db); db_begin_transaction(w->db);
@ -568,15 +570,20 @@ static bool test_payment_crud(const tal_t *ctx)
CHECK(t2->status == t.status); CHECK(t2->status == t.status);
CHECK(pubkey_cmp(&t2->destination, &t.destination) == 0); CHECK(pubkey_cmp(&t2->destination, &t.destination) == 0);
CHECK(t2->msatoshi == t.msatoshi); CHECK(t2->msatoshi == t.msatoshi);
CHECK(!t2->payment_preimage);
t.status = PAYMENT_COMPLETE; t.status = PAYMENT_COMPLETE;
wallet_payment_set_status(w, &t.payment_hash, t.status); t.payment_preimage = tal(w, struct preimage);
memset(t.payment_preimage, 2, sizeof(*t.payment_preimage));
wallet_payment_set_status(w, &t.payment_hash, t.status,
t.payment_preimage);
t2 = wallet_payment_by_hash(ctx, w, &t.payment_hash); t2 = wallet_payment_by_hash(ctx, w, &t.payment_hash);
CHECK(t2 != NULL); CHECK(t2 != NULL);
CHECK(t2->id == t.id); CHECK(t2->id == t.id);
CHECK(t2->status == t.status); CHECK(t2->status == t.status);
CHECK(pubkey_cmp(&t2->destination, &t.destination) == 0); CHECK(pubkey_cmp(&t2->destination, &t.destination) == 0);
CHECK(t2->msatoshi == t.msatoshi); CHECK(t2->msatoshi == t.msatoshi);
CHECK(structeq(t.payment_preimage, t2->payment_preimage));
db_commit_transaction(w->db); db_commit_transaction(w->db);
return true; return true;

22
wallet/wallet.c

@ -1284,6 +1284,11 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx,
sqlite3_column_sha256(stmt, 4, &payment->payment_hash); sqlite3_column_sha256(stmt, 4, &payment->payment_hash);
payment->timestamp = sqlite3_column_int(stmt, 5); payment->timestamp = sqlite3_column_int(stmt, 5);
if (sqlite3_column_type(stmt, 6) != SQLITE_NULL) {
payment->payment_preimage = tal(payment, struct preimage);
sqlite3_column_preimage(stmt, 6, payment->payment_preimage);
} else
payment->payment_preimage = NULL;
return payment; return payment;
} }
@ -1296,7 +1301,7 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
stmt = db_prepare(wallet->db, stmt = db_prepare(wallet->db,
"SELECT id, status, destination," "SELECT id, status, destination,"
"msatoshi, payment_hash, timestamp " "msatoshi, payment_hash, timestamp, payment_preimage "
"FROM payments " "FROM payments "
"WHERE payment_hash = ?"); "WHERE payment_hash = ?");
@ -1310,7 +1315,8 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
void wallet_payment_set_status(struct wallet *wallet, void wallet_payment_set_status(struct wallet *wallet,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const enum wallet_payment_status newstatus) const enum wallet_payment_status newstatus,
const struct preimage *preimage)
{ {
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
@ -1321,6 +1327,16 @@ void wallet_payment_set_status(struct wallet *wallet,
sqlite3_bind_int(stmt, 1, newstatus); sqlite3_bind_int(stmt, 1, newstatus);
sqlite3_bind_sha256(stmt, 2, payment_hash); sqlite3_bind_sha256(stmt, 2, payment_hash);
db_exec_prepared(wallet->db, stmt); db_exec_prepared(wallet->db, stmt);
if (preimage) {
stmt = db_prepare(wallet->db,
"UPDATE payments SET payment_preimage=? "
"WHERE payment_hash=?");
sqlite3_bind_preimage(stmt, 1, preimage);
sqlite3_bind_sha256(stmt, 2, payment_hash);
db_exec_prepared(wallet->db, stmt);
}
} }
const struct wallet_payment **wallet_payment_list(const tal_t *ctx, const struct wallet_payment **wallet_payment_list(const tal_t *ctx,
@ -1333,7 +1349,7 @@ const struct wallet_payment **wallet_payment_list(const tal_t *ctx,
stmt = db_prepare( stmt = db_prepare(
wallet->db, wallet->db,
"SELECT id, status, destination, " "SELECT id, status, destination, "
"msatoshi , payment_hash, timestamp " "msatoshi , payment_hash, timestamp, payment_preimage "
"FROM payments;"); "FROM payments;");
for (int i = 0; sqlite3_step(stmt) == SQLITE_ROW; i++) { for (int i = 0; sqlite3_step(stmt) == SQLITE_ROW; i++) {

5
wallet/wallet.h

@ -88,6 +88,8 @@ struct wallet_payment {
enum wallet_payment_status status; enum wallet_payment_status status;
struct pubkey destination; struct pubkey destination;
u64 msatoshi; u64 msatoshi;
/* Iff PAYMENT_COMPLETE */
struct preimage *payment_preimage;
}; };
/** /**
@ -551,7 +553,8 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
*/ */
void wallet_payment_set_status(struct wallet *wallet, void wallet_payment_set_status(struct wallet *wallet,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const enum wallet_payment_status newstatus); const enum wallet_payment_status newstatus,
const struct preimage *preimage);
/** /**
* wallet_payment_list - Retrieve a list of payments * wallet_payment_list - Retrieve a list of payments

Loading…
Cancel
Save