Skip to content
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

gossip split #6355

Closed
Closed

Conversation

endothermicdev
Copy link
Collaborator

This PR is step one of removing private gossip from the database.

It removes dependence on private data in the gossip store by logging incoming private gossip to the channels table of the database. The major consumers of this data are invoice and offers, which need to create route hints and blinded routes with this private channel data. The listincoming rpc must therefore be replaced in order to fetch both public and private channel data from the public (topology plugin) and private (lightningd database).

wallet/db.c Outdated Show resolved Hide resolved
gossipd/routing.c Outdated Show resolved Hide resolved
plugins/topology.c Outdated Show resolved Hide resolved
Comment on lines 582 to 597
size_t i;
const jsmntok_t *t;
struct node_id node_id;
const struct gossmap_node *node;
struct gossmap_chan *chan;
int half;
struct amount_msat capacity;
struct amount_sat chan_capacity_sat;
struct amount_msat chan_capacity_msat;
u8 *peer_features;
const struct gossmap_node *me;
u32 my_node_idx;
Copy link
Collaborator

@vincenzopalazzo vincenzopalazzo Jun 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

declare all these fields here looks odds. There is any reason that I am missing here?

/* If this is a channel with us, get the inbound
* routing parameters. */
if(me && json_add_channel_inbound(js, my_node_idx, chan))
continue;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the continue has an extra tab?

Comment on lines 4277 to 4279
print(f"ready to test getremoteliquidity({[l3.info['id'], l4.info['id']]})")
liquidity_result = l1.rpc.getremoteliquidity([l3.info['id'], l4.info['id']])
print(liquidity_result)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for prints

Copy link
Collaborator

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to digest this code because the gossipd is always a black box for me, but I had some question and stupid nits

lightningd/gossip_control.c Outdated Show resolved Hide resolved
fromwire_gossipd_remote_channel_update(msg, update);
channel = any_channel_by_scid(ld, &update->scid, true);
if (!channel) {
log_unusual(ld->log, "could not find channel for peer's "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log the update source (which peer) and scid?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log_peer_unusual(ld->log, &update->source_node, "Could not find channel %s for peer's channel_update", type_to_string(tmpctx, struct short_channel_id, &update->scid));

return;
}

/* FIXME: validate channel belongs to node/peer */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check channel->peer->id.

lightningd/gossip_control.c Show resolved Hide resolved
&update->source_node),
type_to_string(tmpctx, struct short_channel_id,
channel->scid));
tal_free(channel->private_update);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't free real update, do:

if (taken(update))
    tal_free(update);

Comment on lines 1371 to 1383
/* Allow ld to process a private channel update */
struct remote_priv_update remote_update;
u8* msg;
remote_update.source_node = peer->id;
remote_update.scid = short_channel_id;
remote_update.fee_base = fee_base_msat;
remote_update.fee_ppm = fee_proportional_millionths;
remote_update.cltv_delta = expiry;
remote_update.htlc_minimum_msat = htlc_minimum;
remote_update.htlc_maximum_msat = htlc_maximum;
msg = towire_gossipd_remote_channel_update(NULL, &remote_update);
daemon_conn_send(peer->daemon->master, take(msg));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are now two of these in gossipd?? Unify into a single ... tell_lightningd_private_cupdate(id, scid, base, ppm, expiry, min, max).?

@@ -554,6 +554,66 @@ static const struct json_command addgossip_command = {
};
AUTODATA(json_command, &addgossip_command);

static struct command_result *json_listprivateinbound(struct command *cmd,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a new API, perhaps we need to enhance listpeerchannels? (optional) remote_private_update object inside that maybe?

In that case, we need to clean it up once channel is public (probably a good idea anyway!) so gossipd needs to tell is when it (first) makes one of our private channels public (i.e. first sees a valid channel_announcement). Note this can fire more than once (lost gossip store!) so don't freak out if we didn't have private info (could happent if they never sent before announcement anyway!).

return command_param_failed();

js = jsonrpc_stream_success(cmd);
json_array_start(js, "nodes");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally get/listXXX contains XXX object. Shahana has been complaining about inconsistency in our APIs!

Comment on lines 721 to 726
static struct command_result *json_listincoming2(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
struct peer *peer;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listincoming2 belongs in topology.

  1. It needs to use listpeerchannels to get info about private channels/updates.
  2. Merge that with its topology info (as it does in getremoteliquidity).
  3. Present a unified view of all peers' calculated capacity.

@rustyrussell rustyrussell added this to the v23.11 milestone Jul 25, 2023
@endothermicdev endothermicdev force-pushed the gs-split3 branch 6 times, most recently from bc9a481 to 0697731 Compare August 28, 2023 16:49
@endothermicdev endothermicdev force-pushed the gs-split3 branch 2 times, most recently from f4a6d1a to 2818316 Compare September 19, 2023 20:56
@endothermicdev endothermicdev force-pushed the gs-split3 branch 5 times, most recently from 189e96b to 4168d80 Compare October 11, 2023 20:57
This allows the removal of private gossip from the gossip store, using
the channels db table instead to populate the listincoming private
channel entries.

Changelog-Changed: Note: Private channels in listincoming deprecated -removal in 24.08.
Changelog-changed: Note: private channels will be deprecated from listchannels in 24.08
@endothermicdev endothermicdev marked this pull request as ready for review October 12, 2023 22:05
Copy link
Contributor

@rustyrussell rustyrussell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might have uncovered an unrelated gossip bug!

fromwire_gossipd_remote_channel_update(msg, update);
channel = any_channel_by_scid(ld, &update->scid, true);
if (!channel) {
log_unusual(ld->log, "could not find channel for peer's "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log_peer_unusual(ld->log, &update->source_node, "Could not find channel %s for peer's channel_update", type_to_string(tmpctx, struct short_channel_id, &update->scid));

case WIRE_GOSSIPD_REMOTE_CHANNEL_UPDATE:
/* Please stash in database for us! */
handle_private_update_data(gossip->ld, msg);
tal_free(msg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't tal_free(msg), it belongs to the caller (and nobody else does!).

Comment on lines 597 to 599
/* struct node_id *peer_id; */
struct peer *peer;
/* struct channel *c, **channels; */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comments...

response = json_stream_success(cmd);
json_array_start(response, "private_channels");

/* channels = tal_arr(tmpctx, struct channel *, 0); */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This too

Comment on lines +617 to +618
if (c->state != CHANNELD_NORMAL &&
c->state != CHANNELD_AWAITING_SPLICE)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer new state filters, in this case "if (!channel_can_add_htlc(c->state))".

Comment on lines +1640 to +1641
if (local_update->cltv_delta == 0)
local_update = tal_free(local_update);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too...

db_bind_null(stmt);
}
if (chan->local_private_update &&
chan->local_private_update->cltv_delta) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too...

@@ -2273,18 +2309,32 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
db_bind_null(stmt);

db_bind_int(stmt, chan->ignore_fee_limits);
if (chan->private_update) {
if (chan->private_update && chan->private_update->cltv_delta) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too

@@ -22,6 +22,8 @@ static struct gossmap *global_gossmap;
static struct node_id local_id;
static struct plugin *plugin;

extern bool deprecated_apis;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already declared in libplugin.h?

Comment on lines +445 to +448
/* FIXME: deprecate private channels in listchannels result in 24.08 */
if (deprecated_apis)
return;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this backwards? I think a simple test is in order...

@rustyrussell
Copy link
Contributor

OK, I tried eliminating gossipd's private channels, and it's clear that this doesn't go far enough. topology still relies on private channels in gossmap :(

In particular, listprivateinbound is the wrong thing. You need to add the private update information to listpeerchannels, where the channel is not public. Then, instead of using listprivateinbound and doing a lookup in gossmap, use private listpeerchannels. i.e. this code must not use gossmap at all (except, perhaps, to make sure it only shows a private channel if it doesn't appear in gossmap, to avoid races).

@rustyrussell rustyrussell removed this from the v23.11 milestone Oct 23, 2023
@rustyrussell
Copy link
Contributor

Parts of this became the gossip rewrite work...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants