From 5f32cfe9cd1cdf1a6b89b9b6bb60d8a67d84b9cd Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 14 May 2020 15:22:49 +0200 Subject: [PATCH] paymod: Implement legacy onion payload computation This is just for testing for now, TLV payload computation will come next. We stage all the payloads in deserialized form so modifiers can modify them more easily and serialize them only before actually calling `createonion`. --- plugins/libplugin-pay.c | 54 +++++++++++++++++++++++++++++++++++++++++ plugins/libplugin-pay.h | 23 ++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 8ebfff25d..cf1078d2a 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -162,7 +162,61 @@ static void payment_getroute(struct payment *p) static void payment_compute_onion_payloads(struct payment *p) { + struct createonion_request *cr; + size_t hopcount; + static struct short_channel_id all_zero_scid; + struct createonion_hop *cur; p->step = PAYMENT_STEP_ONION_PAYLOAD; + hopcount = tal_count(p->route); + + /* 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)); + + /* 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 */ + cur = &cr->hops[i]; + cur->style = p->route[i].style; + cur->pubkey = p->route[i].nodeid; + switch (cur->style) { + case ROUTE_HOP_LEGACY: + cur->legacy_payload = + tal(cr->hops, struct legacy_payload); + cur->legacy_payload->forward_amt = + p->route[i + 1].amount; + cur->legacy_payload->scid = p->route[i + 1].channel_id; + cur->legacy_payload->outgoing_cltv = + p->start_block + p->route[i + 1].delay; + break; + case ROUTE_HOP_TLV: + /* TODO(cdecker) Implement */ + abort(); + } + } + + /* Final hop */ + cur = &cr->hops[hopcount - 1]; + cur->style = p->route[hopcount - 1].style; + cur->pubkey = p->route[hopcount - 1].nodeid; + switch (cur->style) { + case ROUTE_HOP_LEGACY: + cur->legacy_payload = tal(cr->hops, struct legacy_payload); + cur->legacy_payload->forward_amt = + p->route[hopcount - 1].amount; + cur->legacy_payload->scid = all_zero_scid; + cur->legacy_payload->outgoing_cltv = + p->start_block + p->route[hopcount - 1].delay; + break; + case ROUTE_HOP_TLV: + /* TODO(cdecker) Implement */ + abort(); + } + /* 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); diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index 2bd474f91..aab0b41e6 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -19,6 +19,27 @@ struct route_hop { enum route_hop_style style; }; +struct legacy_payload { + struct short_channel_id scid; + struct amount_msat forward_amt; + u32 outgoing_cltv; +}; + +/* struct holding the information necessary to call createonion */ +struct createonion_hop { + struct node_id pubkey; + + enum route_hop_style style; + struct tlv_tlv_payload *tlv_payload; + struct legacy_payload *legacy_payload; +}; + +struct createonion_request { + struct createonion_hop *hops; + u8 *assocdata; + struct secret *session_key; +}; + /* A parsed version of the possible outcomes that a sendpay / payment may * result in. */ struct payment_result { @@ -82,6 +103,8 @@ struct payment { * paths to amend the route later in a mixin. */ struct node_id *getroute_destination; + struct createonion_request *createonion_request; + /* Target amount to be delivered at the destination */ struct amount_msat amount;