-
Notifications
You must be signed in to change notification settings - Fork 913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pay: Share channel_hints across payments and plugins #7487
Changes from all commits
9f46029
1aea198
ab61843
a8504b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -386,6 +386,58 @@ void payment_start(struct payment *p) | |
payment_start_at_blockheight(p, INVALID_BLOCKHEIGHT); | ||
} | ||
|
||
static void channel_hint_to_json(const char *name, const struct channel_hint *hint, struct json_stream *dest) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would normally be called "json_add_channel_hint(struct json_stream *, const char *, const struct channel_hint *)". It's internal, but consistency is nice. |
||
{ | ||
json_object_start(dest, name); | ||
json_add_u32(dest, "timestamp", hint->timestamp); | ||
json_add_short_channel_id_dir(dest, "scid", hint->scid); | ||
json_add_amount_msat(dest, "capacity_msat", hint->estimated_capacity); | ||
json_add_bool(dest, "enabled", hint->enabled); | ||
json_object_end(dest); | ||
} | ||
|
||
/** | ||
* Load a channel_hint from its JSON representation. | ||
* | ||
* @return The initialized `channel_hint` or `NULL` if we encountered a parsing | ||
* error. | ||
*/ | ||
/* | ||
static struct channel_hint *channel_hint_from_json(const tal_t *ctx, | ||
const char *buffer, | ||
const jsmntok_t *toks) | ||
{ | ||
const char *ret; | ||
struct channel_hint *hint = tal(ctx, struct channel_hint); | ||
ret = json_scan(ctx, buffer, toks, | ||
"{timestamp:%,scid:%,capacity_msat:%,enabled:%}", | ||
JSON_SCAN(json_to_u32, &hint->timestamp), | ||
JSON_SCAN(json_to_short_channel_id_dir, &hint->scid), | ||
JSON_SCAN(json_to_msat, &hint->estimated_capacity), | ||
JSON_SCAN(json_to_bool, &hint->enabled)); | ||
|
||
if (ret != NULL) | ||
hint = tal_free(hint); | ||
return hint; | ||
} | ||
Comment on lines
+405
to
+422
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could have split this into a later commit, but it seemed like a good idea to have both the writing and reading part of the notification in one commit. |
||
*/ | ||
/** | ||
* Notify subscribers of the `channel_hint` topic about a changed hint | ||
* | ||
* We share the channel_hints across payments, and across plugins, in order | ||
* to maximize the context they have when performing payments. | ||
*/ | ||
static void channel_hint_notify(struct plugin *plugin, | ||
const struct channel_hint *hint) | ||
{ | ||
struct json_stream *js = | ||
plugin_notification_start(plugin, "channel_hint_update"); | ||
|
||
/* The timestamp used to decay the observation over time. */ | ||
channel_hint_to_json("channel_hint", hint, js); | ||
plugin_notification_end(plugin, js); | ||
} | ||
|
||
static void channel_hints_update(struct payment *p, | ||
const struct short_channel_id scid, | ||
int direction, bool enabled, bool local, | ||
|
@@ -394,6 +446,7 @@ static void channel_hints_update(struct payment *p, | |
{ | ||
struct payment *root = payment_root(p); | ||
struct channel_hint newhint; | ||
u32 timestamp = time_now().ts.tv_sec; | ||
|
||
/* If the channel is marked as enabled it must have an estimate. */ | ||
assert(!enabled || estimated_capacity != NULL); | ||
|
@@ -423,7 +476,8 @@ static void channel_hints_update(struct payment *p, | |
modified = true; | ||
} | ||
|
||
if (modified) | ||
if (modified) { | ||
hint->timestamp = timestamp; | ||
paymod_log(p, LOG_DBG, | ||
"Updated a channel hint for %s: " | ||
"enabled %s, " | ||
|
@@ -433,12 +487,15 @@ static void channel_hints_update(struct payment *p, | |
hint->enabled ? "true" : "false", | ||
fmt_amount_msat(tmpctx, | ||
hint->estimated_capacity)); | ||
channel_hint_notify(p->plugin, hint); | ||
} | ||
return; | ||
} | ||
} | ||
|
||
/* No hint found, create one. */ | ||
newhint.enabled = enabled; | ||
newhint.timestamp = timestamp; | ||
newhint.scid.scid = scid; | ||
newhint.scid.dir = direction; | ||
if (local) { | ||
|
@@ -458,6 +515,7 @@ static void channel_hints_update(struct payment *p, | |
fmt_short_channel_id_dir(tmpctx, &newhint.scid), | ||
newhint.enabled ? "true" : "false", | ||
fmt_amount_msat(tmpctx, newhint.estimated_capacity)); | ||
channel_hint_notify(p->plugin, &newhint); | ||
} | ||
|
||
static void payment_exclude_most_expensive(struct payment *p) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scidd is a complex type, so unlike scids it should be passed as "const struct short_channel_id_dir *". This also means the definition doesn't need to be in the header...