-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Ignore node announcements for nodes not found in any existing channel #227
Ignore node announcements for nodes not found in any existing channel #227
Conversation
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.
I still need to take a close look at the tests, but I've completed an initial round of review.
channeldb/graph.go
Outdated
|
||
nodePub := node.PubKey.SerializeCompressed() | ||
|
||
if err := aliasBucket.Put(nodePub, []byte(node.Alias)); err != nil { |
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.
In the scenario that we're adding a partial node, then we don't yet know it's alias.
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.
Also the order here is off, the alias is written much after the public key. As a result, alias bucket shouldn't yet be updated as we don't have a valid alias for a node if we've only discovered it via a ChannelUpdate
message.
discovery/service.go
Outdated
@@ -537,6 +538,10 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []l | |||
BitcoinKey2: msg.BitcoinKey2, | |||
AuthProof: proof, | |||
} | |||
|
|||
// We will add the edge to the channel router. If the nodes present in this | |||
// channel is not present in the database from before, a partial node will |
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.
is not -> are not
Also "from before" can be dropped.
discovery/service.go
Outdated
// both of the directed infos that make up the channel. | ||
// As peers are expecting channel announcements before node announcements, we | ||
// first retrieve the initial announcement, as well as the latest channel | ||
// update announcement for both of the directed infos that make up each |
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.
directed infos -> directed edges
fundingmanager.go
Outdated
@@ -1246,6 +1246,8 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe | |||
f.cfg.SendAnnouncement(ann.chanAnn) | |||
f.cfg.SendAnnouncement(ann.chanUpdateAnn) | |||
f.cfg.SendAnnouncement(ann.chanProof) | |||
|
|||
// TODO: Send node announcement? |
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.
After reflecting, I think a node announcement should indeed follow any local announcements we send out.
discovery/service_test.go
Outdated
@@ -828,3 +828,85 @@ func TestOrphanSignatureAnnouncement(t *testing.T) { | |||
t.Fatal("wrong number of objects in storage") | |||
} | |||
} | |||
|
|||
// We should ignore node announcements of nodes not associated with any |
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.
Comment should be prefixed with TestOrphanNodeAnnouncement
.
Also I'm not sure that this is the correct package for this test. Correct me if I'm wrong, but the underlying logic of ignoring a node announcement if there aren't any matching channels for it is implemented in the router itself.
7a3dcad
to
b455494
Compare
I added a new field to the Now we also sign and send a new |
PTAL |
a581497
to
8fc68b6
Compare
75abb2c
to
dbc194b
Compare
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.
Just completed a final round of review. I've tested this PR locally, and within a sub-graph of the current Bitcoin testnet deployment and confirmed everything works as advertised. Nice work!
I have a few final comments, none of them major. The most pertinent one is an attempt to ensure that we don't cause extraneous messages to propagate through the network by always updating the timestamp of our NodeAnnouncement
each time a channel is funded.
Also this will need to be rebased to the latest master, as there's a conflict in the fundingManager
. Within the wallet, what used to be the ChannelDB
field is now accessed as wallet.Cfg.Database
.
channeldb/graph.go
Outdated
PubKey *btcec.PublicKey | ||
|
||
// HaveNodeAnnouncement indicates whether we received a node annoucement | ||
// for this particular node. If true, the remaining fiels will be set, |
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.
fiels -> fields
fundingmanager.go
Outdated
// is only accepted after a channel is known for that particular node, | ||
// and this might be our first channel. | ||
graph := f.cfg.Wallet.ChannelDB.ChannelGraph() | ||
self, err := graph.FetchLightningNode(f.cfg.IDKey) |
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.
The graph.SourceNode
method can be used in place of FetchLightningNode
. Worth noting though that I don't consider this a blocker to merging the PR.
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.
Though my comment above invalidates this comment.
@@ -152,6 +152,10 @@ type fundingConfig struct { | |||
// cannot be located, then an error is returned. | |||
SignMessage func(pubKey *btcec.PublicKey, msg []byte) (*btcec.Signature, error) | |||
|
|||
// SignNodeAnnouncement is used by the fundingManager to sign the | |||
// updated self node announcements sent after each channel announcement. | |||
SignNodeAnnouncement func(nodeAnn *lnwire.NodeAnnouncement) (*btcec.Signature, error) |
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.
Rather than requesting a signature for a node announcement, we should instead simply be fetching the latest pre-signed NodeAnnouncment
. We currently create, and sign one at start up within the Start
method of the server
struct.
If we take this path, then we avoid unnecessarily updating our the timestamp on our node announcement. By avoiding this update, we save the network a bit of bandwidth as nodes now don't need to add this (unchanged) announcement to their re-broadcast buffers.
Adds a HaveNodeAnnouncement field to the LightningNode struct, which is used to indicate if we have gotten all the necessary information to fill the remaining fields in the struct. If we haven't gotten a node announcement for this specific node, then we only know the pubkey, and can only fill that field in the struct. Still, we should be able to add it to the channel graph and use it for routes, as long as we know about channels to this node.
This commit introduces the requirement specified in BOLT#7, where we ignore any node announcements for a specific node if we yet haven't seen any channel announcements where this node takes part. This is to prevent someone DoS-ing the network with cheap node announcements. In the router this is enforced by requiring a call to AddNode(node_id) to be preceded by an AddEdge(edge_id) call, where node_id is one of the nodes in edge_id.
According to BOLT#7, nodes will ignore node announcements for nodes not found in any previous channel announcements. This commit makes the discovery service send its known channels before its known nodes when syncing the channel graph with a peer.
Make the fundingmanager send an updated node announcement each time it opens a new channel. This is to make sure our node announcement is propagated in the network, since peers will ignore our node announcements if we haven't opened any channels yet.
dbc194b
to
7aada05
Compare
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.
LGTM 🗼
As specified in BOLT#7, we should ignore any node announcements for nodes that we have not gotten any channel announcements for. This is to prevent an attacker to DoSing the network by creating a lot of cheap nodes.
Fixes #138.