2021-12-04 21:53:56 +10:30
|
|
|
#include "config.h"
|
2021-05-22 14:30:15 +09:30
|
|
|
#include "../libplugin-pay.c"
|
|
|
|
#include <bitcoin/chainparams.h>
|
|
|
|
#include <common/gossip_store.h>
|
2021-11-15 04:22:46 +10:30
|
|
|
#include <common/setup.h>
|
2021-12-05 02:47:38 -05:00
|
|
|
#include <common/utils.h>
|
2021-05-22 14:30:15 +09:30
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
/* AUTOGENERATED MOCKS START */
|
2022-11-09 12:00:10 +10:30
|
|
|
/* Generated stub for blinded_onion_hops */
|
|
|
|
u8 **blinded_onion_hops(const tal_t *ctx UNNEEDED,
|
|
|
|
struct amount_msat final_amount UNNEEDED,
|
|
|
|
u32 final_cltv UNNEEDED,
|
2023-01-12 14:23:38 +10:30
|
|
|
struct amount_msat total_amount UNNEEDED,
|
2022-11-09 12:00:10 +10:30
|
|
|
const struct blinded_path *path UNNEEDED)
|
|
|
|
{ fprintf(stderr, "blinded_onion_hops called!\n"); abort(); }
|
2021-05-22 14:30:15 +09:30
|
|
|
/* Generated stub for command_finished */
|
|
|
|
struct command_result *command_finished(struct command *cmd UNNEEDED, struct json_stream *response UNNEEDED)
|
|
|
|
{ fprintf(stderr, "command_finished called!\n"); abort(); }
|
|
|
|
/* Generated stub for command_still_pending */
|
|
|
|
struct command_result *command_still_pending(struct command *cmd UNNEEDED)
|
|
|
|
{ fprintf(stderr, "command_still_pending called!\n"); abort(); }
|
2023-12-13 16:05:01 +10:30
|
|
|
/* Generated stub for daemon_poll */
|
|
|
|
int daemon_poll(struct pollfd *fds UNNEEDED, nfds_t nfds UNNEEDED, int timeout UNNEEDED)
|
|
|
|
{ fprintf(stderr, "daemon_poll called!\n"); abort(); }
|
2021-05-22 14:30:15 +09:30
|
|
|
/* Generated stub for feature_offered */
|
|
|
|
bool feature_offered(const u8 *features UNNEEDED, size_t f UNNEEDED)
|
|
|
|
{ fprintf(stderr, "feature_offered called!\n"); abort(); }
|
|
|
|
/* Generated stub for fromwire_bigsize */
|
|
|
|
bigsize_t fromwire_bigsize(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
|
|
|
{ fprintf(stderr, "fromwire_bigsize called!\n"); abort(); }
|
|
|
|
/* Generated stub for fromwire_channel_id */
|
2021-12-28 09:54:09 +10:30
|
|
|
bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
2021-05-22 14:30:15 +09:30
|
|
|
struct channel_id *channel_id UNNEEDED)
|
|
|
|
{ fprintf(stderr, "fromwire_channel_id called!\n"); abort(); }
|
2023-12-13 16:05:42 +10:30
|
|
|
/* Generated stub for gossmod_add_localchan */
|
|
|
|
void gossmod_add_localchan(struct gossmap_localmods *mods UNNEEDED,
|
|
|
|
const struct node_id *self UNNEEDED,
|
|
|
|
const struct node_id *peer UNNEEDED,
|
|
|
|
const struct short_channel_id_dir *scidd UNNEEDED,
|
2024-03-18 08:31:42 +01:00
|
|
|
struct amount_msat htlcmin UNNEEDED,
|
|
|
|
struct amount_msat htlcmax UNNEEDED,
|
|
|
|
struct amount_msat spendable UNNEEDED,
|
2023-12-13 16:05:42 +10:30
|
|
|
struct amount_msat fee_base UNNEEDED,
|
|
|
|
u32 fee_proportional UNNEEDED,
|
|
|
|
u32 cltv_delta UNNEEDED,
|
|
|
|
bool enabled UNNEEDED,
|
|
|
|
const char *buf UNUSED UNNEEDED,
|
|
|
|
const jsmntok_t *chantok UNUSED UNNEEDED,
|
|
|
|
void *cbarg UNUSED UNNEEDED)
|
|
|
|
{ fprintf(stderr, "gossmod_add_localchan called!\n"); abort(); }
|
|
|
|
/* Generated stub for gossmods_from_listpeerchannels_ */
|
|
|
|
struct gossmap_localmods *gossmods_from_listpeerchannels_(const tal_t *ctx UNNEEDED,
|
|
|
|
const struct node_id *self UNNEEDED,
|
|
|
|
const char *buf UNNEEDED,
|
|
|
|
const jsmntok_t *toks UNNEEDED,
|
pay: ignore fees on our own channels when determining routing.
I noticed that run-route-infloop chose some worse-looking paths after
routing was fixed, eg the second node:
Before:
Destination node, success, probability, hops, fees, cltv, scid...
02b3aa1e4ed31be83cca4bd367b2c01e39502cb25e282a9b4520ad376a1ba0a01a,1,0.991856,2,1004,40,2572260x39x0/1,2131897x45x0/0
After:
Destination node, success, probability, hops, fees, cltv, scid...
02b3aa1e4ed31be83cca4bd367b2c01e39502cb25e282a9b4520ad376a1ba0a01a,1,0.954540,3,1046,46,2570715x21x0/1,2346882x26x14/1,2131897x45x0/0
This is because although the final costs don't reflect it, routing was taking
into account local channels, and 2572260x39x0/1 has a base fee of 2970.
There's an easy fix: when we the pay plugin creates localmods for our
gossip graph, add all local channels with delay and fees equal to 0.
We do the same thing in our unit test. This improves things across
the board:
Linear success probability (when found): min-max(mean +/- stddev)
Before: 0.487040-0.999543(0.952548+/-0.075)
After: 0.486985-0.999750(0.975978+/-0.053)
Hops:
Before: 1-5(2.98374+/-0.77)
After: 1-5(2.09593+/-0.63)
Fees:
Before: 0-50848(922.457+/-2.7e+03)
After: 0-50041(861.621+/-2.7e+03)
Delay (blocks):
Before: 0-196(65.8081+/-60)
After: 0-190(60.3285+/-60)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Plugins: `pay` route algorithm doesn't bias against our own "expensive" channels any more.
2024-03-07 13:26:58 +10:30
|
|
|
bool zero_rates UNNEEDED,
|
2023-12-13 16:05:42 +10:30
|
|
|
void (*cb)(struct gossmap_localmods *mods UNNEEDED,
|
|
|
|
const struct node_id *self_ UNNEEDED,
|
|
|
|
const struct node_id *peer UNNEEDED,
|
|
|
|
const struct short_channel_id_dir *scidd UNNEEDED,
|
2024-03-18 08:31:42 +01:00
|
|
|
struct amount_msat htlcmin UNNEEDED,
|
|
|
|
struct amount_msat htlcmax UNNEEDED,
|
|
|
|
struct amount_msat spendable UNNEEDED,
|
2023-12-13 16:05:42 +10:30
|
|
|
struct amount_msat fee_base UNNEEDED,
|
|
|
|
u32 fee_proportional UNNEEDED,
|
|
|
|
u32 cltv_delta UNNEEDED,
|
|
|
|
bool enabled UNNEEDED,
|
|
|
|
const char *buf_ UNNEEDED,
|
|
|
|
const jsmntok_t *chantok UNNEEDED,
|
|
|
|
void *cbarg_) UNNEEDED,
|
|
|
|
void *cbarg UNNEEDED)
|
|
|
|
{ fprintf(stderr, "gossmods_from_listpeerchannels_ called!\n"); abort(); }
|
2023-03-14 15:51:50 +10:30
|
|
|
/* Generated stub for json_add_amount_msat */
|
|
|
|
void json_add_amount_msat(struct json_stream *result UNNEEDED,
|
2021-05-22 14:30:15 +09:30
|
|
|
const char *msatfieldname UNNEEDED,
|
|
|
|
struct amount_msat msat)
|
|
|
|
|
2023-03-14 15:51:50 +10:30
|
|
|
{ fprintf(stderr, "json_add_amount_msat called!\n"); abort(); }
|
2021-05-22 14:30:15 +09:30
|
|
|
/* Generated stub for json_add_hex_talarr */
|
|
|
|
void json_add_hex_talarr(struct json_stream *result UNNEEDED,
|
|
|
|
const char *fieldname UNNEEDED,
|
|
|
|
const tal_t *data UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_hex_talarr called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_invstring */
|
|
|
|
void json_add_invstring(struct json_stream *result UNNEEDED, const char *invstring UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_invstring called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_node_id */
|
|
|
|
void json_add_node_id(struct json_stream *response UNNEEDED,
|
|
|
|
const char *fieldname UNNEEDED,
|
|
|
|
const struct node_id *id UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_node_id called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_num */
|
|
|
|
void json_add_num(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
|
|
|
unsigned int value UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_num called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_preimage */
|
|
|
|
void json_add_preimage(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
|
|
|
const struct preimage *preimage UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_preimage called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_secret */
|
|
|
|
void json_add_secret(struct json_stream *response UNNEEDED,
|
|
|
|
const char *fieldname UNNEEDED,
|
|
|
|
const struct secret *secret UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_secret called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_sha256 */
|
|
|
|
void json_add_sha256(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
|
|
|
const struct sha256 *hash UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_sha256 called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_short_channel_id */
|
|
|
|
void json_add_short_channel_id(struct json_stream *response UNNEEDED,
|
|
|
|
const char *fieldname UNNEEDED,
|
2024-03-20 12:29:51 +10:30
|
|
|
struct short_channel_id id UNNEEDED)
|
2021-05-22 14:30:15 +09:30
|
|
|
{ fprintf(stderr, "json_add_short_channel_id called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_string */
|
2022-07-18 21:42:28 +09:30
|
|
|
void json_add_string(struct json_stream *js UNNEEDED,
|
|
|
|
const char *fieldname UNNEEDED,
|
|
|
|
const char *str TAKES UNNEEDED)
|
2021-05-22 14:30:15 +09:30
|
|
|
{ fprintf(stderr, "json_add_string called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_timeabs */
|
|
|
|
void json_add_timeabs(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
|
|
|
struct timeabs t UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_timeabs called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_u32 */
|
|
|
|
void json_add_u32(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
|
|
|
uint32_t value UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_u32 called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_add_u64 */
|
|
|
|
void json_add_u64(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
|
|
|
|
uint64_t value UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_add_u64 called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_array_end */
|
|
|
|
void json_array_end(struct json_stream *js UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_array_end called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_array_start */
|
|
|
|
void json_array_start(struct json_stream *js UNNEEDED, const char *fieldname UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_array_start called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_get_member */
|
|
|
|
const jsmntok_t *json_get_member(const char *buffer UNNEEDED, const jsmntok_t tok[] UNNEEDED,
|
|
|
|
const char *label UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_get_member called!\n"); abort(); }
|
2023-01-03 14:53:28 +10:30
|
|
|
/* Generated stub for json_id_prefix */
|
|
|
|
const char *json_id_prefix(const tal_t *ctx UNNEEDED, const struct command *cmd UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_id_prefix called!\n"); abort(); }
|
2021-05-22 14:30:15 +09:30
|
|
|
/* Generated stub for json_next */
|
|
|
|
const jsmntok_t *json_next(const jsmntok_t *tok UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_next called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_object_end */
|
|
|
|
void json_object_end(struct json_stream *js UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_object_end called!\n"); abort(); }
|
|
|
|
/* 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_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(); }
|
|
|
|
/* Generated stub for json_to_createonion_response */
|
|
|
|
struct createonion_response *json_to_createonion_response(const tal_t *ctx UNNEEDED,
|
|
|
|
const char *buffer UNNEEDED,
|
|
|
|
const jsmntok_t *toks UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_createonion_response called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_int */
|
|
|
|
bool json_to_int(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, int *num UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_int called!\n"); abort(); }
|
2023-01-12 11:48:10 +10:30
|
|
|
/* Generated stub for json_to_listpeers_channels */
|
|
|
|
struct listpeers_channel **json_to_listpeers_channels(const tal_t *ctx UNNEEDED,
|
|
|
|
const char *buffer UNNEEDED,
|
|
|
|
const jsmntok_t *tok UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_listpeers_channels called!\n"); abort(); }
|
2021-05-22 14:30:15 +09:30
|
|
|
/* Generated stub for json_to_msat */
|
|
|
|
bool json_to_msat(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
|
|
|
struct amount_msat *msat UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_msat called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_node_id */
|
|
|
|
bool json_to_node_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
|
|
|
struct node_id *id UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_node_id called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_number */
|
|
|
|
bool json_to_number(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
|
|
|
unsigned int *num UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_number called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_preimage */
|
|
|
|
bool json_to_preimage(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, struct preimage *preimage UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_preimage called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_sat */
|
|
|
|
bool json_to_sat(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
|
|
|
struct amount_sat *sat UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_sat called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_short_channel_id */
|
|
|
|
bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
|
|
|
struct short_channel_id *scid UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_short_channel_id called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_u16 */
|
|
|
|
bool json_to_u16(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
|
|
|
uint16_t *num UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_to_u16 called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_u32 */
|
2022-07-18 21:42:28 +09:30
|
|
|
bool json_to_u32(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, u32 *num UNNEEDED)
|
2021-05-22 14:30:15 +09:30
|
|
|
{ fprintf(stderr, "json_to_u32 called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_to_u64 */
|
2022-07-18 21:42:28 +09:30
|
|
|
bool json_to_u64(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, u64 *num UNNEEDED)
|
2021-05-22 14:30:15 +09:30
|
|
|
{ fprintf(stderr, "json_to_u64 called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_tok_bin_from_hex */
|
|
|
|
u8 *json_tok_bin_from_hex(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_tok_bin_from_hex called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_tok_full */
|
|
|
|
const char *json_tok_full(const char *buffer UNNEEDED, const jsmntok_t *t UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_tok_full called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_tok_full_len */
|
|
|
|
int json_tok_full_len(const jsmntok_t *t UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_tok_full_len called!\n"); abort(); }
|
|
|
|
/* Generated stub for json_tok_streq */
|
|
|
|
bool json_tok_streq(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, const char *str UNNEEDED)
|
|
|
|
{ fprintf(stderr, "json_tok_streq called!\n"); abort(); }
|
|
|
|
/* Generated stub for jsonrpc_request_start_ */
|
|
|
|
struct out_req *jsonrpc_request_start_(struct plugin *plugin UNNEEDED,
|
|
|
|
struct command *cmd UNNEEDED,
|
|
|
|
const char *method UNNEEDED,
|
2023-01-03 14:53:28 +10:30
|
|
|
const char *id_prefix UNNEEDED,
|
2021-05-22 14:30:15 +09:30
|
|
|
struct command_result *(*cb)(struct command *command UNNEEDED,
|
|
|
|
const char *buf UNNEEDED,
|
|
|
|
const jsmntok_t *result UNNEEDED,
|
|
|
|
void *arg) UNNEEDED,
|
|
|
|
struct command_result *(*errcb)(struct command *command UNNEEDED,
|
|
|
|
const char *buf UNNEEDED,
|
|
|
|
const jsmntok_t *result UNNEEDED,
|
|
|
|
void *arg) UNNEEDED,
|
|
|
|
void *arg UNNEEDED)
|
|
|
|
{ fprintf(stderr, "jsonrpc_request_start_ called!\n"); abort(); }
|
|
|
|
/* Generated stub for jsonrpc_stream_fail */
|
|
|
|
struct json_stream *jsonrpc_stream_fail(struct command *cmd UNNEEDED,
|
|
|
|
int code UNNEEDED,
|
|
|
|
const char *err UNNEEDED)
|
|
|
|
{ fprintf(stderr, "jsonrpc_stream_fail called!\n"); abort(); }
|
|
|
|
/* Generated stub for jsonrpc_stream_success */
|
|
|
|
struct json_stream *jsonrpc_stream_success(struct command *cmd UNNEEDED)
|
|
|
|
{ fprintf(stderr, "jsonrpc_stream_success called!\n"); abort(); }
|
|
|
|
/* Generated stub for notleak_ */
|
2021-11-25 06:29:20 +10:30
|
|
|
void *notleak_(void *ptr UNNEEDED, bool plus_children UNNEEDED)
|
2021-05-22 14:30:15 +09:30
|
|
|
{ fprintf(stderr, "notleak_ called!\n"); abort(); }
|
|
|
|
/* Generated stub for plugin_err */
|
|
|
|
void plugin_err(struct plugin *p UNNEEDED, const char *fmt UNNEEDED, ...)
|
|
|
|
{ fprintf(stderr, "plugin_err called!\n"); abort(); }
|
|
|
|
/* Generated stub for plugin_log */
|
|
|
|
void plugin_log(struct plugin *p UNNEEDED, enum log_level l UNNEEDED, const char *fmt UNNEEDED, ...)
|
|
|
|
{ fprintf(stderr, "plugin_log called!\n"); abort(); }
|
|
|
|
/* Generated stub for plugin_notification_end */
|
|
|
|
void plugin_notification_end(struct plugin *plugin UNNEEDED,
|
|
|
|
struct json_stream *stream TAKES UNNEEDED)
|
|
|
|
{ fprintf(stderr, "plugin_notification_end called!\n"); abort(); }
|
|
|
|
/* Generated stub for plugin_notification_start */
|
|
|
|
struct json_stream *plugin_notification_start(struct plugin *plugins UNNEEDED,
|
|
|
|
const char *method UNNEEDED)
|
|
|
|
{ fprintf(stderr, "plugin_notification_start called!\n"); abort(); }
|
|
|
|
/* Generated stub for random_select */
|
|
|
|
bool random_select(double weight UNNEEDED, double *tot_weight UNNEEDED)
|
|
|
|
{ fprintf(stderr, "random_select called!\n"); abort(); }
|
|
|
|
/* Generated stub for send_outreq */
|
|
|
|
struct command_result *send_outreq(struct plugin *plugin UNNEEDED,
|
|
|
|
const struct out_req *req UNNEEDED)
|
|
|
|
{ fprintf(stderr, "send_outreq called!\n"); abort(); }
|
|
|
|
/* Generated stub for towire_bigsize */
|
|
|
|
void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED)
|
|
|
|
{ fprintf(stderr, "towire_bigsize called!\n"); abort(); }
|
|
|
|
/* Generated stub for towire_channel_id */
|
|
|
|
void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED)
|
|
|
|
{ fprintf(stderr, "towire_channel_id called!\n"); abort(); }
|
|
|
|
/* AUTOGENERATED MOCKS END */
|
|
|
|
|
|
|
|
#ifndef SUPERVERBOSE
|
|
|
|
#define SUPERVERBOSE(...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void write_to_store(int store_fd, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct gossip_hdr hdr;
|
|
|
|
|
2023-01-30 16:54:08 +10:30
|
|
|
hdr.flags = cpu_to_be16(0);
|
|
|
|
hdr.len = cpu_to_be16(tal_count(msg));
|
2021-05-22 14:30:15 +09:30
|
|
|
/* We don't actually check these! */
|
|
|
|
hdr.crc = 0;
|
|
|
|
hdr.timestamp = 0;
|
|
|
|
assert(write(store_fd, &hdr, sizeof(hdr)) == sizeof(hdr));
|
|
|
|
assert(write(store_fd, msg, tal_count(msg)) == tal_count(msg));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void update_connection(int store_fd,
|
|
|
|
const struct node_id *from,
|
|
|
|
const struct node_id *to,
|
2024-03-20 12:29:51 +10:30
|
|
|
struct short_channel_id scid,
|
2021-05-22 14:30:15 +09:30
|
|
|
struct amount_msat min,
|
|
|
|
struct amount_msat max,
|
|
|
|
u32 base_fee, s32 proportional_fee,
|
|
|
|
u32 delay,
|
|
|
|
bool disable)
|
|
|
|
{
|
|
|
|
secp256k1_ecdsa_signature dummy_sig;
|
2023-07-27 13:17:33 -07:00
|
|
|
u8 flags = node_id_idx(from, to);
|
2021-05-22 14:30:15 +09:30
|
|
|
u8 *msg;
|
|
|
|
|
2023-07-27 13:17:33 -07:00
|
|
|
if (disable)
|
|
|
|
flags |= ROUTING_FLAGS_DISABLED;
|
|
|
|
|
2021-05-22 14:30:15 +09:30
|
|
|
/* So valgrind doesn't complain */
|
|
|
|
memset(&dummy_sig, 0, sizeof(dummy_sig));
|
|
|
|
|
2022-09-14 13:20:31 +09:30
|
|
|
msg = towire_channel_update(tmpctx,
|
|
|
|
&dummy_sig,
|
|
|
|
&chainparams->genesis_blockhash,
|
|
|
|
scid, 0,
|
|
|
|
ROUTING_OPT_HTLC_MAX_MSAT,
|
2023-07-27 13:17:33 -07:00
|
|
|
flags,
|
2022-09-14 13:20:31 +09:30
|
|
|
delay,
|
|
|
|
min,
|
|
|
|
base_fee,
|
|
|
|
proportional_fee,
|
|
|
|
max);
|
2021-05-22 14:30:15 +09:30
|
|
|
|
|
|
|
write_to_store(store_fd, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void add_connection(int store_fd,
|
|
|
|
const struct node_id *from,
|
|
|
|
const struct node_id *to,
|
2024-03-20 12:29:51 +10:30
|
|
|
struct short_channel_id scid,
|
2021-05-22 14:30:15 +09:30
|
|
|
struct amount_msat min,
|
|
|
|
struct amount_msat max,
|
|
|
|
u32 base_fee, s32 proportional_fee,
|
|
|
|
u32 delay)
|
|
|
|
{
|
|
|
|
secp256k1_ecdsa_signature dummy_sig;
|
|
|
|
struct secret not_a_secret;
|
|
|
|
struct pubkey dummy_key;
|
|
|
|
u8 *msg;
|
|
|
|
const struct node_id *ids[2];
|
|
|
|
|
|
|
|
/* So valgrind doesn't complain */
|
|
|
|
memset(&dummy_sig, 0, sizeof(dummy_sig));
|
|
|
|
memset(¬_a_secret, 1, sizeof(not_a_secret));
|
|
|
|
pubkey_from_secret(¬_a_secret, &dummy_key);
|
|
|
|
|
|
|
|
if (node_id_cmp(from, to) > 0) {
|
|
|
|
ids[0] = to;
|
|
|
|
ids[1] = from;
|
|
|
|
} else {
|
|
|
|
ids[0] = from;
|
|
|
|
ids[1] = to;
|
|
|
|
}
|
|
|
|
msg = towire_channel_announcement(tmpctx, &dummy_sig, &dummy_sig,
|
|
|
|
&dummy_sig, &dummy_sig,
|
|
|
|
/* features */ NULL,
|
|
|
|
&chainparams->genesis_blockhash,
|
|
|
|
scid,
|
|
|
|
ids[0], ids[1],
|
|
|
|
&dummy_key, &dummy_key);
|
|
|
|
write_to_store(store_fd, msg);
|
|
|
|
|
|
|
|
update_connection(store_fd, from, to, scid, min, max,
|
|
|
|
base_fee, proportional_fee,
|
|
|
|
delay, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void node_id_from_privkey(const struct privkey *p, struct node_id *id)
|
|
|
|
{
|
|
|
|
struct pubkey k;
|
|
|
|
pubkey_from_privkey(p, &k);
|
|
|
|
node_id_from_pubkey(id, &k);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NUM_NODES (ROUTING_MAX_HOPS + 1)
|
|
|
|
|
|
|
|
/* We create an arrangement of nodes, each node N connected to N+1 and
|
|
|
|
* to node 1. The cost for each N to N+1 route is 1, for N to 1 is
|
|
|
|
* 2^N. That means it's always cheapest to go the longer route */
|
2021-11-15 04:22:46 +10:30
|
|
|
int main(int argc, char *argv[])
|
2021-05-22 14:30:15 +09:30
|
|
|
{
|
|
|
|
struct node_id ids[NUM_NODES];
|
|
|
|
int store_fd;
|
|
|
|
struct payment *p;
|
|
|
|
struct payment_modifier **mods;
|
2022-09-14 13:20:31 +09:30
|
|
|
char gossip_version = 10;
|
2021-12-05 02:47:38 -05:00
|
|
|
char *gossipfilename;
|
2021-05-22 14:30:15 +09:30
|
|
|
|
2021-11-15 04:22:46 +10:30
|
|
|
common_setup(argv[0]);
|
2021-05-22 14:30:15 +09:30
|
|
|
chainparams = chainparams_for_network("regtest");
|
2021-12-05 02:47:38 -05:00
|
|
|
store_fd = tmpdir_mkstemp(tmpctx, "run-route-overlong.XXXXXX", &gossipfilename);
|
2021-05-22 14:30:15 +09:30
|
|
|
assert(write(store_fd, &gossip_version, sizeof(gossip_version))
|
|
|
|
== sizeof(gossip_version));
|
|
|
|
|
2021-09-23 22:37:09 +09:30
|
|
|
global_gossmap = gossmap_load(tmpctx, gossipfilename, NULL);
|
2021-05-22 14:30:15 +09:30
|
|
|
|
|
|
|
for (size_t i = 0; i < NUM_NODES; i++) {
|
|
|
|
struct privkey tmp;
|
|
|
|
memset(&tmp, i+1, sizeof(tmp));
|
|
|
|
node_id_from_privkey(&tmp, &ids[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
mods = tal_arrz(tmpctx, struct payment_modifier *, 1);
|
|
|
|
p = payment_new(mods, tal(tmpctx, struct command), NULL, mods);
|
|
|
|
|
|
|
|
for (size_t i = 1; i < NUM_NODES; i++) {
|
|
|
|
struct short_channel_id scid;
|
|
|
|
|
|
|
|
if (!mk_short_channel_id(&scid, i, i-1, 0))
|
|
|
|
abort();
|
2024-03-20 12:29:51 +10:30
|
|
|
add_connection(store_fd, &ids[i-1], &ids[i], scid,
|
2021-05-22 14:30:15 +09:30
|
|
|
AMOUNT_MSAT(0),
|
|
|
|
AMOUNT_MSAT(1000000 * 1000),
|
|
|
|
0, 0, 0);
|
|
|
|
SUPERVERBOSE("Joining %s to %s, fee %u\n",
|
2024-03-20 11:17:52 +10:30
|
|
|
fmt_node_id(tmpctx, &ids[i-1]),
|
|
|
|
fmt_node_id(tmpctx, &ids[i]),
|
2021-05-22 14:30:15 +09:30
|
|
|
0);
|
|
|
|
|
|
|
|
if (i <= 2)
|
|
|
|
continue;
|
|
|
|
if (!mk_short_channel_id(&scid, i, 1, 0))
|
|
|
|
abort();
|
2024-03-20 12:29:51 +10:30
|
|
|
add_connection(store_fd, &ids[1], &ids[i], scid,
|
2021-05-22 14:30:15 +09:30
|
|
|
AMOUNT_MSAT(0),
|
|
|
|
AMOUNT_MSAT(1000000 * 1000),
|
|
|
|
1 << i, 0, 0);
|
|
|
|
SUPERVERBOSE("Joining %s to %s, fee %u\n",
|
2024-03-20 11:17:52 +10:30
|
|
|
fmt_node_id(tmpctx, &ids[1]),
|
|
|
|
fmt_node_id(tmpctx, &ids[i]),
|
2021-05-22 14:30:15 +09:30
|
|
|
1 << i);
|
|
|
|
}
|
|
|
|
|
2021-09-23 22:37:09 +09:30
|
|
|
assert(gossmap_refresh(global_gossmap, NULL));
|
2021-05-22 14:30:15 +09:30
|
|
|
for (size_t i = ROUTING_MAX_HOPS; i > 2; i--) {
|
|
|
|
struct gossmap_node *dst, *src;
|
|
|
|
struct route_hop *r;
|
|
|
|
const char *errmsg;
|
|
|
|
SUPERVERBOSE("%s -> %s:\n",
|
2024-03-20 11:17:52 +10:30
|
|
|
fmt_node_id(tmpctx, &ids[0]),
|
|
|
|
fmt_node_id(tmpctx, &ids[NUM_NODES-1]));
|
2021-05-22 14:30:15 +09:30
|
|
|
|
2021-09-23 22:37:09 +09:30
|
|
|
src = gossmap_find_node(global_gossmap, &ids[0]);
|
|
|
|
dst = gossmap_find_node(global_gossmap, &ids[NUM_NODES-1]);
|
|
|
|
r = route(tmpctx, global_gossmap, src, dst, AMOUNT_MSAT(1000), 0, 0.0,
|
2021-05-22 14:30:15 +09:30
|
|
|
i - 1, p, &errmsg);
|
|
|
|
assert(r);
|
|
|
|
/* FIXME: We naively fall back on shortest, rather
|
|
|
|
* than biassing! */
|
|
|
|
assert(tal_count(r) == 2);
|
|
|
|
}
|
|
|
|
|
2021-11-15 04:22:46 +10:30
|
|
|
common_shutdown();
|
2021-05-22 14:30:15 +09:30
|
|
|
return 0;
|
|
|
|
}
|