mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-02 05:44:20 +01:00
sphinx: separate nonfinal from final interface, add tlv option.
For legacy, they were the same, but for TLV we care whether it's the final hop or not. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
c83834ca82
commit
0211712f5e
@@ -149,6 +149,80 @@ void sphinx_add_v0_hop(struct sphinx_path *path, const struct pubkey *pubkey,
|
||||
sphinx_add_raw_hop(path, pubkey, 0, buf);
|
||||
}
|
||||
|
||||
static void sphinx_add_tlv_hop(struct sphinx_path *path,
|
||||
const struct pubkey *pubkey,
|
||||
const struct tlv_tlv_payload *tlv)
|
||||
{
|
||||
u8 *tlvs = tal_arr(path, u8, 0);
|
||||
towire_tlvs(&tlvs, tlvs_tlv_payload, TLVS_TLV_PAYLOAD_ARRAY_SIZE, tlv);
|
||||
sphinx_add_raw_hop(path, pubkey, tal_bytelen(tlvs), tlvs);
|
||||
}
|
||||
|
||||
void sphinx_add_nonfinal_hop(struct sphinx_path *path,
|
||||
const struct pubkey *pubkey,
|
||||
bool use_tlv,
|
||||
const struct short_channel_id *scid,
|
||||
struct amount_msat forward,
|
||||
u32 outgoing_cltv)
|
||||
{
|
||||
if (use_tlv) {
|
||||
struct tlv_tlv_payload *tlv = tlv_tlv_payload_new(tmpctx);
|
||||
struct tlv_tlv_payload_amt_to_forward tlv_amt;
|
||||
struct tlv_tlv_payload_outgoing_cltv_value tlv_cltv;
|
||||
struct tlv_tlv_payload_short_channel_id tlv_scid;
|
||||
|
||||
/* BOLT #4:
|
||||
*
|
||||
* The writer:
|
||||
* - MUST include `amt_to_forward` and `outgoing_cltv_value`
|
||||
* for every node.
|
||||
* - MUST include `short_channel_id` for every non-final node.
|
||||
*/
|
||||
tlv_amt.amt_to_forward = forward.millisatoshis; /* Raw: TLV convert */
|
||||
tlv_cltv.outgoing_cltv_value = outgoing_cltv;
|
||||
tlv_scid.short_channel_id = *scid;
|
||||
tlv->amt_to_forward = &tlv_amt;
|
||||
tlv->outgoing_cltv_value = &tlv_cltv;
|
||||
tlv->short_channel_id = &tlv_scid;
|
||||
|
||||
sphinx_add_tlv_hop(path, pubkey, tlv);
|
||||
} else {
|
||||
sphinx_add_v0_hop(path, pubkey, scid, forward, outgoing_cltv);
|
||||
}
|
||||
}
|
||||
|
||||
void sphinx_add_final_hop(struct sphinx_path *path,
|
||||
const struct pubkey *pubkey,
|
||||
bool use_tlv,
|
||||
struct amount_msat forward,
|
||||
u32 outgoing_cltv)
|
||||
{
|
||||
if (use_tlv) {
|
||||
struct tlv_tlv_payload *tlv = tlv_tlv_payload_new(tmpctx);
|
||||
struct tlv_tlv_payload_amt_to_forward tlv_amt;
|
||||
struct tlv_tlv_payload_outgoing_cltv_value tlv_cltv;
|
||||
|
||||
/* BOLT #4:
|
||||
*
|
||||
* The writer:
|
||||
* - MUST include `amt_to_forward` and `outgoing_cltv_value`
|
||||
* for every node.
|
||||
*...
|
||||
* - MUST NOT include `short_channel_id` for the final node.
|
||||
*/
|
||||
tlv_amt.amt_to_forward = forward.millisatoshis; /* Raw: TLV convert */
|
||||
tlv_cltv.outgoing_cltv_value = outgoing_cltv;
|
||||
tlv->amt_to_forward = &tlv_amt;
|
||||
tlv->outgoing_cltv_value = &tlv_cltv;
|
||||
|
||||
sphinx_add_tlv_hop(path, pubkey, tlv);
|
||||
} else {
|
||||
static struct short_channel_id all_zero_scid;
|
||||
sphinx_add_v0_hop(path, pubkey, &all_zero_scid,
|
||||
forward, outgoing_cltv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Small helper to append data to a buffer and update the position
|
||||
* into the buffer
|
||||
*/
|
||||
|
||||
@@ -231,6 +231,25 @@ void sphinx_add_v0_hop(struct sphinx_path *path, const struct pubkey *pubkey,
|
||||
void sphinx_add_raw_hop(struct sphinx_path *path, const struct pubkey *pubkey,
|
||||
enum sphinx_payload_type type, const u8 *payload);
|
||||
|
||||
/**
|
||||
* Add a non-final hop to the path.
|
||||
*/
|
||||
void sphinx_add_nonfinal_hop(struct sphinx_path *path,
|
||||
const struct pubkey *pubkey,
|
||||
bool use_tlv,
|
||||
const struct short_channel_id *scid,
|
||||
struct amount_msat forward,
|
||||
u32 outgoing_cltv);
|
||||
|
||||
/**
|
||||
* Add a final hop to the path.
|
||||
*/
|
||||
void sphinx_add_final_hop(struct sphinx_path *path,
|
||||
const struct pubkey *pubkey,
|
||||
bool use_tlv,
|
||||
struct amount_msat forward,
|
||||
u32 outgoing_cltv);
|
||||
|
||||
/**
|
||||
* Helper to extract fields from ONION_END.
|
||||
*/
|
||||
|
||||
@@ -99,6 +99,12 @@ void towire_sha256(u8 **pptr UNNEEDED, const struct sha256 *sha256 UNNEEDED)
|
||||
void towire_short_channel_id(u8 **pptr UNNEEDED,
|
||||
const struct short_channel_id *short_channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "towire_short_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for towire_tlvs */
|
||||
void towire_tlvs(u8 **pptr UNNEEDED,
|
||||
const struct tlv_record_type types[] UNNEEDED,
|
||||
size_t num_types UNNEEDED,
|
||||
const void *record UNNEEDED)
|
||||
{ fprintf(stderr, "towire_tlvs called!\n"); abort(); }
|
||||
/* Generated stub for towire_tu32 */
|
||||
void towire_tu32(u8 **pptr UNNEEDED, u32 v UNNEEDED)
|
||||
{ fprintf(stderr, "towire_tu32 called!\n"); abort(); }
|
||||
|
||||
@@ -615,6 +615,20 @@ static struct command_result *wait_payment(struct lightningd *ld,
|
||||
abort();
|
||||
}
|
||||
|
||||
static bool should_use_tlv(enum route_hop_style style)
|
||||
{
|
||||
switch (style) {
|
||||
case ROUTE_HOP_TLV:
|
||||
#if EXPERIMENTAL_FEATURES
|
||||
return true;
|
||||
#endif
|
||||
/* Otherwise fall thru */
|
||||
case ROUTE_HOP_LEGACY:
|
||||
return false;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Returns command_result if cmd was resolved, NULL if not yet called. */
|
||||
static struct command_result *
|
||||
send_payment(struct lightningd *ld,
|
||||
@@ -639,13 +653,11 @@ send_payment(struct lightningd *ld,
|
||||
struct routing_failure *fail;
|
||||
struct channel *channel;
|
||||
struct sphinx_path *path;
|
||||
struct short_channel_id finalscid;
|
||||
struct pubkey pubkey;
|
||||
bool ret;
|
||||
|
||||
/* Expiry for HTLCs is absolute. And add one to give some margin. */
|
||||
base_expiry = get_block_height(ld->topology) + 1;
|
||||
memset(&finalscid, 0, sizeof(struct short_channel_id));
|
||||
|
||||
path = sphinx_path_new(tmpctx, rhash->u.u8);
|
||||
/* Extract IDs for each hop: create_onionpacket wants array. */
|
||||
@@ -656,19 +668,23 @@ send_payment(struct lightningd *ld,
|
||||
for (i = 0; i < n_hops - 1; i++) {
|
||||
ret = pubkey_from_node_id(&pubkey, &ids[i]);
|
||||
assert(ret);
|
||||
sphinx_add_v0_hop(path, &pubkey, &route[i + 1].channel_id,
|
||||
route[i + 1].amount,
|
||||
base_expiry + route[i + 1].delay);
|
||||
|
||||
sphinx_add_nonfinal_hop(path, &pubkey,
|
||||
should_use_tlv(route[i].style),
|
||||
&route[i + 1].channel_id,
|
||||
route[i + 1].amount,
|
||||
base_expiry + route[i + 1].delay);
|
||||
}
|
||||
|
||||
/* And finally set the final hop to the special values in
|
||||
* BOLT04 */
|
||||
memset(&finalscid, 0, sizeof(struct short_channel_id));
|
||||
ret = pubkey_from_node_id(&pubkey, &ids[i]);
|
||||
assert(ret);
|
||||
sphinx_add_v0_hop(path, &pubkey, &finalscid,
|
||||
route[i].amount,
|
||||
base_expiry + route[i].delay);
|
||||
|
||||
sphinx_add_final_hop(path, &pubkey,
|
||||
should_use_tlv(route[i].style),
|
||||
route[i].amount,
|
||||
base_expiry + route[i].delay);
|
||||
|
||||
/* Now, do we already have a payment? */
|
||||
payment = wallet_payment_by_hash(tmpctx, ld->wallet, rhash);
|
||||
|
||||
Reference in New Issue
Block a user