Browse Source

wallet: use wallet_payment only for *outgoing* payments.

Incoming payment information is completely covered by invoices.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
dea0aef52f
  1. 18
      lightningd/invoice.c
  2. 15
      lightningd/pay.c
  3. 1
      wallet/db.c
  4. 26
      wallet/test/run-wallet.c
  5. 35
      wallet/wallet.c
  6. 16
      wallet/wallet.h

18
lightningd/invoice.c

@ -85,7 +85,6 @@ static void json_invoice(struct command *cmd,
struct wallet *wallet = cmd->ld->wallet; struct wallet *wallet = cmd->ld->wallet;
struct bolt11 *b11; struct bolt11 *b11;
char *b11enc; char *b11enc;
struct wallet_payment payment;
u64 expiry = 3600; u64 expiry = 3600;
if (!json_get_params(buffer, params, if (!json_get_params(buffer, params,
@ -160,23 +159,6 @@ 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);
/* 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_object_start(response, NULL);
json_add_hex(response, "payment_hash", json_add_hex(response, "payment_hash",
&invoice->rhash, sizeof(invoice->rhash)); &invoice->rhash, sizeof(invoice->rhash));

15
lightningd/pay.c

@ -243,12 +243,10 @@ static bool send_payment(struct command *cmd,
payment = tal(tmpctx, struct wallet_payment); payment = tal(tmpctx, struct wallet_payment);
payment->id = 0; payment->id = 0;
payment->incoming = false;
payment->payment_hash = *rhash; payment->payment_hash = *rhash;
payment->destination = &ids[n_hops - 1]; payment->destination = ids[n_hops - 1];
payment->status = PAYMENT_PENDING; 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; payment->timestamp = time_now().ts.tv_sec;
} }
pc->cmd = cmd; pc->cmd = cmd;
@ -500,12 +498,9 @@ static void json_listpayments(struct command *cmd, const char *buffer,
const struct wallet_payment *t = payments[i]; const struct wallet_payment *t = payments[i];
json_object_start(response, NULL); json_object_start(response, NULL);
json_add_u64(response, "id", t->id); 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)); json_add_hex(response, "payment_hash", &t->payment_hash, sizeof(t->payment_hash));
if (!t->incoming) json_add_pubkey(response, "destination", &t->destination);
json_add_pubkey(response, "destination", t->destination); json_add_u64(response, "msatoshi", t->msatoshi);
if (t->msatoshi)
json_add_u64(response, "msatoshi", *t->msatoshi);
json_add_u64(response, "timestamp", t->timestamp); json_add_u64(response, "timestamp", t->timestamp);
switch (t->status) { switch (t->status) {
@ -530,6 +525,6 @@ static const struct json_command listpayments_command = {
"listpayments", "listpayments",
json_listpayments, json_listpayments,
"Get a list of incoming and outgoing payments", "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); AUTODATA(json_command, &listpayments_command);

1
wallet/db.c

@ -126,6 +126,7 @@ char *dbmigrations[] = {
" timestamp INTEGER," " timestamp INTEGER,"
" status INTEGER," " status INTEGER,"
" payment_hash BLOB," " payment_hash BLOB,"
/* FIXME: Direction is now always 1 (OUTGOING), can be removed */
" direction INTEGER," " direction INTEGER,"
" destination BLOB," " destination BLOB,"
" msatoshi INTEGER," " msatoshi INTEGER,"

26
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_payment t, *t2;
struct wallet *w = create_test_wallet(ctx); struct wallet *w = create_test_wallet(ctx);
struct pubkey destination;
mempat(&t, sizeof(t)); mempat(&t, sizeof(t));
memset(&destination, 1, sizeof(destination)); memset(&t.destination, 1, sizeof(t.destination));
t.id = 0; t.id = 0;
t.destination = NULL; t.msatoshi = 100;
t.msatoshi = NULL; t.status = PAYMENT_PENDING;
memset(&t.payment_hash, 1, sizeof(t.payment_hash));
db_begin_transaction(w->db); db_begin_transaction(w->db);
CHECK(wallet_payment_add(w, &t)); CHECK(wallet_payment_add(w, &t));
CHECK(t.id != 0); CHECK(t.id != 0);
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 && t2->destination == NULL); CHECK(t2->id == t.id);
CHECK(t2->status == t.status);
t.destination = &destination; CHECK(pubkey_cmp(&t2->destination, &t.destination) == 0);
t.id = 0; CHECK(t2->msatoshi == t.msatoshi);
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); 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); db_commit_transaction(w->db);
return true; return true;

35
wallet/wallet.c

@ -1190,8 +1190,6 @@ void wallet_invoice_resolve(struct wallet *wallet,
u64 msatoshi_received) u64 msatoshi_received)
{ {
invoices_resolve(wallet->invoices, invoice, 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, void wallet_invoice_waitany(const tal_t *ctx,
struct wallet *wallet, struct wallet *wallet,
@ -1263,18 +1261,9 @@ bool wallet_payment_add(struct wallet *wallet,
sqlite3_bind_int(stmt, 1, payment->status); sqlite3_bind_int(stmt, 1, payment->status);
sqlite3_bind_sha256(stmt, 2, &payment->payment_hash); sqlite3_bind_sha256(stmt, 2, &payment->payment_hash);
sqlite3_bind_int(stmt, 3, payment->incoming?DIRECTION_INCOMING:DIRECTION_OUTGOING); sqlite3_bind_int(stmt, 3, DIRECTION_OUTGOING);
sqlite3_bind_pubkey(stmt, 4, &payment->destination);
if (payment->destination) sqlite3_bind_int64(stmt, 5, payment->msatoshi);
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, 6, payment->timestamp); sqlite3_bind_int(stmt, 6, payment->timestamp);
db_exec_prepared(wallet->db, stmt); 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); struct wallet_payment *payment = tal(ctx, struct wallet_payment);
payment->id = sqlite3_column_int64(stmt, 0); payment->id = sqlite3_column_int64(stmt, 0);
payment->status = sqlite3_column_int(stmt, 1); payment->status = sqlite3_column_int(stmt, 1);
payment->incoming = sqlite3_column_int(stmt, 2) == DIRECTION_INCOMING;
if (sqlite3_column_type(stmt, 3) != SQLITE_NULL) { sqlite3_column_pubkey(stmt, 3, &payment->destination);
payment->destination = tal(payment, struct pubkey); payment->msatoshi = sqlite3_column_int64(stmt, 4);
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_sha256(stmt, 5, &payment->payment_hash); sqlite3_column_sha256(stmt, 5, &payment->payment_hash);
payment->timestamp = sqlite3_column_int(stmt, 6); 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," "SELECT id, status, direction, destination,"
"msatoshi , payment_hash, timestamp " "msatoshi , payment_hash, timestamp "
"FROM payments " "FROM payments "
"WHERE payment_hash = ?"); "WHERE payment_hash = ? AND direction = 1");
sqlite3_bind_sha256(stmt, 1, payment_hash); sqlite3_bind_sha256(stmt, 1, payment_hash);
if (sqlite3_step(stmt) == SQLITE_ROW) { if (sqlite3_step(stmt) == SQLITE_ROW) {

16
wallet/wallet.h

@ -68,9 +68,7 @@ struct wallet_channel {
/* Possible states for a wallet_payment. Payments start in /* Possible states for a wallet_payment. Payments start in
* `PENDING`. Outgoing payments are set to `PAYMENT_COMPLETE` once we * `PENDING`. Outgoing payments are set to `PAYMENT_COMPLETE` once we
* get the preimage matching the rhash, or to * get the preimage matching the rhash, or to
* `PAYMENT_FAILED`. Incoming payments are set to `PAYMENT_COMPLETE` * `PAYMENT_FAILED`. */
* once the matching invoice is marked as complete, or `FAILED`
* otherwise. */
/* /!\ This is a DB ENUM, please do not change the numbering of any /* /!\ This is a DB ENUM, please do not change the numbering of any
* already defined elements (adding is ok) /!\ */ * already defined elements (adding is ok) /!\ */
enum wallet_payment_status { enum wallet_payment_status {
@ -79,19 +77,17 @@ enum wallet_payment_status {
PAYMENT_FAILED = 2 PAYMENT_FAILED = 2
}; };
/* Incoming and outgoing payments. A simple persisted representation /* Outgoing payments. A simple persisted representation
* of a payment we either initiated or received. This can be used by * of a payment we initiated. This can be used by
* a UI to display the balance history. We explicitly exclude * a UI (alongside invoices) to display the balance history.
* forwarded payments.
*/ */
struct wallet_payment { struct wallet_payment {
u64 id; u64 id;
u32 timestamp; u32 timestamp;
bool incoming;
struct sha256 payment_hash; struct sha256 payment_hash;
enum wallet_payment_status status; enum wallet_payment_status status;
struct pubkey *destination; struct pubkey destination;
u64 *msatoshi; u64 msatoshi;
}; };
/** /**

Loading…
Cancel
Save