diff --git a/channeld/channeld.c b/channeld/channeld.c index f19b1b2e3153..4cc475334811 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -5314,7 +5314,7 @@ static const u8 *get_cupdate(const struct peer *peer) static void handle_offer_htlc(struct peer *peer, const u8 *inmsg) { u8 *msg; - bool endorsed; + u8 *endorsed; u32 cltv_expiry; struct amount_msat amount; struct sha256 payment_hash; @@ -5332,25 +5332,25 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg) if (!fromwire_channeld_offer_htlc(tmpctx, inmsg, &amount, &cltv_expiry, &payment_hash, - onion_routing_packet, &blinding)) + onion_routing_packet, &blinding, &endorsed)) master_badmsg(WIRE_CHANNELD_OFFER_HTLC, inmsg); if (blinding) { tlvs = tlv_update_add_htlc_tlvs_new(tmpctx); tlvs->blinding_point = tal_dup(tlvs, struct pubkey, blinding); + tlvs->endorsed = endorsed; } else tlvs = NULL; - endorsed = false; e = channel_add_htlc(peer->channel, LOCAL, peer->htlc_id, amount, cltv_expiry, &payment_hash, onion_routing_packet, take(blinding), NULL, &htlc_fee, endorsed, true); - status_debug("Adding HTLC %"PRIu64" amount=%s cltv=%u gave %s endorsed=%d", + status_debug("Adding HTLC %"PRIu64" amount=%s cltv=%u gave %s endorsed=%u", peer->htlc_id, type_to_string(tmpctx, struct amount_msat, &amount), cltv_expiry, channel_add_err_name(e), - endorsed); + endorsed ? *endorsed : 0); switch (e) { case CHANNEL_ERR_ADD_OK: diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index 5174c18e0f95..90d336912a41 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -104,6 +104,7 @@ msgdata,channeld_offer_htlc,cltv_expiry,u32, msgdata,channeld_offer_htlc,payment_hash,sha256, msgdata,channeld_offer_htlc,onion_routing_packet,u8,1366 msgdata,channeld_offer_htlc,blinding,?pubkey, +msgdata,channeld_offer_htlc,endorsed,?u8, # Reply; synchronous since IDs have to increment. msgtype,channeld_offer_htlc_reply,1104 diff --git a/lightningd/pay.c b/lightningd/pay.c index 01329ef12a4d..6a98ea061e3d 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /* Routing failure object */ @@ -768,7 +769,8 @@ static const u8 *send_onion(const tal_t *ctx, struct lightningd *ld, u64 partid, u64 groupid, struct channel *channel, - struct htlc_out **hout) + struct htlc_out **hout, + const u8 *endorsed) { const u8 *onion; unsigned int base_expiry; @@ -778,7 +780,8 @@ static const u8 *send_onion(const tal_t *ctx, struct lightningd *ld, return send_htlc_out(ctx, channel, first_hop->amount, base_expiry + first_hop->delay, final_amount, payment_hash, - blinding, partid, groupid, onion, NULL, hout); + blinding, partid, groupid, onion, NULL, hout, + endorsed); } static struct command_result *check_invoice_request_usage(struct command *cmd, @@ -1084,7 +1087,7 @@ send_payment_core(struct lightningd *ld, const struct wallet_payment *old_payment; struct channel *channel; const u8 *failmsg; - bool endorsed; + const u8 *endorsed; struct htlc_out *hout; struct routing_failure *fail; struct command_result *ret; @@ -1126,10 +1129,8 @@ send_payment_core(struct lightningd *ld, * - SHOULD set `endorsed` to `0`. * - otherwise: * - SHOULD set `endorsed` to `1`. - * - * We wait that someone else smarted than me will provide the way to - * calculate it for now it is just a placesolder. */ - endorsed = false; + **/ + endorsed = NULL; failmsg = send_onion(tmpctx, ld, packet, first_hop, msat, rhash, NULL, partid, group, channel, &hout, endorsed); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index ebbaa869e2dd..aabf2ae2ae29 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -605,7 +605,8 @@ const u8 *send_htlc_out(const tal_t *ctx, u64 groupid, const u8 *onion_routing_packet, struct htlc_in *in, - struct htlc_out **houtp) + struct htlc_out **houtp, + const u8 *endorsed) { u8 *msg; @@ -647,7 +648,8 @@ const u8 *send_htlc_out(const tal_t *ctx, } msg = towire_channeld_offer_htlc(out, amount, cltv, payment_hash, - onion_routing_packet, blinding); + onion_routing_packet, blinding, + (u8 *)endorsed); subd_req(out->peer->ld, out->owner, take(msg), -1, 0, rcvd_htlc_reply, *houtp); @@ -700,7 +702,8 @@ static void forward_htlc(struct htlc_in *hin, const struct short_channel_id *forward_scid, const struct channel_id *forward_to, const u8 next_onion[TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE)], - const struct pubkey *next_blinding) + const struct pubkey *next_blinding, + const u8 *endorsed) { const u8 *failmsg; struct lightningd *ld = hin->key.channel->peer->ld; @@ -811,7 +814,7 @@ static void forward_htlc(struct htlc_in *hin, outgoing_cltv_value, AMOUNT_MSAT(0), &hin->payment_hash, next_blinding, 0 /* partid */, 0 /* groupid */, - next_onion, hin, &hout); + next_onion, hin, &hout, endorsed); if (!failmsg) return; @@ -839,6 +842,11 @@ struct htlc_accepted_hook_payload { u8 *next_onion; u64 failtlvtype; size_t failtlvpos; + /* NULL if the jamming mitigation it is not + * supported */ + u8 *endorsed; + /* FIXME: add the possibility to encode + * and decode the raw tlvs */ }; /* We only handle the simplest cases here */ @@ -924,7 +932,8 @@ static bool htlc_accepted_hook_deserialize(struct htlc_accepted_hook_payload *re struct htlc_in *hin = request->hin; struct lightningd *ld = request->ld; struct preimage payment_preimage; - const jsmntok_t *resulttok, *paykeytok, *payloadtok, *fwdtok; + const jsmntok_t *resulttok, *paykeytok, + *payloadtok, *fwdtok, *endorse_tok; u8 *failonion; if (!toks || !buffer) @@ -976,6 +985,19 @@ static bool htlc_accepted_hook_deserialize(struct htlc_accepted_hook_payload *re } } + endorse_tok = json_get_member(buffer, toks, "endorsed"); + if (endorse_tok) { + bool internal_endorsed; + tal_free(request->endorsed); + request->endorsed = tal(request, u8); + if (json_to_bool(buffer, endorse_tok, &internal_endorsed)) + fatal("Bad endorsed for htlc_accepted" + " hook: %.*s", + endorse_tok->end - endorse_tok->start, + buffer + endorse_tok->start); + *request->endorsed = internal_endorsed ? 1 : 0; + } + if (json_tok_streq(buffer, resulttok, "continue")) { return true; } @@ -1096,6 +1118,8 @@ static void htlc_accepted_hook_serialize(struct htlc_accepted_hook_payload *p, } json_add_hex_talarr(s, "next_onion", p->next_onion); json_add_secret(s, "shared_secret", hin->shared_secret); + if (p->endorsed != NULL) + json_add_bool(s, "endorsed", *p->endorsed == 1); json_object_end(s); if (p->fwd_channel_id) @@ -1144,7 +1168,7 @@ htlc_accepted_hook_final(struct htlc_accepted_hook_payload *request STEALS) request->payload->forward_channel, request->fwd_channel_id, serialize_onionpacket(tmpctx, rs->next), - request->next_blinding); + request->next_blinding, request->endorsed); } else handle_localpay(hin, request->payload->amt_to_forward, diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index db41ccada2e8..9a8de77cb9b3 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -50,7 +50,8 @@ const u8 *send_htlc_out(const tal_t *ctx, u64 groupid, const u8 *onion_routing_packet, struct htlc_in *in, - struct htlc_out **houtp); + struct htlc_out **houtp, + const u8 *endorsed); void onchain_failed_our_htlc(const struct channel *channel, const struct htlc_stub *htlc, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 456a046fb8f9..7b7a17734fc0 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -770,7 +770,7 @@ u8 *towire_channeld_got_commitsig_reply(const tal_t *ctx UNNEEDED) u8 *towire_channeld_got_revoke_reply(const tal_t *ctx UNNEEDED) { fprintf(stderr, "towire_channeld_got_revoke_reply called!\n"); abort(); } /* Generated stub for towire_channeld_offer_htlc */ -u8 *towire_channeld_offer_htlc(const tal_t *ctx UNNEEDED, struct amount_msat amount_msat UNNEEDED, u32 cltv_expiry UNNEEDED, const struct sha256 *payment_hash UNNEEDED, const u8 onion_routing_packet[1366] UNNEEDED, const struct pubkey *blinding UNNEEDED) +u8 *towire_channeld_offer_htlc(const tal_t *ctx UNNEEDED, struct amount_msat amount_msat UNNEEDED, u32 cltv_expiry UNNEEDED, const struct sha256 *payment_hash UNNEEDED, const u8 onion_routing_packet[1366] UNNEEDED, const struct pubkey *blinding UNNEEDED, u8 *endorsed UNNEEDED) { fprintf(stderr, "towire_channeld_offer_htlc called!\n"); abort(); } /* Generated stub for towire_channeld_sending_commitsig_reply */ u8 *towire_channeld_sending_commitsig_reply(const tal_t *ctx UNNEEDED)