mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-18 22:54:25 +01:00
pay: remove struct pay_command.
It's all in wallet_payment, which is persistent. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
ae1d72b978
commit
02e05ba6ff
@@ -129,9 +129,6 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout,
|
||||
return corrupt(hout, abortstr, "Both failed and succeeded");
|
||||
else if (hout->cmd && hout->in)
|
||||
return corrupt(hout, abortstr, "Both local and forwarded");
|
||||
else if (!hout->in && !hout->pay_command)
|
||||
return corrupt(hout, abortstr,
|
||||
"Neither hout->in nor paycommand");
|
||||
|
||||
return cast_const(struct htlc_out *, hout);
|
||||
}
|
||||
@@ -143,7 +140,6 @@ 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 wallet_payment *payment,
|
||||
struct command *cmd)
|
||||
{
|
||||
@@ -168,7 +164,6 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
|
||||
hout->preimage = NULL;
|
||||
|
||||
hout->in = in;
|
||||
hout->pay_command = pc;
|
||||
|
||||
return htlc_out_check(hout, "new_htlc_out");
|
||||
}
|
||||
|
||||
@@ -79,9 +79,6 @@ struct htlc_out {
|
||||
/* Otherwise, this MAY be non-null if there's a pay command waiting */
|
||||
struct command *cmd;
|
||||
|
||||
/* 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;
|
||||
};
|
||||
@@ -139,7 +136,6 @@ 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 wallet_payment *payment,
|
||||
struct command *cmd);
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ static struct lightningd *new_lightningd(const tal_t *ctx,
|
||||
ld->log = new_log(log_book, log_book, "lightningd(%u):", (int)getpid());
|
||||
ld->alias = NULL;
|
||||
ld->rgb = NULL;
|
||||
list_head_init(&ld->pay_commands);
|
||||
list_head_init(&ld->connects);
|
||||
ld->wireaddrs = tal_arr(ld, struct wireaddr, 0);
|
||||
ld->portnum = DEFAULT_PORT;
|
||||
|
||||
@@ -133,9 +133,6 @@ struct lightningd {
|
||||
/* Maintained by invoices.c */
|
||||
struct invoices *invoices;
|
||||
|
||||
/* Any outstanding "pay" commands. */
|
||||
struct list_head pay_commands;
|
||||
|
||||
/* Transaction filter matching what we're interested in */
|
||||
struct txfilter *owned_txfilter;
|
||||
|
||||
|
||||
114
lightningd/pay.c
114
lightningd/pay.c
@@ -17,18 +17,6 @@
|
||||
#include <lightningd/subd.h>
|
||||
#include <sodium/randombytes.h>
|
||||
|
||||
/* Outstanding "pay" commands. */
|
||||
struct pay_command {
|
||||
struct list_node list;
|
||||
struct sha256 rhash;
|
||||
u64 msatoshi;
|
||||
const struct pubkey *ids;
|
||||
/* Set if this is in progress. */
|
||||
struct htlc_out *out;
|
||||
/* Preimage if this succeeded. */
|
||||
const struct preimage *rval;
|
||||
};
|
||||
|
||||
static void json_pay_success(struct command *cmd, const struct preimage *rval)
|
||||
{
|
||||
struct json_result *response;
|
||||
@@ -60,21 +48,17 @@ static void json_pay_failed(struct command *cmd,
|
||||
void payment_succeeded(struct lightningd *ld, struct htlc_out *hout,
|
||||
const struct preimage *rval)
|
||||
{
|
||||
assert(!hout->pay_command->rval);
|
||||
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
||||
PAYMENT_COMPLETE, rval);
|
||||
hout->pay_command->rval = tal_dup(hout->pay_command,
|
||||
struct preimage, rval);
|
||||
/* Can be NULL if JSON RPC goes away. */
|
||||
if (hout->cmd)
|
||||
json_pay_success(hout->cmd, rval);
|
||||
hout->pay_command->out = NULL;
|
||||
hout->cmd = NULL;
|
||||
}
|
||||
|
||||
void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
||||
const char *localfail)
|
||||
{
|
||||
struct pay_command *pc = hout->pay_command;
|
||||
struct onionreply *reply;
|
||||
enum onion_type failcode;
|
||||
struct secret *path_secrets;
|
||||
@@ -82,7 +66,6 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
||||
|
||||
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
||||
PAYMENT_FAILED, NULL);
|
||||
pc->out = NULL;
|
||||
|
||||
/* This gives more details than a generic failure message */
|
||||
if (localfail) {
|
||||
@@ -95,7 +78,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
||||
assert(!hout->failcode);
|
||||
path_secrets = wallet_payment_get_secrets(tmpctx, ld->wallet,
|
||||
&hout->payment_hash);
|
||||
reply = unwrap_onionreply(pc, path_secrets, tal_count(path_secrets),
|
||||
reply = unwrap_onionreply(tmpctx, path_secrets, tal_count(path_secrets),
|
||||
hout->failuremsg);
|
||||
if (!reply) {
|
||||
log_info(hout->key.peer->log,
|
||||
@@ -128,29 +111,11 @@ static void remove_cmd_from_hout(struct command *cmd, struct htlc_out *hout)
|
||||
hout->cmd = NULL;
|
||||
}
|
||||
|
||||
static struct pay_command *find_pay_command(struct lightningd *ld,
|
||||
const struct sha256 *rhash)
|
||||
{
|
||||
struct pay_command *pc;
|
||||
|
||||
list_for_each(&ld->pay_commands, pc, list) {
|
||||
if (structeq(rhash, &pc->rhash))
|
||||
return pc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void pay_command_destroyed(struct pay_command *pc)
|
||||
{
|
||||
list_del(&pc->list);
|
||||
}
|
||||
|
||||
/* Returns true if it's still pending. */
|
||||
static bool send_payment(struct command *cmd,
|
||||
const struct sha256 *rhash,
|
||||
const struct route_hop *route)
|
||||
{
|
||||
struct pay_command *pc;
|
||||
struct peer *peer;
|
||||
const u8 *onion;
|
||||
u8 sessionkey[32];
|
||||
@@ -164,6 +129,7 @@ static bool send_payment(struct command *cmd,
|
||||
struct hop_data *hop_data = tal_arr(tmpctx, struct hop_data, n_hops);
|
||||
struct pubkey *ids = tal_arr(tmpctx, struct pubkey, n_hops);
|
||||
struct wallet_payment *payment = NULL;
|
||||
struct htlc_out *hout;
|
||||
|
||||
/* Expiry for HTLCs is absolute. And add one to give some margin. */
|
||||
base_expiry = get_block_height(cmd->ld->topology) + 1;
|
||||
@@ -187,37 +153,35 @@ static bool send_payment(struct command *cmd,
|
||||
memset(&hop_data[i].channel_id, 0, sizeof(struct short_channel_id));
|
||||
hop_data[i].amt_forward = route[i].amount;
|
||||
|
||||
pc = find_pay_command(cmd->ld, rhash);
|
||||
if (pc) {
|
||||
/* Now, do we already have a payment? */
|
||||
payment = wallet_payment_by_hash(tmpctx, cmd->ld->wallet, rhash);
|
||||
if (payment) {
|
||||
log_debug(cmd->ld->log, "json_sendpay: found previous");
|
||||
if (pc->out) {
|
||||
if (payment->status == PAYMENT_PENDING) {
|
||||
log_add(cmd->ld->log, "... still in progress");
|
||||
command_fail(cmd, "still in progress");
|
||||
return false;
|
||||
}
|
||||
if (pc->rval) {
|
||||
size_t old_nhops = tal_count(pc->ids);
|
||||
if (payment->status == PAYMENT_COMPLETE) {
|
||||
log_add(cmd->ld->log, "... succeeded");
|
||||
/* Must match successful payment parameters. */
|
||||
if (pc->msatoshi != hop_data[n_hops-1].amt_forward) {
|
||||
if (payment->msatoshi != hop_data[n_hops-1].amt_forward) {
|
||||
command_fail(cmd,
|
||||
"already succeeded with amount %"
|
||||
PRIu64, pc->msatoshi);
|
||||
PRIu64, payment->msatoshi);
|
||||
return false;
|
||||
}
|
||||
if (!structeq(&pc->ids[old_nhops-1], &ids[n_hops-1])) {
|
||||
char *previd;
|
||||
previd = pubkey_to_hexstr(cmd,
|
||||
&pc->ids[old_nhops-1]);
|
||||
if (!structeq(&payment->destination, &ids[n_hops-1])) {
|
||||
command_fail(cmd,
|
||||
"already succeeded to %s",
|
||||
previd);
|
||||
type_to_string(cmd, struct pubkey,
|
||||
&payment->destination));
|
||||
return false;
|
||||
}
|
||||
json_pay_success(cmd, pc->rval);
|
||||
json_pay_success(cmd, payment->payment_preimage);
|
||||
return false;
|
||||
}
|
||||
/* FIXME: We can free failed ones... */
|
||||
wallet_payment_delete(cmd->ld->wallet, rhash);
|
||||
log_add(cmd->ld->log, "... retrying");
|
||||
}
|
||||
|
||||
@@ -234,41 +198,25 @@ static bool send_payment(struct command *cmd,
|
||||
sizeof(struct sha256), &path_secrets);
|
||||
onion = serialize_onionpacket(cmd, packet);
|
||||
|
||||
if (pc) {
|
||||
pc->ids = tal_free(pc->ids);
|
||||
} else {
|
||||
pc = tal(cmd->ld, struct pay_command);
|
||||
list_add_tail(&cmd->ld->pay_commands, &pc->list);
|
||||
tal_add_destructor(pc, pay_command_destroyed);
|
||||
/* We write this into db when HTLC is actually sent. */
|
||||
payment = tal(tmpctx, struct wallet_payment);
|
||||
payment->id = 0;
|
||||
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;
|
||||
payment->payment_preimage = NULL;
|
||||
payment->path_secrets = tal_steal(payment, path_secrets);
|
||||
|
||||
payment = tal(tmpctx, struct wallet_payment);
|
||||
payment->id = 0;
|
||||
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;
|
||||
payment->payment_preimage = NULL;
|
||||
payment->path_secrets = tal_steal(payment, path_secrets);
|
||||
}
|
||||
pc->rhash = *rhash;
|
||||
pc->rval = NULL;
|
||||
pc->ids = tal_steal(pc, ids);
|
||||
pc->msatoshi = route[n_hops-1].amount;
|
||||
pc->out = NULL;
|
||||
|
||||
log_info(cmd->ld->log, "Sending %u over %zu hops to deliver %"PRIu64,
|
||||
route[0].amount, n_hops, pc->msatoshi);
|
||||
|
||||
/* They're both children of ld, but on shutdown make sure we
|
||||
* destroy the command before the pc, otherwise the
|
||||
* remove_cmd_from_pc destructor causes a use-after-free */
|
||||
tal_steal(pc, cmd);
|
||||
log_info(cmd->ld->log, "Sending %u over %zu hops to deliver %u",
|
||||
route[0].amount, n_hops, route[n_hops-1].amount);
|
||||
|
||||
/* Steals payment into hout */
|
||||
failcode = send_htlc_out(peer, route[0].amount,
|
||||
base_expiry + route[0].delay,
|
||||
rhash, onion, NULL, payment, pc, cmd,
|
||||
&pc->out);
|
||||
rhash, onion, NULL, payment, cmd,
|
||||
&hout);
|
||||
if (failcode) {
|
||||
command_fail(cmd, "first peer not ready: %s",
|
||||
onion_type_name(failcode));
|
||||
@@ -276,7 +224,7 @@ static bool send_payment(struct command *cmd,
|
||||
}
|
||||
|
||||
/* If we fail, remove cmd ptr from htlc_out. */
|
||||
tal_add_destructor2(cmd, remove_cmd_from_hout, pc->out);
|
||||
tal_add_destructor2(cmd, remove_cmd_from_hout, hout);
|
||||
|
||||
tal_free(tmpctx);
|
||||
return true;
|
||||
|
||||
@@ -373,7 +373,6 @@ enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv,
|
||||
const u8 *onion_routing_packet,
|
||||
struct htlc_in *in,
|
||||
struct wallet_payment *payment,
|
||||
struct pay_command *pc,
|
||||
struct command *cmd,
|
||||
struct htlc_out **houtp)
|
||||
{
|
||||
@@ -395,7 +394,7 @@ 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, cmd);
|
||||
payment, cmd);
|
||||
tal_add_destructor(hout, hout_subd_died);
|
||||
|
||||
msg = towire_channel_offer_htlc(out, amount, cltv, payment_hash,
|
||||
@@ -487,7 +486,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, NULL, NULL);
|
||||
next_onion, hin, NULL, NULL, NULL);
|
||||
if (!failcode)
|
||||
return;
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv,
|
||||
const u8 *onion_routing_packet,
|
||||
struct htlc_in *in,
|
||||
struct wallet_payment *payment,
|
||||
struct pay_command *pc,
|
||||
struct command *cmd,
|
||||
struct htlc_out **houtp);
|
||||
|
||||
|
||||
@@ -1056,7 +1056,6 @@ static bool wallet_stmt2htlc_out(const struct wallet_channel *channel,
|
||||
* htlcs, will wire using origin_htlc_id */
|
||||
out->in = NULL;
|
||||
|
||||
out->pay_command = NULL;
|
||||
out->payment = NULL;
|
||||
|
||||
return ok;
|
||||
|
||||
Reference in New Issue
Block a user