mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 23:24:27 +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");
|
return corrupt(hout, abortstr, "Both failed and succeeded");
|
||||||
else if (hout->cmd && hout->in)
|
else if (hout->cmd && hout->in)
|
||||||
return corrupt(hout, abortstr, "Both local and forwarded");
|
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);
|
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 struct sha256 *payment_hash,
|
||||||
const u8 *onion_routing_packet,
|
const u8 *onion_routing_packet,
|
||||||
struct htlc_in *in,
|
struct htlc_in *in,
|
||||||
struct pay_command *pc,
|
|
||||||
struct wallet_payment *payment,
|
struct wallet_payment *payment,
|
||||||
struct command *cmd)
|
struct command *cmd)
|
||||||
{
|
{
|
||||||
@@ -168,7 +164,6 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
|
|||||||
hout->preimage = NULL;
|
hout->preimage = NULL;
|
||||||
|
|
||||||
hout->in = in;
|
hout->in = in;
|
||||||
hout->pay_command = pc;
|
|
||||||
|
|
||||||
return htlc_out_check(hout, "new_htlc_out");
|
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 */
|
/* Otherwise, this MAY be non-null if there's a pay command waiting */
|
||||||
struct command *cmd;
|
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 */
|
/* Temporary payment store, so we can save everything in one go */
|
||||||
struct wallet_payment *payment;
|
struct wallet_payment *payment;
|
||||||
};
|
};
|
||||||
@@ -139,7 +136,6 @@ 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,
|
||||||
struct htlc_in *in,
|
struct htlc_in *in,
|
||||||
struct pay_command *pc,
|
|
||||||
struct wallet_payment *payment,
|
struct wallet_payment *payment,
|
||||||
struct command *cmd);
|
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->log = new_log(log_book, log_book, "lightningd(%u):", (int)getpid());
|
||||||
ld->alias = NULL;
|
ld->alias = NULL;
|
||||||
ld->rgb = NULL;
|
ld->rgb = NULL;
|
||||||
list_head_init(&ld->pay_commands);
|
|
||||||
list_head_init(&ld->connects);
|
list_head_init(&ld->connects);
|
||||||
ld->wireaddrs = tal_arr(ld, struct wireaddr, 0);
|
ld->wireaddrs = tal_arr(ld, struct wireaddr, 0);
|
||||||
ld->portnum = DEFAULT_PORT;
|
ld->portnum = DEFAULT_PORT;
|
||||||
|
|||||||
@@ -133,9 +133,6 @@ struct lightningd {
|
|||||||
/* Maintained by invoices.c */
|
/* Maintained by invoices.c */
|
||||||
struct invoices *invoices;
|
struct invoices *invoices;
|
||||||
|
|
||||||
/* Any outstanding "pay" commands. */
|
|
||||||
struct list_head pay_commands;
|
|
||||||
|
|
||||||
/* Transaction filter matching what we're interested in */
|
/* Transaction filter matching what we're interested in */
|
||||||
struct txfilter *owned_txfilter;
|
struct txfilter *owned_txfilter;
|
||||||
|
|
||||||
|
|||||||
114
lightningd/pay.c
114
lightningd/pay.c
@@ -17,18 +17,6 @@
|
|||||||
#include <lightningd/subd.h>
|
#include <lightningd/subd.h>
|
||||||
#include <sodium/randombytes.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)
|
static void json_pay_success(struct command *cmd, const struct preimage *rval)
|
||||||
{
|
{
|
||||||
struct json_result *response;
|
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,
|
void payment_succeeded(struct lightningd *ld, struct htlc_out *hout,
|
||||||
const struct preimage *rval)
|
const struct preimage *rval)
|
||||||
{
|
{
|
||||||
assert(!hout->pay_command->rval);
|
|
||||||
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
||||||
PAYMENT_COMPLETE, rval);
|
PAYMENT_COMPLETE, rval);
|
||||||
hout->pay_command->rval = tal_dup(hout->pay_command,
|
|
||||||
struct preimage, rval);
|
|
||||||
/* Can be NULL if JSON RPC goes away. */
|
/* Can be NULL if JSON RPC goes away. */
|
||||||
if (hout->cmd)
|
if (hout->cmd)
|
||||||
json_pay_success(hout->cmd, rval);
|
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,
|
void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
||||||
const char *localfail)
|
const char *localfail)
|
||||||
{
|
{
|
||||||
struct pay_command *pc = hout->pay_command;
|
|
||||||
struct onionreply *reply;
|
struct onionreply *reply;
|
||||||
enum onion_type failcode;
|
enum onion_type failcode;
|
||||||
struct secret *path_secrets;
|
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,
|
wallet_payment_set_status(ld->wallet, &hout->payment_hash,
|
||||||
PAYMENT_FAILED, NULL);
|
PAYMENT_FAILED, NULL);
|
||||||
pc->out = NULL;
|
|
||||||
|
|
||||||
/* This gives more details than a generic failure message */
|
/* This gives more details than a generic failure message */
|
||||||
if (localfail) {
|
if (localfail) {
|
||||||
@@ -95,7 +78,7 @@ void payment_failed(struct lightningd *ld, const struct htlc_out *hout,
|
|||||||
assert(!hout->failcode);
|
assert(!hout->failcode);
|
||||||
path_secrets = wallet_payment_get_secrets(tmpctx, ld->wallet,
|
path_secrets = wallet_payment_get_secrets(tmpctx, ld->wallet,
|
||||||
&hout->payment_hash);
|
&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);
|
hout->failuremsg);
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
log_info(hout->key.peer->log,
|
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;
|
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. */
|
/* Returns true if it's still pending. */
|
||||||
static bool send_payment(struct command *cmd,
|
static bool send_payment(struct command *cmd,
|
||||||
const struct sha256 *rhash,
|
const struct sha256 *rhash,
|
||||||
const struct route_hop *route)
|
const struct route_hop *route)
|
||||||
{
|
{
|
||||||
struct pay_command *pc;
|
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
const u8 *onion;
|
const u8 *onion;
|
||||||
u8 sessionkey[32];
|
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 hop_data *hop_data = tal_arr(tmpctx, struct hop_data, n_hops);
|
||||||
struct pubkey *ids = tal_arr(tmpctx, struct pubkey, n_hops);
|
struct pubkey *ids = tal_arr(tmpctx, struct pubkey, n_hops);
|
||||||
struct wallet_payment *payment = NULL;
|
struct wallet_payment *payment = NULL;
|
||||||
|
struct htlc_out *hout;
|
||||||
|
|
||||||
/* Expiry for HTLCs is absolute. And add one to give some margin. */
|
/* Expiry for HTLCs is absolute. And add one to give some margin. */
|
||||||
base_expiry = get_block_height(cmd->ld->topology) + 1;
|
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));
|
memset(&hop_data[i].channel_id, 0, sizeof(struct short_channel_id));
|
||||||
hop_data[i].amt_forward = route[i].amount;
|
hop_data[i].amt_forward = route[i].amount;
|
||||||
|
|
||||||
pc = find_pay_command(cmd->ld, rhash);
|
/* Now, do we already have a payment? */
|
||||||
if (pc) {
|
payment = wallet_payment_by_hash(tmpctx, cmd->ld->wallet, rhash);
|
||||||
|
if (payment) {
|
||||||
log_debug(cmd->ld->log, "json_sendpay: found previous");
|
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");
|
log_add(cmd->ld->log, "... still in progress");
|
||||||
command_fail(cmd, "still in progress");
|
command_fail(cmd, "still in progress");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pc->rval) {
|
if (payment->status == PAYMENT_COMPLETE) {
|
||||||
size_t old_nhops = tal_count(pc->ids);
|
|
||||||
log_add(cmd->ld->log, "... succeeded");
|
log_add(cmd->ld->log, "... succeeded");
|
||||||
/* Must match successful payment parameters. */
|
/* 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,
|
command_fail(cmd,
|
||||||
"already succeeded with amount %"
|
"already succeeded with amount %"
|
||||||
PRIu64, pc->msatoshi);
|
PRIu64, payment->msatoshi);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!structeq(&pc->ids[old_nhops-1], &ids[n_hops-1])) {
|
if (!structeq(&payment->destination, &ids[n_hops-1])) {
|
||||||
char *previd;
|
|
||||||
previd = pubkey_to_hexstr(cmd,
|
|
||||||
&pc->ids[old_nhops-1]);
|
|
||||||
command_fail(cmd,
|
command_fail(cmd,
|
||||||
"already succeeded to %s",
|
"already succeeded to %s",
|
||||||
previd);
|
type_to_string(cmd, struct pubkey,
|
||||||
|
&payment->destination));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
json_pay_success(cmd, pc->rval);
|
json_pay_success(cmd, payment->payment_preimage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* FIXME: We can free failed ones... */
|
wallet_payment_delete(cmd->ld->wallet, rhash);
|
||||||
log_add(cmd->ld->log, "... retrying");
|
log_add(cmd->ld->log, "... retrying");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,41 +198,25 @@ static bool send_payment(struct command *cmd,
|
|||||||
sizeof(struct sha256), &path_secrets);
|
sizeof(struct sha256), &path_secrets);
|
||||||
onion = serialize_onionpacket(cmd, packet);
|
onion = serialize_onionpacket(cmd, packet);
|
||||||
|
|
||||||
if (pc) {
|
/* We write this into db when HTLC is actually sent. */
|
||||||
pc->ids = tal_free(pc->ids);
|
payment = tal(tmpctx, struct wallet_payment);
|
||||||
} else {
|
payment->id = 0;
|
||||||
pc = tal(cmd->ld, struct pay_command);
|
payment->payment_hash = *rhash;
|
||||||
list_add_tail(&cmd->ld->pay_commands, &pc->list);
|
payment->destination = ids[n_hops - 1];
|
||||||
tal_add_destructor(pc, pay_command_destroyed);
|
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);
|
log_info(cmd->ld->log, "Sending %u over %zu hops to deliver %u",
|
||||||
payment->id = 0;
|
route[0].amount, n_hops, route[n_hops-1].amount);
|
||||||
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);
|
|
||||||
|
|
||||||
|
/* Steals payment into hout */
|
||||||
failcode = send_htlc_out(peer, route[0].amount,
|
failcode = send_htlc_out(peer, route[0].amount,
|
||||||
base_expiry + route[0].delay,
|
base_expiry + route[0].delay,
|
||||||
rhash, onion, NULL, payment, pc, cmd,
|
rhash, onion, NULL, payment, cmd,
|
||||||
&pc->out);
|
&hout);
|
||||||
if (failcode) {
|
if (failcode) {
|
||||||
command_fail(cmd, "first peer not ready: %s",
|
command_fail(cmd, "first peer not ready: %s",
|
||||||
onion_type_name(failcode));
|
onion_type_name(failcode));
|
||||||
@@ -276,7 +224,7 @@ static bool send_payment(struct command *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If we fail, remove cmd ptr from htlc_out. */
|
/* 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);
|
tal_free(tmpctx);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -373,7 +373,6 @@ enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv,
|
|||||||
const u8 *onion_routing_packet,
|
const u8 *onion_routing_packet,
|
||||||
struct htlc_in *in,
|
struct htlc_in *in,
|
||||||
struct wallet_payment *payment,
|
struct wallet_payment *payment,
|
||||||
struct pay_command *pc,
|
|
||||||
struct command *cmd,
|
struct command *cmd,
|
||||||
struct htlc_out **houtp)
|
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. */
|
/* 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,
|
payment_hash, onion_routing_packet, in,
|
||||||
pc, payment, cmd);
|
payment, cmd);
|
||||||
tal_add_destructor(hout, hout_subd_died);
|
tal_add_destructor(hout, hout_subd_died);
|
||||||
|
|
||||||
msg = towire_channel_offer_htlc(out, amount, cltv, payment_hash,
|
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,
|
failcode = send_htlc_out(next, amt_to_forward,
|
||||||
outgoing_cltv_value, &hin->payment_hash,
|
outgoing_cltv_value, &hin->payment_hash,
|
||||||
next_onion, hin, NULL, NULL, NULL, NULL);
|
next_onion, hin, NULL, NULL, NULL);
|
||||||
if (!failcode)
|
if (!failcode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ enum onion_type send_htlc_out(struct peer *out, u64 amount, u32 cltv,
|
|||||||
const u8 *onion_routing_packet,
|
const u8 *onion_routing_packet,
|
||||||
struct htlc_in *in,
|
struct htlc_in *in,
|
||||||
struct wallet_payment *payment,
|
struct wallet_payment *payment,
|
||||||
struct pay_command *pc,
|
|
||||||
struct command *cmd,
|
struct command *cmd,
|
||||||
struct htlc_out **houtp);
|
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 */
|
* htlcs, will wire using origin_htlc_id */
|
||||||
out->in = NULL;
|
out->in = NULL;
|
||||||
|
|
||||||
out->pay_command = NULL;
|
|
||||||
out->payment = NULL;
|
out->payment = NULL;
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
|||||||
Reference in New Issue
Block a user