mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-15 11:59:16 +01:00
renepay: merge struct renepay
and struct payment
into one.
There are a few fields in `struct renepay` which are genuinely transient, but it makes the code much harder to follow than simply having a single structure. More cleanups will follow, but this is the minimal set. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
6d7cd1e729
commit
3b8217bd72
7 changed files with 194 additions and 271 deletions
|
@ -32,9 +32,9 @@
|
|||
static struct pay_plugin the_pay_plugin;
|
||||
struct pay_plugin * const pay_plugin = &the_pay_plugin;
|
||||
|
||||
static void timer_kick(struct renepay * renepay);
|
||||
static void timer_kick(struct payment *payment);
|
||||
static struct command_result *try_paying(struct command *cmd,
|
||||
struct renepay * renepay,
|
||||
struct payment *payment,
|
||||
bool first_time);
|
||||
|
||||
void amount_msat_accumulate_(struct amount_msat *dst,
|
||||
|
@ -126,56 +126,54 @@ static const char *init(struct plugin *p,
|
|||
}
|
||||
|
||||
|
||||
static void renepay_settimer(struct renepay * renepay)
|
||||
static void payment_settimer(struct payment *payment)
|
||||
{
|
||||
renepay->rexmit_timer = tal_free(renepay->rexmit_timer);
|
||||
renepay->rexmit_timer = plugin_timer(
|
||||
payment->rexmit_timer = tal_free(payment->rexmit_timer);
|
||||
payment->rexmit_timer = plugin_timer(
|
||||
pay_plugin->plugin,
|
||||
time_from_msec(TIMER_COLLECT_FAILURES_MSEC),
|
||||
timer_kick, renepay);
|
||||
timer_kick, payment);
|
||||
}
|
||||
|
||||
/* Happens when timer goes off, but also works to arm timer if nothing to do */
|
||||
static void timer_kick(struct renepay * renepay)
|
||||
static void timer_kick(struct payment *payment)
|
||||
{
|
||||
struct payment * const p = renepay->payment;
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
|
||||
switch(p->status)
|
||||
switch (payment->status)
|
||||
{
|
||||
/* Some flows succeeded, we finish the payment. */
|
||||
case PAYMENT_SUCCESS:
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"status is PAYMENT_SUCCESS");
|
||||
renepay_success(renepay);
|
||||
payment_success(payment);
|
||||
break;
|
||||
|
||||
/* Some flows failed, we retry. */
|
||||
case PAYMENT_FAIL:
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"status is PAYMENT_FAIL");
|
||||
payment_assert_delivering_incomplete(p);
|
||||
try_paying(renepay->cmd,renepay,/* always try even if prob is low */ true);
|
||||
payment_assert_delivering_incomplete(payment);
|
||||
try_paying(payment->cmd,payment,/* always try even if prob is low */ true);
|
||||
break;
|
||||
|
||||
/* Nothing has returned yet, we have to wait. */
|
||||
case PAYMENT_PENDING:
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"status is PAYMENT_PENDING");
|
||||
payment_assert_delivering_all(p);
|
||||
renepay_settimer(renepay);
|
||||
payment_assert_delivering_all(payment);
|
||||
payment_settimer(payment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sometimes we don't know exactly who to blame... */
|
||||
static struct command_result *handle_unhandleable_error(struct renepay * renepay,
|
||||
static struct command_result *handle_unhandleable_error(struct payment *payment,
|
||||
struct pay_flow *flow,
|
||||
const char *what)
|
||||
{
|
||||
struct payment * const p = renepay->payment;
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
size_t n = tal_count(flow);
|
||||
|
||||
/* We got a mangled reply. We don't know who to penalize! */
|
||||
debug_paynote(p, "%s on route %s", what, flow_path_to_str(tmpctx, flow));
|
||||
debug_paynote(payment, "%s on route %s", what, flow_path_to_str(tmpctx, flow));
|
||||
|
||||
// TODO(eduardo): does LOG_BROKEN finish the plugin execution?
|
||||
plugin_log(pay_plugin->plugin, LOG_BROKEN,
|
||||
|
@ -185,7 +183,7 @@ static struct command_result *handle_unhandleable_error(struct renepay * renepay
|
|||
if (n == 1)
|
||||
{
|
||||
payflow_fail(flow);
|
||||
return renepay_fail(renepay, PAY_UNPARSEABLE_ONION,
|
||||
return payment_fail(payment, PAY_UNPARSEABLE_ONION,
|
||||
"Got %s from the destination", what);
|
||||
}
|
||||
/* FIXME: check chan_extra_map, since we might have succeeded though
|
||||
|
@ -199,8 +197,8 @@ static struct command_result *handle_unhandleable_error(struct renepay * renepay
|
|||
/* Assume it's not the destination */
|
||||
n = pseudorand(n-1);
|
||||
|
||||
tal_arr_expand(&renepay->disabled, flow->path_scids[n]);
|
||||
debug_paynote(p, "... eliminated %s",
|
||||
tal_arr_expand(&payment->disabled, flow->path_scids[n]);
|
||||
debug_paynote(payment, "... eliminated %s",
|
||||
type_to_string(tmpctx, struct short_channel_id,
|
||||
&flow->path_scids[n]));
|
||||
return NULL;
|
||||
|
@ -219,13 +217,13 @@ static struct command_result *addgossip_done(struct command *cmd,
|
|||
struct addgossip *adg)
|
||||
{
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
struct renepay * renepay = adg->flow->payment->renepay;
|
||||
struct payment * payment = adg->flow->payment;
|
||||
|
||||
/* Release this: if it's the last flow we'll retry immediately */
|
||||
|
||||
payflow_fail(adg->flow);
|
||||
tal_free(adg);
|
||||
renepay_settimer(renepay);
|
||||
payment_settimer(payment);
|
||||
|
||||
return command_still_pending(cmd);
|
||||
}
|
||||
|
@ -236,14 +234,13 @@ static struct command_result *addgossip_failure(struct command *cmd,
|
|||
struct addgossip *adg)
|
||||
|
||||
{
|
||||
struct payment * payment = adg->flow->payment;
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
struct payment * p = adg->flow->payment;
|
||||
struct renepay * renepay = p->renepay;
|
||||
|
||||
debug_paynote(p, "addgossip failed, removing channel %s (%.*s)",
|
||||
debug_paynote(payment, "addgossip failed, removing channel %s (%.*s)",
|
||||
type_to_string(tmpctx, struct short_channel_id, &adg->scid),
|
||||
err->end - err->start, buf + err->start);
|
||||
tal_arr_expand(&renepay->disabled, adg->scid);
|
||||
tal_arr_expand(&payment->disabled, adg->scid);
|
||||
|
||||
return addgossip_done(cmd, buf, err, adg);
|
||||
}
|
||||
|
@ -254,8 +251,7 @@ static struct command_result *submit_update(struct command *cmd,
|
|||
struct short_channel_id errscid)
|
||||
{
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
struct payment * p = flow->payment;
|
||||
struct renepay * renepay = p->renepay;
|
||||
struct payment *payment = flow->payment;
|
||||
struct out_req *req;
|
||||
struct addgossip *adg = tal(cmd, struct addgossip);
|
||||
|
||||
|
@ -264,10 +260,9 @@ static struct command_result *submit_update(struct command *cmd,
|
|||
adg->scid = errscid;
|
||||
adg->flow = flow;
|
||||
/* Disable re-xmit until this returns */
|
||||
renepay->rexmit_timer
|
||||
= tal_free(renepay->rexmit_timer);
|
||||
payment->rexmit_timer = tal_free(payment->rexmit_timer);
|
||||
|
||||
debug_paynote(p, "... extracted channel_update, telling gossipd");
|
||||
debug_paynote(payment, "... extracted channel_update, telling gossipd");
|
||||
plugin_log(pay_plugin->plugin, LOG_DBG, "(update = %s)", tal_hex(tmpctx, update));
|
||||
|
||||
req = jsonrpc_request_start(pay_plugin->plugin, NULL, "addgossip",
|
||||
|
@ -357,13 +352,12 @@ static struct command_result *flow_sendpay_failed(struct command *cmd,
|
|||
{
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
|
||||
struct payment *p = flow->payment;
|
||||
debug_assert(p);
|
||||
struct renepay * renepay = p->renepay;
|
||||
debug_assert(renepay);
|
||||
struct payment *payment = flow->payment;
|
||||
debug_assert(payment);
|
||||
|
||||
/* This is a fail. */
|
||||
payment_fail(p);
|
||||
if (payment->status != PAYMENT_SUCCESS)
|
||||
payment->status=PAYMENT_FAIL;
|
||||
|
||||
u64 errcode;
|
||||
const jsmntok_t *msg = json_get_member(buf, err, "message");
|
||||
|
@ -376,13 +370,13 @@ static struct command_result *flow_sendpay_failed(struct command *cmd,
|
|||
plugin_err(cmd->plugin, "Strange error from sendpay: %.*s",
|
||||
json_tok_full_len(err), json_tok_full(buf, err));
|
||||
|
||||
debug_paynote(p,
|
||||
debug_paynote(payment,
|
||||
"sendpay didn't like first hop, eliminated: %.*s",
|
||||
msg->end - msg->start, buf + msg->start);
|
||||
|
||||
/* There is no new knowledge from this kind of failure.
|
||||
* We just disable this scid. */
|
||||
tal_arr_expand(&renepay->disabled, flow->path_scids[0]);
|
||||
tal_arr_expand(&payment->disabled, flow->path_scids[0]);
|
||||
|
||||
payflow_fail(flow);
|
||||
return command_still_pending(cmd);
|
||||
|
@ -391,11 +385,9 @@ static struct command_result *flow_sendpay_failed(struct command *cmd,
|
|||
|
||||
static struct command_result *
|
||||
sendpay_flows(struct command *cmd,
|
||||
struct renepay * renepay,
|
||||
struct payment *p,
|
||||
struct pay_flow **flows STEALS)
|
||||
{
|
||||
struct payment * const p = renepay->payment;
|
||||
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
debug_paynote(p, "Sending out batch of %zu payments", tal_count(flows));
|
||||
|
||||
|
@ -476,44 +468,43 @@ sendpay_flows(struct command *cmd,
|
|||
tal_free(flows);
|
||||
|
||||
/* Get ready to process replies */
|
||||
renepay_settimer(renepay);
|
||||
payment_settimer(p);
|
||||
|
||||
return command_still_pending(cmd);
|
||||
}
|
||||
|
||||
static struct command_result *try_paying(struct command *cmd,
|
||||
struct renepay *renepay,
|
||||
struct payment *payment,
|
||||
bool first_time)
|
||||
{
|
||||
struct payment * const p = renepay->payment;
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
|
||||
struct amount_msat feebudget, fees_spent, remaining;
|
||||
|
||||
renepay->payment->status=PAYMENT_PENDING;
|
||||
if (time_after(time_now(), p->stop_time))
|
||||
return renepay_fail(renepay, PAY_STOPPED_RETRYING, "Timed out");
|
||||
payment->status = PAYMENT_PENDING;
|
||||
if (time_after(time_now(), payment->stop_time))
|
||||
return payment_fail(payment, PAY_STOPPED_RETRYING, "Timed out");
|
||||
|
||||
/* Total feebudget */
|
||||
if (!amount_msat_sub(&feebudget, p->maxspend, p->amount))
|
||||
if (!amount_msat_sub(&feebudget, payment->maxspend, payment->amount))
|
||||
{
|
||||
plugin_err(pay_plugin->plugin,
|
||||
"%s (line %d) could not substract maxspend=%s and amount=%s.",
|
||||
__PRETTY_FUNCTION__,
|
||||
__LINE__,
|
||||
type_to_string(tmpctx, struct amount_msat, &p->maxspend),
|
||||
type_to_string(tmpctx, struct amount_msat, &p->amount));
|
||||
type_to_string(tmpctx, struct amount_msat, &payment->maxspend),
|
||||
type_to_string(tmpctx, struct amount_msat, &payment->amount));
|
||||
}
|
||||
|
||||
/* Fees spent so far */
|
||||
if (!amount_msat_sub(&fees_spent, p->total_sent, p->total_delivering))
|
||||
if (!amount_msat_sub(&fees_spent, payment->total_sent, payment->total_delivering))
|
||||
{
|
||||
plugin_err(pay_plugin->plugin,
|
||||
"%s (line %d) could not substract total_sent=%s and total_delivering=%s.",
|
||||
__PRETTY_FUNCTION__,
|
||||
__LINE__,
|
||||
type_to_string(tmpctx, struct amount_msat, &p->total_sent),
|
||||
type_to_string(tmpctx, struct amount_msat, &p->total_delivering));
|
||||
type_to_string(tmpctx, struct amount_msat, &payment->total_sent),
|
||||
type_to_string(tmpctx, struct amount_msat, &payment->total_delivering));
|
||||
}
|
||||
|
||||
/* Remaining fee budget. */
|
||||
|
@ -528,14 +519,14 @@ static struct command_result *try_paying(struct command *cmd,
|
|||
}
|
||||
|
||||
/* How much are we still trying to send? */
|
||||
if (!amount_msat_sub(&remaining, p->amount, p->total_delivering))
|
||||
if (!amount_msat_sub(&remaining, payment->amount, payment->total_delivering))
|
||||
{
|
||||
plugin_err(pay_plugin->plugin,
|
||||
"%s (line %d) could not substract amount=%s and total_delivering=%s.",
|
||||
__PRETTY_FUNCTION__,
|
||||
__LINE__,
|
||||
type_to_string(tmpctx, struct amount_msat, &p->amount),
|
||||
type_to_string(tmpctx, struct amount_msat, &p->total_delivering));
|
||||
type_to_string(tmpctx, struct amount_msat, &payment->amount),
|
||||
type_to_string(tmpctx, struct amount_msat, &payment->total_delivering));
|
||||
}
|
||||
|
||||
// plugin_log(pay_plugin->plugin,LOG_DBG,fmt_chan_extra_map(tmpctx,pay_plugin->chan_extra_map));
|
||||
|
@ -544,9 +535,9 @@ static struct command_result *try_paying(struct command *cmd,
|
|||
|
||||
/* We let this return an unlikely path, as it's better to try once
|
||||
* than simply refuse. Plus, models are not truth! */
|
||||
gossmap_apply_localmods(pay_plugin->gossmap, renepay->local_gossmods);
|
||||
gossmap_apply_localmods(pay_plugin->gossmap, payment->local_gossmods);
|
||||
struct pay_flow **pay_flows = get_payflows(
|
||||
renepay,
|
||||
payment,
|
||||
remaining, feebudget,
|
||||
|
||||
/* would you accept unlikely
|
||||
|
@ -554,46 +545,59 @@ static struct command_result *try_paying(struct command *cmd,
|
|||
true,
|
||||
|
||||
/* is entire payment? */
|
||||
amount_msat_eq(p->total_delivering, AMOUNT_MSAT(0)),
|
||||
amount_msat_eq(payment->total_delivering, AMOUNT_MSAT(0)),
|
||||
|
||||
&err_msg);
|
||||
gossmap_remove_localmods(pay_plugin->gossmap, renepay->local_gossmods);
|
||||
gossmap_remove_localmods(pay_plugin->gossmap, payment->local_gossmods);
|
||||
|
||||
// plugin_log(pay_plugin->plugin,LOG_DBG,"get_payflows produced %s",fmt_payflows(tmpctx,pay_flows));
|
||||
|
||||
/* MCF cannot find a feasible route, we stop. */
|
||||
if (!pay_flows)
|
||||
{
|
||||
return renepay_fail(renepay, PAY_ROUTE_NOT_FOUND,
|
||||
return payment_fail(payment, PAY_ROUTE_NOT_FOUND,
|
||||
"Failed to find a route, %s",
|
||||
err_msg);
|
||||
}
|
||||
/* Now begin making payments */
|
||||
|
||||
return sendpay_flows(cmd, renepay, pay_flows);
|
||||
return sendpay_flows(cmd, payment, pay_flows);
|
||||
}
|
||||
|
||||
static void destroy_cmd_payment_ptr(struct command *cmd,
|
||||
struct payment *payment)
|
||||
{
|
||||
assert(payment->cmd == cmd);
|
||||
payment->cmd = NULL;
|
||||
}
|
||||
|
||||
static struct command_result *listpeerchannels_done(
|
||||
struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct renepay *renepay)
|
||||
struct payment *payment)
|
||||
{
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__);
|
||||
if (!uncertainty_network_update_from_listpeerchannels(
|
||||
pay_plugin->chan_extra_map,
|
||||
pay_plugin->my_id,
|
||||
renepay,
|
||||
payment,
|
||||
buf,
|
||||
result))
|
||||
return renepay_fail(renepay,LIGHTNINGD,
|
||||
return command_fail(cmd, LIGHTNINGD,
|
||||
"listpeerchannels malformed: %.*s",
|
||||
json_tok_full_len(result),
|
||||
json_tok_full(buf, result));
|
||||
// TODO(eduardo): check that there won't be a prob. cost associated with
|
||||
// any gossmap local chan. The same way there aren't fees to pay for my
|
||||
// local channels.
|
||||
return try_paying(cmd, renepay, true);
|
||||
|
||||
/* From now on, we keep a record of the payment, so persist it beyond this cmd. */
|
||||
tal_steal(pay_plugin->plugin, payment);
|
||||
/* When we terminate cmd for any reason, clear it from payment so we don't do it again. */
|
||||
tal_add_destructor2(cmd, destroy_cmd_payment_ptr, payment);
|
||||
|
||||
return try_paying(cmd, payment, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -685,10 +689,9 @@ payment_listsendpays_previous(
|
|||
struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct renepay * renepay)
|
||||
struct payment * payment)
|
||||
{
|
||||
debug_info("calling %s",__PRETTY_FUNCTION__);
|
||||
struct payment * p = renepay->payment;
|
||||
|
||||
size_t i;
|
||||
const jsmntok_t *t, *arr, *err;
|
||||
|
@ -841,25 +844,23 @@ payment_listsendpays_previous(
|
|||
json_add_string(ret, "status", "complete");
|
||||
json_add_amount_msat(ret, "amount_msat", complete_msat);
|
||||
json_add_amount_msat(ret, "amount_sent_msat",complete_sent);
|
||||
json_add_node_id(ret, "destination", &p->destination);
|
||||
json_add_sha256(ret, "payment_hash", &p->payment_hash);
|
||||
json_add_node_id(ret, "destination", &payment->destination);
|
||||
json_add_sha256(ret, "payment_hash", &payment->payment_hash);
|
||||
json_add_u32(ret, "created_at", complete_created_at);
|
||||
json_add_num(ret, "parts", complete_parts);
|
||||
|
||||
/* This payment was already completed, we don't keep record of
|
||||
* it twice. */
|
||||
renepay->payment = tal_free(renepay->payment);
|
||||
|
||||
* it twice: payment will be freed with cmd */
|
||||
return command_finished(cmd, ret);
|
||||
} else if (pending) {
|
||||
assert(last_pending_group_id!=INVALID_ID);
|
||||
assert(first_pending_group_id!=INVALID_ID);
|
||||
|
||||
p->groupid = last_pending_group_id;
|
||||
renepay->next_partid = last_pending_partid+1;
|
||||
payment->groupid = last_pending_group_id;
|
||||
payment->next_partid = last_pending_partid+1;
|
||||
|
||||
p->total_sent = pending_sent;
|
||||
p->total_delivering = pending_msat;
|
||||
payment->total_sent = pending_sent;
|
||||
payment->total_delivering = pending_msat;
|
||||
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,
|
||||
"There are pending sendpays to this invoice. "
|
||||
|
@ -867,31 +868,29 @@ payment_listsendpays_previous(
|
|||
"delivering = %s, "
|
||||
"last_partid = %"PRIu64,
|
||||
last_pending_group_id,
|
||||
type_to_string(tmpctx,struct amount_msat,&p->total_delivering),
|
||||
type_to_string(tmpctx,struct amount_msat,&payment->total_delivering),
|
||||
last_pending_partid);
|
||||
|
||||
if( first_pending_group_id != last_pending_group_id)
|
||||
{
|
||||
/* At least two pending groups for the same invoice,
|
||||
* this is weird, we better stop. */
|
||||
renepay->payment = tal_free(renepay->payment);
|
||||
return renepay_fail(renepay, PAY_IN_PROGRESS,
|
||||
return command_fail(cmd, PAY_IN_PROGRESS,
|
||||
"Payment is pending by some other request.");
|
||||
}
|
||||
if(amount_msat_greater_eq(p->total_delivering,p->amount))
|
||||
if(amount_msat_greater_eq(payment->total_delivering,payment->amount))
|
||||
{
|
||||
/* Pending payment already pays the full amount, we
|
||||
* better stop. */
|
||||
renepay->payment = tal_free(renepay->payment);
|
||||
return renepay_fail(renepay, PAY_IN_PROGRESS,
|
||||
return command_fail(cmd, PAY_IN_PROGRESS,
|
||||
"Payment is pending with full amount already commited");
|
||||
}
|
||||
}else
|
||||
{
|
||||
/* There are no pending nor completed sendpays, get me the last
|
||||
* sendpay group. */
|
||||
p->groupid = (last_group==INVALID_ID ? 1 : (last_group+1)) ;
|
||||
renepay->next_partid=1;
|
||||
payment->groupid = (last_group==INVALID_ID ? 1 : (last_group+1)) ;
|
||||
payment->next_partid=1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -899,7 +898,7 @@ payment_listsendpays_previous(
|
|||
/* Get local capacities... */
|
||||
req = jsonrpc_request_start(cmd->plugin, cmd, "listpeerchannels",
|
||||
listpeerchannels_done,
|
||||
listpeerchannels_done, renepay);
|
||||
listpeerchannels_done, payment);
|
||||
return send_outreq(cmd->plugin, req);
|
||||
}
|
||||
|
||||
|
@ -1117,9 +1116,12 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
*use_shadow = 1;
|
||||
#endif
|
||||
|
||||
/* renepay is bound to the command, if the command finishes renepay is
|
||||
* freed. */
|
||||
struct renepay * renepay = renepay_new(cmd,
|
||||
/* Payment is allocated off cmd to start, in case we fail cmd
|
||||
* (e.g. already in progress, already succeeded). Once it's
|
||||
* actually started, it persists beyond the command, so we
|
||||
* tal_steal. */
|
||||
struct payment *payment = payment_new(cmd,
|
||||
cmd,
|
||||
take(invstr),
|
||||
take(label),
|
||||
take(description),
|
||||
|
@ -1138,14 +1140,10 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
*riskfactor_millionths,
|
||||
*min_prob_success_millionths,
|
||||
use_shadow);
|
||||
tal_add_destructor2(renepay,
|
||||
renepay_cleanup,
|
||||
pay_plugin->gossmap);
|
||||
|
||||
/* We inmediately add this payment to the payment list. */
|
||||
tal_steal(pay_plugin->ctx, renepay->payment);
|
||||
list_add_tail(&pay_plugin->payments, &renepay->payment->list);
|
||||
tal_add_destructor(renepay->payment, destroy_payment);
|
||||
/* We immediately add this payment to the payment list. */
|
||||
list_add_tail(&pay_plugin->payments, &payment->list);
|
||||
tal_add_destructor(payment, destroy_payment);
|
||||
|
||||
plugin_log(pay_plugin->plugin,LOG_DBG,"Starting renepay");
|
||||
bool gossmap_changed = gossmap_refresh(pay_plugin->gossmap, NULL);
|
||||
|
@ -1191,7 +1189,7 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
// TODO(eduardo): are there route hints for B12?
|
||||
// Add any extra hidden channel revealed by the routehints to the uncertainty network.
|
||||
if(invstr_is_b11)
|
||||
uncertainty_network_add_routehints(pay_plugin->chan_extra_map,renepay);
|
||||
uncertainty_network_add_routehints(pay_plugin->chan_extra_map, payment);
|
||||
|
||||
if(!uncertainty_network_check_invariants(pay_plugin->chan_extra_map))
|
||||
plugin_log(pay_plugin->plugin,
|
||||
|
@ -1203,9 +1201,9 @@ static struct command_result *json_pay(struct command *cmd,
|
|||
struct out_req *req
|
||||
= jsonrpc_request_start(cmd->plugin, cmd, "listsendpays",
|
||||
payment_listsendpays_previous,
|
||||
payment_listsendpays_previous, renepay);
|
||||
payment_listsendpays_previous, payment);
|
||||
|
||||
json_add_sha256(req->js, "payment_hash", &renepay->payment->payment_hash);
|
||||
json_add_sha256(req->js, "payment_hash", &payment->payment_hash);
|
||||
return send_outreq(cmd->plugin, req);
|
||||
}
|
||||
|
||||
|
@ -1213,12 +1211,10 @@ static void handle_sendpay_failure_renepay(
|
|||
struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *result,
|
||||
struct renepay *renepay,
|
||||
struct payment *p,
|
||||
struct pay_flow *flow)
|
||||
{
|
||||
debug_assert(renepay);
|
||||
debug_assert(flow);
|
||||
struct payment *p = renepay->payment;
|
||||
debug_assert(p);
|
||||
|
||||
u64 errcode;
|
||||
|
@ -1249,11 +1245,11 @@ static void handle_sendpay_failure_renepay(
|
|||
case PAY_TRY_OTHER_ROUTE:
|
||||
break;
|
||||
case PAY_DESTINATION_PERM_FAIL:
|
||||
renepay_fail(renepay,errcode,
|
||||
payment_fail(p, errcode,
|
||||
"Got a final failure from destination");
|
||||
return;
|
||||
default:
|
||||
renepay_fail(renepay,errcode,
|
||||
payment_fail(p, errcode,
|
||||
"Unexpected errocode from sendpay_failure: %.*s",
|
||||
json_tok_full_len(result),
|
||||
json_tok_full(buf,result));
|
||||
|
@ -1315,7 +1311,7 @@ static void handle_sendpay_failure_renepay(
|
|||
{
|
||||
// TODO(eduardo): I wonder which error code should I show the
|
||||
// user in this case?
|
||||
renepay_fail(renepay,LIGHTNINGD,
|
||||
payment_fail(p,LIGHTNINGD,
|
||||
"Failed to get failcode from sendpay_failure notification"
|
||||
", received json: %.*s",
|
||||
json_tok_full_len(result),
|
||||
|
@ -1355,7 +1351,7 @@ static void handle_sendpay_failure_renepay(
|
|||
case WIRE_EXPIRY_TOO_FAR:
|
||||
debug_paynote(p, "we're removing scid %s",
|
||||
type_to_string(tmpctx,struct short_channel_id,&errscid));
|
||||
tal_arr_expand(&renepay->disabled, errscid);
|
||||
tal_arr_expand(&p->disabled, errscid);
|
||||
return;
|
||||
|
||||
/* These can be fixed (maybe) by applying the included channel_update */
|
||||
|
@ -1375,7 +1371,7 @@ static void handle_sendpay_failure_renepay(
|
|||
|
||||
debug_paynote(p, "missing an update, so we're removing scid %s",
|
||||
type_to_string(tmpctx,struct short_channel_id,&errscid));
|
||||
tal_arr_expand(&renepay->disabled, errscid);
|
||||
tal_arr_expand(&p->disabled, errscid);
|
||||
return;
|
||||
|
||||
case WIRE_TEMPORARY_CHANNEL_FAILURE:
|
||||
|
@ -1387,7 +1383,7 @@ static void handle_sendpay_failure_renepay(
|
|||
case WIRE_FINAL_INCORRECT_CLTV_EXPIRY:
|
||||
case WIRE_FINAL_INCORRECT_HTLC_AMOUNT:
|
||||
debug_paynote(p,"final destination failure");
|
||||
renepay_fail(renepay,errcode,
|
||||
payment_fail(p,errcode,
|
||||
"Destination said %s: %s",
|
||||
onion_wire_name(onionerr),
|
||||
message);
|
||||
|
@ -1400,7 +1396,7 @@ static void handle_sendpay_failure_renepay(
|
|||
{
|
||||
debug_paynote(p,"unkown onion error code %u, fatal",
|
||||
onionerr);
|
||||
renepay_fail(renepay,errcode,
|
||||
payment_fail(p,errcode,
|
||||
"Destination gave unknown error code %u: %s",
|
||||
onionerr,message);
|
||||
return;
|
||||
|
@ -1409,12 +1405,12 @@ static void handle_sendpay_failure_renepay(
|
|||
debug_paynote(p,"unkown onion error code %u, removing scid %s",
|
||||
onionerr,
|
||||
type_to_string(tmpctx,struct short_channel_id,&errscid));
|
||||
tal_arr_expand(&renepay->disabled, errscid);
|
||||
tal_arr_expand(&p->disabled, errscid);
|
||||
return;
|
||||
}
|
||||
unhandleable:
|
||||
// TODO(eduardo): check
|
||||
handle_unhandleable_error(renepay, flow, "");
|
||||
handle_unhandleable_error(p, flow, "");
|
||||
}
|
||||
|
||||
static void handle_sendpay_failure_flow(
|
||||
|
@ -1428,7 +1424,8 @@ static void handle_sendpay_failure_flow(
|
|||
debug_assert(flow);
|
||||
|
||||
struct payment * const p = flow->payment;
|
||||
payment_fail(p);
|
||||
if (p->status != PAYMENT_SUCCESS)
|
||||
p->status=PAYMENT_FAIL;
|
||||
|
||||
u64 errcode;
|
||||
if (!json_to_u64(buf, json_get_member(buf, result, "code"), &errcode))
|
||||
|
@ -1620,8 +1617,7 @@ static struct command_result *notification_sendpay_success(
|
|||
// 3. mark as success
|
||||
struct payment * const p = flow->payment;
|
||||
debug_assert(p);
|
||||
|
||||
payment_success(p);
|
||||
p->status = PAYMENT_SUCCESS;
|
||||
|
||||
const jsmntok_t *preimagetok
|
||||
= json_get_member(buf, resulttok, "payment_preimage");
|
||||
|
@ -1633,6 +1629,8 @@ static struct command_result *notification_sendpay_success(
|
|||
json_tok_full_len(params),
|
||||
json_tok_full(buf,params));
|
||||
|
||||
/* We could have preimage from previous part */
|
||||
tal_free(p->preimage);
|
||||
p->preimage = tal_dup_or_null(p,struct preimage,&preimage);
|
||||
|
||||
// 4. update information and release pending HTLCs
|
||||
|
@ -1706,10 +1704,7 @@ static struct command_result *notification_sendpay_failure(
|
|||
handle_sendpay_failure_flow(cmd,buf,resulttok,flow);
|
||||
|
||||
// there is possibly a pending renepay command for this flow
|
||||
struct renepay * const renepay = flow->payment->renepay;
|
||||
|
||||
if(renepay)
|
||||
handle_sendpay_failure_renepay(cmd,buf,resulttok,renepay,flow);
|
||||
handle_sendpay_failure_renepay(cmd,buf,resulttok,flow->payment,flow);
|
||||
|
||||
done:
|
||||
if(flow) payflow_fail(flow);
|
||||
|
|
|
@ -137,11 +137,10 @@ static u64 flow_delay(const struct flow *flow)
|
|||
/* This enhances f->amounts, and returns per-flow cltvs */
|
||||
static u32 *shadow_additions(const tal_t *ctx,
|
||||
const struct gossmap *gossmap,
|
||||
struct renepay *renepay,
|
||||
struct payment *p,
|
||||
struct flow **flows,
|
||||
bool is_entire_payment)
|
||||
{
|
||||
struct payment * p = renepay->payment;
|
||||
u32 *final_cltvs;
|
||||
|
||||
/* Set these up now in case we decide to do nothing */
|
||||
|
@ -279,12 +278,11 @@ static u64 flows_worst_delay(struct flow **flows)
|
|||
}
|
||||
|
||||
/* FIXME: If only path has channels marked disabled, we should try... */
|
||||
static bool disable_htlc_violations_oneflow(struct renepay * renepay,
|
||||
static bool disable_htlc_violations_oneflow(struct payment *p,
|
||||
const struct flow *flow,
|
||||
const struct gossmap *gossmap,
|
||||
bitmap *disabled)
|
||||
{
|
||||
struct payment * p = renepay->payment;
|
||||
bool disabled_some = false;
|
||||
|
||||
for (size_t i = 0; i < tal_count(flow->path); i++) {
|
||||
|
@ -307,7 +305,7 @@ static bool disable_htlc_violations_oneflow(struct renepay * renepay,
|
|||
reason);
|
||||
|
||||
/* Add this for future searches for this payment. */
|
||||
tal_arr_expand(&renepay->disabled, scid);
|
||||
tal_arr_expand(&p->disabled, scid);
|
||||
/* Add to existing bitmap */
|
||||
bitmap_set_bit(disabled,
|
||||
gossmap_chan_idx(gossmap, flow->path[i]));
|
||||
|
@ -318,7 +316,7 @@ static bool disable_htlc_violations_oneflow(struct renepay * renepay,
|
|||
|
||||
/* If we can't use one of these flows because we hit limits, we disable that
|
||||
* channel for future searches and return false */
|
||||
static bool disable_htlc_violations(struct renepay *renepay,
|
||||
static bool disable_htlc_violations(struct payment *payment,
|
||||
struct flow **flows,
|
||||
const struct gossmap *gossmap,
|
||||
bitmap *disabled)
|
||||
|
@ -327,7 +325,7 @@ static bool disable_htlc_violations(struct renepay *renepay,
|
|||
|
||||
/* We continue through all of them, to disable many at once. */
|
||||
for (size_t i = 0; i < tal_count(flows); i++) {
|
||||
disabled_some |= disable_htlc_violations_oneflow(renepay, flows[i],
|
||||
disabled_some |= disable_htlc_violations_oneflow(payment, flows[i],
|
||||
gossmap,
|
||||
disabled);
|
||||
}
|
||||
|
@ -335,7 +333,7 @@ static bool disable_htlc_violations(struct renepay *renepay,
|
|||
}
|
||||
|
||||
/* Get some payment flows to get this amount to destination, or NULL. */
|
||||
struct pay_flow **get_payflows(struct renepay * renepay,
|
||||
struct pay_flow **get_payflows(struct payment *p,
|
||||
struct amount_msat amount,
|
||||
struct amount_msat feebudget,
|
||||
bool unlikely_ok,
|
||||
|
@ -344,12 +342,11 @@ struct pay_flow **get_payflows(struct renepay * renepay,
|
|||
{
|
||||
*err_msg = tal_fmt(tmpctx,"[no error]");
|
||||
|
||||
struct payment * p = renepay->payment;
|
||||
bitmap *disabled;
|
||||
struct pay_flow **pay_flows;
|
||||
const struct gossmap_node *src, *dst;
|
||||
|
||||
disabled = make_disabled_bitmap(tmpctx, pay_plugin->gossmap, renepay->disabled);
|
||||
disabled = make_disabled_bitmap(tmpctx, pay_plugin->gossmap, p->disabled);
|
||||
src = gossmap_find_node(pay_plugin->gossmap, &pay_plugin->my_id);
|
||||
if (!src) {
|
||||
debug_paynote(p, "We don't have any channels?");
|
||||
|
@ -453,7 +450,7 @@ struct pay_flow **get_payflows(struct renepay * renepay,
|
|||
* to do this inside minflow(), but the diagnostics here
|
||||
* are far better, since we can report min/max which
|
||||
* *actually* made us reconsider. */
|
||||
if (disable_htlc_violations(renepay, flows, pay_plugin->gossmap,
|
||||
if (disable_htlc_violations(p, flows, pay_plugin->gossmap,
|
||||
disabled))
|
||||
{
|
||||
continue; // retry
|
||||
|
@ -462,12 +459,12 @@ struct pay_flow **get_payflows(struct renepay * renepay,
|
|||
/* This can adjust amounts and final cltv for each flow,
|
||||
* to make it look like it's going elsewhere */
|
||||
final_cltvs = shadow_additions(tmpctx, pay_plugin->gossmap,
|
||||
renepay, flows, is_entire_payment);
|
||||
p, flows, is_entire_payment);
|
||||
/* OK, we are happy with these flows: convert to
|
||||
* pay_flows to outlive the current gossmap. */
|
||||
pay_flows = flows_to_pay_flows(renepay->payment, pay_plugin->gossmap,
|
||||
pay_flows = flows_to_pay_flows(p, pay_plugin->gossmap,
|
||||
flows, final_cltvs,
|
||||
&renepay->next_partid);
|
||||
&p->next_partid);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -628,7 +625,8 @@ struct pay_flow* payflow_fail(struct pay_flow *flow)
|
|||
struct payment * p = flow->payment;
|
||||
debug_assert(p);
|
||||
|
||||
payment_fail(p);
|
||||
if (p->status != PAYMENT_SUCCESS)
|
||||
p->status = PAYMENT_FAIL;
|
||||
amount_msat_reduce(&p->total_delivering, payflow_delivered(flow));
|
||||
amount_msat_reduce(&p->total_sent, flow->amounts[0]);
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ HTABLE_DEFINE_TYPE(struct pay_flow,
|
|||
payflow_map);
|
||||
|
||||
|
||||
struct pay_flow **get_payflows(struct renepay * renepay,
|
||||
struct pay_flow **get_payflows(struct payment *payment,
|
||||
struct amount_msat amount,
|
||||
struct amount_msat feebudget,
|
||||
bool unlikely_ok,
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
#include <plugins/renepay/debug.h>
|
||||
#include <plugins/renepay/payment.h>
|
||||
|
||||
static struct payment * payment_new(struct renepay * renepay,
|
||||
struct payment *payment_new(const tal_t *ctx,
|
||||
struct command *cmd,
|
||||
const char *invstr TAKES,
|
||||
const char *label TAKES,
|
||||
const char *description TAKES,
|
||||
|
@ -24,8 +25,8 @@ static struct payment * payment_new(struct renepay * renepay,
|
|||
u64 min_prob_success_millionths,
|
||||
bool use_shadow)
|
||||
{
|
||||
struct payment *p = tal(renepay,struct payment);
|
||||
p->renepay = renepay;
|
||||
struct payment *p = tal(ctx,struct payment);
|
||||
p->cmd = cmd;
|
||||
p->paynotes = tal_arr(p, const char *, 0);
|
||||
|
||||
p->total_sent = AMOUNT_MSAT(0);
|
||||
|
@ -61,66 +62,14 @@ static struct payment * payment_new(struct renepay * renepay,
|
|||
p->groupid=1;
|
||||
|
||||
p->result = NULL;
|
||||
p->local_gossmods = gossmap_localmods_new(p);
|
||||
p->disabled = tal_arr(p,struct short_channel_id,0);
|
||||
p->rexmit_timer = NULL;
|
||||
p->next_partid=1;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
struct renepay *renepay_new(struct command *cmd,
|
||||
const char *invstr TAKES,
|
||||
const char *label TAKES,
|
||||
const char *description TAKES,
|
||||
const struct sha256 *local_offer_id TAKES,
|
||||
const struct secret *payment_secret TAKES,
|
||||
const u8 *payment_metadata TAKES,
|
||||
const struct node_id *destination,
|
||||
const struct sha256 *payment_hash,
|
||||
struct amount_msat amount,
|
||||
struct amount_msat maxfee,
|
||||
unsigned int maxdelay,
|
||||
u64 retryfor,
|
||||
u16 final_cltv,
|
||||
/* Tweakable in DEVELOPER mode */
|
||||
u64 base_fee_penalty,
|
||||
u64 prob_cost_factor,
|
||||
u64 riskfactor_millionths,
|
||||
u64 min_prob_success_millionths,
|
||||
bool use_shadow)
|
||||
{
|
||||
struct renepay *renepay = tal(cmd,struct renepay);
|
||||
|
||||
renepay->cmd = cmd;
|
||||
renepay->payment = payment_new(renepay,
|
||||
invstr, label, description,
|
||||
local_offer_id, payment_secret, payment_metadata,
|
||||
destination, payment_hash,
|
||||
amount, maxfee, maxdelay,
|
||||
retryfor, final_cltv,
|
||||
base_fee_penalty,
|
||||
prob_cost_factor,
|
||||
riskfactor_millionths,
|
||||
min_prob_success_millionths,
|
||||
use_shadow);
|
||||
|
||||
renepay->local_gossmods = gossmap_localmods_new(renepay);
|
||||
renepay->disabled = tal_arr(renepay,struct short_channel_id,0);
|
||||
renepay->rexmit_timer = NULL;
|
||||
renepay->next_partid=1;
|
||||
|
||||
return renepay;
|
||||
}
|
||||
|
||||
|
||||
void payment_fail(struct payment * p)
|
||||
{
|
||||
/* If the payment already succeeded this function call must correspond
|
||||
* to an old sendpay. */
|
||||
if(p->status == PAYMENT_SUCCESS)return;
|
||||
p->status=PAYMENT_FAIL;
|
||||
}
|
||||
void payment_success(struct payment * p)
|
||||
{
|
||||
p->status=PAYMENT_SUCCESS;
|
||||
}
|
||||
|
||||
struct amount_msat payment_sent(const struct payment *p)
|
||||
{
|
||||
return p->total_sent;
|
||||
|
@ -180,22 +129,25 @@ void payment_assert_delivering_all(const struct payment *p)
|
|||
}
|
||||
}
|
||||
|
||||
struct command_result *renepay_success(struct renepay * renepay)
|
||||
struct command_result *payment_success(struct payment *p)
|
||||
{
|
||||
debug_info("calling %s",__PRETTY_FUNCTION__);
|
||||
struct payment *p = renepay->payment;
|
||||
|
||||
payment_success(p);
|
||||
p->status = PAYMENT_SUCCESS;
|
||||
payment_assert_delivering_all(p);
|
||||
|
||||
/* We only finish command once: its destructor clears this. */
|
||||
if (!p->cmd)
|
||||
return NULL;
|
||||
|
||||
struct json_stream *response
|
||||
= jsonrpc_stream_success(renepay->cmd);
|
||||
= jsonrpc_stream_success(p->cmd);
|
||||
|
||||
/* Any one succeeding is success. */
|
||||
json_add_preimage(response, "payment_preimage", p->preimage);
|
||||
json_add_sha256(response, "payment_hash", &p->payment_hash);
|
||||
json_add_timeabs(response, "created_at", p->start_time);
|
||||
json_add_u32(response, "parts", renepay_parts(renepay));
|
||||
json_add_u32(response, "parts", payment_parts(p));
|
||||
json_add_amount_msat(response, "amount_msat",
|
||||
p->amount);
|
||||
json_add_amount_msat(response, "amount_sent_msat",
|
||||
|
@ -203,51 +155,45 @@ struct command_result *renepay_success(struct renepay * renepay)
|
|||
json_add_string(response, "status", "complete");
|
||||
json_add_node_id(response, "destination", &p->destination);
|
||||
|
||||
return command_finished(renepay->cmd, response);
|
||||
return command_finished(p->cmd, response);
|
||||
}
|
||||
|
||||
struct command_result *renepay_fail(
|
||||
struct renepay * renepay,
|
||||
struct command_result *payment_fail(
|
||||
struct payment *payment,
|
||||
enum jsonrpc_errcode code,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
/* renepay_fail is called after command finished. */
|
||||
if(renepay==NULL)
|
||||
{
|
||||
return command_still_pending(NULL);
|
||||
}
|
||||
payment_fail(renepay->payment);
|
||||
/* We only finish command once: its destructor clears this. */
|
||||
if (!payment->cmd)
|
||||
return NULL;
|
||||
|
||||
if (payment->status != PAYMENT_SUCCESS)
|
||||
payment->status = PAYMENT_FAIL;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char *message = tal_vfmt(tmpctx,fmt,args);
|
||||
va_end(args);
|
||||
|
||||
debug_paynote(renepay->payment,"%s",message);
|
||||
debug_paynote(payment,"%s",message);
|
||||
|
||||
return command_fail(renepay->cmd,code,"%s",message);
|
||||
return command_fail(payment->cmd,code,"%s",message);
|
||||
}
|
||||
|
||||
u64 renepay_parts(const struct renepay *renepay)
|
||||
u64 payment_parts(const struct payment *payment)
|
||||
{
|
||||
return renepay->next_partid-1;
|
||||
return payment->next_partid-1;
|
||||
}
|
||||
|
||||
/* Either the payment succeeded or failed, we need to cleanup/set the plugin
|
||||
* into a valid state before the next payment. */
|
||||
void renepay_cleanup(
|
||||
struct renepay * renepay,
|
||||
struct gossmap * gossmap)
|
||||
void payment_cleanup(struct payment *payment)
|
||||
{
|
||||
debug_info("calling %s",__PRETTY_FUNCTION__);
|
||||
// TODO(eduardo): it can happen that local_gossmods removed below
|
||||
// contained a set of channels for which there is information in the
|
||||
// uncertainty network (chan_extra_map) and that are part of some pending
|
||||
// payflow (payflow_map). Handle this situation.
|
||||
tal_free(renepay->local_gossmods);
|
||||
|
||||
renepay->rexmit_timer = tal_free(renepay->rexmit_timer);
|
||||
|
||||
if(renepay->payment)
|
||||
renepay->payment->renepay = NULL;
|
||||
payment->local_gossmods = tal_free(payment->local_gossmods);
|
||||
payment->rexmit_timer = tal_free(payment->rexmit_timer);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,20 @@ struct payment {
|
|||
/* Inside pay_plugin->payments list */
|
||||
struct list_node list;
|
||||
|
||||
struct renepay * renepay;
|
||||
/* The command if still running (needed for timer func) */
|
||||
struct command *cmd;
|
||||
|
||||
/* Localmods to apply to gossip_map for our own use. */
|
||||
struct gossmap_localmods *local_gossmods;
|
||||
|
||||
/* Channels we decided to disable for various reasons. */
|
||||
struct short_channel_id *disabled;
|
||||
|
||||
/* Timers. */
|
||||
struct plugin_timer *rexmit_timer;
|
||||
|
||||
/* Used in get_payflows to set ids to each pay_flow. */
|
||||
u64 next_partid;
|
||||
|
||||
/* Chatty description of attempts. */
|
||||
const char **paynotes;
|
||||
|
@ -32,7 +45,6 @@ struct payment {
|
|||
struct node_id destination;
|
||||
struct sha256 payment_hash;
|
||||
|
||||
|
||||
/* Limits on what routes we'll accept. */
|
||||
struct amount_msat maxspend;
|
||||
|
||||
|
@ -100,30 +112,9 @@ struct payment {
|
|||
struct command_result * result;
|
||||
};
|
||||
|
||||
/* Data only kept while the payment is being processed. */
|
||||
struct renepay
|
||||
{
|
||||
/* The command, and our owner (needed for timer func) */
|
||||
struct command *cmd;
|
||||
|
||||
/* Payment information that will eventually outlive renepay and be
|
||||
* registered. */
|
||||
struct payment * payment;
|
||||
|
||||
/* Localmods to apply to gossip_map for our own use. */
|
||||
struct gossmap_localmods *local_gossmods;
|
||||
|
||||
/* Channels we decided to disable for various reasons. */
|
||||
struct short_channel_id *disabled;
|
||||
|
||||
/* Timers. */
|
||||
struct plugin_timer *rexmit_timer;
|
||||
|
||||
/* Used in get_payflows to set ids to each pay_flow. */
|
||||
u64 next_partid;
|
||||
};
|
||||
|
||||
struct renepay *renepay_new(struct command *cmd,
|
||||
struct payment *payment_new(const tal_t *ctx,
|
||||
struct command *cmd,
|
||||
const char *invstr TAKES,
|
||||
const char *label TAKES,
|
||||
const char *description TAKES,
|
||||
|
@ -144,12 +135,6 @@ struct renepay *renepay_new(struct command *cmd,
|
|||
u64 min_prob_success_millionths,
|
||||
bool use_shadow);
|
||||
|
||||
void renepay_cleanup(
|
||||
struct renepay * renepay,
|
||||
struct gossmap * gossmap);
|
||||
|
||||
void payment_fail(struct payment * p);
|
||||
void payment_success(struct payment * p);
|
||||
struct amount_msat payment_sent(const struct payment *p);
|
||||
struct amount_msat payment_delivered(const struct payment *p);
|
||||
struct amount_msat payment_amount(const struct payment *p);
|
||||
|
@ -159,13 +144,14 @@ void payment_note(struct payment *p, const char *fmt, ...);
|
|||
void payment_assert_delivering_incomplete(const struct payment *p);
|
||||
void payment_assert_delivering_all(const struct payment *p);
|
||||
|
||||
struct command_result *renepay_success(struct renepay *renepay);
|
||||
struct command_result *payment_success(struct payment *payment);
|
||||
|
||||
struct command_result *renepay_fail(
|
||||
struct renepay * renepay,
|
||||
struct command_result *payment_fail(
|
||||
struct payment *payment,
|
||||
enum jsonrpc_errcode code,
|
||||
const char *fmt, ...);
|
||||
|
||||
u64 renepay_parts(const struct renepay *renepay);
|
||||
u64 payment_parts(const struct payment *payment);
|
||||
void payment_cleanup(struct payment *payment);
|
||||
|
||||
#endif /* LIGHTNING_PLUGINS_RENEPAY_PAYMENT_H */
|
||||
|
|
|
@ -41,7 +41,7 @@ bool uncertainty_network_check_invariants(struct chan_extra_map *chan_extra_map)
|
|||
|
||||
static void add_hintchan(
|
||||
struct chan_extra_map *chan_extra_map,
|
||||
struct renepay * renepay,
|
||||
struct payment *payment,
|
||||
const struct node_id *src,
|
||||
const struct node_id *dst,
|
||||
u16 cltv_expiry_delta,
|
||||
|
@ -63,9 +63,9 @@ static void add_hintchan(
|
|||
scid,
|
||||
MAX_CAP);
|
||||
/* FIXME: features? */
|
||||
gossmap_local_addchan(renepay->local_gossmods,
|
||||
gossmap_local_addchan(payment->local_gossmods,
|
||||
src, dst, &scid, NULL);
|
||||
gossmap_local_updatechan(renepay->local_gossmods,
|
||||
gossmap_local_updatechan(payment->local_gossmods,
|
||||
&scid,
|
||||
/* We assume any HTLC is allowed */
|
||||
AMOUNT_MSAT(0), MAX_CAP,
|
||||
|
@ -84,15 +84,14 @@ static void add_hintchan(
|
|||
/* Add routehints provided by bolt11 */
|
||||
void uncertainty_network_add_routehints(
|
||||
struct chan_extra_map *chan_extra_map,
|
||||
struct renepay *renepay)
|
||||
struct payment *p)
|
||||
{
|
||||
const struct payment *const p = renepay->payment;
|
||||
struct bolt11 *b11;
|
||||
char *fail;
|
||||
|
||||
b11 =
|
||||
bolt11_decode(tmpctx, p->invstr,
|
||||
plugin_feature_set(renepay->cmd->plugin),
|
||||
plugin_feature_set(p->cmd->plugin),
|
||||
p->description, chainparams, &fail);
|
||||
if (b11 == NULL)
|
||||
debug_err("add_routehints: Invalid bolt11: %s", fail);
|
||||
|
@ -104,7 +103,7 @@ void uncertainty_network_add_routehints(
|
|||
for (int j = tal_count(r)-1; j >= 0; j--) {
|
||||
add_hintchan(
|
||||
chan_extra_map,
|
||||
renepay, &r[j].pubkey, end,
|
||||
p, &r[j].pubkey, end,
|
||||
r[j].cltv_expiry_delta,
|
||||
r[j].short_channel_id,
|
||||
r[j].fee_base_msat,
|
||||
|
@ -232,11 +231,10 @@ void uncertainty_network_channel_can_send(
|
|||
bool uncertainty_network_update_from_listpeerchannels(
|
||||
struct chan_extra_map * chan_extra_map,
|
||||
struct node_id my_id,
|
||||
struct renepay * renepay,
|
||||
struct payment *p,
|
||||
const char *buf,
|
||||
const jsmntok_t *toks)
|
||||
{
|
||||
struct payment * const p = renepay->payment;
|
||||
const jsmntok_t *channels, *channel;
|
||||
size_t i;
|
||||
|
||||
|
@ -270,7 +268,7 @@ bool uncertainty_network_update_from_listpeerchannels(
|
|||
type_to_string(tmpctx,
|
||||
struct short_channel_id,
|
||||
&scid));
|
||||
tal_arr_expand(&renepay->disabled, scid);
|
||||
tal_arr_expand(&p->disabled, scid);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -302,7 +300,7 @@ bool uncertainty_network_update_from_listpeerchannels(
|
|||
|
||||
/* Don't report opening/closing channels */
|
||||
if (!json_tok_streq(buf, statetok, "CHANNELD_NORMAL")) {
|
||||
tal_arr_expand(&renepay->disabled, scid);
|
||||
tal_arr_expand(&p->disabled, scid);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -316,9 +314,9 @@ bool uncertainty_network_update_from_listpeerchannels(
|
|||
scid,
|
||||
capacity);
|
||||
/* FIXME: features? */
|
||||
gossmap_local_addchan(renepay->local_gossmods,
|
||||
gossmap_local_addchan(p->local_gossmods,
|
||||
&src, &dst, &scid, NULL);
|
||||
gossmap_local_updatechan(renepay->local_gossmods,
|
||||
gossmap_local_updatechan(p->local_gossmods,
|
||||
&scid,
|
||||
|
||||
/* TODO(eduardo): does it
|
||||
|
|
|
@ -14,7 +14,7 @@ bool uncertainty_network_check_invariants(struct chan_extra_map *chan_extra_map)
|
|||
/* Add routehints provided by bolt11 */
|
||||
void uncertainty_network_add_routehints(
|
||||
struct chan_extra_map *chan_extra_map,
|
||||
struct renepay *renepay);
|
||||
struct payment *payment);
|
||||
|
||||
/* Mirror the gossmap in the public uncertainty network.
|
||||
* result: Every channel in gossmap must have associated data in chan_extra_map,
|
||||
|
@ -40,7 +40,7 @@ void uncertainty_network_channel_can_send(
|
|||
bool uncertainty_network_update_from_listpeerchannels(
|
||||
struct chan_extra_map * chan_extra_map,
|
||||
struct node_id my_id,
|
||||
struct renepay * renepay,
|
||||
struct payment *payment,
|
||||
const char *buf,
|
||||
const jsmntok_t *toks);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue