mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 01:43:36 +01:00
htlc: Defer saving the outgoing payment until we store the HTLC
This addresses a performance regression introduced by
6ceb375650
. We were storing it in an
otherwise empty DB transaction, which means that DB transaction was no
longer a no-op. Now we defer storing until we need to store the
corresponding HTLC anyway, so we can just piggyback on top of that
transaction.
This is also more consistent since we'd be forgetting the payment
anyway if we restart between adding the HTLC and committing to it.
Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
547d3f0a0b
commit
79443d6f94
@ -138,7 +138,8 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
|
||||
const struct sha256 *payment_hash,
|
||||
const u8 *onion_routing_packet,
|
||||
struct htlc_in *in,
|
||||
struct pay_command *pc)
|
||||
struct pay_command *pc,
|
||||
struct wallet_payment *payment)
|
||||
{
|
||||
struct htlc_out *hout = tal(ctx, struct htlc_out);
|
||||
|
||||
@ -149,6 +150,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
|
||||
hout->msatoshi = msatoshi;
|
||||
hout->cltv_expiry = cltv_expiry;
|
||||
hout->payment_hash = *payment_hash;
|
||||
hout->payment = payment;
|
||||
memcpy(hout->onion_routing_packet, onion_routing_packet,
|
||||
sizeof(hout->onion_routing_packet));
|
||||
|
||||
|
@ -72,6 +72,9 @@ struct htlc_out {
|
||||
|
||||
/* Otherwise, payment command which created it. */
|
||||
struct pay_command *pay_command;
|
||||
|
||||
/* Temporary payment store, so we can save everything in one go */
|
||||
struct wallet_payment *payment;
|
||||
};
|
||||
|
||||
static inline const struct htlc_key *keyof_htlc_in(const struct htlc_in *in)
|
||||
@ -127,7 +130,8 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
|
||||
const struct sha256 *payment_hash,
|
||||
const u8 *onion_routing_packet,
|
||||
struct htlc_in *in,
|
||||
struct pay_command *pc);
|
||||
struct pay_command *pc,
|
||||
struct wallet_payment *payment);
|
||||
|
||||
void connect_htlc_in(struct htlc_in_map *map, struct htlc_in *hin);
|
||||
void connect_htlc_out(struct htlc_out_map *map, struct htlc_out *hout);
|
||||
|
@ -165,7 +165,7 @@ static void send_payment(struct command *cmd,
|
||||
size_t i, n_hops = tal_count(route);
|
||||
struct hop_data *hop_data = tal_arr(cmd, struct hop_data, n_hops);
|
||||
struct pubkey *ids = tal_arr(cmd, struct pubkey, n_hops);
|
||||
struct wallet_payment payment;
|
||||
struct wallet_payment *payment = NULL;
|
||||
|
||||
/* Expiry for HTLCs is absolute. And add one to give some margin. */
|
||||
base_expiry = get_block_height(cmd->ld->topology) + 1;
|
||||
@ -223,23 +223,6 @@ static void send_payment(struct command *cmd,
|
||||
log_add(cmd->ld->log, "... retrying");
|
||||
}
|
||||
|
||||
/* If this is a new payment, then store the payment so we can
|
||||
* later show it in the history */
|
||||
if (!pc) {
|
||||
payment.id = 0;
|
||||
payment.incoming = false;
|
||||
payment.payment_hash = *rhash;
|
||||
payment.destination = &ids[n_hops - 1];
|
||||
payment.status = PAYMENT_PENDING;
|
||||
payment.msatoshi = route[n_hops-1].amount;
|
||||
payment.timestamp = time_now().ts.tv_sec;
|
||||
|
||||
if (!wallet_payment_add(cmd->ld->wallet, &payment)) {
|
||||
command_fail(cmd, "Unable to record payment in the database.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
peer = peer_by_id(cmd->ld, &ids[0]);
|
||||
if (!peer) {
|
||||
command_fail(cmd, "no connection to first peer found");
|
||||
@ -259,6 +242,15 @@ static void send_payment(struct command *cmd,
|
||||
pc = tal(cmd->ld, struct pay_command);
|
||||
list_add_tail(&cmd->ld->pay_commands, &pc->list);
|
||||
tal_add_destructor(pc, pay_command_destroyed);
|
||||
|
||||
payment = tal(pc, struct wallet_payment);
|
||||
payment->id = 0;
|
||||
payment->incoming = false;
|
||||
payment->payment_hash = *rhash;
|
||||
payment->destination = &ids[n_hops - 1];
|
||||
payment->status = PAYMENT_PENDING;
|
||||
payment->msatoshi = route[n_hops-1].amount;
|
||||
payment->timestamp = time_now().ts.tv_sec;
|
||||
}
|
||||
pc->cmd = cmd;
|
||||
pc->rhash = *rhash;
|
||||
@ -280,7 +272,8 @@ static void send_payment(struct command *cmd,
|
||||
|
||||
failcode = send_htlc_out(peer, route[0].amount,
|
||||
base_expiry + route[0].delay,
|
||||
rhash, onion, NULL, pc, &pc->out);
|
||||
rhash, onion, NULL, payment, pc,
|
||||
&pc->out);
|
||||
if (failcode) {
|
||||
command_fail(cmd, "first peer not ready: %s",
|
||||
onion_type_name(failcode));
|
||||
|
@ -447,6 +447,7 @@ enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv,
|
||||
const struct sha256 *payment_hash,
|
||||
const u8 *onion_routing_packet,
|
||||
struct htlc_in *in,
|
||||
struct wallet_payment *payment,
|
||||
struct pay_command *pc,
|
||||
struct htlc_out **houtp)
|
||||
{
|
||||
@ -467,7 +468,8 @@ enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv,
|
||||
|
||||
/* 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, pc);
|
||||
payment_hash, onion_routing_packet, in,
|
||||
pc, payment);
|
||||
tal_add_destructor(hout, hout_subd_died);
|
||||
|
||||
msg = towire_channel_offer_htlc(out, amount, cltv, payment_hash,
|
||||
@ -558,7 +560,7 @@ static void forward_htlc(struct htlc_in *hin,
|
||||
|
||||
failcode = send_htlc_out(next, amt_to_forward,
|
||||
outgoing_cltv_value, &hin->payment_hash,
|
||||
next_onion, hin, NULL, NULL);
|
||||
next_onion, hin, NULL, NULL, NULL);
|
||||
if (!failcode)
|
||||
return;
|
||||
|
||||
@ -927,8 +929,21 @@ static bool update_out_htlc(struct peer *peer, u64 id, enum htlc_state newstate)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hout->dbid)
|
||||
if (!hout->dbid) {
|
||||
wallet_htlc_save_out(peer->ld->wallet, peer->channel, hout);
|
||||
}
|
||||
|
||||
/* We only have a payment if we initiated the payment. */
|
||||
if (hout->payment) {
|
||||
/* Now that we are committed, and inside the
|
||||
* transaction context of the update, add the payment
|
||||
* to the history. */
|
||||
wallet_payment_add(peer->ld->wallet, hout->payment);
|
||||
|
||||
/* No need to carry the payment info around anymore,
|
||||
* we'll update in the database directly */
|
||||
hout->payment = tal_free(hout->payment);
|
||||
}
|
||||
|
||||
if (!htlc_out_update_state(peer, hout, newstate))
|
||||
return false;
|
||||
|
@ -39,6 +39,7 @@ enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv,
|
||||
const struct sha256 *payment_hash,
|
||||
const u8 *onion_routing_packet,
|
||||
struct htlc_in *in,
|
||||
struct wallet_payment *payment,
|
||||
struct pay_command *pc,
|
||||
struct htlc_out **houtp);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user