Skip to content

Commit

Permalink
pay: Implement offset and chainlag computation when paying
Browse files Browse the repository at this point in the history
This actually uses the `chainlag` to make unsynced payments possible.
  • Loading branch information
cdecker authored and rustyrussell committed May 9, 2024
1 parent 4d27efc commit ff0b748
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 49 deletions.
22 changes: 6 additions & 16 deletions lightningd/test/run-invoice-select-inchan.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,16 +587,14 @@ void json_add_u64(struct json_stream *result UNNEEDED, const char *fieldname UNN
uint64_t value UNNEEDED)
{ fprintf(stderr, "json_add_u64 called!\n"); abort(); }
/* Generated stub for json_add_uncommitted_channel */
void json_add_uncommitted_channel(struct json_stream *response UNNEEDED,
const struct uncommitted_channel *uc UNNEEDED,
/* Only set for listpeerchannels */
const struct peer *peer UNNEEDED)
void json_add_uncommitted_channel(struct json_stream *response UNNEEDED,
const struct uncommitted_channel *uc UNNEEDED,
const struct peer *peer UNNEEDED)
{ fprintf(stderr, "json_add_uncommitted_channel called!\n"); abort(); }
/* Generated stub for json_add_unsaved_channel */
void json_add_unsaved_channel(struct json_stream *response UNNEEDED,
const struct channel *channel UNNEEDED,
/* Only set for listpeerchannels */
const struct peer *peer UNNEEDED)
void json_add_unsaved_channel(struct json_stream *response UNNEEDED,
const struct channel *channel UNNEEDED,
const struct peer *peer UNNEEDED)
{ fprintf(stderr, "json_add_unsaved_channel called!\n"); abort(); }
/* Generated stub for json_array_end */
void json_array_end(struct json_stream *js UNNEEDED)
Expand Down Expand Up @@ -680,14 +678,6 @@ struct jsonrpc_request *jsonrpc_request_start_(
void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,
const char *why UNNEEDED)
{ fprintf(stderr, "kill_uncommitted_channel called!\n"); abort(); }
/* Generated stub for lightningd_deprecated_out_ok */
bool lightningd_deprecated_out_ok(struct lightningd *ld UNNEEDED,
bool deprecated_apis UNNEEDED,
const char *subsys UNNEEDED,
const char *api UNNEEDED,
const char *start UNNEEDED,
const char *end UNNEEDED)
{ fprintf(stderr, "lightningd_deprecated_out_ok called!\n"); abort(); }
/* Generated stub for lockin_complete */
void lockin_complete(struct channel *channel UNNEEDED,
enum channel_state expected_state UNNEEDED)
Expand Down
64 changes: 53 additions & 11 deletions plugins/libplugin-pay.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,16 +278,53 @@ struct payment_tree_result payment_collect_result(struct payment *p)
return res;
}

static struct command_result *payment_waitblockheight_cb(struct command *cmd,
const char *buffer,
const jsmntok_t *toks,
struct payment *p)
{
u32 syncheight;
json_scan(tmpctx, buffer, toks, "{blockheight:%}",
JSON_SCAN(json_to_u32, &syncheight));
paymod_log(p, LOG_DBG, "waitblockheight reports syncheight=%d",
syncheight);
p->chainlag = p->start_block - syncheight;
if (p->chainlag > 0)
paymod_log(p, LOG_INFORM,
"Starting the payment with chainlag=%d "
"(syncheight=%d < headercount=%d)",
p->chainlag, syncheight, p->start_block);

payment_continue(p);
return command_still_pending(cmd);
}

static struct command_result *
payment_getblockheight_success(struct command *cmd,
const char *buffer,
const jsmntok_t *toks,
struct payment *p)
{
const jsmntok_t *blockheighttok =
json_get_member(buffer, toks, "blockheight");
json_to_number(buffer, blockheighttok, &p->start_block);
payment_continue(p);
struct out_req *req;
u32 blockcount, headercount;

json_scan(tmpctx, buffer, toks, "{blockcount:%,headercount:%}",
JSON_SCAN(json_to_u32, &blockcount),
JSON_SCAN(json_to_u32, &headercount));
paymod_log(p, LOG_DBG,
"Received getchaininfo blockcount=%d, headercount=%d",
blockcount, headercount);

p->start_block = headercount;

/* Now we just need to ask `lightningd` what height it has
* synced up to, and we remember that as chainlag. */
req = jsonrpc_request_start(p->plugin, NULL, "waitblockheight",
&payment_waitblockheight_cb,
&payment_rpc_failure, p);
json_add_u32(req->js, "blockheight", 0);
send_outreq(p->plugin, req);

return command_still_pending(cmd);
}

Expand Down Expand Up @@ -325,17 +362,15 @@ void payment_start_at_blockheight(struct payment *p, u32 blockheight)
return payment_continue(p);
}

/* `waitblockheight 0` can be used as a query for the current
* block height.
* This is slightly better than `getinfo` since `getinfo`
* counts the channels and addresses and pushes more data
* onto the RPC but all we care about is the blockheight.
/* Check with the backend what it believes the network's
* height to be. We'll base all of our offsets based on that
* height, allowing us to send while still syncing.
*/
struct out_req *req;
req = jsonrpc_request_start(p->plugin, NULL, "waitblockheight",
req = jsonrpc_request_start(p->plugin, NULL, "getchaininfo",
&payment_getblockheight_success,
&payment_rpc_failure, p);
json_add_u32(req->js, "blockheight", 0);
json_add_u32(req->js, "last_height", 0);
send_outreq(p->plugin, req);
}

Expand Down Expand Up @@ -951,6 +986,13 @@ static struct command_result *payment_getroute(struct payment *p)
abort();
}

/* Go through the route, and adjust the CLTV values to take
* the chain lag into consideration. */
paymod_log(p, LOG_DBG, "Adjusting route with a chainlag=%d", p->chainlag);

for (size_t i = 0; i < tal_count(p->route); i++)
p->route[i].delay += p->chainlag;

/* Allow modifiers to modify the route, before
* payment_compute_onion_payloads uses the route to generate the
* onion_payloads */
Expand Down
7 changes: 7 additions & 0 deletions plugins/test/run-route-calc.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ void json_object_end(struct json_stream *js UNNEEDED)
/* Generated stub for json_object_start */
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
/* Generated stub for json_scan */
const char *json_scan(const tal_t *ctx UNNEEDED,
const char *buffer UNNEEDED,
const jsmntok_t *tok UNNEEDED,
const char *guide UNNEEDED,
...)
{ fprintf(stderr, "json_scan called!\n"); abort(); }
/* Generated stub for json_strdup */
char *json_strdup(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
{ fprintf(stderr, "json_strdup called!\n"); abort(); }
Expand Down
7 changes: 7 additions & 0 deletions plugins/test/run-route-overlong.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ void json_object_end(struct json_stream *js UNNEEDED)
/* Generated stub for json_object_start */
void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED)
{ fprintf(stderr, "json_object_start called!\n"); abort(); }
/* Generated stub for json_scan */
const char *json_scan(const tal_t *ctx UNNEEDED,
const char *buffer UNNEEDED,
const jsmntok_t *tok UNNEEDED,
const char *guide UNNEEDED,
...)
{ fprintf(stderr, "json_scan called!\n"); abort(); }
/* Generated stub for json_strdup */
char *json_strdup(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
{ fprintf(stderr, "json_strdup called!\n"); abort(); }
Expand Down
28 changes: 6 additions & 22 deletions wallet/test/run-wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,6 @@ struct command_result *command_check_done(struct command *cmd)
/* Generated stub for command_check_only */
bool command_check_only(const struct command *cmd UNNEEDED)
{ fprintf(stderr, "command_check_only called!\n"); abort(); }
/* Generated stub for command_deprecated_in_ok */
bool command_deprecated_in_ok(struct command *cmd UNNEEDED,
const char *param UNNEEDED,
const char *depr_start UNNEEDED,
const char *depr_end UNNEEDED)
{ fprintf(stderr, "command_deprecated_in_ok called!\n"); abort(); }
/* Generated stub for command_fail */
struct command_result *command_fail(struct command *cmd UNNEEDED, enum jsonrpc_errcode code UNNEEDED,
const char *fmt UNNEEDED, ...)
Expand Down Expand Up @@ -516,16 +510,14 @@ void json_add_u64(struct json_stream *result UNNEEDED, const char *fieldname UNN
uint64_t value UNNEEDED)
{ fprintf(stderr, "json_add_u64 called!\n"); abort(); }
/* Generated stub for json_add_uncommitted_channel */
void json_add_uncommitted_channel(struct json_stream *response UNNEEDED,
const struct uncommitted_channel *uc UNNEEDED,
/* Only set for listpeerchannels */
const struct peer *peer UNNEEDED)
void json_add_uncommitted_channel(struct json_stream *response UNNEEDED,
const struct uncommitted_channel *uc UNNEEDED,
const struct peer *peer UNNEEDED)
{ fprintf(stderr, "json_add_uncommitted_channel called!\n"); abort(); }
/* Generated stub for json_add_unsaved_channel */
void json_add_unsaved_channel(struct json_stream *response UNNEEDED,
const struct channel *channel UNNEEDED,
/* Only set for listpeerchannels */
const struct peer *peer UNNEEDED)
void json_add_unsaved_channel(struct json_stream *response UNNEEDED,
const struct channel *channel UNNEEDED,
const struct peer *peer UNNEEDED)
{ fprintf(stderr, "json_add_unsaved_channel called!\n"); abort(); }
/* Generated stub for json_array_end */
void json_array_end(struct json_stream *js UNNEEDED)
Expand Down Expand Up @@ -600,14 +592,6 @@ bool json_tok_streq(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,
const char *why UNNEEDED)
{ fprintf(stderr, "kill_uncommitted_channel called!\n"); abort(); }
/* Generated stub for lightningd_deprecated_out_ok */
bool lightningd_deprecated_out_ok(struct lightningd *ld UNNEEDED,
bool deprecated_apis UNNEEDED,
const char *subsys UNNEEDED,
const char *api UNNEEDED,
const char *start UNNEEDED,
const char *end UNNEEDED)
{ fprintf(stderr, "lightningd_deprecated_out_ok called!\n"); abort(); }
/* Generated stub for lockin_complete */
void lockin_complete(struct channel *channel UNNEEDED,
enum channel_state expected_state UNNEEDED)
Expand Down

0 comments on commit ff0b748

Please sign in to comment.