db: add partid field to htlc_out.

This is in preparation for partial payments.  For existing payments,
partid is 0 (to match the corresponding payment).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2019-12-12 10:09:07 +10:30 committed by Christian Decker
parent 2d18c3a209
commit 345ca9b122
7 changed files with 43 additions and 21 deletions

View file

@ -252,6 +252,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const u8 *onion_routing_packet, const u8 *onion_routing_packet,
bool am_origin, bool am_origin,
u64 partid,
struct htlc_in *in) struct htlc_in *in)
{ {
struct htlc_out *hout = tal(ctx, struct htlc_out); struct htlc_out *hout = tal(ctx, struct htlc_out);
@ -273,6 +274,8 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
hout->preimage = NULL; hout->preimage = NULL;
hout->am_origin = am_origin; hout->am_origin = am_origin;
if (am_origin)
hout->partid = partid;
hout->in = NULL; hout->in = NULL;
if (in) if (in)
htlc_out_connect_htlc_in(hout, in); htlc_out_connect_htlc_in(hout, in);

View file

@ -82,6 +82,9 @@ struct htlc_out {
/* Is this a locally-generated payment? Implies ->in is NULL. */ /* Is this a locally-generated payment? Implies ->in is NULL. */
bool am_origin; bool am_origin;
/* If am_origin, this is the partid of the payment. */
u64 partid;
/* Where it's from, if not going to us. */ /* Where it's from, if not going to us. */
struct htlc_in *in; struct htlc_in *in;
}; };
@ -140,6 +143,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
const u8 *onion_routing_packet, const u8 *onion_routing_packet,
bool am_origin, bool am_origin,
u64 partid,
struct htlc_in *in); struct htlc_in *in);
void connect_htlc_in(struct htlc_in_map *map, struct htlc_in *hin); void connect_htlc_in(struct htlc_in_map *map, struct htlc_in *hin);

View file

@ -503,7 +503,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
payment = wallet_payment_by_hash(tmpctx, ld->wallet, payment = wallet_payment_by_hash(tmpctx, ld->wallet,
&hout->payment_hash, &hout->payment_hash,
/* FIXME: Set partid! */0); hout->partid);
#ifdef COMPAT_V052 #ifdef COMPAT_V052
/* Prior to "pay: delete HTLC when we delete payment." we would /* Prior to "pay: delete HTLC when we delete payment." we would
@ -573,11 +573,13 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
} }
/* Save to DB */ /* Save to DB */
payment_store(ld, &hout->payment_hash, /* FIXME: Set partid! */ 0); payment_store(ld, &hout->payment_hash, hout->partid);
wallet_payment_set_status(ld->wallet, &hout->payment_hash, /* FIXME: Set partid! */ 0, wallet_payment_set_status(ld->wallet, &hout->payment_hash,
hout->partid,
PAYMENT_FAILED, NULL); PAYMENT_FAILED, NULL);
wallet_payment_set_failinfo(ld->wallet, wallet_payment_set_failinfo(ld->wallet,
&hout->payment_hash, /* FIXME: Set partid! */ 0, &hout->payment_hash,
hout->partid,
fail ? NULL : hout->failuremsg, fail ? NULL : hout->failuremsg,
pay_errcode == PAY_DESTINATION_PERM_FAIL, pay_errcode == PAY_DESTINATION_PERM_FAIL,
fail ? fail->erring_index : -1, fail ? fail->erring_index : -1,
@ -697,19 +699,20 @@ static bool should_use_tlv(enum route_hop_style style)
} }
static enum onion_type send_onion(struct lightningd *ld, static enum onion_type send_onion(struct lightningd *ld,
const struct onionpacket *packet, const struct onionpacket *packet,
const struct route_hop *first_hop, const struct route_hop *first_hop,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
struct channel *channel, u64 partid,
struct htlc_out **hout) struct channel *channel,
struct htlc_out **hout)
{ {
const u8 *onion; const u8 *onion;
unsigned int base_expiry; unsigned int base_expiry;
base_expiry = get_block_height(ld->topology) + 1; base_expiry = get_block_height(ld->topology) + 1;
onion = serialize_onionpacket(tmpctx, packet); onion = serialize_onionpacket(tmpctx, packet);
return send_htlc_out(channel, first_hop->amount, return send_htlc_out(channel, first_hop->amount,
base_expiry + first_hop->delay, base_expiry + first_hop->delay,
payment_hash, onion, NULL, hout); payment_hash, partid, onion, NULL, hout);
} }
/* Returns command_result if cmd was resolved, NULL if not yet called. */ /* Returns command_result if cmd was resolved, NULL if not yet called. */
@ -840,7 +843,8 @@ send_payment(struct lightningd *ld,
} }
packet = create_onionpacket(tmpctx, path, &path_secrets); packet = create_onionpacket(tmpctx, path, &path_secrets);
failcode = send_onion(ld, packet, &route[0], rhash, channel, &hout); failcode = send_onion(ld, packet, &route[0], rhash, partid,
channel, &hout);
log_info(ld->log, "Sending %s over %zu hops to deliver %s", log_info(ld->log, "Sending %s over %zu hops to deliver %s",
type_to_string(tmpctx, struct amount_msat, &route[0].amount), type_to_string(tmpctx, struct amount_msat, &route[0].amount),
n_hops, type_to_string(tmpctx, struct amount_msat, &msat)); n_hops, type_to_string(tmpctx, struct amount_msat, &msat));
@ -1048,7 +1052,7 @@ static struct command_result *json_sendonion(struct command *cmd,
wallet_local_htlc_out_delete(ld->wallet, channel, 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, failcode = send_onion(cmd->ld, &packet, first_hop, payment_hash, /* FIXME: Set partid! */0, channel,
&hout); &hout);
payment = tal(hout, struct wallet_payment); payment = tal(hout, struct wallet_payment);

View file

@ -452,6 +452,7 @@ static void htlc_offer_timeout(struct channel *channel)
enum onion_type send_htlc_out(struct channel *out, enum onion_type send_htlc_out(struct channel *out,
struct amount_msat amount, u32 cltv, struct amount_msat amount, u32 cltv,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u64 partid,
const u8 *onion_routing_packet, const u8 *onion_routing_packet,
struct htlc_in *in, struct htlc_in *in,
struct htlc_out **houtp) struct htlc_out **houtp)
@ -479,7 +480,8 @@ enum onion_type send_htlc_out(struct channel *out,
/* Make peer's daemon own it, catch if it dies. */ /* Make peer's daemon own it, catch if it dies. */
hout = new_htlc_out(out->owner, out, amount, cltv, hout = new_htlc_out(out->owner, out, amount, cltv,
payment_hash, onion_routing_packet, in == NULL, in); payment_hash, onion_routing_packet, in == NULL,
partid, in);
tal_add_destructor(hout, destroy_hout_subd_died); tal_add_destructor(hout, destroy_hout_subd_died);
/* Give channel 30 seconds to commit (first) htlc. */ /* Give channel 30 seconds to commit (first) htlc. */
@ -590,7 +592,7 @@ static void forward_htlc(struct htlc_in *hin,
hout = tal(tmpctx, struct htlc_out); hout = tal(tmpctx, struct htlc_out);
failcode = send_htlc_out(next, amt_to_forward, failcode = send_htlc_out(next, amt_to_forward,
outgoing_cltv_value, &hin->payment_hash, outgoing_cltv_value, &hin->payment_hash,
next_onion, hin, &hout); 0, next_onion, hin, &hout);
if (!failcode) if (!failcode)
return; return;
@ -1274,8 +1276,7 @@ static bool update_out_htlc(struct channel *channel,
/* For our own HTLCs, we commit payment to db lazily */ /* For our own HTLCs, we commit payment to db lazily */
if (hout->origin_htlc_id == 0) if (hout->origin_htlc_id == 0)
payment_store(ld, payment_store(ld,
&hout->payment_hash, &hout->payment_hash, hout->partid);
/* FIXME: Set partid! */ 0);
} }
if (!htlc_out_update_state(channel, hout, newstate)) if (!htlc_out_update_state(channel, hout, newstate))

View file

@ -51,6 +51,7 @@ void update_per_commit_point(struct channel *channel,
enum onion_type send_htlc_out(struct channel *out, enum onion_type send_htlc_out(struct channel *out,
struct amount_msat amount, u32 cltv, struct amount_msat amount, u32 cltv,
const struct sha256 *payment_hash, const struct sha256 *payment_hash,
u64 partid,
const u8 *onion_routing_packet, const u8 *onion_routing_packet,
struct htlc_in *in, struct htlc_in *in,
struct htlc_out **houtp); struct htlc_out **houtp);

View file

@ -559,6 +559,8 @@ static struct migration dbmigrations[] = {
{SQL("UPDATE payments SET total_msat = msatoshi;"), NULL}, {SQL("UPDATE payments SET total_msat = msatoshi;"), NULL},
{SQL("UPDATE payments SET partid = 0;"), NULL}, {SQL("UPDATE payments SET partid = 0;"), NULL},
{SQL("DROP TABLE temp_payments;"), NULL}, {SQL("DROP TABLE temp_payments;"), NULL},
{SQL("ALTER TABLE channel_htlcs ADD partid BIGINT;"), NULL},
{SQL("UPDATE channel_htlcs SET partid = 0;"), NULL},
}; };
/* Leak tracking. */ /* Leak tracking. */

View file

@ -1661,7 +1661,8 @@ void wallet_htlc_save_out(struct wallet *wallet,
" payment_hash," " payment_hash,"
" payment_key," " payment_key,"
" hstate," " hstate,"
" routing_onion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); " routing_onion,"
" partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
db_bind_u64(stmt, 0, chan->dbid); db_bind_u64(stmt, 0, chan->dbid);
db_bind_u64(stmt, 1, out->key.id); db_bind_u64(stmt, 1, out->key.id);
@ -1682,6 +1683,10 @@ void wallet_htlc_save_out(struct wallet *wallet,
db_bind_blob(stmt, 9, out->onion_routing_packet, db_bind_blob(stmt, 9, out->onion_routing_packet,
sizeof(out->onion_routing_packet)); sizeof(out->onion_routing_packet));
if (!out->am_origin)
db_bind_null(stmt, 10);
else
db_bind_u64(stmt, 10, out->partid);
db_exec_prepared_v2(stmt); db_exec_prepared_v2(stmt);
out->dbid = db_last_insert_id_v2(stmt); out->dbid = db_last_insert_id_v2(stmt);
@ -1796,6 +1801,7 @@ static bool wallet_stmt2htlc_out(struct channel *channel,
out->am_origin = false; out->am_origin = false;
} else { } else {
out->origin_htlc_id = 0; out->origin_htlc_id = 0;
out->partid = db_column_u64(stmt, 13);
out->am_origin = true; out->am_origin = true;
} }
@ -1900,6 +1906,7 @@ bool wallet_htlcs_load_for_channel(struct wallet *wallet,
", origin_htlc" ", origin_htlc"
", shared_secret" ", shared_secret"
", received_time" ", received_time"
", partid"
" FROM channel_htlcs" " FROM channel_htlcs"
" WHERE direction = ?" " WHERE direction = ?"
" AND channel_id = ?" " AND channel_id = ?"
@ -2047,15 +2054,15 @@ void wallet_local_htlc_out_delete(struct wallet *wallet,
{ {
struct db_stmt *stmt; 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" stmt = db_prepare_v2(wallet->db, SQL("DELETE FROM channel_htlcs"
" WHERE direction = ?" " WHERE direction = ?"
" AND origin_htlc = ?" " AND origin_htlc = ?"
" AND payment_hash = ?")); " AND payment_hash = ?"
" AND partid = ?;"));
db_bind_int(stmt, 0, DIRECTION_OUTGOING); db_bind_int(stmt, 0, DIRECTION_OUTGOING);
db_bind_int(stmt, 1, 0); db_bind_int(stmt, 1, 0);
db_bind_sha256(stmt, 2, payment_hash); db_bind_sha256(stmt, 2, payment_hash);
db_bind_u64(stmt, 3, partid);
db_exec_prepared_v2(take(stmt)); db_exec_prepared_v2(take(stmt));
} }