Browse Source

routing: Simplify code to read the route back in

This was overly complex since it was off-by-one and we were storing
some information elsewhere. Now this just loads the route as is into
structs, extracts some information for our outgoing HTLC, and then
shifts by the array of structs by one, and finally fills in the last
instruction, which is the terminal.
ppa-0.6.1
Christian Decker 8 years ago
parent
commit
b9dcb909b8
  1. 67
      lightningd/pay.c

67
lightningd/pay.c

@ -151,7 +151,7 @@ static void json_sendpay(struct command *cmd,
struct pubkey *ids; struct pubkey *ids;
jsmntok_t *routetok, *rhashtok; jsmntok_t *routetok, *rhashtok;
const jsmntok_t *t, *end; const jsmntok_t *t, *end;
unsigned int delay, first_delay, base_expiry; unsigned int delay, base_expiry;
size_t n_hops; size_t n_hops;
struct sha256 rhash; struct sha256 rhash;
struct peer *peer; struct peer *peer;
@ -159,6 +159,7 @@ static void json_sendpay(struct command *cmd,
const u8 *onion; const u8 *onion;
u8 sessionkey[32]; u8 sessionkey[32];
struct hop_data *hop_data; struct hop_data *hop_data;
struct hop_data first_hop_data;
u64 amount, lastamount; u64 amount, lastamount;
struct onionpacket *packet; struct onionpacket *packet;
u8 *msg; u8 *msg;
@ -194,12 +195,9 @@ static void json_sendpay(struct command *cmd,
n_hops = 0; n_hops = 0;
ids = tal_arr(cmd, struct pubkey, n_hops); ids = tal_arr(cmd, struct pubkey, n_hops);
/* Switching to hop_data in the next commit, and it causes a hop_data = tal_arr(cmd, struct hop_data, n_hops);
* double free in peer_control otherwise */
hop_data = tal_arr(NULL, struct hop_data, 0);
for (t = routetok + 1; t < end; t = json_next(t)) { for (t = routetok + 1; t < end; t = json_next(t)) {
const jsmntok_t *amttok, *idtok, *delaytok, *chantok; const jsmntok_t *amttok, *idtok, *delaytok, *chantok;
struct short_channel_id scid;
if (t->type != JSMN_OBJECT) { if (t->type != JSMN_OBJECT) {
command_fail(cmd, "route %zu '%.*s' is not an object", command_fail(cmd, "route %zu '%.*s' is not an object",
@ -218,29 +216,20 @@ static void json_sendpay(struct command *cmd,
return; return;
} }
if (n_hops == 0) { tal_resize(&hop_data, n_hops + 1);
/* What we will send */ tal_resize(&ids, n_hops+1);
if (!json_tok_u64(buffer, amttok, &amount)) { hop_data[n_hops].realm = 0;
command_fail(cmd, "route %zu invalid msatoshi", /* What that hop will forward */
n_hops); if (!json_tok_u64(buffer, amttok, &amount)) {
return; command_fail(cmd, "route %zu invalid msatoshi",
} n_hops);
lastamount = amount; return;
} else {
/* What that hop will forward */
tal_resize(&hop_data, n_hops);
if (!json_tok_u64(buffer, amttok, &lastamount)) {
command_fail(cmd, "route %zu invalid msatoshi",
n_hops);
return;
}
hop_data[n_hops - 1].amt_forward = lastamount;
} }
hop_data[n_hops].amt_forward = amount;
tal_resize(&ids, n_hops+1);
if (!short_channel_id_from_str(buffer + chantok->start, if (!short_channel_id_from_str(buffer + chantok->start,
chantok->end - chantok->start, chantok->end - chantok->start,
&scid)) { &hop_data[n_hops].channel_id)) {
command_fail(cmd, "route %zu invalid id", n_hops); command_fail(cmd, "route %zu invalid id", n_hops);
return; return;
} }
@ -254,13 +243,7 @@ static void json_sendpay(struct command *cmd,
command_fail(cmd, "route %zu invalid delay", n_hops); command_fail(cmd, "route %zu invalid delay", n_hops);
return; return;
} }
if (n_hops == 0) hop_data[n_hops].outgoing_cltv = base_expiry + delay;
first_delay = delay;
else {
hop_data[n_hops-1].outgoing_cltv
= base_expiry + delay;
hop_data[n_hops-1].channel_id = scid;
}
n_hops++; n_hops++;
} }
@ -269,12 +252,20 @@ static void json_sendpay(struct command *cmd,
return; return;
} }
/* Add payload for final hop */ /* Store some info we'll need for our own HTLC */
tal_resize(&hop_data, n_hops); amount = hop_data[0].amt_forward;
/* Memset here since we need it in the onion creation but will lastamount = hop_data[n_hops-1].amt_forward;
* shave it off immediately again */ first_hop_data = hop_data[0];
memset(&hop_data[n_hops-1], 0, sizeof(struct hop_data));
/* Shift the hop_data down by one, so each hop gets its
* instructions, not how we got there */
for (size_t i=0; i < n_hops - 1; i++) {
hop_data[i] = hop_data[i+1];
}
/* And finally set the final hop to the special values in
* BOLT04 */
hop_data[n_hops-1].outgoing_cltv = base_expiry + delay; hop_data[n_hops-1].outgoing_cltv = base_expiry + delay;
memset(&hop_data[n_hops-1].channel_id, 0, sizeof(struct short_channel_id));
pc = find_pay_command(ld, &rhash); pc = find_pay_command(ld, &rhash);
if (pc) { if (pc) {
@ -357,7 +348,7 @@ static void json_sendpay(struct command *cmd,
log_info(ld->log, "Sending %"PRIu64" over %zu hops to deliver %"PRIu64, log_info(ld->log, "Sending %"PRIu64" over %zu hops to deliver %"PRIu64,
amount, n_hops, lastamount); amount, n_hops, lastamount);
msg = towire_channel_offer_htlc(pc, amount, msg = towire_channel_offer_htlc(pc, amount,
base_expiry + first_delay, first_hop_data.outgoing_cltv,
&pc->rhash, onion); &pc->rhash, onion);
subd_req(pc, peer->owner, take(msg), -1, 0, rcvd_htlc_reply, pc); subd_req(pc, peer->owner, take(msg), -1, 0, rcvd_htlc_reply, pc);

Loading…
Cancel
Save