diff --git a/lightningd/htlc_end.c b/lightningd/htlc_end.c index c38068ea1..459525428 100644 --- a/lightningd/htlc_end.c +++ b/lightningd/htlc_end.c @@ -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)); diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index 9a502d2cc..d3e758785 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -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); diff --git a/lightningd/pay.c b/lightningd/pay.c index da065479e..6e9372e17 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -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)); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 2350d5183..cdc816ef7 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -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; diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index c5ea41a44..79828e0af 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -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);