mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 07:04:22 +01:00
wallet: add path_secrets to payment table.
We need these to decode any returned errors. We remove it from struct pay_command too, and load directly from db when we need it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
9b99b74c41
commit
559010f525
@@ -28,9 +28,6 @@ struct pay_command {
|
|||||||
/* Preimage if this succeeded. */
|
/* Preimage if this succeeded. */
|
||||||
const struct preimage *rval;
|
const struct preimage *rval;
|
||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
|
|
||||||
/* Remember all shared secrets, so we can unwrap an eventual failure */
|
|
||||||
struct secret *path_secrets;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void json_pay_success(struct command *cmd, const struct preimage *rval)
|
static void json_pay_success(struct command *cmd, const struct preimage *rval)
|
||||||
@@ -82,6 +79,8 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||||||
struct pay_command *pc = hout->pay_command;
|
struct pay_command *pc = hout->pay_command;
|
||||||
struct onionreply *reply;
|
struct onionreply *reply;
|
||||||
enum onion_type failcode;
|
enum onion_type failcode;
|
||||||
|
struct secret *path_secrets;
|
||||||
|
const tal_t *tmpctx = tal_tmpctx(ld);
|
||||||
|
|
||||||
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
||||||
PAYMENT_FAILED, NULL);
|
PAYMENT_FAILED, NULL);
|
||||||
@@ -89,13 +88,15 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||||||
/* This gives more details than a generic failure message */
|
/* This gives more details than a generic failure message */
|
||||||
if (localfail) {
|
if (localfail) {
|
||||||
json_pay_failed(pc, NULL, hout->failcode, localfail);
|
json_pay_failed(pc, NULL, hout->failcode, localfail);
|
||||||
|
tal_free(tmpctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be remote fail. */
|
/* Must be remote fail. */
|
||||||
assert(!hout->failcode);
|
assert(!hout->failcode);
|
||||||
reply = unwrap_onionreply(pc, pc->path_secrets,
|
path_secrets = wallet_payment_get_secrets(tmpctx, ld->wallet,
|
||||||
tal_count(pc->path_secrets),
|
&hout->payment_hash);
|
||||||
|
reply = unwrap_onionreply(pc, path_secrets, tal_count(path_secrets),
|
||||||
hout->failuremsg);
|
hout->failuremsg);
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
log_info(hout->key.peer->log,
|
log_info(hout->key.peer->log,
|
||||||
@@ -118,6 +119,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||||||
/* check_for_routing_failure(i, sender, failure_code); */
|
/* check_for_routing_failure(i, sender, failure_code); */
|
||||||
|
|
||||||
json_pay_failed(pc, NULL, failcode, "reply from remote");
|
json_pay_failed(pc, NULL, failcode, "reply from remote");
|
||||||
|
tal_free(tmpctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When JSON RPC goes away, cmd is freed: detach from any running paycommand */
|
/* When JSON RPC goes away, cmd is freed: detach from any running paycommand */
|
||||||
@@ -237,7 +239,6 @@ static bool send_payment(struct command *cmd,
|
|||||||
|
|
||||||
if (pc) {
|
if (pc) {
|
||||||
pc->ids = tal_free(pc->ids);
|
pc->ids = tal_free(pc->ids);
|
||||||
pc->path_secrets = tal_free(pc->path_secrets);
|
|
||||||
} else {
|
} else {
|
||||||
pc = tal(cmd->ld, struct pay_command);
|
pc = tal(cmd->ld, struct pay_command);
|
||||||
list_add_tail(&cmd->ld->pay_commands, &pc->list);
|
list_add_tail(&cmd->ld->pay_commands, &pc->list);
|
||||||
@@ -251,13 +252,13 @@ static bool send_payment(struct command *cmd,
|
|||||||
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;
|
payment->payment_preimage = NULL;
|
||||||
|
payment->path_secrets = tal_steal(payment, path_secrets);
|
||||||
}
|
}
|
||||||
pc->cmd = cmd;
|
pc->cmd = cmd;
|
||||||
pc->rhash = *rhash;
|
pc->rhash = *rhash;
|
||||||
pc->rval = NULL;
|
pc->rval = NULL;
|
||||||
pc->ids = tal_steal(pc, ids);
|
pc->ids = tal_steal(pc, ids);
|
||||||
pc->msatoshi = route[n_hops-1].amount;
|
pc->msatoshi = route[n_hops-1].amount;
|
||||||
pc->path_secrets = tal_steal(pc, path_secrets);
|
|
||||||
pc->out = NULL;
|
pc->out = NULL;
|
||||||
|
|
||||||
log_info(cmd->ld->log, "Sending %u over %zu hops to deliver %"PRIu64,
|
log_info(cmd->ld->log, "Sending %u over %zu hops to deliver %"PRIu64,
|
||||||
|
|||||||
@@ -175,6 +175,8 @@ char *dbmigrations[] = {
|
|||||||
"DROP TABLE temp_payments;",
|
"DROP TABLE temp_payments;",
|
||||||
/* We need to keep the preimage in case they ask to pay again. */
|
/* We need to keep the preimage in case they ask to pay again. */
|
||||||
"ALTER TABLE payments ADD COLUMN payment_preimage BLOB;",
|
"ALTER TABLE payments ADD COLUMN payment_preimage BLOB;",
|
||||||
|
/* We need to keep the shared secrets to decode error returns. */
|
||||||
|
"ALTER TABLE payments ADD COLUMN path_secrets BLOB;",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -533,6 +535,8 @@ struct secret *sqlite3_column_secrets(const tal_t *ctx,
|
|||||||
|
|
||||||
/* Must fit exactly */
|
/* Must fit exactly */
|
||||||
assert(n * sizeof(struct secret) == sqlite3_column_bytes(stmt, col));
|
assert(n * sizeof(struct secret) == sqlite3_column_bytes(stmt, col));
|
||||||
|
if (n == 0)
|
||||||
|
return NULL;
|
||||||
secrets = tal_arr(ctx, struct secret, n);
|
secrets = tal_arr(ctx, struct secret, n);
|
||||||
return memcpy(secrets, sqlite3_column_blob(stmt, col), tal_len(secrets));
|
return memcpy(secrets, sqlite3_column_blob(stmt, col), tal_len(secrets));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1289,6 +1289,9 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx,
|
|||||||
sqlite3_column_preimage(stmt, 6, payment->payment_preimage);
|
sqlite3_column_preimage(stmt, 6, payment->payment_preimage);
|
||||||
} else
|
} else
|
||||||
payment->payment_preimage = NULL;
|
payment->payment_preimage = NULL;
|
||||||
|
|
||||||
|
/* Can be NULL for old db! */
|
||||||
|
payment->path_secrets = sqlite3_column_secrets(payment, stmt, 7);
|
||||||
return payment;
|
return payment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1301,7 +1304,8 @@ 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, payment_preimage "
|
"msatoshi, payment_hash, timestamp, payment_preimage, "
|
||||||
|
"path_secrets "
|
||||||
"FROM payments "
|
"FROM payments "
|
||||||
"WHERE payment_hash = ?");
|
"WHERE payment_hash = ?");
|
||||||
|
|
||||||
@@ -1313,6 +1317,26 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
|
|||||||
return payment;
|
return payment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct secret *wallet_payment_get_secrets(const tal_t *ctx,
|
||||||
|
struct wallet *wallet,
|
||||||
|
const struct sha256 *payment_hash)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
struct secret *path_secrets = NULL;
|
||||||
|
|
||||||
|
stmt = db_prepare(wallet->db,
|
||||||
|
"SELECT path_secrets "
|
||||||
|
"FROM payments "
|
||||||
|
"WHERE payment_hash = ?");
|
||||||
|
|
||||||
|
sqlite3_bind_sha256(stmt, 1, payment_hash);
|
||||||
|
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||||
|
path_secrets = sqlite3_column_secrets(ctx, stmt, 0);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(stmt);
|
||||||
|
return path_secrets;
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
@@ -1349,7 +1373,8 @@ 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, payment_preimage "
|
"msatoshi, payment_hash, timestamp, payment_preimage, "
|
||||||
|
"path_secrets "
|
||||||
"FROM payments;");
|
"FROM payments;");
|
||||||
|
|
||||||
for (int i = 0; sqlite3_step(stmt) == SQLITE_ROW; i++) {
|
for (int i = 0; sqlite3_step(stmt) == SQLITE_ROW; i++) {
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ struct wallet_payment {
|
|||||||
u64 msatoshi;
|
u64 msatoshi;
|
||||||
/* Iff PAYMENT_COMPLETE */
|
/* Iff PAYMENT_COMPLETE */
|
||||||
struct preimage *payment_preimage;
|
struct preimage *payment_preimage;
|
||||||
|
struct secret *path_secrets;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -556,6 +557,15 @@ void wallet_payment_set_status(struct wallet *wallet,
|
|||||||
const enum wallet_payment_status newstatus,
|
const enum wallet_payment_status newstatus,
|
||||||
const struct preimage *preimage);
|
const struct preimage *preimage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wallet_payment_get_secrets - Get the secrets array for a given `payment_hash`
|
||||||
|
*
|
||||||
|
* Returns a tal_array: can return NULL for old dbs.
|
||||||
|
*/
|
||||||
|
struct secret *wallet_payment_get_secrets(const tal_t *ctx,
|
||||||
|
struct wallet *wallet,
|
||||||
|
const struct sha256 *payment_hash);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wallet_payment_list - Retrieve a list of payments
|
* wallet_payment_list - Retrieve a list of payments
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user