db: add partid, total_msat fields to payment entries.
This is in preparation for partial payments. For existing payments, partid is 0 (arbitrarity) and total_msat is msatoshi. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
727d6a0415
commit
2d18c3a209
|
@ -81,6 +81,8 @@ void json_add_payment_fields(struct json_stream *response,
|
|||
{
|
||||
json_add_u64(response, "id", t->id);
|
||||
json_add_sha256(response, "payment_hash", &t->payment_hash);
|
||||
if (t->partid)
|
||||
json_add_u64(response, "partid", t->partid);
|
||||
if (t->destination != NULL)
|
||||
json_add_node_id(response, "destination", t->destination);
|
||||
|
||||
|
@ -278,9 +280,11 @@ void payment_succeeded(struct lightningd *ld, struct htlc_out *hout,
|
|||
struct wallet_payment *payment;
|
||||
|
||||
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
||||
/* FIXME: Set partid! */ 0,
|
||||
PAYMENT_COMPLETE, rval);
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet,
|
||||
&hout->payment_hash);
|
||||
&hout->payment_hash,
|
||||
/* FIXME: Set partid! */ 0);
|
||||
assert(payment);
|
||||
|
||||
tell_waiters_success(ld, &hout->payment_hash, payment);
|
||||
|
@ -467,14 +471,16 @@ remote_routing_failure(const tal_t *ctx,
|
|||
return routing_failure;
|
||||
}
|
||||
|
||||
void payment_store(struct lightningd *ld, const struct sha256 *payment_hash)
|
||||
void payment_store(struct lightningd *ld,
|
||||
const struct sha256 *payment_hash, u64 partid)
|
||||
{
|
||||
struct sendpay_command *pc;
|
||||
struct sendpay_command *next;
|
||||
const struct wallet_payment *payment;
|
||||
|
||||
wallet_payment_store(ld->wallet, payment_hash);
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment_hash);
|
||||
wallet_payment_store(ld->wallet, payment_hash, partid);
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet,
|
||||
payment_hash, partid);
|
||||
assert(payment);
|
||||
|
||||
/* Trigger any sendpay commands waiting for the store to occur. */
|
||||
|
@ -496,7 +502,8 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||
int pay_errcode;
|
||||
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet,
|
||||
&hout->payment_hash);
|
||||
&hout->payment_hash,
|
||||
/* FIXME: Set partid! */0);
|
||||
|
||||
#ifdef COMPAT_V052
|
||||
/* Prior to "pay: delete HTLC when we delete payment." we would
|
||||
|
@ -566,11 +573,11 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||
}
|
||||
|
||||
/* Save to DB */
|
||||
payment_store(ld, &hout->payment_hash);
|
||||
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
||||
payment_store(ld, &hout->payment_hash, /* FIXME: Set partid! */ 0);
|
||||
wallet_payment_set_status(ld->wallet, &hout->payment_hash, /* FIXME: Set partid! */ 0,
|
||||
PAYMENT_FAILED, NULL);
|
||||
wallet_payment_set_failinfo(ld->wallet,
|
||||
&hout->payment_hash,
|
||||
&hout->payment_hash, /* FIXME: Set partid! */ 0,
|
||||
fail ? NULL : hout->failuremsg,
|
||||
pay_errcode == PAY_DESTINATION_PERM_FAIL,
|
||||
fail ? fail->erring_index : -1,
|
||||
|
@ -590,7 +597,8 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||
* Return callback if we called already, otherwise NULL. */
|
||||
static struct command_result *wait_payment(struct lightningd *ld,
|
||||
struct command *cmd,
|
||||
const struct sha256 *payment_hash)
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid)
|
||||
{
|
||||
struct wallet_payment *payment;
|
||||
u8 *failonionreply;
|
||||
|
@ -604,7 +612,8 @@ static struct command_result *wait_payment(struct lightningd *ld,
|
|||
struct routing_failure *fail;
|
||||
int faildirection;
|
||||
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment_hash);
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet,
|
||||
payment_hash, partid);
|
||||
if (!payment) {
|
||||
return command_fail(cmd, PAY_NO_SUCH_PAYMENT,
|
||||
"Never attempted payment for '%s'",
|
||||
|
@ -622,7 +631,9 @@ static struct command_result *wait_payment(struct lightningd *ld,
|
|||
|
||||
case PAYMENT_FAILED:
|
||||
/* Get error from DB */
|
||||
wallet_payment_get_failinfo(tmpctx, ld->wallet, payment_hash,
|
||||
wallet_payment_get_failinfo(tmpctx, ld->wallet,
|
||||
payment_hash,
|
||||
partid,
|
||||
&failonionreply,
|
||||
&faildestperm,
|
||||
&failindex,
|
||||
|
@ -706,8 +717,10 @@ static struct command_result *
|
|||
send_payment(struct lightningd *ld,
|
||||
struct command *cmd,
|
||||
const struct sha256 *rhash,
|
||||
u64 partid,
|
||||
const struct route_hop *route,
|
||||
struct amount_msat msat,
|
||||
struct amount_msat total_msat,
|
||||
const char *label TAKES,
|
||||
const char *b11str TAKES,
|
||||
const struct secret *payment_secret)
|
||||
|
@ -779,7 +792,7 @@ send_payment(struct lightningd *ld,
|
|||
sphinx_add_hop(path, &pubkey, onion);
|
||||
|
||||
/* Now, do we already have a payment? */
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet, rhash);
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet, rhash, partid);
|
||||
if (payment) {
|
||||
/* FIXME: We should really do something smarter here! */
|
||||
if (payment->status == PAYMENT_PENDING) {
|
||||
|
@ -853,18 +866,21 @@ send_payment(struct lightningd *ld,
|
|||
* onchain_failed_our_htlc->payment_failed with no payment.
|
||||
*/
|
||||
if (payment) {
|
||||
wallet_payment_delete(ld->wallet, rhash);
|
||||
wallet_local_htlc_out_delete(ld->wallet, channel, rhash);
|
||||
wallet_payment_delete(ld->wallet, rhash, payment->partid);
|
||||
wallet_local_htlc_out_delete(ld->wallet, channel, rhash,
|
||||
payment->partid);
|
||||
}
|
||||
|
||||
/* If hout fails, payment should be freed too. */
|
||||
payment = tal(hout, struct wallet_payment);
|
||||
payment->id = 0;
|
||||
payment->payment_hash = *rhash;
|
||||
payment->partid = partid;
|
||||
payment->destination = tal_dup(payment, struct node_id, &ids[n_hops - 1]);
|
||||
payment->status = PAYMENT_PENDING;
|
||||
payment->msatoshi = msat;
|
||||
payment->msatoshi_sent = route[0].amount;
|
||||
payment->total_msat = total_msat;
|
||||
payment->timestamp = time_now().ts.tv_sec;
|
||||
payment->payment_preimage = NULL;
|
||||
payment->path_secrets = tal_steal(payment, path_secrets);
|
||||
|
@ -998,7 +1014,7 @@ static struct command_result *json_sendonion(struct command *cmd,
|
|||
failcode);
|
||||
|
||||
/* Now, do we already have a payment? */
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment_hash);
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment_hash, /* FIXME: Set partid! */0);
|
||||
if (payment) {
|
||||
if (payment->status == PAYMENT_PENDING) {
|
||||
log_debug(ld->log, "send_payment: previous still in progress");
|
||||
|
@ -1028,8 +1044,8 @@ static struct command_result *json_sendonion(struct command *cmd,
|
|||
|
||||
/* Cleanup any prior payment. We're about to retry. */
|
||||
if (payment) {
|
||||
wallet_payment_delete(ld->wallet, payment_hash);
|
||||
wallet_local_htlc_out_delete(ld->wallet, channel, payment_hash);
|
||||
wallet_payment_delete(ld->wallet, payment_hash, /* FIXME: Set partid! */0);
|
||||
wallet_local_htlc_out_delete(ld->wallet, channel, payment_hash, /* FIXME: Set partid! */0);
|
||||
}
|
||||
|
||||
failcode = send_onion(cmd->ld, &packet, first_hop, payment_hash, channel,
|
||||
|
@ -1247,7 +1263,10 @@ static struct command_result *json_sendpay(struct command *cmd,
|
|||
}
|
||||
#endif
|
||||
|
||||
res = send_payment(cmd->ld, cmd, rhash, route,
|
||||
res = send_payment(cmd->ld, cmd, rhash, /* FIXME: Set partid! */ 0,
|
||||
route,
|
||||
msat ? *msat : route[routetok->size-1].amount,
|
||||
/* FIXME: Set total_msat! */
|
||||
msat ? *msat : route[routetok->size-1].amount,
|
||||
label, b11str, payment_secret);
|
||||
if (res)
|
||||
|
@ -1284,7 +1303,7 @@ static struct command_result *json_waitsendpay(struct command *cmd,
|
|||
NULL))
|
||||
return command_param_failed();
|
||||
|
||||
res = wait_payment(cmd->ld, cmd, rhash);
|
||||
res = wait_payment(cmd->ld, cmd, rhash, /* FIXME: Set partid! */0);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||
const char *localfail);
|
||||
|
||||
/* Inform payment system to save the payment. */
|
||||
void payment_store(struct lightningd *ld, const struct sha256 *payment_hash);
|
||||
void payment_store(struct lightningd *ld,
|
||||
const struct sha256 *payment_hash, u64 partid);
|
||||
|
||||
/* This json will be also used in 'sendpay_success' notifictaion. */
|
||||
void json_add_payment_fields(struct json_stream *response,
|
||||
|
|
|
@ -1274,7 +1274,8 @@ static bool update_out_htlc(struct channel *channel,
|
|||
/* For our own HTLCs, we commit payment to db lazily */
|
||||
if (hout->origin_htlc_id == 0)
|
||||
payment_store(ld,
|
||||
&hout->payment_hash);
|
||||
&hout->payment_hash,
|
||||
/* FIXME: Set partid! */ 0);
|
||||
}
|
||||
|
||||
if (!htlc_out_update_state(channel, hout, newstate))
|
||||
|
|
78
wallet/db.c
78
wallet/db.c
|
@ -481,6 +481,84 @@ static struct migration dbmigrations[] = {
|
|||
{SQL("UPDATE forwarded_payments SET received_time=0 WHERE received_time IS NULL;"),
|
||||
NULL},
|
||||
{SQL("ALTER TABLE invoices ADD COLUMN features BLOB DEFAULT '';"), NULL},
|
||||
/* We can now have multiple payments in progress for a single hash, so
|
||||
* add two fields; combination of payment_hash & partid is unique. */
|
||||
{SQL("ALTER TABLE payments RENAME TO temp_payments;"), NULL},
|
||||
{SQL("CREATE TABLE payments ("
|
||||
" id BIGSERIAL"
|
||||
", timestamp INTEGER"
|
||||
", status INTEGER"
|
||||
", payment_hash BLOB"
|
||||
", destination BLOB"
|
||||
", msatoshi BIGINT"
|
||||
", payment_preimage BLOB"
|
||||
", path_secrets BLOB"
|
||||
", route_nodes BLOB"
|
||||
", route_channels BLOB"
|
||||
", failonionreply BLOB"
|
||||
", faildestperm INTEGER"
|
||||
", failindex INTEGER"
|
||||
", failcode INTEGER"
|
||||
", failnode BLOB"
|
||||
", failchannel TEXT"
|
||||
", failupdate BLOB"
|
||||
", msatoshi_sent BIGINT"
|
||||
", faildetail TEXT"
|
||||
", description TEXT"
|
||||
", faildirection INTEGER"
|
||||
", bolt11 TEXT"
|
||||
", total_msat BIGINT"
|
||||
", partid BIGINT"
|
||||
", PRIMARY KEY (id)"
|
||||
", UNIQUE (payment_hash, partid))"), NULL},
|
||||
{SQL("INSERT INTO payments ("
|
||||
"id"
|
||||
", timestamp"
|
||||
", status"
|
||||
", payment_hash"
|
||||
", destination"
|
||||
", msatoshi"
|
||||
", payment_preimage"
|
||||
", path_secrets"
|
||||
", route_nodes"
|
||||
", route_channels"
|
||||
", failonionreply"
|
||||
", faildestperm"
|
||||
", failindex"
|
||||
", failcode"
|
||||
", failnode"
|
||||
", failchannel"
|
||||
", failupdate"
|
||||
", msatoshi_sent"
|
||||
", faildetail"
|
||||
", description"
|
||||
", faildirection"
|
||||
", bolt11)"
|
||||
"SELECT id"
|
||||
", timestamp"
|
||||
", status"
|
||||
", payment_hash"
|
||||
", destination"
|
||||
", msatoshi"
|
||||
", payment_preimage"
|
||||
", path_secrets"
|
||||
", route_nodes"
|
||||
", route_channels"
|
||||
", failonionreply"
|
||||
", faildestperm"
|
||||
", failindex"
|
||||
", failcode"
|
||||
", failnode"
|
||||
", failchannel"
|
||||
", failupdate"
|
||||
", msatoshi_sent"
|
||||
", faildetail"
|
||||
", description"
|
||||
", faildirection"
|
||||
", bolt11 FROM temp_payments;"), NULL},
|
||||
{SQL("UPDATE payments SET total_msat = msatoshi;"), NULL},
|
||||
{SQL("UPDATE payments SET partid = 0;"), NULL},
|
||||
{SQL("DROP TABLE temp_payments;"), NULL},
|
||||
};
|
||||
|
||||
/* Leak tracking. */
|
||||
|
|
|
@ -486,7 +486,8 @@ void payment_failed(struct lightningd *ld UNNEEDED, const struct htlc_out *hout
|
|||
const char *localfail UNNEEDED)
|
||||
{ fprintf(stderr, "payment_failed called!\n"); abort(); }
|
||||
/* Generated stub for payment_store */
|
||||
void payment_store(struct lightningd *ld UNNEEDED, const struct sha256 *payment_hash UNNEEDED)
|
||||
void payment_store(struct lightningd *ld UNNEEDED,
|
||||
const struct sha256 *payment_hash UNNEEDED, u64 partid UNNEEDED)
|
||||
{ fprintf(stderr, "payment_store called!\n"); abort(); }
|
||||
/* Generated stub for payment_succeeded */
|
||||
void payment_succeeded(struct lightningd *ld UNNEEDED, struct htlc_out *hout UNNEEDED,
|
||||
|
@ -1254,29 +1255,36 @@ static bool test_payment_crud(struct lightningd *ld, const tal_t *ctx)
|
|||
t->id = 0;
|
||||
t->msatoshi = AMOUNT_MSAT(100);
|
||||
t->msatoshi_sent = AMOUNT_MSAT(101);
|
||||
t->total_msat = t->msatoshi;
|
||||
t->status = PAYMENT_PENDING;
|
||||
t->payment_preimage = NULL;
|
||||
memset(&t->payment_hash, 1, sizeof(t->payment_hash));
|
||||
t->partid = 0;
|
||||
|
||||
db_begin_transaction(w->db);
|
||||
wallet_payment_setup(w, tal_dup(NULL, struct wallet_payment, t));
|
||||
wallet_payment_store(w, &t->payment_hash);
|
||||
t2 = wallet_payment_by_hash(ctx, w, &t->payment_hash);
|
||||
wallet_payment_store(w, &t->payment_hash, 0);
|
||||
t2 = wallet_payment_by_hash(ctx, w, &t->payment_hash, 0);
|
||||
CHECK(t2 != NULL);
|
||||
CHECK(t2->status == t->status);
|
||||
CHECK(sha256_eq(&t2->payment_hash, &t->payment_hash));
|
||||
CHECK(t2->partid == t->partid);
|
||||
CHECK(node_id_cmp(t2->destination, t->destination) == 0);
|
||||
CHECK(amount_msat_eq(t2->msatoshi, t->msatoshi));
|
||||
CHECK(amount_msat_eq(t2->msatoshi_sent, t->msatoshi_sent));
|
||||
CHECK(amount_msat_eq(t2->total_msat, t->total_msat));
|
||||
CHECK(!t2->payment_preimage);
|
||||
|
||||
t->status = PAYMENT_COMPLETE;
|
||||
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,
|
||||
wallet_payment_set_status(w, &t->payment_hash, t->partid, 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, t->partid);
|
||||
CHECK(t2 != NULL);
|
||||
CHECK(t2->status == t->status);
|
||||
CHECK(sha256_eq(&t2->payment_hash, &t->payment_hash));
|
||||
CHECK(t2->partid == t->partid);
|
||||
CHECK(node_id_eq(t2->destination, t->destination));
|
||||
CHECK(amount_msat_eq(t2->msatoshi, t->msatoshi));
|
||||
CHECK(amount_msat_eq(t2->msatoshi_sent, t->msatoshi_sent));
|
||||
|
|
|
@ -2042,10 +2042,12 @@ struct htlc_stub *wallet_htlc_stubs(const tal_t *ctx, struct wallet *wallet,
|
|||
|
||||
void wallet_local_htlc_out_delete(struct wallet *wallet,
|
||||
struct channel *chan,
|
||||
const struct sha256 *payment_hash)
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid)
|
||||
{
|
||||
struct db_stmt *stmt;
|
||||
|
||||
/* FIXME: Put partid into locally-generated htlc_out, select here! */
|
||||
stmt = db_prepare_v2(wallet->db, SQL("DELETE FROM channel_htlcs"
|
||||
" WHERE direction = ?"
|
||||
" AND origin_htlc = ?"
|
||||
|
@ -2058,12 +2060,15 @@ void wallet_local_htlc_out_delete(struct wallet *wallet,
|
|||
}
|
||||
|
||||
static struct wallet_payment *
|
||||
find_unstored_payment(struct wallet *wallet, const struct sha256 *payment_hash)
|
||||
find_unstored_payment(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid)
|
||||
{
|
||||
struct wallet_payment *i;
|
||||
|
||||
list_for_each(&wallet->unstored_payments, i, list) {
|
||||
if (sha256_eq(payment_hash, &i->payment_hash))
|
||||
if (sha256_eq(payment_hash, &i->payment_hash)
|
||||
&& i->partid == partid)
|
||||
return i;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -2076,19 +2081,21 @@ static void destroy_unstored_payment(struct wallet_payment *payment)
|
|||
|
||||
void wallet_payment_setup(struct wallet *wallet, struct wallet_payment *payment)
|
||||
{
|
||||
assert(!find_unstored_payment(wallet, &payment->payment_hash));
|
||||
assert(!find_unstored_payment(wallet, &payment->payment_hash,
|
||||
payment->partid));
|
||||
|
||||
list_add_tail(&wallet->unstored_payments, &payment->list);
|
||||
tal_add_destructor(payment, destroy_unstored_payment);
|
||||
}
|
||||
|
||||
void wallet_payment_store(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash)
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid)
|
||||
{
|
||||
struct db_stmt *stmt;
|
||||
struct wallet_payment *payment;
|
||||
|
||||
payment = find_unstored_payment(wallet, payment_hash);
|
||||
payment = find_unstored_payment(wallet, payment_hash, partid);
|
||||
if (!payment) {
|
||||
/* Already stored on-disk */
|
||||
#if DEVELOPER
|
||||
|
@ -2098,8 +2105,10 @@ void wallet_payment_store(struct wallet *wallet,
|
|||
bool res;
|
||||
stmt =
|
||||
db_prepare_v2(wallet->db, SQL("SELECT status FROM payments"
|
||||
" WHERE payment_hash=?;"));
|
||||
" WHERE payment_hash=?"
|
||||
" AND partid = ?;"));
|
||||
db_bind_sha256(stmt, 0, payment_hash);
|
||||
db_bind_u64(stmt, 1, partid);
|
||||
db_query_prepared(stmt);
|
||||
res = db_step(stmt);
|
||||
assert(res);
|
||||
|
@ -2124,8 +2133,10 @@ void wallet_payment_store(struct wallet *wallet,
|
|||
" route_channels,"
|
||||
" msatoshi_sent,"
|
||||
" description,"
|
||||
" bolt11"
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
" bolt11,"
|
||||
" total_msat,"
|
||||
" partid"
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
|
||||
|
||||
db_bind_int(stmt, 0, payment->status);
|
||||
db_bind_sha256(stmt, 1, &payment->payment_hash);
|
||||
|
@ -2164,26 +2175,32 @@ void wallet_payment_store(struct wallet *wallet,
|
|||
else
|
||||
db_bind_null(stmt, 10);
|
||||
|
||||
db_bind_amount_msat(stmt, 11, &payment->total_msat);
|
||||
db_bind_u64(stmt, 12, payment->partid);
|
||||
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
tal_free(payment);
|
||||
}
|
||||
|
||||
void wallet_payment_delete(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash)
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid)
|
||||
{
|
||||
struct db_stmt *stmt;
|
||||
struct wallet_payment *payment;
|
||||
|
||||
payment = find_unstored_payment(wallet, payment_hash);
|
||||
payment = find_unstored_payment(wallet, payment_hash, partid);
|
||||
if (payment) {
|
||||
tal_free(payment);
|
||||
return;
|
||||
}
|
||||
|
||||
stmt = db_prepare_v2(
|
||||
wallet->db, SQL("DELETE FROM payments WHERE payment_hash = ?"));
|
||||
wallet->db, SQL("DELETE FROM payments WHERE payment_hash = ?"
|
||||
" AND partid = ?"));
|
||||
|
||||
db_bind_sha256(stmt, 0, payment_hash);
|
||||
db_bind_u64(stmt, 1, partid);
|
||||
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
|
@ -2251,18 +2268,21 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx,
|
|||
else
|
||||
payment->failonion = NULL;
|
||||
|
||||
db_column_amount_msat(stmt, 14, &payment->total_msat);
|
||||
payment->partid = db_column_u64(stmt, 15);
|
||||
return payment;
|
||||
}
|
||||
|
||||
struct wallet_payment *
|
||||
wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
|
||||
const struct sha256 *payment_hash)
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid)
|
||||
{
|
||||
struct db_stmt *stmt;
|
||||
struct wallet_payment *payment;
|
||||
|
||||
/* Present the illusion that it's in the db... */
|
||||
payment = find_unstored_payment(wallet, payment_hash);
|
||||
payment = find_unstored_payment(wallet, payment_hash, partid);
|
||||
if (payment)
|
||||
return payment;
|
||||
|
||||
|
@ -2281,10 +2301,14 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
|
|||
", description"
|
||||
", bolt11"
|
||||
", failonionreply"
|
||||
", total_msat"
|
||||
", partid"
|
||||
" FROM payments"
|
||||
" WHERE payment_hash = ?"));
|
||||
" WHERE payment_hash = ?"
|
||||
" AND partid = ?"));
|
||||
|
||||
db_bind_sha256(stmt, 0, payment_hash);
|
||||
db_bind_u64(stmt, 1, partid);
|
||||
db_query_prepared(stmt);
|
||||
if (db_step(stmt)) {
|
||||
payment = wallet_stmt2payment(ctx, stmt);
|
||||
|
@ -2295,6 +2319,7 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
|
|||
|
||||
void wallet_payment_set_status(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid,
|
||||
const enum wallet_payment_status newstatus,
|
||||
const struct preimage *preimage)
|
||||
{
|
||||
|
@ -2302,7 +2327,7 @@ void wallet_payment_set_status(struct wallet *wallet,
|
|||
struct wallet_payment *payment;
|
||||
|
||||
/* We can only fail an unstored payment! */
|
||||
payment = find_unstored_payment(wallet, payment_hash);
|
||||
payment = find_unstored_payment(wallet, payment_hash, partid);
|
||||
if (payment) {
|
||||
assert(newstatus == PAYMENT_FAILED);
|
||||
tal_free(payment);
|
||||
|
@ -2311,19 +2336,21 @@ void wallet_payment_set_status(struct wallet *wallet,
|
|||
|
||||
stmt = db_prepare_v2(wallet->db,
|
||||
SQL("UPDATE payments SET status=? "
|
||||
"WHERE payment_hash=?"));
|
||||
"WHERE payment_hash=? AND partid=?"));
|
||||
|
||||
db_bind_int(stmt, 0, wallet_payment_status_in_db(newstatus));
|
||||
db_bind_sha256(stmt, 1, payment_hash);
|
||||
db_bind_u64(stmt, 2, partid);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
|
||||
if (preimage) {
|
||||
stmt = db_prepare_v2(wallet->db,
|
||||
SQL("UPDATE payments SET payment_preimage=? "
|
||||
"WHERE payment_hash=?"));
|
||||
"WHERE payment_hash=? AND partid=?"));
|
||||
|
||||
db_bind_preimage(stmt, 0, preimage);
|
||||
db_bind_sha256(stmt, 1, payment_hash);
|
||||
db_bind_u64(stmt, 2, partid);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
if (newstatus != PAYMENT_PENDING) {
|
||||
|
@ -2332,8 +2359,10 @@ void wallet_payment_set_status(struct wallet *wallet,
|
|||
" SET path_secrets = NULL"
|
||||
" , route_nodes = NULL"
|
||||
" , route_channels = NULL"
|
||||
" WHERE payment_hash = ?;"));
|
||||
" WHERE payment_hash = ?"
|
||||
" AND partid = ?;"));
|
||||
db_bind_sha256(stmt, 0, payment_hash);
|
||||
db_bind_u64(stmt, 1, partid);
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
}
|
||||
|
@ -2341,6 +2370,7 @@ void wallet_payment_set_status(struct wallet *wallet,
|
|||
void wallet_payment_get_failinfo(const tal_t *ctx,
|
||||
struct wallet *wallet,
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid,
|
||||
/* outputs */
|
||||
u8 **failonionreply,
|
||||
bool *faildestperm,
|
||||
|
@ -2362,8 +2392,9 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
|
|||
", failnode, failchannel"
|
||||
", failupdate, faildetail, faildirection"
|
||||
" FROM payments"
|
||||
" WHERE payment_hash=?;"));
|
||||
" WHERE payment_hash=? AND partid=?;"));
|
||||
db_bind_sha256(stmt, 0, payment_hash);
|
||||
db_bind_u64(stmt, 1, partid);
|
||||
db_query_prepared(stmt);
|
||||
resb = db_step(stmt);
|
||||
assert(resb);
|
||||
|
@ -2412,6 +2443,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
|
|||
|
||||
void wallet_payment_set_failinfo(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid,
|
||||
const u8 *failonionreply /*tal_arr*/,
|
||||
bool faildestperm,
|
||||
int failindex,
|
||||
|
@ -2434,7 +2466,8 @@ void wallet_payment_set_failinfo(struct wallet *wallet,
|
|||
" , failupdate=?"
|
||||
" , faildetail=?"
|
||||
" , faildirection=?"
|
||||
" WHERE payment_hash=?;"));
|
||||
" WHERE payment_hash=?"
|
||||
" AND partid=?;"));
|
||||
if (failonionreply)
|
||||
db_bind_blob(stmt, 0, failonionreply,
|
||||
tal_count(failonionreply));
|
||||
|
@ -2469,6 +2502,7 @@ void wallet_payment_set_failinfo(struct wallet *wallet,
|
|||
db_bind_null(stmt, 7);
|
||||
|
||||
db_bind_sha256(stmt, 9, payment_hash);
|
||||
db_bind_u64(stmt, 10, partid);
|
||||
|
||||
db_exec_prepared_v2(take(stmt));
|
||||
}
|
||||
|
@ -2501,6 +2535,8 @@ wallet_payment_list(const tal_t *ctx,
|
|||
", description"
|
||||
", bolt11"
|
||||
", failonionreply"
|
||||
", total_msat"
|
||||
", partid"
|
||||
" FROM payments"
|
||||
" WHERE payment_hash = ?;"));
|
||||
db_bind_sha256(stmt, 0, payment_hash);
|
||||
|
@ -2520,6 +2556,8 @@ wallet_payment_list(const tal_t *ctx,
|
|||
", description"
|
||||
", bolt11"
|
||||
", failonionreply"
|
||||
", total_msat"
|
||||
", partid"
|
||||
" FROM payments;"));
|
||||
}
|
||||
db_query_prepared(stmt);
|
||||
|
|
|
@ -249,13 +249,18 @@ struct wallet_payment {
|
|||
struct list_node list;
|
||||
u64 id;
|
||||
u32 timestamp;
|
||||
|
||||
/* The combination of these two fields is unique: */
|
||||
struct sha256 payment_hash;
|
||||
u64 partid;
|
||||
|
||||
enum wallet_payment_status status;
|
||||
|
||||
/* The destination may not be known if we used `sendonion` */
|
||||
struct node_id *destination;
|
||||
struct amount_msat msatoshi;
|
||||
struct amount_msat msatoshi_sent;
|
||||
struct amount_msat total_msat;
|
||||
/* If and only if PAYMENT_COMPLETE */
|
||||
struct preimage *payment_preimage;
|
||||
/* Needed for recovering from routing failures. */
|
||||
|
@ -930,7 +935,8 @@ void wallet_payment_setup(struct wallet *wallet, struct wallet_payment *payment)
|
|||
* Stores the payment in the database.
|
||||
*/
|
||||
void wallet_payment_store(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash);
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid);
|
||||
|
||||
/**
|
||||
* wallet_payment_delete - Remove a payment
|
||||
|
@ -938,7 +944,8 @@ void wallet_payment_store(struct wallet *wallet,
|
|||
* Removes the payment from the database.
|
||||
*/
|
||||
void wallet_payment_delete(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash);
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid);
|
||||
|
||||
/**
|
||||
* wallet_local_htlc_out_delete - Remove a local outgoing failed HTLC
|
||||
|
@ -949,7 +956,8 @@ void wallet_payment_delete(struct wallet *wallet,
|
|||
*/
|
||||
void wallet_local_htlc_out_delete(struct wallet *wallet,
|
||||
struct channel *chan,
|
||||
const struct sha256 *payment_hash);
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid);
|
||||
|
||||
/**
|
||||
* wallet_payment_by_hash - Retrieve a specific payment
|
||||
|
@ -958,7 +966,8 @@ void wallet_local_htlc_out_delete(struct wallet *wallet,
|
|||
*/
|
||||
struct wallet_payment *
|
||||
wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
|
||||
const struct sha256 *payment_hash);
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid);
|
||||
|
||||
/**
|
||||
* wallet_payment_set_status - Update the status of the payment
|
||||
|
@ -968,6 +977,7 @@ wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,
|
|||
*/
|
||||
void wallet_payment_set_status(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid,
|
||||
const enum wallet_payment_status newstatus,
|
||||
const struct preimage *preimage);
|
||||
|
||||
|
@ -981,6 +991,7 @@ void wallet_payment_set_status(struct wallet *wallet,
|
|||
void wallet_payment_get_failinfo(const tal_t *ctx,
|
||||
struct wallet *wallet,
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid,
|
||||
/* outputs */
|
||||
u8 **failonionreply,
|
||||
bool *faildestperm,
|
||||
|
@ -997,6 +1008,7 @@ void wallet_payment_get_failinfo(const tal_t *ctx,
|
|||
*/
|
||||
void wallet_payment_set_failinfo(struct wallet *wallet,
|
||||
const struct sha256 *payment_hash,
|
||||
u64 partid,
|
||||
const u8 *failonionreply,
|
||||
bool faildestperm,
|
||||
int failindex,
|
||||
|
|
Loading…
Reference in New Issue