#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static struct gossmap *global_gossmap; static void init_gossmap(struct plugin *plugin) { size_t num_channel_updates_rejected; global_gossmap = notleak_with_children(gossmap_load(NULL, GOSSIP_STORE_FILENAME, &num_channel_updates_rejected)); if (!global_gossmap) plugin_err(plugin, "Could not load gossmap %s: %s", GOSSIP_STORE_FILENAME, strerror(errno)); if (num_channel_updates_rejected) plugin_log(plugin, LOG_DBG, "gossmap ignored %zu channel updates", num_channel_updates_rejected); } struct gossmap *get_gossmap(struct plugin *plugin) { if (!global_gossmap) init_gossmap(plugin); else gossmap_refresh(global_gossmap, NULL); return global_gossmap; } struct payment *payment_new(tal_t *ctx, struct command *cmd, struct payment *parent, struct payment_modifier **mods) { struct payment *p = tal(ctx, struct payment); static u64 next_id = 0; p->children = tal_arr(p, struct payment *, 0); p->parent = parent; p->modifiers = mods; p->cmd = cmd; p->start_time = time_now(); p->result = NULL; p->why = NULL; p->getroute = tal(p, struct getroute_request); p->label = NULL; p->failreason = NULL; p->getroute->riskfactorppm = 10000000; p->abort = false; p->invstring_used = false; p->route = NULL; p->temp_exclusion = NULL; p->failroute_retry = false; p->routetxt = NULL; p->max_htlcs = UINT32_MAX; p->aborterror = NULL; p->on_payment_success = NULL; p->on_payment_failure = NULL; /* Copy over the relevant pieces of information. */ if (parent != NULL) { assert(cmd == NULL); tal_arr_expand(&parent->children, p); p->destination = parent->destination; p->amount = parent->amount; p->label = parent->label; p->payment_hash = parent->payment_hash; p->partid = payment_root(p->parent)->next_partid++; p->plugin = parent->plugin; /* Re-establish the unmodified constraints for our sub-payment. */ p->constraints = *parent->start_constraints; p->deadline = parent->deadline; p->min_final_cltv_expiry = parent->min_final_cltv_expiry; p->routes = parent->routes; p->features = parent->features; p->id = parent->id; p->local_id = parent->local_id; p->local_invreq_id = parent->local_invreq_id; p->groupid = parent->groupid; p->invstring = parent->invstring; p->description = parent->description; } else { assert(cmd != NULL); p->partid = 0; p->next_partid = 1; p->plugin = cmd->plugin; p->channel_hints = tal_arr(p, struct channel_hint, 0); p->excluded_nodes = tal_arr(p, struct node_id, 0); p->id = next_id++; p->description = NULL; /* Caller must set this. */ p->local_id = NULL; p->local_invreq_id = NULL; p->groupid = 0; } /* Initialize all modifier data so we can point to the fields when * wiring into the param() call in a JSON-RPC handler. The callback * can also just `memcpy` the parent if this outside access is not * required. */ p->modifier_data = tal_arr(p, void *, 0); for (size_t i=0; mods[i] != NULL; i++) { if (mods[i]->data_init != NULL) tal_arr_expand(&p->modifier_data, mods[i]->data_init(p)); else tal_arr_expand(&p->modifier_data, NULL); } return p; } struct payment *payment_root(struct payment *p) { if (p->parent == NULL) return p; else return payment_root(p->parent); } static void paymod_log_header(struct payment *p, const char **type, u64 *id) { struct payment *root = payment_root(p); /* We prefer to show the command ID here since it is also known * by `lightningd`, so in theory it can be used to correlate * debugging logs between the main `lightningd` and whatever * plugin is using the paymod system. * We only fall back to a unique id per root payment if there * is no command with an id associated with this payment. */ if (root->cmd && root->cmd->id) { *type = "cmd"; *id = *root->cmd->id; } else { *type = "id"; *id = root->id; } } static void paymod_log(struct payment *p, enum log_level l, const char *fmt, ...) { const char *type; u64 id; char *txt; va_list ap; va_start(ap, fmt); txt = tal_vfmt(tmpctx, fmt, ap); va_end(ap); paymod_log_header(p, &type, &id); plugin_log(p->plugin, l, "%s %"PRIu64" partid %"PRIu32": %s", type, id, p->partid, txt); } static void paymod_err(struct payment *p, const char *fmt, ...) { const char *type; u64 id; char *txt; va_list ap; va_start(ap, fmt); txt = tal_vfmt(tmpctx, fmt, ap); va_end(ap); paymod_log_header(p, &type, &id); plugin_err(p->plugin, "%s %"PRIu64" partid %"PRIu32": %s", type, id, p->partid, txt); } /* Generic handler for RPC failures that should end up failing the payment. */ static struct command_result *payment_rpc_failure(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { payment_fail(p, "Failing a partial payment due to a failed RPC call: %.*s", toks->end - toks->start, buffer + toks->start); return command_still_pending(cmd); } struct payment_tree_result payment_collect_result(struct payment *p) { struct payment_tree_result res; size_t numchildren = tal_count(p->children); res.sent = AMOUNT_MSAT(0); res.attempts = 1; res.treestates = p->step; res.leafstates = 0; res.preimage = NULL; res.failure = NULL; if (p->step == PAYMENT_STEP_FAILED && p->result != NULL) res.failure = p->result; if (numchildren == 0) { res.leafstates |= p->step; if (p->result && p->result->state == PAYMENT_COMPLETE) { res.sent = p->result->amount_sent; res.preimage = p->result->payment_preimage; } } for (size_t i = 0; i < numchildren; i++) { struct payment_tree_result cres = payment_collect_result(p->children[i]); /* Some of our subpayments have succeeded, aggregate how much * we sent in total. */ if (!amount_msat_add(&res.sent, res.sent, cres.sent)) paymod_err( p, "Number overflow summing partial payments: %s + %s", type_to_string(tmpctx, struct amount_msat, &res.sent), type_to_string(tmpctx, struct amount_msat, &cres.sent)); /* Bubble up the first preimage we see. */ if (res.preimage == NULL && cres.preimage != NULL) res.preimage = cres.preimage; res.leafstates |= cres.leafstates; res.treestates |= cres.treestates; res.attempts += cres.attempts; /* We bubble the failure result with the highest failcode up * to the root. */ if (res.failure == NULL || (cres.failure != NULL && cres.failure->failcode > res.failure->failcode)) { res.failure = cres.failure; } } return res; } static struct command_result * payment_getblockheight_success(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { const jsmntok_t *blockheighttok = json_get_member(buffer, toks, "blockheight"); json_to_number(buffer, blockheighttok, &p->start_block); payment_continue(p); return command_still_pending(cmd); } #define INVALID_BLOCKHEIGHT UINT32_MAX static void payment_start_at_blockheight(struct payment *p, u32 blockheight) { struct payment *root = payment_root(p); /* Should have been set in root payment, or propagated from root * payment to all child payments. */ assert(p->local_id); p->step = PAYMENT_STEP_INITIALIZED; p->current_modifier = -1; /* Pre-generate the getroute request, so modifiers can have their say, * before we actually call `getroute` */ p->getroute->destination = p->destination; p->getroute->max_hops = ROUTING_MAX_HOPS; p->getroute->cltv = root->min_final_cltv_expiry; p->getroute->amount = p->amount; p->start_constraints = tal_dup(p, struct payment_constraints, &p->constraints); if (blockheight != INVALID_BLOCKHEIGHT) { /* The caller knows the actual blockheight. */ p->start_block = blockheight; return payment_continue(p); } if (p->parent) { /* The parent should have a start block. */ p->start_block = p->parent->start_block; return payment_continue(p); } /* `waitblockheight 0` can be used as a query for the current * block height. * This is slightly better than `getinfo` since `getinfo` * counts the channels and addresses and pushes more data * onto the RPC but all we care about is the blockheight. */ struct out_req *req; req = jsonrpc_request_start(p->plugin, NULL, "waitblockheight", &payment_getblockheight_success, &payment_rpc_failure, p); json_add_u32(req->js, "blockheight", 0); send_outreq(p->plugin, req); } void payment_start(struct payment *p) { payment_start_at_blockheight(p, INVALID_BLOCKHEIGHT); } static void channel_hints_update(struct payment *p, const struct short_channel_id scid, int direction, bool enabled, bool local, const struct amount_msat *estimated_capacity, u16 *htlc_budget) { struct payment *root = payment_root(p); struct channel_hint newhint; /* If the channel is marked as enabled it must have an estimate. */ assert(!enabled || estimated_capacity != NULL); /* Try and look for an existing hint: */ for (size_t i=0; ichannel_hints); i++) { struct channel_hint *hint = &root->channel_hints[i]; if (short_channel_id_eq(&hint->scid.scid, &scid) && hint->scid.dir == direction) { bool modified = false; /* Prefer to disable a channel. */ if (!enabled && hint->enabled) { hint->enabled = false; modified = true; } /* Prefer the more conservative estimate. */ if (estimated_capacity != NULL && amount_msat_greater(hint->estimated_capacity, *estimated_capacity)) { hint->estimated_capacity = *estimated_capacity; modified = true; } if (htlc_budget != NULL) { assert(hint->local); hint->local->htlc_budget = *htlc_budget; modified = true; } if (modified) paymod_log(p, LOG_DBG, "Updated a channel hint for %s: " "enabled %s, " "estimated capacity %s", type_to_string(tmpctx, struct short_channel_id_dir, &hint->scid), hint->enabled ? "true" : "false", type_to_string(tmpctx, struct amount_msat, &hint->estimated_capacity)); return; } } /* No hint found, create one. */ newhint.enabled = enabled; newhint.scid.scid = scid; newhint.scid.dir = direction; if (local) { newhint.local = tal(root->channel_hints, struct local_hint); assert(htlc_budget); newhint.local->htlc_budget = *htlc_budget; } else newhint.local = NULL; if (estimated_capacity != NULL) newhint.estimated_capacity = *estimated_capacity; tal_arr_expand(&root->channel_hints, newhint); paymod_log( p, LOG_DBG, "Added a channel hint for %s: enabled %s, estimated capacity %s", type_to_string(tmpctx, struct short_channel_id_dir, &newhint.scid), newhint.enabled ? "true" : "false", type_to_string(tmpctx, struct amount_msat, &newhint.estimated_capacity)); } static void payment_exclude_most_expensive(struct payment *p) { struct route_hop *e = &p->route[0]; struct amount_msat fee, worst = AMOUNT_MSAT(0); for (size_t i = 0; i < tal_count(p->route)-1; i++) { if (!amount_msat_sub(&fee, p->route[i].amount, p->route[i+1].amount)) paymod_err(p, "Negative fee in a route."); if (amount_msat_greater_eq(fee, worst)) { e = &p->route[i]; worst = fee; } } channel_hints_update(p, e->scid, e->direction, false, false, NULL, NULL); } static void payment_exclude_longest_delay(struct payment *p) { struct route_hop *e = &p->route[0]; u32 delay, worst = 0; for (size_t i = 0; i < tal_count(p->route)-1; i++) { delay = p->route[i].delay - p->route[i+1].delay; if (delay >= worst) { e = &p->route[i]; worst = delay; } } channel_hints_update(p, e->scid, e->direction, false, false, NULL, NULL); } static struct amount_msat payment_route_fee(struct payment *p) { struct amount_msat fee; if (!amount_msat_sub(&fee, p->route[0].amount, p->amount)) { paymod_log( p, LOG_BROKEN, "gossipd returned a route with a negative fee: sending %s " "to deliver %s", type_to_string(tmpctx, struct amount_msat, &p->route[0].amount), type_to_string(tmpctx, struct amount_msat, &p->amount)); abort(); } return fee; } /* Update the constraints by subtracting the delta_fee and delta_cltv if the * result is positive. Returns whether or not the update has been applied. */ static WARN_UNUSED_RESULT bool payment_constraints_update(struct payment_constraints *cons, const struct amount_msat delta_fee, const u32 delta_cltv) { if (delta_cltv > cons->cltv_budget) return false; /* amount_msat_sub performs a check before actually subtracting. */ if (!amount_msat_sub(&cons->fee_budget, cons->fee_budget, delta_fee)) return false; cons->cltv_budget -= delta_cltv; return true; } static struct channel_hint *payment_chanhints_get(struct payment *p, struct route_hop *h) { struct payment *root = payment_root(p); struct channel_hint *curhint; for (size_t j = 0; j < tal_count(root->channel_hints); j++) { curhint = &root->channel_hints[j]; if (short_channel_id_eq(&curhint->scid.scid, &h->scid) && curhint->scid.dir == h->direction) { return curhint; } } return NULL; } /* Given a route and a couple of channel hints, apply the route to the channel * hints, so we have a better estimation of channel's capacity. We apply a * route to a channel hint before calling `sendonion` so subsequent `route` * calls don't accidentally try to use those out-of-date estimates. We unapply * if the payment failed, i.e., all HTLCs we might have added have been torn * down again. Finally we leave the update in place if the payment went * through, since the balances really changed in that case. The `remove` * argument indicates whether we want to apply (`remove=false`), or clear a * prior application (`remove=true`). */ static bool payment_chanhints_apply_route(struct payment *p, bool remove) { bool apply; struct route_hop *curhop; struct channel_hint *curhint; struct payment *root = payment_root(p); assert(p->route != NULL); /* No need to check for applicability if we increase * capacity and budgets. */ if (remove) goto apply_changes; /* First round: make sure we can cleanly apply the update. */ for (size_t i = 0; i < tal_count(p->route); i++) { curhop = &p->route[i]; curhint = payment_chanhints_get(root, curhop); /* If we don't have a hint we can't fail updating it. */ if (!curhint) continue; /* For local channels we check that we don't overwhelm * them with too many HTLCs. */ apply = (!curhint->local) || (curhint->local->htlc_budget > 0); /* For all channels we check that they have a * sufficiently large estimated capacity to have some * chance of succeeding. */ apply &= amount_msat_greater_eq(curhint->estimated_capacity, curhop->amount); if (!apply) { /* This can happen in case of multiple * concurrent getroute calls using the * same channel_hints, no biggy, it's * an estimation anyway. */ paymod_log(p, LOG_DBG, "Could not update the channel hint " "for %s. Could be a concurrent " "`getroute` call.", type_to_string(tmpctx, struct short_channel_id_dir, &curhint->scid)); paymod_log( p, LOG_DBG, "Capacity: estimated_capacity=%s, hop_amount=%s. " "local=%s%s", type_to_string(tmpctx, struct amount_msat, &curhint->estimated_capacity), type_to_string(tmpctx, struct amount_msat, &curhop->amount), curhint->local ? "Y" : "N", curhint->local ? tal_fmt(tmpctx, " HTLC Budget: htlc_budget=%d", curhint->local->htlc_budget) : ""); return false; } } apply_changes: /* Second round: apply the changes, now that we know they'll succeed. */ for (size_t i = 0; i < tal_count(p->route); i++) { curhop = &p->route[i]; curhint = payment_chanhints_get(root, curhop); if (!curhint) continue; /* Update the number of htlcs for any local * channel in the route */ if (curhint->local) { if (remove) curhint->local->htlc_budget++; else curhint->local->htlc_budget--; } if (remove && !amount_msat_add( &curhint->estimated_capacity, curhint->estimated_capacity, curhop->amount)) { /* This should never happen, it'd mean * that we unapply a route that would * result in a msatoshi * wrap-around. */ abort(); } else if (!amount_msat_sub( &curhint->estimated_capacity, curhint->estimated_capacity, curhop->amount)) { /* Given our preemptive test * above, this should never * happen either. */ abort(); } } return true; } static const struct short_channel_id_dir * payment_get_excluded_channels(const tal_t *ctx, struct payment *p) { struct payment *root = payment_root(p); struct channel_hint *hint; struct short_channel_id_dir *res = tal_arr(ctx, struct short_channel_id_dir, 0); for (size_t i = 0; i < tal_count(root->channel_hints); i++) { hint = &root->channel_hints[i]; if (!hint->enabled) tal_arr_expand(&res, hint->scid); else if (amount_msat_greater(p->amount, hint->estimated_capacity)) tal_arr_expand(&res, hint->scid); else if (hint->local && hint->local->htlc_budget == 0) /* If we cannot add any HTLCs to the channel we * shouldn't look for a route through that channel */ tal_arr_expand(&res, hint->scid); } return res; } static const struct node_id *payment_get_excluded_nodes(const tal_t *ctx, struct payment *p) { struct payment *root = payment_root(p); return root->excluded_nodes; } /* FIXME: This is slow! */ static const struct channel_hint *find_hint(const struct channel_hint *hints, const struct short_channel_id *scid, int dir) { for (size_t i = 0; i < tal_count(hints); i++) { if (short_channel_id_eq(scid, &hints[i].scid.scid) && dir == hints[i].scid.dir) return &hints[i]; } return NULL; } /* FIXME: This is slow! */ static bool dst_is_excluded(const struct gossmap *gossmap, const struct gossmap_chan *c, int dir, const struct node_id *nodes) { struct node_id dstid; /* Premature optimization */ if (!tal_count(nodes)) return false; gossmap_node_get_id(gossmap, gossmap_nth_node(gossmap, c, !dir), &dstid); for (size_t i = 0; i < tal_count(nodes); i++) { if (node_id_eq(&dstid, &nodes[i])) return true; } return false; } static bool payment_route_check(const struct gossmap *gossmap, const struct gossmap_chan *c, int dir, struct amount_msat amount, struct payment *p) { struct short_channel_id scid; const struct channel_hint *hint; if (dst_is_excluded(gossmap, c, dir, payment_root(p)->excluded_nodes)) return false; if (dst_is_excluded(gossmap, c, dir, p->temp_exclusion)) return false; scid = gossmap_chan_scid(gossmap, c); hint = find_hint(payment_root(p)->channel_hints, &scid, dir); if (!hint) return true; if (!hint->enabled) return false; if (amount_msat_greater_eq(amount, hint->estimated_capacity)) /* We exclude on equality because we've set the * estimate to the smallest failed attempt. */ return false; if (hint->local && hint->local->htlc_budget == 0) /* If we cannot add any HTLCs to the channel we * shouldn't look for a route through that channel */ return false; return true; } static bool payment_route_can_carry(const struct gossmap *map, const struct gossmap_chan *c, int dir, struct amount_msat amount, struct payment *p) { if (!route_can_carry(map, c, dir, amount, p)) return false; return payment_route_check(map, c, dir, amount, p); } static bool payment_route_can_carry_even_disabled(const struct gossmap *map, const struct gossmap_chan *c, int dir, struct amount_msat amount, struct payment *p) { if (!route_can_carry_even_disabled(map, c, dir, amount, p)) return false; return payment_route_check(map, c, dir, amount, p); } /* Rene Pickhardt: * * Btw the linear term of the Taylor series of -log((c+1-x)/(c+1)) is 1/(c+1) * meaning that another suitable Weight for Dijkstra would be amt/(c+1) + * \mu*fee(amt) which is the linearized version which for small amounts and * suitable value of \mu should be good enough) */ static u64 capacity_bias(const struct gossmap *map, const struct gossmap_chan *c, int dir, struct amount_msat amount) { struct amount_sat capacity; u64 amtmsat = amount.millisatoshis; /* Raw: lengthy math */ double capmsat; /* Can fail in theory if gossmap changed underneath. */ if (!gossmap_chan_get_capacity(map, c, &capacity)) return 0; capmsat = (double)capacity.satoshis * 1000; /* Raw: lengthy math */ return -log((capmsat + 1 - amtmsat) / (capmsat + 1)); } /* Prioritize costs over distance, but bias to larger channels. */ static u64 route_score(u32 distance, struct amount_msat cost, struct amount_msat risk, int dir, const struct gossmap_chan *c) { u64 cmsat = cost.millisatoshis; /* Raw: lengthy math */ u64 rmsat = risk.millisatoshis; /* Raw: lengthy math */ u64 bias = capacity_bias(global_gossmap, c, dir, cost); /* Smoothed harmonic mean to avoid division by 0 */ u64 costs = (cmsat * rmsat * bias) / (cmsat + rmsat + bias + 1); if (costs > 0xFFFFFFFF) costs = 0xFFFFFFFF; return costs; } static struct route_hop *route(const tal_t *ctx, struct gossmap *gossmap, const struct gossmap_node *src, const struct gossmap_node *dst, struct amount_msat amount, u32 final_delay, double riskfactor, size_t max_hops, struct payment *p, const char **errmsg) { const struct dijkstra *dij; struct route_hop *r; bool (*can_carry)(const struct gossmap *, const struct gossmap_chan *, int, struct amount_msat, struct payment *); can_carry = payment_route_can_carry; dij = dijkstra(tmpctx, gossmap, dst, amount, riskfactor, can_carry, route_score, p); r = route_from_dijkstra(ctx, gossmap, dij, src, amount, final_delay); if (!r) { /* Try using disabled channels too */ /* FIXME: is there somewhere we can annotate this for paystatus? */ can_carry = payment_route_can_carry_even_disabled; dij = dijkstra(tmpctx, gossmap, dst, amount, riskfactor, can_carry, route_score, p); r = route_from_dijkstra(ctx, gossmap, dij, src, amount, final_delay); if (!r) { *errmsg = "No path found"; return NULL; } } /* If it's too far, fall back to using shortest path. */ if (tal_count(r) > max_hops) { tal_free(r); /* FIXME: is there somewhere we can annotate this for paystatus? */ dij = dijkstra(tmpctx, gossmap, dst, amount, riskfactor, can_carry, route_score_shorter, p); r = route_from_dijkstra(ctx, gossmap, dij, src, amount, final_delay); if (!r) { *errmsg = "No path found"; return NULL; } /* If it's still too far, fail. */ if (tal_count(r) > max_hops) { *errmsg = tal_fmt(ctx, "Shortest path found was length %zu", tal_count(r)); return tal_free(r); } } return r; } static struct command_result *payment_getroute(struct payment *p) { const struct gossmap_node *dst, *src; struct amount_msat fee; const char *errstr; struct gossmap *gossmap; /* If we retry the getroute call we might already have a route, so * free an eventual stale route. */ p->route = tal_free(p->route); gossmap = get_gossmap(p->plugin); dst = gossmap_find_node(gossmap, p->getroute->destination); if (!dst) { payment_fail( p, "Unknown destination %s", type_to_string(tmpctx, struct node_id, p->getroute->destination)); /* Let payment_finished_ handle this, so we mark it as pending */ return command_still_pending(p->cmd); } /* If we don't exist in gossip, routing can't happen. */ src = gossmap_find_node(gossmap, p->local_id); if (!src) { payment_fail(p, "We don't have any channels"); /* Let payment_finished_ handle this, so we mark it as pending */ return command_still_pending(p->cmd); } p->route = route(p, gossmap, src, dst, p->getroute->amount, p->getroute->cltv, p->getroute->riskfactorppm / 1000000.0, p->getroute->max_hops, p, &errstr); if (!p->route) { payment_fail(p, "%s", errstr); /* Let payment_finished_ handle this, so we mark it as pending */ return command_still_pending(p->cmd); } /* OK, now we *have* a route */ p->step = PAYMENT_STEP_GOT_ROUTE; if (tal_count(p->route) == 0) { payment_root(p)->abort = true; payment_fail(p, "Empty route returned by getroute, are you " "trying to pay yourself?"); } fee = payment_route_fee(p); /* Ensure that our fee and CLTV budgets are respected. */ if (amount_msat_greater(fee, p->constraints.fee_budget)) { payment_exclude_most_expensive(p); p->route = tal_free(p->route); payment_fail( p, "Fee exceeds our fee budget: %s > %s, discarding route", type_to_string(tmpctx, struct amount_msat, &fee), type_to_string(tmpctx, struct amount_msat, &p->constraints.fee_budget)); return command_still_pending(p->cmd); } if (p->route[0].delay > p->constraints.cltv_budget) { u32 delay = p->route[0].delay; payment_exclude_longest_delay(p); p->route = tal_free(p->route); payment_fail(p, "CLTV delay exceeds our CLTV budget: %d > %d", delay, p->constraints.cltv_budget); return command_still_pending(p->cmd); } /* Now update the constraints in fee_budget and cltv_budget so * modifiers know what constraints they need to adhere to. */ if (!payment_constraints_update(&p->constraints, fee, p->route[0].delay)) { paymod_log(p, LOG_BROKEN, "Could not update constraints."); abort(); } /* Allow modifiers to modify the route, before * payment_compute_onion_payloads uses the route to generate the * onion_payloads */ payment_continue(p); return command_still_pending(p->cmd); } static struct payment_result *tal_sendpay_result_from_json(const tal_t *ctx, const char *buffer, const jsmntok_t *toks) { const jsmntok_t *idtok = json_get_member(buffer, toks, "id"); const jsmntok_t *hashtok = json_get_member(buffer, toks, "payment_hash"); const jsmntok_t *partidtok = json_get_member(buffer, toks, "partid"); const jsmntok_t *senttok = json_get_member(buffer, toks, "amount_sent_msat"); const jsmntok_t *statustok = json_get_member(buffer, toks, "status"); const jsmntok_t *preimagetok = json_get_member(buffer, toks, "payment_preimage"); const jsmntok_t *codetok = json_get_member(buffer, toks, "code"); const jsmntok_t *datatok = json_get_member(buffer, toks, "data"); const jsmntok_t *erridxtok, *msgtok, *failcodetok, *rawmsgtok, *failcodenametok, *errchantok, *errnodetok, *errdirtok; struct payment_result *result; /* Check if we have an error and need to descend into data to get * details. */ if (codetok != NULL && datatok != NULL) { idtok = json_get_member(buffer, datatok, "id"); hashtok = json_get_member(buffer, datatok, "payment_hash"); partidtok = json_get_member(buffer, datatok, "partid"); senttok = json_get_member(buffer, datatok, "amount_sent_msat"); statustok = json_get_member(buffer, datatok, "status"); } /* Initial sanity checks, all these fields must exist. */ if (idtok == NULL || idtok->type != JSMN_PRIMITIVE || hashtok == NULL || hashtok->type != JSMN_STRING || senttok == NULL || statustok == NULL || statustok->type != JSMN_STRING) { return NULL; } result = tal(ctx, struct payment_result); if (codetok != NULL) json_to_u32(buffer, codetok, &result->code); else result->code = 0; /* If the partid is 0 it'd be omitted in waitsendpay, fix this here. */ if (partidtok != NULL) json_to_u32(buffer, partidtok, &result->partid); else result->partid = 0; json_to_u64(buffer, idtok, &result->id); json_to_msat(buffer, senttok, &result->amount_sent); if (json_tok_streq(buffer, statustok, "pending")) { result->state = PAYMENT_PENDING; } else if (json_tok_streq(buffer, statustok, "complete")) { result->state = PAYMENT_COMPLETE; } else if (json_tok_streq(buffer, statustok, "failed")) { result->state = PAYMENT_FAILED; } else { goto fail; } if (preimagetok != NULL) { result->payment_preimage = tal(result, struct preimage); json_to_preimage(buffer, preimagetok, result->payment_preimage); } /* Now extract the error details if the error code is not 0 */ if (result->code != 0) { erridxtok = json_get_member(buffer, datatok, "erring_index"); errnodetok = json_get_member(buffer, datatok, "erring_node"); errchantok = json_get_member(buffer, datatok, "erring_channel"); errdirtok = json_get_member(buffer, datatok, "erring_direction"); failcodetok = json_get_member(buffer, datatok, "failcode"); failcodenametok =json_get_member(buffer, datatok, "failcodename"); msgtok = json_get_member(buffer, toks, "message"); rawmsgtok = json_get_member(buffer, datatok, "raw_message"); if (failcodetok == NULL || failcodetok->type != JSMN_PRIMITIVE || (failcodenametok != NULL && failcodenametok->type != JSMN_STRING) || (erridxtok != NULL && erridxtok->type != JSMN_PRIMITIVE) || (errnodetok != NULL && errnodetok->type != JSMN_STRING) || (errchantok != NULL && errchantok->type != JSMN_STRING) || (errdirtok != NULL && errdirtok->type != JSMN_PRIMITIVE) || msgtok == NULL || msgtok->type != JSMN_STRING || (rawmsgtok != NULL && rawmsgtok->type != JSMN_STRING)) goto fail; if (rawmsgtok != NULL) result->raw_message = json_tok_bin_from_hex(result, buffer, rawmsgtok); else result->raw_message = NULL; if (failcodenametok != NULL) result->failcodename = json_strdup(result, buffer, failcodenametok); else result->failcodename = NULL; json_to_u32(buffer, failcodetok, &result->failcode); result->message = json_strdup(result, buffer, msgtok); if (erridxtok != NULL) { result->erring_index = tal(result, u32); json_to_u32(buffer, erridxtok, result->erring_index); } else { result->erring_index = NULL; } if (errdirtok != NULL) { result->erring_direction = tal(result, int); json_to_int(buffer, errdirtok, result->erring_direction); } else { result->erring_direction = NULL; } if (errnodetok != NULL) { result->erring_node = tal(result, struct node_id); json_to_node_id(buffer, errnodetok, result->erring_node); } else { result->erring_node = NULL; } if (errchantok != NULL) { result->erring_channel = tal(result, struct short_channel_id); json_to_short_channel_id(buffer, errchantok, result->erring_channel); } else { result->erring_channel = NULL; } } return result; fail: return tal_free(result); } /* Try to infer the erring_node, erring_channel and erring_direction from what * we know, but don't override the values that are returned by `waitsendpay`. */ static void payment_result_infer(struct route_hop *route, struct payment_result *r) { int i, len; assert(r != NULL); if (r->code == 0 || r->erring_index == NULL || route == NULL) return; len = tal_count(route); i = *r->erring_index; assert(i <= len); if (r->erring_node == NULL) r->erring_node = &route[i-1].node_id; /* The above assert was enough for the erring_node, but might be off * by one on channel and direction, in case the destination failed on * us. */ if (i == len) return; if (r->erring_channel == NULL) r->erring_channel = &route[i].scid; if (r->erring_direction == NULL) r->erring_direction = &route[i].direction; } /* If a node takes too much fee or cltv, the next one reports it. We don't * know who to believe, but log it */ static void report_tampering(struct payment *p, size_t report_pos, const char *style) { const struct node_id *id = &p->route[report_pos].node_id; if (report_pos == 0) { paymod_log(p, LOG_UNUSUAL, "Node #%zu (%s) claimed we sent them invalid %s", report_pos + 1, type_to_string(tmpctx, struct node_id, id), style); } else { paymod_log(p, LOG_UNUSUAL, "Node #%zu (%s) claimed #%zu (%s) sent them invalid %s", report_pos + 1, type_to_string(tmpctx, struct node_id, id), report_pos, type_to_string(tmpctx, struct node_id, &p->route[report_pos-1].node_id), style); } } static bool failure_is_blockheight_disagreement(const struct payment *p, u32 *blockheight) { struct amount_msat unused; assert(p && p->result); if (p->result->failcode == 17 /* Former final_expiry_too_soon */) *blockheight = p->start_block + 1; else if (!fromwire_incorrect_or_unknown_payment_details( p->result->raw_message, &unused, blockheight)) /* If it's incorrect_or_unknown_payment_details, that tells us * what height they're at */ return false; /* If we are already at the desired blockheight there is no point in * waiting, and it is likely just some other error. Notice that * start_block gets set by the initial getinfo call for each * attempt.*/ if (*blockheight <= p->start_block) return false; return true; } static char *describe_failcode(const tal_t *ctx, enum onion_wire failcode) { char *rv = tal_strdup(ctx, ""); if (failcode & BADONION) { tal_append_fmt(&rv, "BADONION|"); failcode &= ~BADONION; } if (failcode & PERM) { tal_append_fmt(&rv, "PERM|"); failcode &= ~PERM; } if (failcode & NODE) { tal_append_fmt(&rv, "NODE|"); failcode &= ~NODE; } if (failcode & UPDATE) { tal_append_fmt(&rv, "UPDATE|"); failcode &= ~UPDATE; } tal_append_fmt(&rv, "%u", failcode); return rv; } static struct command_result * handle_final_failure(struct command *cmd, struct payment *p, const struct node_id *final_id, enum onion_wire failcode) { u32 unused; /* Need to check for blockheight disagreement case here, * otherwise we would set the abort flag too eagerly. */ if (failure_is_blockheight_disagreement(p, &unused)) { paymod_log(p, LOG_DBG, "Blockheight disagreement, not aborting."); goto nonerror; } paymod_log(p, LOG_DBG, "Final node %s reported %04x (%s) on route %s", type_to_string(tmpctx, struct node_id, final_id), failcode, onion_wire_name(failcode), p->routetxt); /* We use an exhaustive switch statement here so you get a compile * warning when new ones are added, and can think about where they go */ switch (failcode) { case WIRE_FINAL_INCORRECT_CLTV_EXPIRY: report_tampering(p, tal_count(p->route)-1, "cltv"); goto error; case WIRE_FINAL_INCORRECT_HTLC_AMOUNT: report_tampering(p, tal_count(p->route)-1, "amount"); goto error; /* BOLT #4: * * A _forwarding node_ MAY, but a _final node_ MUST NOT: *... * - return an `invalid_onion_version` error. *... * - return an `invalid_onion_hmac` error. *... * - return an `invalid_onion_key` error. *... * - return a `temporary_channel_failure` error. *... * - return a `permanent_channel_failure` error. *... * - return a `required_channel_feature_missing` error. *... * - return an `unknown_next_peer` error. *... * - return an `amount_below_minimum` error. *... * - return a `fee_insufficient` error. *... * - return an `incorrect_cltv_expiry` error. *... * - return an `expiry_too_soon` error. *... * - return an `expiry_too_far` error. *... * - return a `channel_disabled` error. */ case WIRE_INVALID_ONION_VERSION: case WIRE_INVALID_ONION_HMAC: case WIRE_INVALID_ONION_KEY: case WIRE_TEMPORARY_CHANNEL_FAILURE: case WIRE_PERMANENT_CHANNEL_FAILURE: case WIRE_REQUIRED_CHANNEL_FEATURE_MISSING: case WIRE_UNKNOWN_NEXT_PEER: case WIRE_AMOUNT_BELOW_MINIMUM: case WIRE_FEE_INSUFFICIENT: case WIRE_INCORRECT_CLTV_EXPIRY: case WIRE_EXPIRY_TOO_FAR: case WIRE_EXPIRY_TOO_SOON: case WIRE_CHANNEL_DISABLED: goto strange_error; case WIRE_INVALID_ONION_PAYLOAD: case WIRE_INVALID_REALM: case WIRE_PERMANENT_NODE_FAILURE: case WIRE_TEMPORARY_NODE_FAILURE: case WIRE_REQUIRED_NODE_FEATURE_MISSING: case WIRE_INVALID_ONION_BLINDING: case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS: case WIRE_MPP_TIMEOUT: goto error; } strange_error: paymod_log(p, LOG_UNUSUAL, "Final node %s reported strange error code %04x (%s)", type_to_string(tmpctx, struct node_id, final_id), failcode, describe_failcode(tmpctx, failcode)); error: p->result->code = PAY_DESTINATION_PERM_FAIL; payment_root(p)->abort = true; nonerror: payment_fail(p, "%s", p->result->message); return command_still_pending(cmd); } static struct command_result * handle_intermediate_failure(struct command *cmd, struct payment *p, const struct node_id *errnode, const struct route_hop *errchan, enum onion_wire failcode) { struct payment *root = payment_root(p); struct amount_msat estimated; paymod_log(p, LOG_DBG, "Intermediate node %s reported %04x (%s) at %s on route %s", type_to_string(tmpctx, struct node_id, errnode), failcode, onion_wire_name(failcode), type_to_string(tmpctx, struct short_channel_id, &errchan->scid), p->routetxt); /* We use an exhaustive switch statement here so you get a compile * warning when new ones are added, and can think about where they go */ switch (failcode) { /* BOLT #4: * * An _intermediate hop_ MUST NOT, but the _final node_: *... * - MUST return an `incorrect_or_unknown_payment_details` error. *... * - MUST return `final_incorrect_cltv_expiry` error. *... * - MUST return a `final_incorrect_htlc_amount` error. */ case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS: case WIRE_FINAL_INCORRECT_CLTV_EXPIRY: case WIRE_FINAL_INCORRECT_HTLC_AMOUNT: /* FIXME: Document in BOLT that intermediates must not return this! */ case WIRE_MPP_TIMEOUT: goto strange_error; case WIRE_PERMANENT_CHANNEL_FAILURE: case WIRE_CHANNEL_DISABLED: case WIRE_UNKNOWN_NEXT_PEER: case WIRE_REQUIRED_CHANNEL_FEATURE_MISSING: /* All of these result in the channel being marked as disabled. */ channel_hints_update(root, errchan->scid, errchan->direction, false, false, NULL, NULL); break; case WIRE_TEMPORARY_CHANNEL_FAILURE: { estimated = errchan->amount; /* Subtract one msat more, since we know that the amount did not * work. This allows us to then allow on equality, this is for * example necessary for local channels where exact matches * should be allowed. */ if (!amount_msat_sub(&estimated, estimated, AMOUNT_MSAT(1))) abort(); /* These are an indication that the capacity was insufficient, * remember the amount we tried as an estimate. */ channel_hints_update(root, errchan->scid, errchan->direction, true, false, &estimated, NULL); goto error; } case WIRE_INCORRECT_CLTV_EXPIRY: report_tampering(p, errchan - p->route, "cltv"); goto error; case WIRE_INVALID_ONION_VERSION: case WIRE_INVALID_ONION_HMAC: case WIRE_INVALID_ONION_KEY: case WIRE_PERMANENT_NODE_FAILURE: case WIRE_TEMPORARY_NODE_FAILURE: case WIRE_REQUIRED_NODE_FEATURE_MISSING: case WIRE_INVALID_ONION_PAYLOAD: case WIRE_INVALID_REALM: case WIRE_INVALID_ONION_BLINDING: tal_arr_expand(&root->excluded_nodes, *errnode); goto error; case WIRE_AMOUNT_BELOW_MINIMUM: case WIRE_FEE_INSUFFICIENT: case WIRE_EXPIRY_TOO_FAR: case WIRE_EXPIRY_TOO_SOON: goto error; } strange_error: paymod_log(p, LOG_UNUSUAL, "Intermediate node %s reported strange error code %04x (%s)", type_to_string(tmpctx, struct node_id, errnode), failcode, describe_failcode(tmpctx, failcode)); error: payment_fail(p, "%s", p->result->message); return command_still_pending(cmd); } /* From the docs: * * - *erring_index*: The index of the node along the route that * reported the error. 0 for the local node, 1 for the first hop, * and so on. * * The only difficulty is mapping the erring_index to the correct hop. * We split into the erring node, and the error channel, since they're * used in different contexts. NULL error_channel means it's the final * node, whose errors are treated differently. */ static bool assign_blame(const struct payment *p, const struct node_id **errnode, const struct route_hop **errchan) { int index; if (p->result->erring_index == NULL) return false; index = *p->result->erring_index; /* BADONION errors are reported on behalf of the next node. */ if (p->result->failcode & BADONION) index++; /* Final node *shouldn't* report BADONION, but don't assume. */ if (index >= tal_count(p->route)) { *errchan = NULL; *errnode = &p->route[tal_count(p->route) - 1].node_id; return true; } *errchan = &p->route[index]; if (index == 0) *errnode = p->local_id; else *errnode = &p->route[index - 1].node_id; return true; } /* Fix up the channel_update to include the type if it doesn't currently have * one. See ElementsProject/lightning#1730 and lightningnetwork/lnd#1599 for the * in-depth discussion on why we break message parsing here... */ static u8 *patch_channel_update(const tal_t *ctx, u8 *channel_update TAKES) { u8 *fixed; if (channel_update != NULL && fromwire_peektype(channel_update) != WIRE_CHANNEL_UPDATE) { /* This should be a channel_update, prefix with the * WIRE_CHANNEL_UPDATE type, but isn't. Let's prefix it. */ fixed = tal_arr(ctx, u8, 0); towire_u16(&fixed, WIRE_CHANNEL_UPDATE); towire(&fixed, channel_update, tal_bytelen(channel_update)); if (taken(channel_update)) tal_free(channel_update); return fixed; } else { return tal_dup_talarr(ctx, u8, channel_update); } } /* Return NULL if the wrapped onion error message has no channel_update field, * or return the embedded channel_update message otherwise. */ static u8 *channel_update_from_onion_error(const tal_t *ctx, const u8 *onion_message) { u8 *channel_update = NULL; struct amount_msat unused_msat; u32 unused32; /* Identify failcodes that have some channel_update. * * TODO > BOLT 1.0: Add new failcodes when updating to a * new BOLT version. */ if (!fromwire_temporary_channel_failure(ctx, onion_message, &channel_update) && !fromwire_amount_below_minimum(ctx, onion_message, &unused_msat, &channel_update) && !fromwire_fee_insufficient(ctx, onion_message, &unused_msat, &channel_update) && !fromwire_incorrect_cltv_expiry(ctx, onion_message, &unused32, &channel_update) && !fromwire_expiry_too_soon(ctx, onion_message, &channel_update)) /* No channel update. */ return NULL; return patch_channel_update(ctx, take(channel_update)); } static struct command_result * payment_addgossip_success(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { const struct node_id *errnode; const struct route_hop *errchan; if (!assign_blame(p, &errnode, &errchan)) { paymod_log(p, LOG_UNUSUAL, "No erring_index set in `waitsendpay` result: %.*s", json_tok_full_len(toks), json_tok_full(buffer, toks)); /* FIXME: Pick a random channel to fail? */ payment_set_step(p, PAYMENT_STEP_FAILED); payment_continue(p); return command_still_pending(cmd); } if (!errchan) return handle_final_failure(cmd, p, errnode, p->result->failcode); return handle_intermediate_failure(cmd, p, errnode, errchan, p->result->failcode); } /* If someone gives us an invalid update, all we can do is log it */ static struct command_result * payment_addgossip_failure(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { paymod_log(p, LOG_DBG, "Invalid channel_update: %.*s", json_tok_full_len(toks), json_tok_full(buffer, toks)); return payment_addgossip_success(cmd, NULL, NULL, p); } static struct command_result * payment_waitsendpay_finished(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { u8 *update; assert(p->route != NULL); p->end_time = time_now(); p->result = tal_sendpay_result_from_json(p, buffer, toks); if (p->result == NULL) { paymod_log(p, LOG_UNUSUAL, "Unable to parse `waitsendpay` result: %.*s", json_tok_full_len(toks), json_tok_full(buffer, toks)); payment_set_step(p, PAYMENT_STEP_FAILED); payment_continue(p); return command_still_pending(cmd); } payment_result_infer(p->route, p->result); if (p->result->state == PAYMENT_COMPLETE) { payment_set_step(p, PAYMENT_STEP_SUCCESS); payment_continue(p); return command_still_pending(cmd); } payment_chanhints_apply_route(p, true); /* Tell gossipd, if we received an update */ update = channel_update_from_onion_error(tmpctx, p->result->raw_message); if (update) { struct out_req *req; paymod_log(p, LOG_DBG, "Extracted channel_update %s from onionreply %s", tal_hex(tmpctx, update), tal_hex(tmpctx, p->result->raw_message)); req = jsonrpc_request_start(p->plugin, NULL, "addgossip", payment_addgossip_success, payment_addgossip_failure, p); json_add_hex_talarr(req->js, "message", update); send_outreq(p->plugin, req); return command_still_pending(cmd); } return payment_addgossip_success(cmd, NULL, NULL, p); } static struct command_result *payment_sendonion_success(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { struct out_req *req; req = jsonrpc_request_start(p->plugin, NULL, "waitsendpay", payment_waitsendpay_finished, payment_waitsendpay_finished, p); json_add_sha256(req->js, "payment_hash", p->payment_hash); json_add_num(req->js, "partid", p->partid); json_add_u64(req->js, "groupid", p->groupid); send_outreq(p->plugin, req); return command_still_pending(cmd); } static struct command_result *payment_createonion_success(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { struct out_req *req; struct route_hop *first = &p->route[0]; struct secret *secrets; struct payment *root = payment_root(p); p->createonion_response = json_to_createonion_response(p, buffer, toks); req = jsonrpc_request_start(p->plugin, NULL, "sendonion", payment_sendonion_success, payment_rpc_failure, p); json_add_hex_talarr(req->js, "onion", p->createonion_response->onion); json_object_start(req->js, "first_hop"); json_add_amount_msat(req->js, "amount_msat", first->amount); json_add_num(req->js, "delay", first->delay); json_add_node_id(req->js, "id", &first->node_id); json_add_short_channel_id(req->js, "channel", &first->scid); json_object_end(req->js); json_add_sha256(req->js, "payment_hash", p->payment_hash); json_add_amount_msat(req->js, "amount_msat", p->amount); json_array_start(req->js, "shared_secrets"); secrets = p->createonion_response->shared_secrets; for(size_t i=0; ijs, NULL, &secrets[i]); json_array_end(req->js); json_add_num(req->js, "partid", p->partid); json_add_u64(req->js, "groupid", p->groupid); if (p->label) json_add_string(req->js, "label", p->label); if (!root->invstring_used) { /* FIXME: rename parameter to invstring */ json_add_string(req->js, "bolt11", p->invstring); if (p->description) json_add_string(req->js, "description", p->description); root->invstring_used = true; } if (p->destination) json_add_node_id(req->js, "destination", p->destination); if (p->local_invreq_id) json_add_sha256(req->js, "localinvreqid", p->local_invreq_id); send_outreq(p->plugin, req); return command_still_pending(cmd); } /* Temporary serialization method for the tlv_payload.data until we rework the * API that is generated from the specs to use the setter/getter interface. */ static void tlvstream_set_tlv_payload_data(struct tlv_field **stream, const struct secret *payment_secret, u64 total_msat) { u8 *ser = tal_arr(NULL, u8, 0); towire_secret(&ser, payment_secret); towire_tu64(&ser, total_msat); tlvstream_set_raw(stream, TLV_PAYLOAD_PAYMENT_DATA, ser, tal_bytelen(ser)); tal_free(ser); } static void payment_add_hop_onion_payload(struct payment *p, struct createonion_hop *dst, struct route_hop *node, struct route_hop *next, bool final, struct secret *payment_secret, const u8 *payment_metadata) { struct createonion_request *cr = p->createonion_request; u32 cltv = p->start_block + next->delay + 1; u64 msat = next->amount.millisatoshis; /* Raw: TLV payload generation*/ struct tlv_field **fields; struct payment *root = payment_root(p); /* This is the information of the node processing this payload, while * `next` are the instructions to include in the payload, which is * basically the channel going to the next node. */ dst->pubkey = node->node_id; dst->tlv_payload = tlv_payload_new(cr->hops); fields = &dst->tlv_payload->fields; tlvstream_set_tu64(fields, TLV_PAYLOAD_AMT_TO_FORWARD, msat); tlvstream_set_tu32(fields, TLV_PAYLOAD_OUTGOING_CLTV_VALUE, cltv); if (!final) tlvstream_set_short_channel_id(fields, TLV_PAYLOAD_SHORT_CHANNEL_ID, &next->scid); if (payment_secret != NULL) { assert(final); tlvstream_set_tlv_payload_data( fields, payment_secret, root->amount.millisatoshis); /* Raw: TLV payload generation*/ } if (payment_metadata != NULL) { assert(final); tlvstream_set_raw(fields, TLV_PAYLOAD_PAYMENT_METADATA, payment_metadata, tal_bytelen(payment_metadata)); } } static void payment_add_blindedpath(const tal_t *ctx, struct createonion_hop *hops, const struct blinded_path *bpath, struct amount_msat final_amt, u32 final_cltv) { /* It's a bit of a weird API for us, so we convert it back to * the struct tlv_payload */ u8 **tlvs = blinded_onion_hops(tmpctx, final_amt, final_cltv, final_amt, bpath); for (size_t i = 0; i < tal_count(tlvs); i++) { const u8 *cursor = tlvs[i]; size_t max = tal_bytelen(tlvs[i]); /* First one has to use real node_id */ if (i == 0) node_id_from_pubkey(&hops[i].pubkey, &bpath->first_node_id); else node_id_from_pubkey(&hops[i].pubkey, &bpath->path[i]->blinded_node_id); /* Length is prepended, discard that first! */ fromwire_bigsize(&cursor, &max); hops[i].tlv_payload = fromwire_tlv_payload(ctx, &cursor, &max); } } static void payment_compute_onion_payloads(struct payment *p) { struct createonion_request *cr; size_t hopcount; struct payment *root = payment_root(p); char *routetxt = tal_strdup(tmpctx, ""); p->step = PAYMENT_STEP_ONION_PAYLOAD; hopcount = tal_count(p->route); /* Now that we are about to fix the route parameters by * encoding them in an onion is the right time to update the * channel hints. */ if (!payment_chanhints_apply_route(p, false)) { /* We can still end up with a failed channel_hints * update, either because a plugin changed the route, * or because a modifier was not synchronous, allowing * for multiple concurrent routes being built. If that * is the case, discard this route and retry. */ payment_set_step(p, PAYMENT_STEP_RETRY_GETROUTE); return payment_continue(p); } /* Now compute the payload we're about to pass to `createonion` */ cr = p->createonion_request = tal(p, struct createonion_request); cr->assocdata = tal_arr(cr, u8, 0); towire_sha256(&cr->assocdata, p->payment_hash); cr->session_key = NULL; cr->hops = tal_arr(cr, struct createonion_hop, tal_count(p->route) + (root->blindedpath ? tal_count(root->blindedpath->path) - 1: 0)); /* Non-final hops */ for (size_t i = 0; i < hopcount - 1; i++) { /* The message is destined for hop i, but contains fields for * i+1 */ payment_add_hop_onion_payload(p, &cr->hops[i], &p->route[i], &p->route[i + 1], false, NULL, NULL); tal_append_fmt(&routetxt, "%s -> ", type_to_string(tmpctx, struct short_channel_id, &p->route[i].scid)); } /* If we're headed to a blinded path, connect that now. */ if (root->blindedpath) { payment_add_blindedpath(cr->hops, cr->hops + hopcount - 1, root->blindedpath, root->blindedfinalamount, root->blindedfinalcltv); tal_append_fmt(&routetxt, "%s -> blinded path (%zu hops)", type_to_string(tmpctx, struct short_channel_id, &p->route[hopcount-1].scid), tal_count(root->blindedpath->path)); } else { /* Final hop */ payment_add_hop_onion_payload( p, &cr->hops[hopcount - 1], &p->route[hopcount - 1], &p->route[hopcount - 1], true, root->payment_secret, root->payment_metadata); tal_append_fmt(&routetxt, "%s", type_to_string(tmpctx, struct short_channel_id, &p->route[hopcount - 1].scid)); } paymod_log(p, LOG_DBG, "Created outgoing onion for route: %s", routetxt); p->routetxt = tal_steal(p, routetxt); /* Now allow all the modifiers to mess with the payloads, before we * serialize via a call to createonion in the next step. */ payment_continue(p); } static void payment_sendonion(struct payment *p) { struct out_req *req; u8 *payload, *tlv; req = jsonrpc_request_start(p->plugin, NULL, "createonion", payment_createonion_success, payment_rpc_failure, p); json_array_start(req->js, "hops"); for (size_t i = 0; i < tal_count(p->createonion_request->hops); i++) { json_object_start(req->js, NULL); struct createonion_hop *hop = &p->createonion_request->hops[i]; json_add_node_id(req->js, "pubkey", &hop->pubkey); tlv = tal_arr(tmpctx, u8, 0); towire_tlvstream_raw(&tlv, hop->tlv_payload->fields); payload = tal_arr(tmpctx, u8, 0); towire_bigsize(&payload, tal_bytelen(tlv)); towire(&payload, tlv, tal_bytelen(tlv)); json_add_hex_talarr(req->js, "payload", payload); tal_free(tlv); tal_free(payload); json_object_end(req->js); } json_array_end(req->js); json_add_hex_talarr(req->js, "assocdata", p->createonion_request->assocdata); if (p->createonion_request->session_key) json_add_secret(req->js, "sessionkey", p->createonion_request->session_key); send_outreq(p->plugin, req); } /* Mutual recursion. */ static void payment_finished(struct payment *p); /* A payment is finished if a) it is in a final state, of b) it's in a * child-spawning state and all of its children are in a final state. */ static bool payment_is_finished(const struct payment *p) { top: if (p->step == PAYMENT_STEP_FAILED || p->step == PAYMENT_STEP_SUCCESS || p->abort) return true; else if (p->step == PAYMENT_STEP_SPLIT || p->step == PAYMENT_STEP_RETRY) { size_t num_children = tal_count(p->children); /* Retry case will almost always have just one child, so avoid * the overhead of pushing and popping off the C stack and * tail-recurse manually. */ if (num_children == 1) { p = p->children[0]; goto top; } for (size_t i = 0; i < num_children; i++) /* In other words: if any child is unfinished, * we are unfinished. */ if (!payment_is_finished(p->children[i])) return false; return true; } else { return false; } } static enum payment_step payment_aggregate_states(struct payment *p) { enum payment_step agg = p->step; for (size_t i=0; ichildren); i++) agg |= payment_aggregate_states(p->children[i]); return agg; } /* A payment is finished if a) it is in a final state, of b) it's in a * child-spawning state and all of its children are in a final state. */ static bool payment_is_success(struct payment *p) { return (payment_aggregate_states(p) & PAYMENT_STEP_SUCCESS) != 0; } /* Function to bubble up completions to the root, which actually holds on to * the command that initiated the flow. */ static void payment_child_finished(struct payment *p, struct payment *child) { if (!payment_is_finished(p)) return; /* Should we continue bubbling up? */ payment_finished(p); } static void payment_add_attempt(struct json_stream *s, const char *fieldname, struct payment *p, bool recurse) { bool finished = p->step >= PAYMENT_STEP_RETRY, success = p->step == PAYMENT_STEP_SUCCESS; /* A fieldname is only reasonable if we're not recursing. Otherwise the * fieldname would be reused for all attempts. */ assert(!recurse || fieldname == NULL); json_object_start(s, fieldname); if (!finished) json_add_string(s, "status", "pending"); else if (success) json_add_string(s, "status", "success"); else json_add_string(s, "status", "failed"); if (p->failreason != NULL) json_add_string(s, "failreason", p->failreason); json_add_u64(s, "partid", p->partid); json_add_amount_msat(s, "amount_msat", p->amount); if (p->parent != NULL) json_add_u64(s, "parent_partid", p->parent->partid); json_object_end(s); for (size_t i=0; ichildren); i++) { payment_add_attempt(s, fieldname, p->children[i], recurse); } } static void payment_json_add_attempts(struct json_stream *s, const char *fieldname, struct payment *p) { assert(p == payment_root(p)); json_array_start(s, fieldname); payment_add_attempt(s, NULL, p, true); json_array_end(s); } static void payment_notify_failure(struct payment *p, const char *error_message) { struct payment *root = payment_root(p); struct json_stream *n; n = plugin_notification_start(p->plugin, "pay_failure"); json_add_sha256(n, "payment_hash", p->payment_hash); if (root->invstring != NULL) json_add_string(n, "bolt11", root->invstring); json_object_start(n, "error"); json_add_string(n, "message", error_message); json_object_end(n); /* .error */ plugin_notification_end(p->plugin, n); } /* Code shared by selfpay fast-path: populate JSON output for successful * payment, and send pay_success notification. */ void json_add_payment_success(struct json_stream *js, struct payment *p, const struct preimage *preimage, const struct payment_tree_result *result) { struct json_stream *n; struct payment *root = payment_root(p); json_add_node_id(js, "destination", p->destination); json_add_sha256(js, "payment_hash", p->payment_hash); json_add_timeabs(js, "created_at", p->start_time); if (result) json_add_num(js, "parts", result->attempts); else json_add_num(js, "parts", 1); json_add_amount_msat(js, "amount_msat", p->amount); if (result) json_add_amount_msat(js, "amount_sent_msat", result->sent); else json_add_amount_msat(js, "amount_sent_msat", p->amount); if (result && result->leafstates != PAYMENT_STEP_SUCCESS) json_add_string(js, "warning_partial_completion", "Some parts of the payment are not yet " "completed, but we have the confirmation " "from the recipient."); json_add_preimage(js, "payment_preimage", preimage); json_add_string(js, "status", "complete"); n = plugin_notification_start(p->plugin, "pay_success"); json_add_sha256(n, "payment_hash", p->payment_hash); if (root->invstring != NULL) json_add_string(n, "bolt11", root->invstring); plugin_notification_end(p->plugin, n); } /* This function is called whenever a payment ends up in a final state, or all * leafs in the subtree rooted in the payment are all in a final state. It is * called only once, and it is guaranteed to be called in post-order * traversal, i.e., all children are finished before the parent is called. */ static void payment_finished(struct payment *p) { struct payment_tree_result result = payment_collect_result(p); struct json_stream *ret; struct command *cmd = p->cmd; const char *msg; /* Either none of the leaf attempts succeeded yet, or we have a * preimage. */ assert((result.leafstates & PAYMENT_STEP_SUCCESS) == 0 || result.preimage != NULL); if (p->parent == NULL) { /* We are about to reply, unset the pointer to the cmd so we * don't attempt to return a response twice. */ p->cmd = NULL; if (cmd == NULL) { /* This is the tree root, but we already reported * success or failure, so noop. */ return; } else if (payment_is_success(p)) { assert(result.treestates & PAYMENT_STEP_SUCCESS); assert(result.leafstates & PAYMENT_STEP_SUCCESS); assert(result.preimage != NULL); /* Call any callback we might have registered. */ if (p->on_payment_success != NULL) p->on_payment_success(p); ret = jsonrpc_stream_success(cmd); json_add_payment_success(ret, p, result.preimage, &result); if (command_finished(cmd, ret)) {/* Ignore result. */} p->cmd = NULL; return; } else if (p->aborterror != NULL) { /* We set an explicit toplevel error message, * so let's report that. */ ret = jsonrpc_stream_fail(cmd, PAY_STOPPED_RETRYING, p->aborterror); payment_json_add_attempts(ret, "attempts", p); payment_notify_failure(p, p->aborterror); if (command_finished(cmd, ret)) {/* Ignore result. */} p->cmd = NULL; return; } else if (result.failure == NULL || result.failure->failcode < NODE) { if (p->on_payment_failure != NULL) p->on_payment_failure(p); /* This is failing because we have no more routes to try */ msg = tal_fmt(cmd, "Ran out of routes to try after " "%d attempt%s: see `paystatus`", result.attempts, result.attempts == 1 ? "" : "s"); ret = jsonrpc_stream_fail(cmd, PAY_STOPPED_RETRYING, msg); payment_json_add_attempts(ret, "attempts", p); payment_notify_failure(p, msg); if (command_finished(cmd, ret)) {/* Ignore result. */} p->cmd = NULL; return; } else { struct payment_result *failure = result.failure; assert(failure!= NULL); if (p->on_payment_failure != NULL) p->on_payment_failure(p); ret = jsonrpc_stream_fail(cmd, failure->code, failure->message); json_add_u64(ret, "id", failure->id); json_add_u32(ret, "failcode", failure->failcode); json_add_string(ret, "failcodename", failure->failcodename); if (p->invstring) json_add_invstring(ret, p->invstring); json_add_hex_talarr(ret, "raw_message", result.failure->raw_message); json_add_num(ret, "created_at", p->start_time.ts.tv_sec); json_add_node_id(ret, "destination", p->destination); json_add_sha256(ret, "payment_hash", p->payment_hash); if (result.leafstates & PAYMENT_STEP_SUCCESS) { /* If one sub-payment succeeded then we have * proof of payment, and the payment is a * success. */ json_add_string(ret, "status", "complete"); } else if (result.leafstates & ~PAYMENT_STEP_FAILED) { /* If there are non-failed leafs we are still trying. */ json_add_string(ret, "status", "pending"); } else { json_add_string(ret, "status", "failed"); } json_add_amount_msat(ret, "amount_msat", p->amount); json_add_amount_msat(ret, "amount_sent_msat", result.sent); if (failure != NULL) { if (failure->erring_index) json_add_num(ret, "erring_index", *failure->erring_index); if (failure->erring_node) json_add_node_id(ret, "erring_node", failure->erring_node); if (failure->erring_channel) json_add_short_channel_id( ret, "erring_channel", failure->erring_channel); if (failure->erring_direction) json_add_num( ret, "erring_direction", *failure->erring_direction); } payment_notify_failure(p, failure->message); if (command_finished(cmd, ret)) { /* Ignore result. */} p->cmd = NULL; return; } } else { payment_child_finished(p->parent, p); return; } } void payment_set_step(struct payment *p, enum payment_step newstep) { p->current_modifier = -1; p->step = newstep; /* Any final state needs an end_time */ if (p->step >= PAYMENT_STEP_SPLIT) p->end_time = time_now(); } void payment_continue(struct payment *p) { struct payment_modifier *mod; void *moddata; /* If we are in the middle of calling the modifiers, continue calling * them, otherwise we can continue with the payment state-machine. */ p->current_modifier++; mod = p->modifiers[p->current_modifier]; if (mod != NULL) { /* There is another modifier, so call it. */ moddata = p->modifier_data[p->current_modifier]; return mod->post_step_cb(moddata, p); } else { /* There are no more modifiers, so reset the call chain and * proceed to the next state. */ p->current_modifier = -1; switch (p->step) { case PAYMENT_STEP_INITIALIZED: case PAYMENT_STEP_RETRY_GETROUTE: payment_getroute(p); return; case PAYMENT_STEP_GOT_ROUTE: payment_compute_onion_payloads(p); return; case PAYMENT_STEP_ONION_PAYLOAD: payment_sendonion(p); return; case PAYMENT_STEP_SUCCESS: case PAYMENT_STEP_FAILED: payment_finished(p); return; case PAYMENT_STEP_RETRY: case PAYMENT_STEP_SPLIT: /* Do nothing, we'll get pinged by a child succeeding * or failing. */ return; } } /* We should never get here, it'd mean one of the state machine called * `payment_continue` after the final state. */ abort(); } void payment_abort(struct payment *p, const char *fmt, ...) { va_list ap; struct payment *root = payment_root(p); payment_set_step(p, PAYMENT_STEP_FAILED); p->end_time = time_now(); /* We can fail twice, it seems. */ tal_free(p->failreason); va_start(ap, fmt); p->failreason = tal_vfmt(p, fmt, ap); va_end(ap); root->abort = true; /* Only set the abort error if it's not yet set, otherwise we * might end up clobbering the earliest and decisive failure * with less relevant ones. */ if (root->aborterror == NULL) root->aborterror = tal_dup_talarr(root, char, p->failreason); paymod_log(p, LOG_INFORM, "%s", p->failreason); /* Do not use payment_continue, because that'd continue * applying the modifiers before calling * payment_finished(). */ payment_finished(p); } void payment_fail(struct payment *p, const char *fmt, ...) { va_list ap; p->end_time = time_now(); payment_set_step(p, PAYMENT_STEP_FAILED); /* We can fail twice, it seems. */ tal_free(p->failreason); va_start(ap, fmt); p->failreason = tal_vfmt(p, fmt, ap); va_end(ap); paymod_log(p, LOG_INFORM, "%s", p->failreason); payment_continue(p); } void *payment_mod_get_data(const struct payment *p, const struct payment_modifier *mod) { for (size_t i = 0; p->modifiers[i] != NULL; i++) if (p->modifiers[i] == mod) return p->modifier_data[i]; /* If we ever get here it means that we asked for the data for a * non-existent modifier. This is a compile-time/wiring issue, so we * better check that modifiers match the data we ask for. */ abort(); } static struct retry_mod_data *retry_data_init(struct payment *p); static inline void retry_step_cb(struct retry_mod_data *rd, struct payment *p); static struct retry_mod_data * retry_data_init(struct payment *p) { struct retry_mod_data *rdata = tal(p, struct retry_mod_data); struct retry_mod_data *parent_rdata; /* We start the retry counter from scratch for the root payment, or if * the parent was split, meaning this is a new attempt with new * amounts. */ if (p->parent == NULL || p->parent->step == PAYMENT_STEP_SPLIT) { rdata->retries = 10; } else { parent_rdata = payment_mod_retry_get_data(p->parent); rdata->retries = parent_rdata->retries - 1; } return rdata; } /* Determine whether retrying could possibly succeed. Retrying in this case * means that we repeat the entire flow, including computing a new route, new * payload and a new sendonion call. It does not mean we retry the exact same * attempt that just failed. */ static bool payment_can_retry(struct payment *p) { struct payment_result *res = p->result; u32 idx; bool is_final; if (p->result == NULL) return p->failroute_retry; idx = res->erring_index != NULL ? *res->erring_index : 0; is_final = (idx == tal_count(p->route)); /* Full matrix of failure code x is_final. Prefer to retry once too * often over eagerly failing. */ switch (res->failcode) { case WIRE_EXPIRY_TOO_FAR: case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS: case WIRE_INVALID_ONION_PAYLOAD: case WIRE_INVALID_ONION_VERSION: case WIRE_INVALID_REALM: case WIRE_MPP_TIMEOUT: case WIRE_PERMANENT_NODE_FAILURE: case WIRE_REQUIRED_NODE_FEATURE_MISSING: case WIRE_TEMPORARY_NODE_FAILURE: case WIRE_UNKNOWN_NEXT_PEER: return !is_final; case WIRE_AMOUNT_BELOW_MINIMUM: case WIRE_CHANNEL_DISABLED: case WIRE_EXPIRY_TOO_SOON: case WIRE_FEE_INSUFFICIENT: case WIRE_FINAL_INCORRECT_CLTV_EXPIRY: case WIRE_FINAL_INCORRECT_HTLC_AMOUNT: case WIRE_INCORRECT_CLTV_EXPIRY: case WIRE_INVALID_ONION_HMAC: case WIRE_INVALID_ONION_KEY: case WIRE_PERMANENT_CHANNEL_FAILURE: case WIRE_REQUIRED_CHANNEL_FEATURE_MISSING: case WIRE_TEMPORARY_CHANNEL_FAILURE: case WIRE_INVALID_ONION_BLINDING: return true; } /* We should never get here, otherwise the above `switch` isn't * exhaustive. Nevertheless the failcode is provided by the erring * node, so retry anyway. `abort()`ing on externally supplied info is * not a good idea. */ return true; } static inline void retry_step_cb(struct retry_mod_data *rd, struct payment *p) { struct payment *subpayment, *root = payment_root(p); struct retry_mod_data *rdata = payment_mod_retry_get_data(p); struct timeabs now = time_now(); if (p->step != PAYMENT_STEP_FAILED) return payment_continue(p); if (time_after(now, p->deadline)) { paymod_log( p, LOG_INFORM, "Payment deadline expired, not retrying (partial-)payment " "%s/%d", type_to_string(tmpctx, struct sha256, p->payment_hash), p->partid); root->abort = true; return payment_continue(p); } /* If we failed to find a route, it's unlikely we can suddenly find a * new one without any other changes, so it's time to give up. */ if (p->route == NULL && !p->failroute_retry) return payment_continue(p); /* If the root is marked as abort, we do not retry anymore */ if (payment_root(p)->abort) return payment_continue(p); if (!payment_can_retry(p)) return payment_continue(p); /* If the failure was not final, and we tried a route, try again. */ if (rdata->retries > 0) { payment_set_step(p, PAYMENT_STEP_RETRY); subpayment = payment_new(p, NULL, p, p->modifiers); payment_start(subpayment); subpayment->why = tal_fmt(subpayment, "Still have %d attempts left", rdata->retries - 1); paymod_log( p, LOG_DBG, "Retrying %s/%d (%s), new partid %d. %d attempts left\n", type_to_string(tmpctx, struct sha256, p->payment_hash), p->partid, type_to_string(tmpctx, struct amount_msat, &p->amount), subpayment->partid, rdata->retries - 1); } payment_continue(p); } REGISTER_PAYMENT_MODIFIER(retry, struct retry_mod_data *, retry_data_init, retry_step_cb); static struct command_result * local_channel_hints_listpeerchannels(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { struct listpeers_channel **chans; chans = json_to_listpeers_channels(tmpctx, buffer, toks); for (size_t i = 0; i < tal_count(chans); i++) { bool enabled; u16 htlc_budget; /* Filter out local channels if they are * either a) disconnected, or b) not in normal * state. */ enabled = chans[i]->connected && (streq(chans[i]->state, "CHANNELD_NORMAL") || streq(chans[i]->state, "CHANNELD_AWAITING_SPLICE")); /* Take the configured number of max_htlcs and * subtract any HTLCs that might already be added to * the channel. This is a best effort estimate and * mostly considers stuck htlcs, concurrent payments * may throw us off a bit. */ if (chans[i]->num_htlcs > chans[i]->max_accepted_htlcs) htlc_budget = 0; else htlc_budget = chans[i]->max_accepted_htlcs - chans[i]->num_htlcs; /* If we have both a scid and a local alias we want to * use the scid, and mark the alias as * unusable. Otherwise `getroute` might return the * alias, which we resolve correctly, but our * channel_hints would be off after updates, since * we'd only ever update one of the aliases. Causing * the other to be considered usable. */ if (chans[i]->scid != NULL) { channel_hints_update( p, *chans[i]->scid, chans[i]->direction, enabled, true, &chans[i]->spendable_msat, &htlc_budget); if (chans[i]->alias[LOCAL] != NULL) channel_hints_update(p, *chans[i]->alias[LOCAL], chans[i]->direction, false /* not enabled */, true, &AMOUNT_MSAT(0), &htlc_budget); } else { channel_hints_update(p, *chans[i]->alias[LOCAL], chans[i]->direction, enabled, true, &chans[i]->spendable_msat, &htlc_budget); } } payment_continue(p); return command_still_pending(cmd); } static void local_channel_hints_cb(void *d UNUSED, struct payment *p) { struct out_req *req; /* If we are not the root we don't look up the channel balances since * it is unlikely that the capacities have changed much since the root * payment looked at them. We also only call `listpeers` when the * payment is in state PAYMENT_STEP_INITIALIZED, right before calling * `getroute`. */ if (p->parent != NULL || p->step != PAYMENT_STEP_INITIALIZED) return payment_continue(p); req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels", local_channel_hints_listpeerchannels, local_channel_hints_listpeerchannels, p); send_outreq(p->plugin, req); } REGISTER_PAYMENT_MODIFIER(local_channel_hints, void *, NULL, local_channel_hints_cb); /* Trim route to this length by taking from the *front* of route * (end points to destination, so we need that bit!) */ static void trim_route(struct route_info **route, size_t n) { size_t remove = tal_count(*route) - n; memmove(*route, *route + remove, sizeof(**route) * n); tal_resize(route, n); } /* Make sure routehints are reasonable length, and (since we assume we * can append), not directly to us. Note: untrusted data! */ static struct route_info **filter_routehints(struct gossmap *map, struct payment *p, struct routehints_data *d, struct node_id *myid, struct route_info **hints) { const size_t max_hops = ROUTING_MAX_HOPS / 2; char *mods = tal_strdup(tmpctx, ""); struct gossmap_node *src = gossmap_find_node(map, p->local_id); if (src == NULL) { tal_append_fmt(&mods, "Could not locate ourselves in the gossip map, " "leaving routehints untouched. "); } for (size_t i = 0; i < tal_count(hints) && src != NULL; i++) { struct gossmap_node *entrynode; u32 distance; /* Trim any routehint > 10 hops */ if (tal_count(hints[i]) > max_hops) { tal_append_fmt(&mods, "Trimmed routehint %zu (%zu hops) to %zu. ", i, tal_count(hints[i]), max_hops); trim_route(&hints[i], max_hops); } /* If we are first hop, trim. */ if (tal_count(hints[i]) > 0 && node_id_eq(&hints[i][0].pubkey, myid)) { tal_append_fmt(&mods, "Removed ourselves from routehint %zu. ", i); trim_route(&hints[i], tal_count(hints[i])-1); } /* If route is empty, remove altogether. */ if (tal_count(hints[i]) == 0) { tal_append_fmt(&mods, "Removed empty routehint %zu. ", i); tal_arr_remove(&hints, i); i--; continue; } /* If routehint entrypoint is unreachable there's no * point in keeping it. */ entrynode = gossmap_find_node(map, &hints[i][0].pubkey); if (entrynode == NULL) { tal_append_fmt(&mods, "Removed routehint %zu because " "entrypoint %s is unknown. ", i, type_to_string(tmpctx, struct node_id, &hints[i][0].pubkey)); plugin_log(p->plugin, LOG_DBG, "Removed routehint %zu because " "entrypoint %s is unknown. ", i, type_to_string(tmpctx, struct node_id, &hints[i][0].pubkey)); tal_arr_remove(&hints, i); i--; continue; } distance = dijkstra_distance( dijkstra(tmpctx, map, entrynode, AMOUNT_MSAT(0), 1, payment_route_can_carry_even_disabled, route_score_cheaper, p), gossmap_node_idx(map, src)); if (distance == UINT_MAX) { tal_append_fmt(&mods, "Removed routehint %zu because " "entrypoint %s is unreachable. ", i, type_to_string(tmpctx, struct node_id, &hints[i][0].pubkey)); plugin_log(p->plugin, LOG_DBG, "Removed routehint %zu because " "entrypoint %s is unreachable. ", i, type_to_string(tmpctx, struct node_id, &hints[i][0].pubkey)); tal_arr_remove(&hints, i); i--; } } if (!streq(mods, "")) d->routehint_modifications = tal_steal(d, mods); return tal_steal(d, hints); } static bool route_msatoshi(struct amount_msat *total, const struct amount_msat msat, const struct route_info *route, size_t num_route); static bool routehint_excluded(struct payment *p, const struct route_info *routehint) { const struct node_id *nodes = payment_get_excluded_nodes(tmpctx, p); const struct short_channel_id_dir *chans = payment_get_excluded_channels(tmpctx, p); const struct channel_hint *hints = payment_root(p)->channel_hints; /* Note that we ignore direction here: in theory, we could have * found that one direction of a channel is unavailable, but they * are suggesting we use it the other way. Very unlikely though! */ for (size_t i = 0; i < tal_count(routehint); i++) { const struct route_info *r = &routehint[i]; for (size_t j = 0; j < tal_count(nodes); j++) if (node_id_eq(&r->pubkey, &nodes[j])) return true; for (size_t j = 0; j < tal_count(chans); j++) if (short_channel_id_eq(&chans[j].scid, &r->short_channel_id)) return true; /* Skip the capacity check if this is the last hop * in the routehint. * The last hop in the routehint delivers the exact * final amount to the destination, which * payment_get_excluded_channels uses for excluding * already. * Thus, the capacity check below only really matters * for multi-hop routehints. */ if (i == tal_count(routehint) - 1) continue; /* Check our capacity fits. */ struct amount_msat needed_capacity; if (!route_msatoshi(&needed_capacity, p->amount, r + 1, tal_count(routehint) - i - 1)) return true; /* Why do we scan the hints again if * payment_get_excluded_channels already does? * Because payment_get_excluded_channels checks the * amount at destination, but we know that we are * a specific distance from the destination and we * know the exact capacity we need to send via this * channel, which is greater than the destination. */ for (size_t j = 0; j < tal_count(hints); j++) { if (!short_channel_id_eq(&hints[j].scid.scid, &r->short_channel_id)) continue; /* We exclude on equality because we set the estimate * to the smallest failed attempt. */ if (amount_msat_greater_eq(needed_capacity, hints[j].estimated_capacity)) return true; } } return false; } static struct route_info *next_routehint(struct routehints_data *d, struct payment *p) { size_t numhints = tal_count(d->routehints); struct route_info *curr; if (d->routehints == NULL || numhints == 0) return NULL; /* BOLT #11: * * - if a writer offers more than one of any field type, it: * - MUST specify the most-preferred field first, followed * by less-preferred fields, in order. */ for (; d->offset < numhints; d->offset++) { curr = d->routehints[(d->base + d->offset) % numhints]; if (curr == NULL || !routehint_excluded(p, curr)) return curr; } return NULL; } /* Calculate how many millisatoshi we need at the start of this route * to get msatoshi to the end. */ static bool route_msatoshi(struct amount_msat *total, const struct amount_msat msat, const struct route_info *route, size_t num_route) { *total = msat; for (ssize_t i = num_route - 1; i >= 0; i--) { if (!amount_msat_add_fee(total, route[i].fee_base_msat, route[i].fee_proportional_millionths)) return false; } return true; } /* The pubkey to use is the destination of this routehint. */ static const struct node_id *route_pubkey(const struct payment *p, const struct route_info *routehint, size_t n) { if (n == tal_count(routehint)) return p->destination; return &routehint[n].pubkey; } static u32 route_cltv(u32 cltv, const struct route_info *route, size_t num_route) { for (size_t i = 0; i < num_route; i++) cltv += route[i].cltv_expiry_delta; return cltv; } /** routehint_generate_exclusion_list * * @brief generate a list of items to append to `excludes` * parameter of `getroute`. * * @param ctx - the context to allocate off of. * @param routehint - the actual routehint, a `tal` array. * @param payment - the payment that we will create an * exclusion list for. * * @return an array of strings that will be appended to the * `excludes` parameter of `getroute`. */ static struct node_id *routehint_generate_exclusion_list(const tal_t *ctx, struct route_info *routehint, struct payment *payment) { struct node_id *exc; if (!routehint || tal_count(routehint) == 0) /* Nothing to exclude. */ return NULL; exc = tal_arr(ctx, struct node_id, tal_count(routehint)); /* Exclude every node except the first, because the first is * the entry point to the routehint. */ for (size_t i = 1 /* Skip the first! */; i < tal_count(routehint); ++i) exc[i-1] = routehint[i].pubkey; /* Also exclude the destination, because it would be foolish to * pass through it and *then* go to the routehint entry point. */ exc[tal_count(routehint)-1] = *payment->destination; return exc; } /* Change the destination and compute the final msatoshi amount to send to the * routehint entry point. */ static void routehint_pre_getroute(struct routehints_data *d, struct payment *p) { bool have_more; d->current_routehint = next_routehint(d, p); /* Signal that we could retry with another routehint even if getroute * fails. */ have_more = (d->offset < tal_count(d->routehints) - 1); p->failroute_retry = have_more; p->temp_exclusion = tal_free(p->temp_exclusion); if (d->current_routehint != NULL) { if (!route_msatoshi(&p->getroute->amount, p->amount, d->current_routehint, tal_count(d->current_routehint))) { } d->final_cltv = p->getroute->cltv; p->getroute->destination = &d->current_routehint[0].pubkey; p->getroute->cltv = route_cltv(p->getroute->cltv, d->current_routehint, tal_count(d->current_routehint)); paymod_log( p, LOG_DBG, "Using routehint %s (%s) cltv_delta=%d", type_to_string(tmpctx, struct node_id, &d->current_routehint->pubkey), type_to_string(tmpctx, struct short_channel_id, &d->current_routehint->short_channel_id), d->current_routehint->cltv_expiry_delta); /* Exclude the entrypoint to the routehint, so we don't end up * going through the destination to the entrypoint. */ p->temp_exclusion = routehint_generate_exclusion_list(p, d->current_routehint, p); } else paymod_log(p, LOG_DBG, "Not using a routehint"); } static void routehint_check_reachable(struct payment *p) { const struct gossmap_node *dst, *src; struct gossmap *gossmap = get_gossmap(p->plugin); const struct dijkstra *dij; struct route_hop *r; struct payment *root = payment_root(p); struct routehints_data *d = payment_mod_routehints_get_data(root); /* Start a tiny exploratory route computation, so we know * whether we stand any chance of reaching the destination * without routehints. This will later be used to mix in * attempts without routehints. */ src = gossmap_find_node(gossmap, p->local_id); dst = gossmap_find_node(gossmap, p->destination); if (dst == NULL) d->destination_reachable = false; else if (src != NULL) { dij = dijkstra(tmpctx, gossmap, dst, AMOUNT_MSAT(0), 10 / 1000000.0, payment_route_can_carry_even_disabled, route_score_cheaper, p); r = route_from_dijkstra(tmpctx, gossmap, dij, src, AMOUNT_MSAT(0), 0); /* If there was a route the destination is reachable * without routehints. */ d->destination_reachable = r != NULL; } else { paymod_log(p, LOG_DBG, "Could not locate ourselves in the network. " "Allowing direct attempts"); d->destination_reachable = true; } if (d->destination_reachable) { tal_arr_expand(&d->routehints, NULL); /* The above could trigger a realloc. * However, p->routes and d->routehints are * actually the same array, so we need to update the * p->routes pointer, since the realloc * might have changed pointer addresses, in order to * ensure that the pointers are not stale. */ p->routes = d->routehints; /* FIXME: ***DO*** we need to add this extra routehint? * Once we run out of routehints the default system will * just attempt directly routing to the destination anyway. */ } else if (tal_count(d->routehints) == 0) { /* If we don't have any routehints and the destination * isn't reachable, then there is no point in * continuing. */ payment_abort( p, "Destination %s is not reachable directly and " "all routehints were unusable.", type_to_string(tmpctx, struct node_id, p->destination)); return; } routehint_pre_getroute(d, p); paymod_log(p, LOG_DBG, "The destination is%s directly reachable %s attempts " "without routehints", d->destination_reachable ? "" : " not", d->destination_reachable ? "including" : "excluding"); /* Now we can continue on our merry way. */ payment_continue(p); } static void routehint_step_cb(struct routehints_data *d, struct payment *p) { struct route_hop hop; const struct payment *root = payment_root(p); struct gossmap *map; if (p->step == PAYMENT_STEP_INITIALIZED) { if (root->routes == NULL) return payment_continue(p); /* We filter out non-functional routehints once at the * beginning, and every other payment will filter out the * exluded ones on the fly. */ if (p->parent == NULL) { map = get_gossmap(p->plugin); d->routehints = filter_routehints( map, p, d, p->local_id, p->routes); /* filter_routehints modifies the array, but * this could trigger a resize and the resize * could trigger a realloc. * Keep the invoice pointer up-to-date. * FIXME: We should really consider that if we are * mutating p->routes, maybe we should * drop d->routehints and just use p->routes * directly. * It is probably not a good idea to *copy* the * routehints: other paymods are interested in * p->routes, and if the routehints system * itself adds or removes routehints from its * copy, the *actual* number of routehints that we * end up using is the one that the routehints paymod * is maintaining and traversing, and it is *that* * set of routehints that is the important one. * So rather than copying the array of routehints * in paymod, paymod should use (and mutate) the * p->routes array, and */ p->routes = d->routehints; paymod_log(p, LOG_DBG, "After filtering routehints we're left with " "%zu usable hints", tal_count(d->routehints)); /* Do not continue normally, instead go and check if * we can reach the destination directly. */ return routehint_check_reachable(p); } routehint_pre_getroute(d, p); } else if (p->step == PAYMENT_STEP_GOT_ROUTE && d->current_routehint != NULL) { /* Now it's time to stitch the two partial routes together. */ struct amount_msat dest_amount; struct route_info *routehint = d->current_routehint; struct route_hop *prev_hop; for (ssize_t i = 0; i < tal_count(routehint); i++) { prev_hop = &p->route[tal_count(p->route)-1]; if (!route_msatoshi(&dest_amount, p->amount, routehint + i + 1, tal_count(routehint) - i - 1)) { /* Just let it fail, since we couldn't stitch * the routes together. */ return payment_continue(p); } hop.node_id = *route_pubkey(p, routehint, i + 1); hop.scid = routehint[i].short_channel_id; hop.amount = dest_amount; hop.delay = route_cltv(d->final_cltv, routehint + i + 1, tal_count(routehint) - i - 1); /* Should we get a failure inside the routehint we'll * need the direction so we can exclude it. Luckily * it's rather easy to compute given the two * subsequent hops. */ hop.direction = node_id_cmp(&prev_hop->node_id, &hop.node_id) > 0 ? 1 : 0; tal_arr_expand(&p->route, hop); } } payment_continue(p); } static struct routehints_data *routehint_data_init(struct payment *p) { struct routehints_data *pd, *d = tal(p, struct routehints_data); /* If for some reason we skipped the getroute call (directpay) we'll * need this to be initialized. */ d->current_routehint = NULL; if (p->parent != NULL) { pd = payment_mod_routehints_get_data(payment_root(p)); d->destination_reachable = pd->destination_reachable; d->routehints = pd->routehints; pd = payment_mod_routehints_get_data(p->parent); if (p->parent->step == PAYMENT_STEP_RETRY) { d->base = pd->base; d->offset = pd->offset; /* If the previous try failed to route, advance * to the next routehint. */ if (!p->parent->route) ++d->offset; } else { size_t num_routehints = tal_count(d->routehints); d->offset = 0; /* This used to be pseudorand. * * However, it turns out that using the partid for * this payment has some nice properties. * The partid is in general quite random, due to * getting entropy from the network on the timing * of when payments complete/fail, and the routehint * randomization is not a privacy or security feature, * only a reliability one, thus does not need a lot * of entropy. * * But the most important bit is that *splits * get contiguous partids*, e.g. an adaptive * split will get two consecutive partid. * Because of the contiguity, using the partid * for the base will cause the split-up * payments to have fairly diverse initial * routehints. */ if (num_routehints == 0) d->base = 0; else d->base = (p->partid - 1) % num_routehints; } return d; } else { /* We defer the actual initialization of the routehints array to * the step callback when we have the invoice attached. */ d->routehints = NULL; d->base = 0; d->offset = 0; d->destination_reachable = false; return d; } return d; } REGISTER_PAYMENT_MODIFIER(routehints, struct routehints_data *, routehint_data_init, routehint_step_cb); /* For tiny payments the fees incurred due to the fixed base_fee may dominate * the overall cost of the payment. Since these payments are often used as a * way to signal, rather than actually transfer the amount, we add an * exemption that allows tiny payments to exceed the fee allowance. This is * implemented by setting a larger allowance than we would normally do if the * payment is below the threshold. */ static struct exemptfee_data *exemptfee_data_init(struct payment *p) { if (p->parent == NULL) { struct exemptfee_data *d = tal(p, struct exemptfee_data); d->amount = AMOUNT_MSAT(5000); return d; } else { return payment_mod_exemptfee_get_data(p->parent); } } static void exemptfee_cb(struct exemptfee_data *d, struct payment *p) { if (p->step != PAYMENT_STEP_INITIALIZED || p->parent != NULL) return payment_continue(p); if (amount_msat_greater_eq(d->amount, p->constraints.fee_budget)) { paymod_log( p, LOG_INFORM, "Payment fee constraint %s is below exemption threshold, " "allowing a maximum fee of %s", type_to_string(tmpctx, struct amount_msat, &p->constraints.fee_budget), type_to_string(tmpctx, struct amount_msat, &d->amount)); p->constraints.fee_budget = d->amount; p->start_constraints->fee_budget = d->amount; } return payment_continue(p); } REGISTER_PAYMENT_MODIFIER(exemptfee, struct exemptfee_data *, exemptfee_data_init, exemptfee_cb); /* BOLT #7: * * If a route is computed by simply routing to the intended recipient and * summing the `cltv_expiry_delta`s, then it's possible for intermediate nodes * to guess their position in the route. Knowing the CLTV of the HTLC, the * surrounding network topology, and the `cltv_expiry_delta`s gives an * attacker a way to guess the intended recipient. Therefore, it's highly * desirable to add a random offset to the CLTV that the intended recipient * will receive, which bumps all CLTVs along the route. * * In order to create a plausible offset, the origin node MAY start a limited * random walk on the graph, starting from the intended recipient and summing * the `cltv_expiry_delta`s, and use the resulting sum as the offset. This * effectively creates a _shadow route extension_ to the actual route and * provides better protection against this attack vector than simply picking a * random offset would. */ static struct shadow_route_data *shadow_route_init(struct payment *p) { struct shadow_route_data *d = tal(p, struct shadow_route_data), *pd; /* If we're not the root we need to inherit the flags set only on the * root payment. Since we inherit them at each step it's sufficient to * do so from our direct parent. */ if (p->parent != NULL) { pd = payment_mod_shadowroute_get_data(p->parent); d->fuzz_amount = pd->fuzz_amount; d->use_shadow = pd->use_shadow; } else { d->fuzz_amount = true; } return d; } /* Mutual recursion */ static struct command_result *shadow_route_listchannels(struct command *cmd, const char *buf, const jsmntok_t *result, struct payment *p); static struct command_result *shadow_route_extend(struct shadow_route_data *d, struct payment *p) { struct out_req *req; req = jsonrpc_request_start(p->plugin, NULL, "listchannels", shadow_route_listchannels, payment_rpc_failure, p); json_add_node_id(req->js, "source", &d->destination); return send_outreq(p->plugin, req); } static struct command_result *shadow_route_listchannels(struct command *cmd, const char *buf, const jsmntok_t *result, struct payment *p) { struct shadow_route_data *d = payment_mod_shadowroute_get_data(p); struct payment_constraints *cons = &d->constraints; struct route_info *best = NULL; double total_weight = 0.0; size_t i; struct amount_msat best_fee; const jsmntok_t *sattok, *delaytok, *basefeetok, *propfeetok, *desttok, *channelstok, *chan, *scidtok; /* Check the invariants on the constraints between payment and modifier. */ assert(d->constraints.cltv_budget <= p->constraints.cltv_budget / 4); assert(amount_msat_greater_eq(p->constraints.fee_budget, d->constraints.fee_budget)); channelstok = json_get_member(buf, result, "channels"); json_for_each_arr(i, chan, channelstok) { struct route_info curr; struct amount_sat capacity; struct amount_msat fee; sattok = json_get_member(buf, chan, "satoshis"); delaytok = json_get_member(buf, chan, "delay"); basefeetok = json_get_member(buf, chan, "base_fee_millisatoshi"); propfeetok = json_get_member(buf, chan, "fee_per_millionth"); scidtok = json_get_member(buf, chan, "short_channel_id"); desttok = json_get_member(buf, chan, "destination"); if (sattok == NULL || delaytok == NULL || delaytok->type != JSMN_PRIMITIVE || basefeetok == NULL || basefeetok->type != JSMN_PRIMITIVE || propfeetok == NULL || propfeetok->type != JSMN_PRIMITIVE || desttok == NULL || scidtok == NULL) continue; json_to_u16(buf, delaytok, &curr.cltv_expiry_delta); json_to_number(buf, basefeetok, &curr.fee_base_msat); json_to_number(buf, propfeetok, &curr.fee_proportional_millionths); json_to_short_channel_id(buf, scidtok, &curr.short_channel_id); json_to_sat(buf, sattok, &capacity); json_to_node_id(buf, desttok, &curr.pubkey); /* If the capacity is insufficient to pass the amount * it's not a plausible extension. */ if (amount_msat_greater_sat(p->amount, capacity)) continue; if (curr.cltv_expiry_delta > cons->cltv_budget) continue; if (!amount_msat_fee( &fee, p->amount, curr.fee_base_msat, curr.fee_proportional_millionths)) { /* Fee computation failed... */ continue; } if (amount_msat_greater_eq(fee, cons->fee_budget)) continue; if (random_select(1.0, &total_weight)) { best = tal_dup(tmpctx, struct route_info, &curr); best_fee = fee; } } if (best != NULL) { /* Check that we could apply the shadow route extension. Check * against both the shadow route budget as well as the * original payment's budget. */ if (best->cltv_expiry_delta > d->constraints.cltv_budget || best->cltv_expiry_delta > p->constraints.cltv_budget) { best = NULL; goto next; } /* Check the fee budget only if we didn't opt out, since * testing against a virtual budget is not useful if we do not * actually use it (it could give false positives and fail * attempts that might have gone through, */ if (d->fuzz_amount && (amount_msat_greater(best_fee, d->constraints.fee_budget) || (amount_msat_greater(best_fee, p->constraints.fee_budget)))) { best = NULL; goto next; } /* Now we can be sure that adding the shadow route will succeed */ paymod_log( p, LOG_DBG, "Adding shadow_route hop over channel %s: adding %s " "in fees and %d CLTV delta", type_to_string(tmpctx, struct short_channel_id, &best->short_channel_id), type_to_string(tmpctx, struct amount_msat, &best_fee), best->cltv_expiry_delta); d->destination = best->pubkey; d->constraints.cltv_budget -= best->cltv_expiry_delta; p->getroute->cltv += best->cltv_expiry_delta; if (!d->fuzz_amount) goto next; /* Only try to apply the fee budget changes if we want to fuzz * the amount. Virtual fees that we then don't deliver to the * destination could otherwise cause the route to be too * expensive, while really being ok. If any of these fail then * the above checks are insufficient. */ if (!amount_msat_sub(&d->constraints.fee_budget, d->constraints.fee_budget, best_fee) || !amount_msat_sub(&p->constraints.fee_budget, p->constraints.fee_budget, best_fee)) paymod_err(p, "Could not update fee constraints " "for shadow route extension. " "payment fee budget %s, modifier " "fee budget %s, shadow fee to add %s", type_to_string(tmpctx, struct amount_msat, &p->constraints.fee_budget), type_to_string(tmpctx, struct amount_msat, &d->constraints.fee_budget), type_to_string(tmpctx, struct amount_msat, &best_fee)); } next: /* Now it's time to decide whether we want to extend or continue. */ if (best == NULL || pseudorand(2) == 0) { payment_continue(p); return command_still_pending(cmd); } else { return shadow_route_extend(d, p); } } static void shadow_route_cb(struct shadow_route_data *d, struct payment *p) { if (!d->use_shadow) return payment_continue(p); if (p->step != PAYMENT_STEP_INITIALIZED) return payment_continue(p); d->destination = *p->destination; /* Allow shadowroutes to consume up to 1/4th of our budget. */ d->constraints.cltv_budget = p->constraints.cltv_budget / 4; d->constraints.fee_budget = amount_msat_div(p->constraints.fee_budget, 4); if (pseudorand(2) == 0) { return payment_continue(p); } else { shadow_route_extend(d, p); } } REGISTER_PAYMENT_MODIFIER(shadowroute, struct shadow_route_data *, shadow_route_init, shadow_route_cb); static void direct_pay_override(struct payment *p) { /* The root has performed the search for a direct channel. */ struct payment *root = payment_root(p); struct direct_pay_data *d; struct channel_hint *hint = NULL; /* If we were unable to find a direct channel we don't need to do * anything. */ d = payment_mod_directpay_get_data(root); if (d->chan == NULL) return payment_continue(p); /* If we have a channel we need to make sure that it still has * sufficient capacity. Look it up in the channel_hints. */ for (size_t i=0; ichannel_hints); i++) { struct short_channel_id_dir *cur = &root->channel_hints[i].scid; if (short_channel_id_eq(&cur->scid, &d->chan->scid) && cur->dir == d->chan->dir) { hint = &root->channel_hints[i]; break; } } if (hint && hint->enabled && amount_msat_greater(hint->estimated_capacity, p->amount)) { /* Now build a route that consists only of this single hop */ p->route = tal_arr(p, struct route_hop, 1); p->route[0].amount = p->amount; p->route[0].delay = p->getroute->cltv; p->route[0].scid = hint->scid.scid; p->route[0].direction = hint->scid.dir; p->route[0].node_id = *p->destination; paymod_log(p, LOG_DBG, "Found a direct channel (%s) with sufficient " "capacity, skipping route computation.", type_to_string(tmpctx, struct short_channel_id_dir, &hint->scid)); payment_set_step(p, PAYMENT_STEP_GOT_ROUTE); } payment_continue(p); } /* Now that we have the listpeerchannels result for the root payment, let's search * for a direct channel that is a) connected and b) in state normal. We will * check the capacity based on the channel_hints in the override. */ static struct command_result *direct_pay_listpeerchannels(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { struct listpeers_channel **channels = json_to_listpeers_channels(tmpctx, buffer, toks); struct direct_pay_data *d = payment_mod_directpay_get_data(p); for (size_t i=0; iconnected) continue; if (!streq(chan->state, "CHANNELD_NORMAL") && !streq(chan->state, "CHANNELD_AWAITING_SPLICE")) continue; /* Must have either a local alias for zeroconf * channels or a final scid. */ assert(chan->alias[LOCAL] || chan->scid); tal_free(d->chan); d->chan = tal(d, struct short_channel_id_dir); if (chan->scid) { d->chan->scid = *chan->scid; } else { d->chan->scid = *chan->alias[LOCAL]; } d->chan->dir = chan->direction; } direct_pay_override(p); return command_still_pending(cmd); } static void direct_pay_cb(struct direct_pay_data *d, struct payment *p) { struct out_req *req; /* Look up the direct channel only on root. */ if (p->step != PAYMENT_STEP_INITIALIZED) return payment_continue(p); req = jsonrpc_request_start(p->plugin, NULL, "listpeerchannels", direct_pay_listpeerchannels, direct_pay_listpeerchannels, p); json_add_node_id(req->js, "id", p->destination); send_outreq(p->plugin, req); } static struct direct_pay_data *direct_pay_init(struct payment *p) { struct direct_pay_data *d = tal(p, struct direct_pay_data); d->chan = NULL; return d; } REGISTER_PAYMENT_MODIFIER(directpay, struct direct_pay_data *, direct_pay_init, direct_pay_cb); static struct command_result *waitblockheight_rpc_cb(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { const jsmntok_t *blockheighttok, *codetok; u32 blockheight; int code; struct payment *subpayment; blockheighttok = json_get_member(buffer, toks, "blockheight"); if (!blockheighttok || !json_to_number(buffer, blockheighttok, &blockheight)) { codetok = json_get_member(buffer, toks, "code"); json_to_int(buffer, codetok, &code); if (code == WAIT_TIMEOUT) { payment_fail( p, "Timed out while attempting to sync to blockheight " "returned by destination. Please finish syncing " "with the blockchain and try again."); } else { plugin_err( p->plugin, "Unexpected result from waitblockheight: %.*s", json_tok_full_len(toks), json_tok_full(buffer, toks)); } } else { subpayment = payment_new(p, NULL, p, p->modifiers); payment_start_at_blockheight(subpayment, blockheight); payment_set_step(p, PAYMENT_STEP_RETRY); subpayment->why = tal_fmt( subpayment, "Retrying after waiting for blockchain sync."); paymod_log( p, LOG_DBG, "Retrying after waitblockheight, new partid %" PRIu32, subpayment->partid); payment_continue(p); } return command_still_pending(cmd); } static void waitblockheight_cb(void *d, struct payment *p) { struct out_req *req; struct timeabs now = time_now(); struct timerel remaining; u32 blockheight; if (p->step != PAYMENT_STEP_FAILED) return payment_continue(p); /* If we don't have an error message to parse we can't wait for blockheight. */ if (p->result == NULL) return payment_continue(p); /* Check if we'd be waiting more than 0 seconds. If we have * less than a second then waitblockheight would return * immediately resulting in a loop. */ if (time_after(now, p->deadline)) return payment_continue(p); remaining = time_between(p->deadline, now); if (time_to_sec(remaining) < 1) return payment_continue(p); /* *Was* it a blockheight disagreement that caused the failure? */ if (!failure_is_blockheight_disagreement(p, &blockheight)) return payment_continue(p); paymod_log(p, LOG_INFORM, "Remote node appears to be on a longer chain, which causes " "CLTV timeouts to be incorrect. Waiting up to %" PRIu64 " seconds to catch up to block %d before retrying.", time_to_sec(remaining), blockheight); /* Set temporarily set the state of the payment to not failed, so * interim status queries don't show this as terminally failed. We're * in control for this payment so nobody else could be fooled by * this. The callback will set it to retry anyway. */ payment_set_step(p, PAYMENT_STEP_RETRY); req = jsonrpc_request_start(p->plugin, NULL, "waitblockheight", waitblockheight_rpc_cb, waitblockheight_rpc_cb, p); json_add_u32(req->js, "blockheight", blockheight); json_add_u32(req->js, "timeout", time_to_sec(remaining)); send_outreq(p->plugin, req); } REGISTER_PAYMENT_MODIFIER(waitblockheight, void *, NULL, waitblockheight_cb); static u32 payment_max_htlcs(const struct payment *p) { const struct payment *root; struct channel_hint *h; u32 res = 0; for (size_t i = 0; i < tal_count(p->channel_hints); i++) { h = &p->channel_hints[i]; if (h->local && h->enabled) res += h->local->htlc_budget; } root = p; while (root->parent) root = root->parent; if (res > root->max_htlcs) res = root->max_htlcs; return res; } /** payment_lower_max_htlcs * * @brief indicates that we have a good reason to believe that * we should limit our number of max HTLCs. * * @desc Causes future payment_max_htlcs to have a maximum value * they return. * Can be called by multiple paymods: the lowest one any paymod * has given will be used. * If this is called with a limit higher than the existing limit, * it just successfully returns without doing anything. * * @param p - a payment on the payment tree we should limit. * @param limit - the number of max HTLCs. * @param why - the reason we think the given max HTLCs is * reasonable. */ static void payment_lower_max_htlcs(struct payment *p, u32 limit, const char *why) { struct payment *root = payment_root(p); if (root->max_htlcs > limit) { paymod_log(p, LOG_INFORM, "%s limit on max HTLCs: %"PRIu32", %s", root->max_htlcs == UINT32_MAX ? "Initial" : "Lowering", limit, why); root->max_htlcs = limit; } } static bool payment_supports_mpp(struct payment *p) { return feature_offered(p->features, OPT_BASIC_MPP); } /***************************************************************************** * Adaptive splitter -- Split payment if we can't get it through. * * The adaptive splitter splits the amount of a failed payment in half, with * +/- 10% randomness, and then starts two attempts, one for either side of * the split. The goal is to find two smaller routes, that still adhere to our * constraints, but that can complete the payment. * * This modifier also checks whether we can split and still have enough HTLCs * available on the channels and aborts if that's no longer the case. */ #define MPP_ADAPTIVE_LOWER_LIMIT AMOUNT_MSAT(100 * 1000) static struct adaptive_split_mod_data *adaptive_splitter_data_init(struct payment *p) { struct adaptive_split_mod_data *d; if (p->parent == NULL) { d = tal(p, struct adaptive_split_mod_data); d->disable = false; d->htlc_budget = 0; return d; } else { return payment_mod_adaptive_splitter_get_data(p->parent); } } static void adaptive_splitter_cb(struct adaptive_split_mod_data *d, struct payment *p) { struct payment *root = payment_root(p); struct adaptive_split_mod_data *root_data = payment_mod_adaptive_splitter_get_data(root); if (d->disable) return payment_continue(p); if (!payment_supports_mpp(p) || root->abort) return payment_continue(p); if (p->parent == NULL && d->htlc_budget == 0) { /* Now that we potentially had an early splitter run, let's * update our htlc_budget that we own exclusively from now * on. */ int children = tal_count(p->children); d->htlc_budget = payment_max_htlcs(p); if (children > d->htlc_budget) { p->abort = true; return payment_fail( p, "Cannot add %d HTLCs to our channels, we " "only have %d HTLCs available.", children, d->htlc_budget); } d->htlc_budget -= children; } if (p->step == PAYMENT_STEP_ONION_PAYLOAD) { /* We need to tell the last hop the total we're going * to send. MPP disables amount fuzzing, so we should * always get the exact value through. */ size_t lastidx = tal_count(p->createonion_request->hops) - 1; struct createonion_hop *hop = &p->createonion_request->hops[lastidx]; struct tlv_field **fields = &hop->tlv_payload->fields; tlvstream_set_tlv_payload_data( fields, root->payment_secret, root->amount.millisatoshis); /* Raw: onion payload */ } else if (p->step == PAYMENT_STEP_FAILED && !p->abort) { if (amount_msat_greater(p->amount, MPP_ADAPTIVE_LOWER_LIMIT)) { struct payment *a, *b; /* Random number in the range [90%, 110%] */ double rand = pseudorand_double() * 0.2 + 0.9; u64 mid = p->amount.millisatoshis / 2 * rand; /* Raw: multiplication */ bool ok; /* Use the start constraints, not the ones updated by routes and shadow-routes. */ struct payment_constraints *pconstraints = p->start_constraints; /* First check that splitting doesn't exceed our HTLC budget */ if (root_data->htlc_budget == 0) { root->abort = true; return payment_fail( p, "Cannot split payment any further without " "exceeding the maximum number of HTLCs " "allowed by our channels"); } p->step = PAYMENT_STEP_SPLIT; a = payment_new(p, NULL, p, p->modifiers); b = payment_new(p, NULL, p, p->modifiers); a->amount.millisatoshis = mid; /* Raw: split. */ b->amount.millisatoshis -= mid; /* Raw: split. */ double multiplier = amount_msat_ratio(a->amount, p->amount); assert(multiplier >= 0.4 && multiplier < 0.6); /* Adjust constraints since we don't want to double our * fee allowance when we split. */ if (!amount_msat_scale(&a->constraints.fee_budget, pconstraints->fee_budget, multiplier)) abort(); ok = amount_msat_sub(&b->constraints.fee_budget, pconstraints->fee_budget, a->constraints.fee_budget); /* Should not fail, mid is less than 55% of original * amount. fee_budget_a <= 55% of fee_budget_p (parent * of the new payments).*/ assert(ok); payment_start(a); payment_start(b); paymod_log(p, LOG_DBG, "Adaptively split into 2 sub-payments: " "new partid %"PRIu32" (%s), " "new partid %"PRIu32" (%s)", a->partid, type_to_string(tmpctx, struct amount_msat, &a->amount), b->partid, type_to_string(tmpctx, struct amount_msat, &b->amount)); /* Take note that we now have an additional split that * may end up using an HTLC. */ root_data->htlc_budget--; } else { paymod_log(p, LOG_INFORM, "Lower limit of adaptive splitter reached " "(%s < %s), not splitting further.", type_to_string(tmpctx, struct amount_msat, &p->amount), type_to_string(tmpctx, struct amount_msat, &MPP_ADAPTIVE_LOWER_LIMIT)); } } payment_continue(p); } REGISTER_PAYMENT_MODIFIER(adaptive_splitter, struct adaptive_split_mod_data *, adaptive_splitter_data_init, adaptive_splitter_cb); /***************************************************************************** * payee_incoming_limit * * @desc every channel has a limit on the number of HTLCs it is willing to * transport. * This is particularly crucial for the payers and payees, as they represent * the bottleneck to and from the network. * The `payment_max_htlcs` function will, by itself, be able to count the * payer-side channels, but assessing the payee requires us to probe the * area around it. * * This paymod must be *after* `routehints` paymod: * * - If we cannot find the destination on the public network, we can only * use channels it put in the routehints. * In this case, that is the number of channels we assess the payee as * having. * However, the `routehints` paymod may filter out some routehints, thus * we should assess based on the post-filtered routehints. */ /* The default `max-concurrent-htlcs` is 30, but node operators might want * to push it even lower to reduce their liabilities in case they have to * unilaterally close. * This will not necessarily improve even in a post-anchor-commitments world, * since one of the reasons to unilaterally close is if some HTLC is about to * expire, which of course requires the HTLCs to be published anyway, meaning * it will still be potentially costly. * So our initial assumption is 15 HTLCs per channel. */ #define ASSUMED_MAX_HTLCS_PER_CHANNEL 15 static struct command_result * payee_incoming_limit_count(struct command *cmd, const char *buf, const jsmntok_t *result, struct payment *p) { const jsmntok_t *channelstok; size_t num_channels = 0; channelstok = json_get_member(buf, result, "channels"); assert(channelstok); /* Count channels. * `listchannels` returns half-channels, i.e. it normally * gives two objects per channel, one for each direction. * However, `listchannels ` returns only half-channel * objects whose `source` is the given channel. * Thus, the length of `channels` is accurately the number * of channels. */ num_channels = channelstok->size; /* If num_channels is 0, check if there is an invoice. */ if (num_channels == 0) num_channels = tal_count(p->routes); /* If we got a decent number of channels, limit! */ if (num_channels != 0) { const char *why; u32 lim; why = tal_fmt(tmpctx, "Destination %s has %zd channels, " "assuming %d HTLCs per channel", type_to_string(tmpctx, struct node_id, p->destination), num_channels, ASSUMED_MAX_HTLCS_PER_CHANNEL); lim = num_channels * ASSUMED_MAX_HTLCS_PER_CHANNEL; payment_lower_max_htlcs(p, lim, why); } payment_continue(p); return command_still_pending(cmd); } static void payee_incoming_limit_step_cb(void *d UNUSED, struct payment *p) { /* Only operate at the initialization of te root payment. * Also, no point operating if payment does not support MPP anyway. */ if (p->parent || p->step != PAYMENT_STEP_INITIALIZED || !payment_supports_mpp(p)) return payment_continue(p); /* Get information on the destination. */ struct out_req *req; req = jsonrpc_request_start(p->plugin, NULL, "listchannels", &payee_incoming_limit_count, &payment_rpc_failure, p); json_add_node_id(req->js, "source", p->destination); (void) send_outreq(p->plugin, req); } REGISTER_PAYMENT_MODIFIER(payee_incoming_limit, void *, NULL, payee_incoming_limit_step_cb); /***************************************************************************** * check_preapproveinvoice * * @desc submit the invoice to the HSM for approval, fail the payment if not approved. * * This paymod checks the invoice for approval with the HSM, which might: * - check with the user for specific approval * - enforce velocity controls * - automatically approve the invoice (default) */ static struct command_result * check_preapproveinvoice_allow(struct command *cmd, const char *buf, const jsmntok_t *result, struct payment *p) { /* On success, an empty object is returned. */ payment_continue(p); return command_still_pending(cmd); } static struct command_result *preapproveinvoice_rpc_failure(struct command *cmd, const char *buffer, const jsmntok_t *toks, struct payment *p) { payment_abort(p, "Failing payment due to a failed RPC call: %.*s", toks->end - toks->start, buffer + toks->start); return command_still_pending(cmd); } static void check_preapproveinvoice_start(void *d UNUSED, struct payment *p) { /* Ask the HSM if the invoice is OK to pay */ struct out_req *req; req = jsonrpc_request_start(p->plugin, NULL, "preapproveinvoice", &check_preapproveinvoice_allow, &preapproveinvoice_rpc_failure, p); /* FIXME: rename parameter to invstring */ json_add_string(req->js, "bolt11", p->invstring); (void) send_outreq(p->plugin, req); } REGISTER_PAYMENT_MODIFIER(check_preapproveinvoice, void *, NULL, check_preapproveinvoice_start); static struct route_exclusions_data * route_exclusions_data_init(struct payment *p) { struct route_exclusions_data *d; if (p->parent != NULL) { return payment_mod_route_exclusions_get_data(p->parent); } else { d = tal(p, struct route_exclusions_data); d->exclusions = NULL; } return d; } static void route_exclusions_step_cb(struct route_exclusions_data *d, struct payment *p) { if (p->parent) return payment_continue(p); struct route_exclusion **exclusions = d->exclusions; for (size_t i = 0; i < tal_count(exclusions); i++) { struct route_exclusion *e = exclusions[i]; if (e->type == EXCLUDE_CHANNEL) { channel_hints_update(p, e->u.chan_id.scid, e->u.chan_id.dir, false, false, NULL, NULL); } else { if (node_id_eq(&e->u.node_id, p->destination)) { payment_abort(p, "Payee is manually excluded"); return; } else if (node_id_eq(&e->u.node_id, p->local_id)) { payment_abort(p, "Payer is manually excluded"); return; } tal_arr_expand(&p->excluded_nodes, e->u.node_id); } } payment_continue(p); } REGISTER_PAYMENT_MODIFIER(route_exclusions, struct route_exclusions_data *, route_exclusions_data_init, route_exclusions_step_cb);