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;