common/onion: handle payment by node_id.

In a blinded path, you can specify node_id instead of scid.  Handle
that case.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-11-09 12:00:10 +10:30 committed by Christian Decker
parent 987df688ed
commit c5656ec90a
4 changed files with 54 additions and 13 deletions

View File

@ -159,14 +159,16 @@ static bool handle_blinded_forward(struct onion_payload *p,
return false;
}
/* FIXME: handle fwd-by-node-id */
if (!enc->short_channel_id) {
*failtlvtype = TLV_TLV_PAYLOAD_ENCRYPTED_RECIPIENT_DATA;
return false;
if (enc->short_channel_id) {
p->forward_channel = tal_dup(p, struct short_channel_id,
enc->short_channel_id);
p->forward_node_id = NULL;
} else {
p->forward_channel = NULL;
p->forward_node_id = tal_dup(p, struct pubkey,
enc->next_node_id);
}
p->forward_channel = tal_dup(p, struct short_channel_id,
enc->short_channel_id);
p->total_msat = NULL;
/* BOLT-route-blinding #4:
@ -231,6 +233,8 @@ static bool handle_blinded_terminal(struct onion_payload *p,
p->outgoing_cltv = *tlv->outgoing_cltv_value;
p->forward_channel = NULL;
p->forward_node_id = NULL;
if (tlv->total_amount_msat) {
p->total_msat = tal(p, struct amount_msat);
*p->total_msat = amount_msat(*tlv->total_amount_msat);
@ -454,6 +458,9 @@ struct onion_payload *onion_decode(const tal_t *ctx,
&p->amt_to_forward);
}
/* Non-blinded is (currently) always by scid */
p->forward_node_id = NULL;
p->payment_secret = NULL;
if (p->tlv->payment_data) {
p->payment_secret = tal_dup(p, struct secret,

View File

@ -11,7 +11,11 @@ struct onion_payload {
struct amount_msat amt_to_forward;
u32 outgoing_cltv;
struct amount_msat *total_msat;
/* One of these is set */
struct short_channel_id *forward_channel;
struct pubkey *forward_node_id;
struct secret *payment_secret;
u8 *payment_metadata;

View File

@ -714,7 +714,7 @@ static void forward_htlc(struct htlc_in *hin,
/* Update this to where we're actually trying to send. */
if (next)
forward_scid = channel_scid_or_local_alias(next);
}else
} else
next = NULL;
/* Unknown peer, or peer not ready. */
@ -1077,6 +1077,9 @@ static void htlc_accepted_hook_serialize(struct htlc_accepted_hook_payload *p,
if (p->payload->forward_channel)
json_add_short_channel_id(s, "short_channel_id",
p->payload->forward_channel);
if (p->payload->forward_node_id)
json_add_pubkey(s, "next_node_id",
p->payload->forward_node_id);
if (deprecated_apis)
json_add_string(s, "forward_amount",
fmt_amount_msat(tmpctx,
@ -1202,20 +1205,42 @@ static struct channel_id *calc_forwarding_channel(struct lightningd *ld,
const struct route_step *rs)
{
const struct onion_payload *p = hp->payload;
struct peer *peer;
struct channel *c, *best;
if (rs->nextcase != ONION_FORWARD)
return NULL;
if (!p || !p->forward_channel)
if (!p)
return NULL;
c = any_channel_by_scid(ld, p->forward_channel, false);
if (!c)
return NULL;
if (p->forward_channel) {
c = any_channel_by_scid(ld, p->forward_channel, false);
if (!c)
return NULL;
peer = c->peer;
} else {
struct node_id id;
if (!p->forward_node_id)
return NULL;
node_id_from_pubkey(&id, p->forward_node_id);
peer = peer_by_id(ld, &id);
if (!peer)
return NULL;
c = NULL;
}
best = best_channel(ld, c->peer, p->amt_to_forward, c);
if (best != c) {
best = best_channel(ld, peer, p->amt_to_forward, c);
if (!c) {
if (!best)
return NULL;
log_debug(hp->channel->log,
"Chose channel %s for peer %s",
type_to_string(tmpctx, struct short_channel_id,
channel_scid_or_local_alias(best)),
type_to_string(tmpctx, struct node_id,
&peer->id));
} else if (best != c) {
log_debug(hp->channel->log,
"Chose a better channel than %s: %s",
type_to_string(tmpctx, struct short_channel_id,

View File

@ -347,6 +347,11 @@ void json_add_node_id(struct json_stream *response UNNEEDED,
void json_add_num(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
unsigned int value UNNEEDED)
{ fprintf(stderr, "json_add_num called!\n"); abort(); }
/* Generated stub for json_add_pubkey */
void json_add_pubkey(struct json_stream *response UNNEEDED,
const char *fieldname UNNEEDED,
const struct pubkey *key UNNEEDED)
{ fprintf(stderr, "json_add_pubkey called!\n"); abort(); }
/* Generated stub for json_add_s32 */
void json_add_s32(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
int32_t value UNNEEDED)