diff --git a/plugins/renepay/debug.h b/plugins/renepay/debug.h index 3a1b051e91b5..eb35e4614541 100644 --- a/plugins/renepay/debug.h +++ b/plugins/renepay/debug.h @@ -30,9 +30,6 @@ void _debug_exec_branch(const char* fname,const char* fun, int lineno); #define debug_err(...) \ {_debug_info(MYLOG,__VA_ARGS__); abort();} -#define debug_paynote(p,...) \ - {payment_note(p,__VA_ARGS__);_debug_info(MYLOG,__VA_ARGS__);} - #else /* Debugging information goes either to payment notes or to lightningd log. */ @@ -42,9 +39,6 @@ void _debug_exec_branch(const char* fname,const char* fun, int lineno); #define debug_err(...) \ plugin_err(pay_plugin->plugin,__VA_ARGS__) -#define debug_paynote(p,...) \ - payment_note(p,__VA_ARGS__); - #endif #define debug_assert(expr) \ diff --git a/plugins/renepay/flow.c b/plugins/renepay/flow.c index 97523dcebc8b..f53a567b91ee 100644 --- a/plugins/renepay/flow.c +++ b/plugins/renepay/flow.c @@ -48,6 +48,52 @@ const char *fmt_chan_extra_map( return buff; } +const char *fmt_chan_extra_details(const tal_t *ctx, + struct chan_extra_map* chan_extra_map, + const struct short_channel_id_dir *scidd) +{ + const struct chan_extra *ce = chan_extra_map_get(chan_extra_map, + scidd->scid); + const struct chan_extra_half *ch; + char *str = tal_strdup(ctx, ""); + char sep = '('; + + if (!ce) + return str; + + ch = &ce->half[scidd->dir]; + if (ch->num_htlcs != 0) { + tal_append_fmt(&str, "%c%s in %zu htlcs", + sep, + fmt_amount_msat(tmpctx, ch->htlc_total), + ch->num_htlcs); + sep = ','; + } + /* Happens with local channels, where we're certain. */ + if (amount_msat_eq(ch->known_min, ch->known_max)) { + tal_append_fmt(&str, "%cmin=max=%s", + sep, + fmt_amount_msat(tmpctx, ch->known_min)); + sep = ','; + } else { + if (amount_msat_greater(ch->known_min, AMOUNT_MSAT(0))) { + tal_append_fmt(&str, "%cmin=%s", + sep, + fmt_amount_msat(tmpctx, ch->known_min)); + sep = ','; + } + if (!amount_msat_eq(ch->known_max, ce->capacity)) { + tal_append_fmt(&str, "%cmax=%s", + sep, + fmt_amount_msat(tmpctx, ch->known_max)); + sep = ','; + } + } + if (!streq(str, "")) + tal_append_fmt(&str, ")"); + return str; +} + struct chan_extra *new_chan_extra( struct chan_extra_map *chan_extra_map, const struct short_channel_id scid, @@ -120,82 +166,77 @@ static void chan_extra_can_send_( chan_extra_adjust_half(ce,!dir); } + void chan_extra_can_send( struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, + const struct short_channel_id_dir *scidd, struct amount_msat x) { struct chan_extra *ce = chan_extra_map_get(chan_extra_map, - scid); + scidd->scid); if(!ce) { debug_err("%s unexpected chan_extra ce is NULL", __PRETTY_FUNCTION__); } - if(!amount_msat_add(&x,x,ce->half[dir].htlc_total)) + if(!amount_msat_add(&x,x,ce->half[scidd->dir].htlc_total)) { debug_err("%s (line %d) cannot add x=%s and htlc_total=%s", __PRETTY_FUNCTION__,__LINE__, type_to_string(tmpctx,struct amount_msat,&x), - type_to_string(tmpctx,struct amount_msat,&ce->half[dir].htlc_total)); + type_to_string(tmpctx,struct amount_msat,&ce->half[scidd->dir].htlc_total)); } - chan_extra_can_send_(ce,dir,x); + chan_extra_can_send_(ce,scidd->dir,x); } -/* Update the knowledge that this (channel,direction) cannot send x msat.*/ +/* Update the knowledge that this (channel,direction) cannot send.*/ void chan_extra_cannot_send( - struct payment *p, + struct pay_flow *pf, struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, - struct amount_msat x) + const struct short_channel_id_dir *scidd, + struct amount_msat sent) { + struct amount_msat oldmin, oldmax, x; struct chan_extra *ce = chan_extra_map_get(chan_extra_map, - scid); + scidd->scid); if(!ce) { debug_err("%s (line %d) unexpected chan_extra ce is NULL", __PRETTY_FUNCTION__,__LINE__); } - /* If a channel cannot send x it means that the upper bound for the - * liquidity is MAX_L < x + htlc_total */ - if(!amount_msat_add(&x,x,ce->half[dir].htlc_total)) + /* Note: sent is already included in htlc_total! */ + if(!amount_msat_sub(&x,ce->half[scidd->dir].htlc_total,AMOUNT_MSAT(1))) { - debug_err("%s (line %d) cannot add x=%s and htlc_total=%s", + debug_err("%s (line %d) unexpected htlc_total=%s is less than 0msat", __PRETTY_FUNCTION__,__LINE__, - type_to_string(tmpctx,struct amount_msat,&x), - type_to_string(tmpctx,struct amount_msat,&ce->half[dir].htlc_total)); - } - - if(!amount_msat_sub(&x,x,AMOUNT_MSAT(1))) - { - debug_err("%s (line %d) unexpected x=%s is less than 0msat", - __PRETTY_FUNCTION__,__LINE__, - type_to_string(tmpctx,struct amount_msat,&x) + type_to_string(tmpctx,struct amount_msat, + &ce->half[scidd->dir].htlc_total) ); x = AMOUNT_MSAT(0); } + oldmin = ce->half[scidd->dir].known_min; + oldmax = ce->half[scidd->dir].known_max; + /* If we "knew" the capacity was at least this, we just showed we're wrong! */ - if (amount_msat_less_eq(x, ce->half[dir].known_min)) { - debug_paynote(p, "Expected scid=%s, dir=%d min %s, but %s failed! Setting min to 0", - type_to_string(tmpctx,struct short_channel_id,&scid), - dir, - type_to_string(tmpctx,struct amount_msat,&ce->half[dir].known_min), - type_to_string(tmpctx,struct amount_msat,&x)); - ce->half[dir].known_min = AMOUNT_MSAT(0); - } - ce->half[dir].known_max = amount_msat_min(ce->half[dir].known_max,x); - - debug_paynote(p,"Update chan knowledge scid=%s, dir=%d: [%s,%s]", - type_to_string(tmpctx,struct short_channel_id,&scid), - dir, - type_to_string(tmpctx,struct amount_msat,&ce->half[dir].known_min), - type_to_string(tmpctx,struct amount_msat,&ce->half[dir].known_max)); + if (amount_msat_less(x, ce->half[scidd->dir].known_min)) { + /* Skip to half of x, since we don't know (rounds down) */ + ce->half[scidd->dir].known_min = amount_msat_div(x, 2); + } - chan_extra_adjust_half(ce,!dir); + ce->half[scidd->dir].known_max = amount_msat_min(ce->half[scidd->dir].known_max,x); + + payflow_note(pf, LOG_INFORM, + "Failure of %s for %s capacity [%s,%s] -> [%s,%s]", + fmt_amount_msat(tmpctx, sent), + type_to_string(tmpctx,struct short_channel_id_dir,scidd), + fmt_amount_msat(tmpctx, oldmin), + fmt_amount_msat(tmpctx, oldmax), + fmt_amount_msat(tmpctx, ce->half[scidd->dir].known_min), + fmt_amount_msat(tmpctx, ce->half[scidd->dir].known_max)); + + chan_extra_adjust_half(ce,!scidd->dir); } /* Update the knowledge that this (channel,direction) has liquidity x.*/ static void chan_extra_set_liquidity_( @@ -220,25 +261,33 @@ static void chan_extra_set_liquidity_( } void chan_extra_set_liquidity( struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, + const struct short_channel_id_dir *scidd, struct amount_msat x) { struct chan_extra *ce = chan_extra_map_get(chan_extra_map, - scid); + scidd->scid); if(!ce) { debug_err("%s unexpected chan_extra ce is NULL", __PRETTY_FUNCTION__); } - chan_extra_set_liquidity_(ce,dir,x); + chan_extra_set_liquidity_(ce,scidd->dir,x); } /* Update the knowledge that this (channel,direction) has sent x msat.*/ -static void chan_extra_sent_success_( - struct chan_extra *ce, - int dir, +void chan_extra_sent_success( + struct pay_flow *pf, + struct chan_extra_map *chan_extra_map, + const struct short_channel_id_dir *scidd, struct amount_msat x) { + struct chan_extra *ce = chan_extra_map_get(chan_extra_map, + scidd->scid); + if(!ce) + { + debug_err("%s unexpected chan_extra ce is NULL", + __PRETTY_FUNCTION__); + } + if(amount_msat_greater(x,ce->capacity)) { debug_err("%s unexpected capacity=%s is less than x=%s", @@ -251,30 +300,24 @@ static void chan_extra_sent_success_( struct amount_msat new_a, new_b; - if(!amount_msat_sub(&new_a,ce->half[dir].known_min,x)) + if(!amount_msat_sub(&new_a,ce->half[scidd->dir].known_min,x)) new_a = AMOUNT_MSAT(0); - if(!amount_msat_sub(&new_b,ce->half[dir].known_max,x)) + if(!amount_msat_sub(&new_b,ce->half[scidd->dir].known_max,x)) new_b = AMOUNT_MSAT(0); - ce->half[dir].known_min = new_a; - ce->half[dir].known_max = new_b; + payflow_note(pf, LOG_DBG, + "Success of %s for %s capacity [%s,%s] -> [%s,%s]", + fmt_amount_msat(tmpctx, x), + type_to_string(tmpctx,struct short_channel_id_dir,scidd), + fmt_amount_msat(tmpctx, ce->half[scidd->dir].known_min), + fmt_amount_msat(tmpctx, ce->half[scidd->dir].known_max), + fmt_amount_msat(tmpctx, new_a), + fmt_amount_msat(tmpctx, new_b)); - chan_extra_adjust_half(ce,!dir); -} -void chan_extra_sent_success( - struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, - struct amount_msat x) -{ - struct chan_extra *ce = chan_extra_map_get(chan_extra_map, - scid); - if(!ce) - { - debug_err("%s unexpected chan_extra ce is NULL", - __PRETTY_FUNCTION__); - } - chan_extra_sent_success_(ce,dir,x); + ce->half[scidd->dir].known_min = new_a; + ce->half[scidd->dir].known_max = new_b; + + chan_extra_adjust_half(ce,!scidd->dir); } /* Forget a bit about this (channel,direction) state. */ static void chan_extra_relax_( @@ -298,19 +341,18 @@ static void chan_extra_relax_( } void chan_extra_relax( struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, + const struct short_channel_id_dir *scidd, struct amount_msat x, struct amount_msat y) { struct chan_extra *ce = chan_extra_map_get(chan_extra_map, - scid); + scidd->scid); if(!ce) { debug_err("%s unexpected chan_extra ce is NULL", __PRETTY_FUNCTION__); } - chan_extra_relax_(ce,dir,x,y); + chan_extra_relax_(ce,scidd->dir,x,y); } /* Forget the channel information by a fraction of the capacity. */ @@ -334,15 +376,14 @@ void chan_extra_relax_fraction( /* Returns either NULL, or an entry from the hash */ struct chan_extra_half * get_chan_extra_half_by_scid(struct chan_extra_map *chan_extra_map, - const struct short_channel_id scid, - int dir) + const struct short_channel_id_dir *scidd) { struct chan_extra *ce; - ce = chan_extra_map_get(chan_extra_map, scid); + ce = chan_extra_map_get(chan_extra_map, scidd->scid); if (!ce) return NULL; - return &ce->half[dir]; + return &ce->half[scidd->dir]; } /* Helper if we have a gossmap_chan */ struct chan_extra_half * @@ -351,9 +392,11 @@ get_chan_extra_half_by_chan(const struct gossmap *gossmap, const struct gossmap_chan *chan, int dir) { - return get_chan_extra_half_by_scid(chan_extra_map, - gossmap_chan_scid(gossmap, chan), - dir); + struct short_channel_id_dir scidd; + + scidd.scid = gossmap_chan_scid(gossmap, chan); + scidd.dir = dir; + return get_chan_extra_half_by_scid(chan_extra_map, &scidd); } @@ -371,9 +414,12 @@ get_chan_extra_half_by_chan_verify( int dir) { - const struct short_channel_id scid = gossmap_chan_scid(gossmap,chan); + struct short_channel_id_dir scidd; + + scidd.scid = gossmap_chan_scid(gossmap,chan); + scidd.dir = dir; struct chan_extra_half *h = get_chan_extra_half_by_scid( - chan_extra_map,scid,dir); + chan_extra_map,&scidd); if (!h) { struct amount_sat cap; struct amount_msat cap_msat; @@ -386,7 +432,7 @@ get_chan_extra_half_by_chan_verify( __PRETTY_FUNCTION__, __LINE__); } - h = & new_chan_extra(chan_extra_map,scid,cap_msat)->half[dir]; + h = & new_chan_extra(chan_extra_map,scidd.scid,cap_msat)->half[scidd.dir]; } return h; diff --git a/plugins/renepay/flow.h b/plugins/renepay/flow.h index c2887235850b..0ee448a30efd 100644 --- a/plugins/renepay/flow.h +++ b/plugins/renepay/flow.h @@ -118,6 +118,12 @@ const char *fmt_chan_extra_map( const tal_t *ctx, struct chan_extra_map* chan_extra_map); +/* Returns "" if nothing useful known about channel, otherwise + * "(details)" */ +const char *fmt_chan_extra_details(const tal_t *ctx, + struct chan_extra_map* chan_extra_map, + const struct short_channel_id_dir *scidd); + /* Creates a new chan_extra and adds it to the chan_extra_map. */ struct chan_extra *new_chan_extra( struct chan_extra_map *chan_extra_map, @@ -148,33 +154,29 @@ static inline struct amount_msat amount_msat_max( /* Update the knowledge that this (channel,direction) can send x msat.*/ void chan_extra_can_send(struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, + const struct short_channel_id_dir *scidd, struct amount_msat x); /* Update the knowledge that this (channel,direction) cannot send x msat.*/ -void chan_extra_cannot_send(struct payment* p, +void chan_extra_cannot_send(struct pay_flow* pf, struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, + const struct short_channel_id_dir *scidd, struct amount_msat x); /* Update the knowledge that this (channel,direction) has liquidity x.*/ void chan_extra_set_liquidity(struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, + const struct short_channel_id_dir *scidd, struct amount_msat x); /* Update the knowledge that this (channel,direction) has sent x msat.*/ -void chan_extra_sent_success(struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, +void chan_extra_sent_success(struct pay_flow *pf, + struct chan_extra_map *chan_extra_map, + const struct short_channel_id_dir *scidd, struct amount_msat x); /* Forget a bit about this (channel,direction) state. */ void chan_extra_relax(struct chan_extra_map *chan_extra_map, - struct short_channel_id scid, - int dir, + const struct short_channel_id_dir *scidd, struct amount_msat down, struct amount_msat up); @@ -186,8 +188,7 @@ void chan_extra_relax_fraction( /* Returns either NULL, or an entry from the hash */ struct chan_extra_half *get_chan_extra_half_by_scid(struct chan_extra_map *chan_extra_map, - const struct short_channel_id scid, - int dir); + const struct short_channel_id_dir *scidd); /* If the channel is not registered, then a new entry is created. scid must be * present in the gossmap. */ struct chan_extra_half * diff --git a/plugins/renepay/pay.c b/plugins/renepay/pay.c index b3ef3956a476..e2396e2b156a 100644 --- a/plugins/renepay/pay.c +++ b/plugins/renepay/pay.c @@ -121,12 +121,8 @@ static struct pf_result *handle_unhandleable_error(struct pay_flow *pf, size_t n = tal_count(pf); /* We got a mangled reply. We don't know who to penalize! */ - debug_paynote(pf->payment, "%s on route %s", what, flow_path_to_str(tmpctx, pf)); - - // TODO(eduardo): does LOG_BROKEN finish the plugin execution? - plugin_log(pay_plugin->plugin, LOG_BROKEN, - "%s on route %s", - what, flow_path_to_str(tmpctx, pf)); + payflow_note(pf, LOG_UNUSUAL, "%s on route %s", + what, flow_path_to_str(tmpctx, pf)); if (n == 1) { @@ -144,10 +140,8 @@ static struct pf_result *handle_unhandleable_error(struct pay_flow *pf, /* Assume it's not the destination */ n = pseudorand(n-1); - tal_arr_expand(&pf->payment->disabled, pf->path_scids[n]); - debug_paynote(pf->payment, "... eliminated %s", - type_to_string(tmpctx, struct short_channel_id, - &pf->path_scids[n])); + payflow_disable_chan(pf, pf->path_scidds[n].scid, + LOG_INFORM, "randomly chosen"); return pay_flow_failed(pf); } @@ -179,13 +173,11 @@ static struct command_result *addgossip_failure(struct command *cmd, struct addgossip *adg) { - struct payment * payment = adg->pf->payment; plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__); - 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(&payment->disabled, adg->scid); + payflow_disable_chan(adg->pf, adg->scid, + LOG_INFORM, "addgossip failed (%.*s)", + err->end - err->start, buf + err->start); return addgossip_done(cmd, buf, err, adg); } @@ -195,7 +187,6 @@ static struct pf_result *submit_update(struct pay_flow *pf, struct short_channel_id errscid) { plugin_log(pay_plugin->plugin,LOG_DBG,"calling %s",__PRETTY_FUNCTION__); - struct payment *payment = pf->payment; struct out_req *req; struct addgossip *adg = tal(pf, struct addgossip); @@ -204,8 +195,7 @@ static struct pf_result *submit_update(struct pay_flow *pf, adg->scid = errscid; adg->pf = pf; - debug_paynote(payment, "... extracted channel_update, telling gossipd"); - plugin_log(pay_plugin->plugin, LOG_DBG, "(update = %s)", tal_hex(tmpctx, update)); + payflow_note(pf, LOG_DBG, "... extracted channel_update %s, telling gossipd", tal_hex(tmpctx, update)); req = jsonrpc_request_start(pay_plugin->plugin, NULL, "addgossip", addgossip_done, @@ -312,12 +302,11 @@ 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(payment, - "sendpay didn't like first hop, eliminated: %s", msg) - /* There is no new knowledge from this kind of failure. * We just disable this scid. */ - tal_arr_expand(&payment->disabled, pf->path_scids[0]); + payflow_disable_chan(pf, pf->path_scidds[0].scid, + LOG_INFORM, + "sendpay didn't like first hop: %s", msg); pay_flow_failed(pf); return command_still_pending(cmd); @@ -329,15 +318,11 @@ static void sendpay_new_flows(struct payment *p) struct pay_flow *pf; list_for_each(&p->flows, pf, list) { + struct out_req *req; + if (pf->state != PAY_FLOW_NOT_STARTED) continue; - debug_paynote(p, "sendpay flow groupid=%"PRIu64", partid=%"PRIu64", delivering=%s, probability=%.3lf", - pf->key.groupid, - pf->key.partid, - fmt_amount_msat(tmpctx, payflow_delivered(pf)), - pf->success_prob); - struct out_req *req; /* FIXME: We don't actually want cmd to own this sendpay, so we use NULL here, * but we should use a variant which allows us to set json id! */ req = jsonrpc_request_start(pay_plugin->plugin, NULL, "sendpay", @@ -350,11 +335,11 @@ static void sendpay_new_flows(struct payment *p) json_add_node_id(req->js, "id", &pf->path_nodes[j]); json_add_short_channel_id(req->js, "channel", - &pf->path_scids[j]); + &pf->path_scidds[j].scid); json_add_amount_msat(req->js, "amount_msat", pf->amounts[j]); json_add_num(req->js, "direction", - pf->path_dirs[j]); + pf->path_scidds[j].dir); json_add_u32(req->js, "delay", pf->cltv_delays[j]); json_add_string(req->js,"style","tlv"); @@ -1061,36 +1046,22 @@ static struct pf_result *handle_sendpay_failure_payment(struct pay_flow *pf STEA const u8 *raw) { struct short_channel_id errscid; - struct payment *p = pf->payment; const u8 *update; debug_assert(pf); - debug_assert(p); /* Final node is usually a hard failure */ - if (erridx == tal_count(pf->path_scids)) { - debug_paynote(p, - "onion error %s from final node #%u: %s", - onion_wire_name(onionerr), - erridx, - message); - + if (erridx == tal_count(pf->path_scidds)) { if (onionerr == WIRE_MPP_TIMEOUT) { return pay_flow_failed(pf); } - debug_paynote(p,"final destination failure"); + payflow_note(pf, LOG_INFORM, + "final destination permanent failure"); return pay_flow_failed_final(pf, PAY_DESTINATION_PERM_FAIL, message); } - errscid = pf->path_scids[erridx]; - debug_paynote(p, - "onion error %s from node #%u %s: %s", - onion_wire_name(onionerr), - erridx, - type_to_string(tmpctx, struct short_channel_id, &errscid), - message); - + errscid = pf->path_scidds[erridx].scid; switch (onionerr) { /* These definitely mean eliminate channel */ case WIRE_PERMANENT_CHANNEL_FAILURE: @@ -1110,9 +1081,9 @@ static struct pf_result *handle_sendpay_failure_payment(struct pay_flow *pf STEA case WIRE_INVALID_ONION_PAYLOAD: case WIRE_INVALID_ONION_BLINDING: 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(&p->disabled, errscid); + payflow_disable_chan(pf, errscid, LOG_UNUSUAL, + "%s", + onion_wire_name(onionerr)); return pay_flow_failed(pf); /* These can be fixed (maybe) by applying the included channel_update */ @@ -1127,9 +1098,8 @@ static struct pf_result *handle_sendpay_failure_payment(struct pay_flow *pf STEA if (update) return submit_update(pf, update, errscid); - debug_paynote(p, "missing an update, so we're removing scid %s", - type_to_string(tmpctx,struct short_channel_id,&errscid)); - tal_arr_expand(&p->disabled, errscid); + payflow_disable_chan(pf, errscid, + LOG_UNUSUAL, "missing channel_update"); return pay_flow_failed(pf); case WIRE_TEMPORARY_CHANNEL_FAILURE: @@ -1149,10 +1119,9 @@ static struct pf_result *handle_sendpay_failure_payment(struct pay_flow *pf STEA break; } - debug_paynote(p,"unkown onion error code %u, removing scid %s", - onionerr, - type_to_string(tmpctx,struct short_channel_id,&errscid)); - tal_arr_expand(&p->disabled, errscid); + payflow_disable_chan(pf, errscid, + LOG_UNUSUAL, "unexpected error code %u", + onionerr); return pay_flow_failed(pf); } @@ -1163,18 +1132,6 @@ static void handle_sendpay_failure_flow(struct pay_flow *pf, { debug_assert(pf); - struct payment * const p = pf->payment; - - plugin_log(pay_plugin->plugin, LOG_UNUSUAL, - "onion error %s from node #%u %s: " - "%s", - onion_wire_name(onionerr), - erridx, - erridx == tal_count(pf->path_scids) - ? "final" - : type_to_string(tmpctx, struct short_channel_id, &pf->path_scids[erridx]), - msg); - /* we know that all channels before erridx where able to commit to this payment */ uncertainty_network_channel_can_send( pay_plugin->chan_extra_map, @@ -1183,19 +1140,11 @@ static void handle_sendpay_failure_flow(struct pay_flow *pf, /* Insufficient funds (not from final, that's weird!) */ if((enum onion_wire)onionerr == WIRE_TEMPORARY_CHANNEL_FAILURE - && erridx < tal_count(pf->path_scids)) + && erridx < tal_count(pf->path_scidds)) { - plugin_log(pay_plugin->plugin,LOG_DBG, - "sendpay_failure says insufficient funds!"); - - chan_extra_cannot_send(p,pay_plugin->chan_extra_map, - pf->path_scids[erridx], - pf->path_dirs[erridx], - /* This channel can't send all that was - * commited in HTLCs. - * Had we removed the commited amount then - * we would have to put here pf->amounts[erridx]. */ - AMOUNT_MSAT(0)); + chan_extra_cannot_send(pf,pay_plugin->chan_extra_map, + &pf->path_scidds[erridx], + pf->amounts[erridx]); } } @@ -1249,6 +1198,8 @@ static struct command_result *notification_sendpay_success( json_tok_full(buf, params)); } + payflow_note(pf, LOG_INFORM, "Success"); + // 2. update information uncertainty_network_flow_success(pay_plugin->chan_extra_map, pf); @@ -1271,8 +1222,6 @@ static struct pf_result *sendpay_failure(struct pay_flow *pf, /* Only one code is really actionable */ switch (errcode) { case PAY_UNPARSEABLE_ONION: - debug_paynote(pf->payment, "Unparsable onion reply on route %s", - flow_path_to_str(tmpctx, pf)); return handle_unhandleable_error(pf, "Unparsable onion reply"); case PAY_TRY_OTHER_ROUTE: @@ -1300,13 +1249,15 @@ static struct pf_result *sendpay_failure(struct pay_flow *pf, return handle_unhandleable_error(pf, err); /* Answer must be sane: but note, erridx can be final node! */ - if (erridx > tal_count(pf->path_scids)) { + if (erridx > tal_count(pf->path_scidds)) { plugin_err(pay_plugin->plugin, "Erring channel %u/%zu in path %s", - erridx, tal_count(pf->path_scids), + erridx, tal_count(pf->path_scidds), flow_path_to_str(tmpctx, pf)); } + payflow_note(pf, LOG_INFORM, "Failed at node #%u (%s): %s", + erridx, onion_wire_name(onionerr), msg); handle_sendpay_failure_flow(pf, msg, erridx, onionerr); return handle_sendpay_failure_payment(pf, msg, erridx, onionerr, raw); diff --git a/plugins/renepay/pay_flow.c b/plugins/renepay/pay_flow.c index 7454bf626fc8..1a0206ae5393 100644 --- a/plugins/renepay/pay_flow.c +++ b/plugins/renepay/pay_flow.c @@ -1,6 +1,5 @@ /* Routines to get suitable pay_flow array from pay constraints */ #include "config.h" -#include #include #include #include @@ -39,11 +38,10 @@ static void remove_htlc_payflow( struct chan_extra_map *chan_extra_map, struct pay_flow *pf) { - for (size_t i = 0; i < tal_count(pf->path_scids); i++) { + for (size_t i = 0; i < tal_count(pf->path_scidds); i++) { struct chan_extra_half *h = get_chan_extra_half_by_scid( chan_extra_map, - pf->path_scids[i], - pf->path_dirs[i]); + &pf->path_scidds[i]); if(!h) { plugin_err(pay_plugin->plugin, @@ -75,11 +73,10 @@ static void commit_htlc_payflow( struct chan_extra_map *chan_extra_map, const struct pay_flow *pf) { - for (size_t i = 0; i < tal_count(pf->path_scids); i++) { + for (size_t i = 0; i < tal_count(pf->path_scidds); i++) { struct chan_extra_half *h = get_chan_extra_half_by_scid( chan_extra_map, - pf->path_scids[i], - pf->path_dirs[i]); + &pf->path_scidds[i]); if(!h) { plugin_err(pay_plugin->plugin, @@ -223,11 +220,12 @@ static u32 *shadow_additions(const tal_t *ctx, shadow_delay = shadow_one_flow(gossmap, flows[i], &shadow_fee); if (flow_delay(flows[i]) + shadow_delay > p->maxdelay) { - debug_paynote(p, "No shadow for flow %zu/%zu:" - " delay would add %u to %"PRIu64", exceeding max delay.", - i, tal_count(flows), - shadow_delay, - flow_delay(flows[i])); + payment_note(p, LOG_UNUSUAL, + "No shadow for flow %zu/%zu:" + " delay would add %u to %"PRIu64", exceeding max delay.", + i, tal_count(flows), + shadow_delay, + flow_delay(flows[i])); continue; } @@ -238,7 +236,8 @@ static u32 *shadow_additions(const tal_t *ctx, if (is_entire_payment && tal_count(flows) == 1) { if (!add_to_amounts(gossmap, flows[i], p->maxspend, shadow_fee)) { - debug_paynote(p, "No shadow fee for flow %zu/%zu:" + payment_note(p, LOG_UNUSUAL, + "No shadow fee for flow %zu/%zu:" " fee would add %s to %s, exceeding budget %s.", i, tal_count(flows), type_to_string(tmpctx, struct amount_msat, @@ -248,14 +247,15 @@ static u32 *shadow_additions(const tal_t *ctx, type_to_string(tmpctx, struct amount_msat, &p->maxspend)); } else { - debug_paynote(p, "No MPP, so added %s shadow fee", + payment_note(p, LOG_DBG, + "No MPP, so added %s shadow fee", type_to_string(tmpctx, struct amount_msat, &shadow_fee)); } } final_cltvs[i] += shadow_delay; - debug_paynote(p, "Shadow route on flow %zu/%zu added %u block delay. now %u", + payment_note(p, LOG_DBG, "Shadow route on flow %zu/%zu added %u block delay. now %u", i, tal_count(flows), shadow_delay, final_cltvs[i]); } @@ -267,6 +267,23 @@ static void destroy_payment_flow(struct pay_flow *pf) list_del_from(&pf->payment->flows, &pf->list); } +/* Print out flow, and any information we already know */ +static const char *flow_path_annotated(const tal_t *ctx, + const struct pay_flow *flow) +{ + char *s = tal_strdup(ctx, ""); + for (size_t i = 0; i < tal_count(flow->path_scidds); i++) { + tal_append_fmt(&s, "-%s%s->", + type_to_string(tmpctx, + struct short_channel_id_dir, + &flow->path_scidds[i]), + fmt_chan_extra_details(tmpctx, + pay_plugin->chan_extra_map, + &flow->path_scidds[i])); + } + return s; +} + /* Calculates delays and converts to scids, and links to the payment. * Frees flows. */ static void convert_and_attach_flows(struct payment *payment, @@ -289,14 +306,15 @@ static void convert_and_attach_flows(struct payment *payment, pf->key.payment_hash = payment->payment_hash; /* Convert gossmap_chan into scids and nodes */ - pf->path_scids = tal_arr(pf, struct short_channel_id, plen); + pf->path_scidds = tal_arr(pf, struct short_channel_id_dir, plen); pf->path_nodes = tal_arr(pf, struct node_id, plen); for (size_t j = 0; j < plen; j++) { struct gossmap_node *n; n = gossmap_nth_node(gossmap, f->path[j], !f->dirs[j]); gossmap_node_get_id(gossmap, n, &pf->path_nodes[j]); - pf->path_scids[j] + pf->path_scidds[j].scid = gossmap_chan_scid(gossmap, f->path[j]); + pf->path_scidds[j].dir = f->dirs[j]; } /* Calculate cumulative delays (backwards) */ @@ -307,12 +325,20 @@ static void convert_and_attach_flows(struct payment *payment, + f->path[j]->half[f->dirs[j]].delay; } pf->amounts = tal_steal(pf, f->amounts); - pf->path_dirs = tal_steal(pf, f->dirs); pf->success_prob = f->success_prob; /* Payment keeps a list of its flows. */ list_add(&payment->flows, &pf->list); + /* First time they see this: annotate important points */ + payflow_note(pf, LOG_INFORM, + "amount=%s prob=%.3lf fees=%s delay=%u path=%s", + fmt_amount_msat(tmpctx, payflow_delivered(pf)), + pf->success_prob, + fmt_amount_msat(tmpctx, payflow_fee(pf)), + pf->cltv_delays[0] - pf->cltv_delays[plen-1], + flow_path_annotated(tmpctx, pf)); + /* Increase totals for payment */ amount_msat_accumulate(&payment->total_sent, pf->amounts[0]); amount_msat_accumulate(&payment->total_delivering, @@ -381,12 +407,7 @@ static bool disable_htlc_violations_oneflow(struct payment *p, continue; scid = gossmap_chan_scid(gossmap, flow->path[i]); - debug_paynote(p, "...disabling channel %s: %s", - type_to_string(tmpctx, struct short_channel_id, &scid), - reason); - - /* Add this for future searches for this payment. */ - tal_arr_expand(&p->disabled, scid); + payment_disable_chan(p, scid, LOG_INFORM, "%s", reason); /* Add to existing bitmap */ bitmap_set_bit(disabled, gossmap_chan_idx(gossmap, flow->path[i])); @@ -423,16 +444,14 @@ const char *add_payflows(const tal_t *ctx, bitmap *disabled; const struct gossmap_node *src, *dst; - disabled = make_disabled_bitmap(tmpctx, pay_plugin->gossmap, p->disabled); + disabled = make_disabled_bitmap(tmpctx, pay_plugin->gossmap, p->disabled_scids); src = gossmap_find_node(pay_plugin->gossmap, &pay_plugin->my_id); if (!src) { - debug_paynote(p, "We don't have any channels?"); *ecode = PAY_ROUTE_NOT_FOUND; return tal_fmt(ctx, "We don't have any channels."); } dst = gossmap_find_node(pay_plugin->gossmap, &p->destination); if (!dst) { - debug_paynote(p, "No trace of destination in network gossip"); *ecode = PAY_ROUTE_NOT_FOUND; return tal_fmt(ctx, "Destination is unknown in the network gossip."); } @@ -454,10 +473,6 @@ const char *add_payflows(const tal_t *ctx, p->base_fee_penalty, p->prob_cost_factor); if (!flows) { - debug_paynote(p, - "minflow couldn't find a feasible flow for %s", - type_to_string(tmpctx,struct amount_msat,&amount)); - *ecode = PAY_ROUTE_NOT_FOUND; return tal_fmt(ctx, "minflow couldn't find a feasible flow for %s", @@ -469,7 +484,7 @@ const char *add_payflows(const tal_t *ctx, fee = flow_set_fee(flows); delay = flows_worst_delay(flows) + p->final_cltv; - debug_paynote(p, + payment_note(p, LOG_INFORM, "we have computed a set of %ld flows with probability %.3lf, fees %s and delay %ld", tal_count(flows), prob, @@ -479,9 +494,6 @@ const char *add_payflows(const tal_t *ctx, too_expensive = amount_msat_greater(fee, feebudget); if (too_expensive) { - debug_paynote(p, "Flows too expensive, fee = %s (max %s)", - type_to_string(tmpctx, struct amount_msat, &fee), - type_to_string(tmpctx, struct amount_msat, &feebudget)); *ecode = PAY_ROUTE_TOO_EXPENSIVE; return tal_fmt(ctx, "Fee exceeds our fee budget, " @@ -491,12 +503,8 @@ const char *add_payflows(const tal_t *ctx, } too_delayed = (delay > p->maxdelay); if (too_delayed) { - debug_paynote(p, "Flows too delayed, delay = %"PRIu64" (max %u)", - delay, p->maxdelay); - /* FIXME: What is a sane limit? */ if (p->delay_feefactor > 1000) { - debug_paynote(p, "Giving up!"); *ecode = PAY_ROUTE_TOO_EXPENSIVE; return tal_fmt(ctx, "CLTV delay exceeds our CLTV budget, " @@ -505,8 +513,10 @@ const char *add_payflows(const tal_t *ctx, } p->delay_feefactor *= 2; - debug_paynote(p, "Doubling delay_feefactor to %f", - p->delay_feefactor); + payment_note(p, LOG_INFORM, + "delay %"PRIu64" exceeds our max %u, so doubling delay_feefactor to %f", + delay, p->maxdelay, + p->delay_feefactor); continue; // retry } @@ -540,85 +550,30 @@ const char *add_payflows(const tal_t *ctx, const char *flow_path_to_str(const tal_t *ctx, const struct pay_flow *flow) { char *s = tal_strdup(ctx, ""); - for (size_t i = 0; i < tal_count(flow->path_scids); i++) { + for (size_t i = 0; i < tal_count(flow->path_scidds); i++) { tal_append_fmt(&s, "-%s->", type_to_string(tmpctx, struct short_channel_id, - &flow->path_scids[i])); + &flow->path_scidds[i].scid)); } return s; } -const char* fmt_payflows(const tal_t *ctx, - struct pay_flow ** flows) -{ - struct json_out *jout = json_out_new(ctx); - json_out_start(jout, NULL, '{'); - json_out_start(jout,"Pay_flows",'['); - - for(size_t i=0;isuccess_prob); - - json_out_start(jout,"path_scids",'['); - for(size_t j=0;jpath_scids);++j) - { - json_out_add(jout,NULL,true,"%s", - type_to_string(ctx,struct short_channel_id,&f->path_scids[j])); - } - json_out_end(jout,']'); - - json_out_start(jout,"path_dirs",'['); - for(size_t j=0;jpath_dirs);++j) - { - json_out_add(jout,NULL,false,"%d",f->path_dirs[j]); - } - json_out_end(jout,']'); - - json_out_start(jout,"amounts",'['); - for(size_t j=0;jamounts);++j) - { - json_out_add(jout,NULL,true,"%s", - type_to_string(ctx,struct amount_msat,&f->amounts[j])); - } - json_out_end(jout,']'); - - json_out_start(jout,"cltv_delays",'['); - for(size_t j=0;jcltv_delays);++j) - { - json_out_add(jout,NULL,false,"%d",f->cltv_delays[j]); - } - json_out_end(jout,']'); - - json_out_start(jout,"path_nodes",'['); - for(size_t j=0;jpath_nodes);++j) - { - json_out_add(jout,NULL,true,"%s", - type_to_string(ctx,struct node_id,&f->path_nodes[j])); - } - json_out_end(jout,']'); - - json_out_end(jout,'}'); - } - - json_out_end(jout,']'); - json_out_end(jout, '}'); - json_out_direct(jout, 1)[0] = '\n'; - json_out_direct(jout, 1)[0] = '\0'; - json_out_finished(jout); - - size_t len; - return json_out_contents(jout,&len); -} - /* How much does this flow deliver to destination? */ struct amount_msat payflow_delivered(const struct pay_flow *flow) { return flow->amounts[tal_count(flow->amounts)-1]; } +/* How much does this flow pay in fees? */ +struct amount_msat payflow_fee(const struct pay_flow *pf) +{ + struct amount_msat fee; + + if (!amount_msat_sub(&fee, pf->amounts[0], payflow_delivered(pf))) + abort(); + return fee; +} + static struct pf_result *pf_resolve(struct pay_flow *pf, enum pay_flow_state oldstate, enum pay_flow_state newstate, diff --git a/plugins/renepay/pay_flow.h b/plugins/renepay/pay_flow.h index 4756ad7a2a4e..4a62adb2dec5 100644 --- a/plugins/renepay/pay_flow.h +++ b/plugins/renepay/pay_flow.h @@ -50,9 +50,8 @@ struct pay_flow { } key; /* The series of channels and nodes to traverse. */ - struct short_channel_id *path_scids; + struct short_channel_id_dir *path_scidds; struct node_id *path_nodes; - int *path_dirs; /* CLTV delays for each hop */ u32 *cltv_delays; /* The amounts at each step */ @@ -134,10 +133,10 @@ struct pf_result *pay_flow_succeeded(struct pay_flow *pf STEALS, /* Formatting helpers */ const char *flow_path_to_str(const tal_t *ctx, const struct pay_flow *flow); -const char* fmt_payflows(const tal_t *ctx, - struct pay_flow ** flows); - /* How much does this flow deliver to destination? */ struct amount_msat payflow_delivered(const struct pay_flow *flow); +/* At what cost? */ +struct amount_msat payflow_fee(const struct pay_flow *flow); + #endif /* LIGHTNING_PLUGINS_RENEPAY_PAY_FLOW_H */ diff --git a/plugins/renepay/payment.c b/plugins/renepay/payment.c index 26be01e6bf19..0a95ae7663d9 100644 --- a/plugins/renepay/payment.c +++ b/plugins/renepay/payment.c @@ -65,13 +65,48 @@ struct payment *payment_new(const tal_t *ctx, p->groupid=1; p->local_gossmods = gossmap_localmods_new(p); - p->disabled = tal_arr(p,struct short_channel_id,0); + p->disabled_scids = tal_arr(p,struct short_channel_id,0); p->next_partid=1; p->progress_deadline = NULL; return p; } +/* Disable this scid for this payment, and tell me why! */ +void payflow_disable_chan(struct pay_flow *pf, + struct short_channel_id scid, + enum log_level lvl, + const char *fmt, ...) +{ + va_list ap; + const char *str; + + va_start(ap, fmt); + str = tal_vfmt(tmpctx, fmt, ap); + va_end(ap); + payflow_note(pf, lvl, "disabling %s: %s", + type_to_string(tmpctx, struct short_channel_id, &scid), + str); + tal_arr_expand(&pf->payment->disabled_scids, scid); +} + +void payment_disable_chan(struct payment *p, + struct short_channel_id scid, + enum log_level lvl, + const char *fmt, ...) +{ + va_list ap; + const char *str; + + va_start(ap, fmt); + str = tal_vfmt(tmpctx, fmt, ap); + va_end(ap); + payment_note(p, lvl, "disabling %s: %s", + type_to_string(tmpctx, struct short_channel_id, &scid), + str); + tal_arr_expand(&p->disabled_scids, scid); +} + struct amount_msat payment_sent(const struct payment *p) { return p->total_sent; @@ -98,7 +133,9 @@ struct amount_msat payment_fees(const struct payment *p) return fees; } -void payment_note(struct payment *p, const char *fmt, ...) +void payment_note(struct payment *p, + enum log_level lvl, + const char *fmt, ...) { va_list ap; const char *str; @@ -107,10 +144,27 @@ void payment_note(struct payment *p, const char *fmt, ...) str = tal_vfmt(p->paynotes, fmt, ap); va_end(ap); tal_arr_expand(&p->paynotes, str); - debug_info("%s",str); + /* Log at debug, unless it's weird... */ + plugin_log(pay_plugin->plugin, + lvl < LOG_UNUSUAL ? LOG_DBG : lvl, "%s", str); if (p->cmd) - plugin_notify_message(p->cmd, LOG_INFORM, "%s", str); + plugin_notify_message(p->cmd, lvl, "%s", str); +} + +void payflow_note(struct pay_flow *pf, + enum log_level lvl, + const char *fmt, ...) +{ + va_list ap; + const char *str; + + va_start(ap, fmt); + str = tal_vfmt(tmpctx, fmt, ap); + va_end(ap); + + payment_note(pf->payment, lvl, " Flow %"PRIu64": %s", + pf->key.partid, str); } void payment_assert_delivering_incomplete(const struct payment *p) @@ -163,6 +217,8 @@ struct command_result *payment_fail( enum jsonrpc_errcode code, const char *fmt, ...) { + struct command *cmd; + /* We usually get called because a flow failed, but we * can also get called because we couldn't route any more * or some strange error. */ @@ -177,9 +233,14 @@ struct command_result *payment_fail( char *message = tal_vfmt(tmpctx,fmt,args); va_end(args); - debug_paynote(payment,"%s",message); + /* Don't bother notifying command, it's about to get failure */ + cmd = payment->cmd; + payment->cmd = NULL; + payment_note(payment, LOG_DBG, "%s", message); + /* Restore to keep destructor happy! */ + payment->cmd = cmd; - return command_fail(payment->cmd,code,"%s",message); + return command_fail(cmd,code,"%s",message); } u64 payment_parts(const struct payment *payment) @@ -216,7 +277,8 @@ void payment_reconsider(struct payment *payment) final_msg = tal_steal(tmpctx, i->final_msg); break; case PAY_FLOW_FAILED_GOSSIP_PENDING: - break; + /* Don't free, it's still going! */ + continue; case PAY_FLOW_SUCCESS: if (payment->preimage) { /* This should be impossible without breaking SHA256 */ diff --git a/plugins/renepay/payment.h b/plugins/renepay/payment.h index 219b4a2f534a..da22ad775ad0 100644 --- a/plugins/renepay/payment.h +++ b/plugins/renepay/payment.h @@ -4,6 +4,8 @@ #include #include +struct pay_flow; + enum payment_status { PAYMENT_PENDING, PAYMENT_SUCCESS, PAYMENT_FAIL }; @@ -28,7 +30,7 @@ struct payment { struct gossmap_localmods *local_gossmods; /* Channels we decided to disable for various reasons. */ - struct short_channel_id *disabled; + struct short_channel_id *disabled_scids; /* Used in get_payflows to set ids to each pay_flow. */ u64 next_partid; @@ -140,7 +142,13 @@ struct amount_msat payment_delivered(const struct payment *p); struct amount_msat payment_amount(const struct payment *p); struct amount_msat payment_fees(const struct payment *p); -void payment_note(struct payment *p, const char *fmt, ...); +/* These log at LOG_DBG, append to notes, and send command notification */ +void payment_note(struct payment *p, + enum log_level lvl, + const char *fmt, ...); +void payflow_note(struct pay_flow *pf, + enum log_level lvl, + const char *fmt, ...); void payment_assert_delivering_incomplete(const struct payment *p); void payment_assert_delivering_all(const struct payment *p); @@ -149,6 +157,18 @@ void payment_reconsider(struct payment *p); u64 payment_parts(const struct payment *payment); +/* Disable this scid for this payment, and tell me why! */ +void payflow_disable_chan(struct pay_flow *pf, + struct short_channel_id scid, + enum log_level lvl, + const char *fmt, ...); + +/* Sometimes, disabling chan is independent of a flow. */ +void payment_disable_chan(struct payment *p, + struct short_channel_id scid, + enum log_level lvl, + const char *fmt, ...); + struct command_result *payment_fail( struct payment *payment, enum jsonrpc_errcode code, diff --git a/plugins/renepay/uncertainty_network.c b/plugins/renepay/uncertainty_network.c index 22e3d77af25f..9ee183c4d591 100644 --- a/plugins/renepay/uncertainty_network.c +++ b/plugins/renepay/uncertainty_network.c @@ -188,12 +188,11 @@ void uncertainty_network_flow_success( struct chan_extra_map *chan_extra_map, struct pay_flow *pf) { - for (size_t i = 0; i < tal_count(pf->path_scids); i++) + for (size_t i = 0; i < tal_count(pf->path_scidds); i++) { chan_extra_sent_success( - chan_extra_map, - pf->path_scids[i], - pf->path_dirs[i], + pf, chan_extra_map, + &pf->path_scidds[i], pf->amounts[i]); } } @@ -207,9 +206,7 @@ void uncertainty_network_channel_can_send( for (size_t i = 0; i < erridx; i++) { chan_extra_can_send(chan_extra_map, - pf->path_scids[i], - pf->path_dirs[i], - + &pf->path_scidds[i], /* This channel can send all that was * commited in HTLCs. * Had we removed the commited amount then @@ -238,14 +235,14 @@ bool uncertainty_network_update_from_listpeerchannels( goto malformed; json_for_each_arr(i, channel, channels) { - struct short_channel_id scid; + struct short_channel_id_dir scidd; const jsmntok_t *scidtok = json_get_member(buf, channel, "short_channel_id"); /* If channel is still opening, this won't be there. * Also it won't be in the gossmap, so there is * no need to mark it as disabled. */ if (!scidtok) continue; - if (!json_to_short_channel_id(buf, scidtok, &scid)) + if (!json_to_short_channel_id(buf, scidtok, &scidd.scid)) goto malformed; bool connected; @@ -255,19 +252,14 @@ bool uncertainty_network_update_from_listpeerchannels( goto malformed; if (!connected) { - debug_paynote(p, "local channel %s disabled:" - " peer disconnected", - type_to_string(tmpctx, - struct short_channel_id, - &scid)); - tal_arr_expand(&p->disabled, scid); + payment_disable_chan(p, scidd.scid, LOG_DBG, + "peer disconnected"); continue; } const jsmntok_t *spendabletok, *dirtok,*statetok, *totaltok, *peeridtok; struct amount_msat spendable,capacity; - int dir; const struct node_id src=my_id; struct node_id dst; @@ -285,7 +277,7 @@ bool uncertainty_network_update_from_listpeerchannels( goto malformed; if (!json_to_msat(buf, totaltok, &capacity)) goto malformed; - if (!json_to_int(buf, dirtok,&dir)) + if (!json_to_int(buf, dirtok, &scidd.dir)) goto malformed; if(!json_to_node_id(buf,peeridtok,&dst)) goto malformed; @@ -293,24 +285,27 @@ bool uncertainty_network_update_from_listpeerchannels( /* Don't report opening/closing channels */ if (!json_tok_streq(buf, statetok, "CHANNELD_NORMAL") && !json_tok_streq(buf, statetok, "CHANNELD_AWAITING_SPLICE")) { - tal_arr_expand(&p->disabled, scid); + payment_disable_chan(p, scidd.scid, LOG_DBG, + "channel in state %.*s", + statetok->end - statetok->start, + buf + statetok->start); continue; } struct chan_extra *ce = chan_extra_map_get(chan_extra_map, - scid); + scidd.scid); if(!ce) { /* this channel is not public, but it belongs to us */ ce = new_chan_extra(chan_extra_map, - scid, + scidd.scid, capacity); /* FIXME: features? */ gossmap_local_addchan(p->local_gossmods, - &src, &dst, &scid, NULL); + &src, &dst, &scidd.scid, NULL); gossmap_local_updatechan(p->local_gossmods, - &scid, + &scidd.scid, /* TODO(eduardo): does it * matter to consider HTLC @@ -323,14 +318,14 @@ bool uncertainty_network_update_from_listpeerchannels( * matter to set this delay? */ /*delay=*/0, true, - dir); + scidd.dir); } // TODO(eduardo): this includes pending HTLC of previous // payments! /* We know min and max liquidity exactly now! */ chan_extra_set_liquidity(chan_extra_map, - scid,dir,spendable); + &scidd,spendable); } return true;