From 345ca9b12216955116be4ac3904a7e919f4d7ec0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 12 Dec 2019 10:09:07 +1030 Subject: [PATCH] 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 --- lightningd/htlc_end.c | 3 +++ lightningd/htlc_end.h | 4 ++++ lightningd/pay.c | 30 +++++++++++++++++------------- lightningd/peer_htlcs.c | 9 +++++---- lightningd/peer_htlcs.h | 1 + wallet/db.c | 2 ++ wallet/wallet.c | 15 +++++++++++---- 7 files changed, 43 insertions(+), 21 deletions(-) diff --git a/lightningd/htlc_end.c b/lightningd/htlc_end.c index ab3737767..ff89ada43 100644 --- a/lightningd/htlc_end.c +++ b/lightningd/htlc_end.c @@ -252,6 +252,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx, const struct sha256 *payment_hash, const u8 *onion_routing_packet, bool am_origin, + u64 partid, struct htlc_in *in) { 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->am_origin = am_origin; + if (am_origin) + hout->partid = partid; hout->in = NULL; if (in) htlc_out_connect_htlc_in(hout, in); diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index a955487bc..16e20bb1e 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -82,6 +82,9 @@ struct htlc_out { /* Is this a locally-generated payment? Implies ->in is NULL. */ bool am_origin; + /* If am_origin, this is the partid of the payment. */ + u64 partid; + /* Where it's from, if not going to us. */ struct htlc_in *in; }; @@ -140,6 +143,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx, const struct sha256 *payment_hash, const u8 *onion_routing_packet, bool am_origin, + u64 partid, struct htlc_in *in); void connect_htlc_in(struct htlc_in_map *map, struct htlc_in *hin); diff --git a/lightningd/pay.c b/lightningd/pay.c index 33608db98..809b2a3de 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -503,7 +503,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout, payment = wallet_payment_by_hash(tmpctx, ld->wallet, &hout->payment_hash, - /* FIXME: Set partid! */0); + hout->partid); #ifdef COMPAT_V052 /* 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 */ - payment_store(ld, &hout->payment_hash, /* FIXME: Set partid! */ 0); - wallet_payment_set_status(ld->wallet, &hout->payment_hash, /* FIXME: Set partid! */ 0, + payment_store(ld, &hout->payment_hash, hout->partid); + wallet_payment_set_status(ld->wallet, &hout->payment_hash, + hout->partid, PAYMENT_FAILED, NULL); wallet_payment_set_failinfo(ld->wallet, - &hout->payment_hash, /* FIXME: Set partid! */ 0, + &hout->payment_hash, + hout->partid, fail ? NULL : hout->failuremsg, pay_errcode == PAY_DESTINATION_PERM_FAIL, 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, - const struct onionpacket *packet, - const struct route_hop *first_hop, - const struct sha256 *payment_hash, - struct channel *channel, - struct htlc_out **hout) + const struct onionpacket *packet, + const struct route_hop *first_hop, + const struct sha256 *payment_hash, + u64 partid, + struct channel *channel, + struct htlc_out **hout) { const u8 *onion; unsigned int base_expiry; base_expiry = get_block_height(ld->topology) + 1; onion = serialize_onionpacket(tmpctx, packet); return send_htlc_out(channel, first_hop->amount, - base_expiry + first_hop->delay, - payment_hash, onion, NULL, hout); + base_expiry + first_hop->delay, + payment_hash, partid, onion, NULL, hout); } /* 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); - 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", type_to_string(tmpctx, struct amount_msat, &route[0].amount), 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); } - 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); payment = tal(hout, struct wallet_payment); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 39df3f2a9..1edb6b50b 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -452,6 +452,7 @@ static void htlc_offer_timeout(struct channel *channel) enum onion_type send_htlc_out(struct channel *out, struct amount_msat amount, u32 cltv, const struct sha256 *payment_hash, + u64 partid, const u8 *onion_routing_packet, struct htlc_in *in, 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. */ 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); /* 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); failcode = send_htlc_out(next, amt_to_forward, outgoing_cltv_value, &hin->payment_hash, - next_onion, hin, &hout); + 0, next_onion, hin, &hout); if (!failcode) return; @@ -1274,8 +1276,7 @@ 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, - /* FIXME: Set partid! */ 0); + &hout->payment_hash, hout->partid); } if (!htlc_out_update_state(channel, hout, newstate)) diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index fdf0b4e47..da8e75623 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -51,6 +51,7 @@ void update_per_commit_point(struct channel *channel, enum onion_type send_htlc_out(struct channel *out, struct amount_msat amount, u32 cltv, const struct sha256 *payment_hash, + u64 partid, const u8 *onion_routing_packet, struct htlc_in *in, struct htlc_out **houtp); diff --git a/wallet/db.c b/wallet/db.c index 6497ee293..8652224b5 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -559,6 +559,8 @@ static struct migration dbmigrations[] = { {SQL("UPDATE payments SET total_msat = msatoshi;"), NULL}, {SQL("UPDATE payments SET partid = 0;"), 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. */ diff --git a/wallet/wallet.c b/wallet/wallet.c index e452a4234..1af89b55d 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1661,7 +1661,8 @@ void wallet_htlc_save_out(struct wallet *wallet, " payment_hash," " payment_key," " hstate," - " routing_onion) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); + " routing_onion," + " partid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); db_bind_u64(stmt, 0, chan->dbid); 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, 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); out->dbid = db_last_insert_id_v2(stmt); @@ -1796,6 +1801,7 @@ static bool wallet_stmt2htlc_out(struct channel *channel, out->am_origin = false; } else { out->origin_htlc_id = 0; + out->partid = db_column_u64(stmt, 13); out->am_origin = true; } @@ -1900,6 +1906,7 @@ bool wallet_htlcs_load_for_channel(struct wallet *wallet, ", origin_htlc" ", shared_secret" ", received_time" + ", partid" " FROM channel_htlcs" " WHERE direction = ?" " AND channel_id = ?" @@ -2047,15 +2054,15 @@ void wallet_local_htlc_out_delete(struct wallet *wallet, { 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 = ?" - " AND payment_hash = ?")); + " AND payment_hash = ?" + " AND partid = ?;")); db_bind_int(stmt, 0, DIRECTION_OUTGOING); db_bind_int(stmt, 1, 0); db_bind_sha256(stmt, 2, payment_hash); - + db_bind_u64(stmt, 3, partid); db_exec_prepared_v2(take(stmt)); }