#include "config.h" #include #include #include #include #include #include #include #include #include /* BOLT #4: * * ### `tlv_payload` format * * This is a more flexible format, which avoids the redundant * `short_channel_id` field for the final node. It is formatted * according to the Type-Length-Value format defined in [BOLT * #1](01-messaging.md#type-length-value-format). */ static u8 *make_tlv_hop(const tal_t *ctx, const struct tlv_tlv_payload *tlv) { /* We can't have over 64k anyway */ u8 *tlvs = tal_arr(ctx, u8, 3); towire_tlv_tlv_payload(&tlvs, tlv); switch (bigsize_put(tlvs, tal_bytelen(tlvs) - 3)) { case 1: /* Move over two unused bytes */ memmove(tlvs + 1, tlvs + 3, tal_bytelen(tlvs) - 3); tal_resize(&tlvs, tal_bytelen(tlvs) - 2); return tlvs; case 3: return tlvs; } abort(); } u8 *onion_nonfinal_hop(const tal_t *ctx, const struct short_channel_id *scid, struct amount_msat forward, u32 outgoing_cltv) { struct tlv_tlv_payload *tlv = tlv_tlv_payload_new(tmpctx); /* BOLT #4: * * The writer: *... * - For every node: * - MUST include `amt_to_forward` and `outgoing_cltv_value`. * - For every non-final node: * - MUST include `short_channel_id` * - MUST NOT include `payment_data` */ tlv->amt_to_forward = &forward.millisatoshis; /* Raw: TLV convert */ tlv->outgoing_cltv_value = &outgoing_cltv; tlv->short_channel_id = cast_const(struct short_channel_id *, scid); return make_tlv_hop(ctx, tlv); } u8 *onion_final_hop(const tal_t *ctx, struct amount_msat forward, u32 outgoing_cltv, struct amount_msat total_msat, const struct secret *payment_secret, const u8 *payment_metadata) { struct tlv_tlv_payload *tlv = tlv_tlv_payload_new(tmpctx); struct tlv_tlv_payload_payment_data tlv_pdata; /* These go together! */ if (!payment_secret) assert(amount_msat_eq(total_msat, forward)); /* BOLT #4: * * The writer: *... * - For every node: * - MUST include `amt_to_forward` and `outgoing_cltv_value`. *... * - For the final node: * - MUST NOT include `short_channel_id` * - if the recipient provided `payment_secret`: * - MUST include `payment_data` * - MUST set `payment_secret` to the one provided * - MUST set `total_msat` to the total amount it will send */ tlv->amt_to_forward = &forward.millisatoshis; /* Raw: TLV convert */ tlv->outgoing_cltv_value = &outgoing_cltv; if (payment_secret) { tlv_pdata.payment_secret = *payment_secret; tlv_pdata.total_msat = total_msat.millisatoshis; /* Raw: TLV convert */ tlv->payment_data = &tlv_pdata; } tlv->payment_metadata = cast_const(u8 *, payment_metadata); return make_tlv_hop(ctx, tlv); } u8 *onion_blinded_hop(const tal_t *ctx, const struct amount_msat *amt_to_forward, const u32 *outgoing_cltv_value, const u8 *enctlv, const struct pubkey *blinding) { struct tlv_tlv_payload *tlv = tlv_tlv_payload_new(tmpctx); if (amt_to_forward) { tlv->amt_to_forward = cast_const(u64 *, &amt_to_forward->millisatoshis); /* Raw: TLV convert */ } tlv->outgoing_cltv_value = cast_const(u32 *, outgoing_cltv_value); tlv->encrypted_recipient_data = cast_const(u8 *, enctlv); tlv->blinding_point = cast_const(struct pubkey *, blinding); return make_tlv_hop(ctx, tlv); }