-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Re-send AnnouncementSignature not more than once per connection. #9957
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
base: master
Are you sure you want to change the base?
Conversation
|
Important Review skippedAuto reviews are limited to specific labels. 🏷️ Labels to auto review (1)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
gijswijs
left a comment
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.
Pushed new code. The only thing that still doesn't sit with me well is the simulation of the peer disconnecting.
Obviously when I recreate the mockPeer the state of the previous mockPeer is gone, so that reasoning is almost circular. (That also holds true for the way we simulated the gossiper before tho).
I think to truly test this we should make an itest. @ellemouton what do you think?
ellemouton
left a comment
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.
looking good - left one more suggestion regarding approach.
I think the suggestion also answers your question:
doesn't sit with me well is the simulation of the peer disconnecting.
cause now with the suggestion, simulating this is quite easily done from a unit test since the "PeerDisconnected" is just a call-back on the gossiper passed to the peer in question.
discovery/gossiper.go
Outdated
| remoteNSB, | ||
| remoteBSB, 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.
unaddressed
discovery/gossiper.go
Outdated
| chanInfo.AuthProof, chanInfo, e1, e2, | ||
| chanAP := chanInfo.AuthProof | ||
| var remoteNSB []byte | ||
| var remoteBSB []byte |
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 think the name remote* is confusing cause it makes it sound like we are sending them their own proof. local* would make more sense no?
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 think this was resolved without a reply? 😊
| // We create an active syncer for our remote peer. | ||
| err = syncMgr.InitSyncState(remotePeer) | ||
| require.NoError(t, err, "failed to init sync state") | ||
| remoteSyncer := assertSyncerExistence(t, syncMgr, remotePeer) | ||
| assertTransitionToChansSynced(t, remoteSyncer, remotePeer) | ||
| assertActiveGossipTimestampRange(t, remotePeer) | ||
| assertSyncerStatus(t, remoteSyncer, chansSynced, ActiveSync) |
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.
hmm do we still need this?
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 changed it into tCtx.gossiper.InitSyncState(remotePeer) which now handles the clearing of the map[peer][chanID]bool and also calls into syncMgr.InitSyncState(remotePeer). I've kept the assertions, which although slight overkill, are an assertion that everything went aOK so far.
462f1ee to
f0dc8d3
Compare
The config file format changed. The tool golangci-lint migrate was used to migrate the old config. However old comments and also the structure of the disabled linters was preserved. Moreover the new v2 version introduced new linters, we disable 3 of them because they are very noise and we do not really want to check for them: funcorder, noinlineerr, embeddedstructfieldcheck.
The custom file is only needed in the tools directory.
Roasbeef
left a comment
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.
Straight forward solution.
Main comments are re better encapsluation, and reducing duplication in the unit test.
| sentMsgs: sentMsgs, | ||
| quit: quit, | ||
| } | ||
| p.disconnected.Store(disconnected) |
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.
A new addition?
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.
Not sure if I follow. It's just a small refactor that introduces a constructor instead of a ton of &mockPeer{someKey.PubKey(), nil, nil, atomic.Bool{}}
It's never called with anything other than disconnected == false so in theory we could do without that parameter and just initialize it with the zero value of atomic.Bool. It probably doesn't make sense to construct a disconnected peer from the get go.
What do you think?
| "announcement signatures to peer=%x", | ||
| ann.ChannelID, peerID) | ||
|
|
||
| ca, _, _, err := netann.CreateChanAnnouncement( |
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.
Any reason to not also send the chan ann as well? So send the ann sig, and the channel ann.
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.
BOLT07 requires us to send the ann sig: https://github.com/ddustin/lightning-rfc/blob/a2d314df9a791dd1a38be7c34d201bf798ad3525/07-routing-gossip.md?plain=1#L93
Is there a good reason to also send the channel ann? We should assume that our peers do not expect a channel ann.
discovery/gossiper.go
Outdated
| // sentAnnSigs tracks which announcement signatures we've sent to which | ||
| // peers. We'll use this to ensure we don't re-send the same signatures | ||
| // to a peer during a single connection. | ||
| sentAnnSigs map[route.Vertex]map[lnwire.ChannelID]struct{} |
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.
Do we need to limit the size of this map?
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.
Let's also further encapsulate this new data structure. We can expose easy to use methods that: delete, check existence, and add. All while handling thread safety on behalf of the caller.
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 don't think it's smart to limit the size of the map. We need to keep state for every channel anyway, so I wouldn't inadvertently run into the limit of the map. It's hardly a DOS-vector since we only ever hit this map after channel_ready has been sent and received AND the funding transaction has enough confirmations. That's enough disincentivization if you'd ask me.
I agree with the proposed methods tho.
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've encapsulated the map in its own struct sentAnnSigsTracker. It uses its own sync.Mutex to provide better lock granularity. The memory overhead of an extra mutex is very small, and it (hopefully) reduces contention.
…ls-feature Use golangs new tool feature
And ensure that both versions 1 and 2 implement it.
Define a GossipVersion enum along with a GossipMessage interface to be satisfied by all gossip related messages. This will be useful later on when we want to make decisions based on the protocol version that a message is part of.
Since the gossip protocols are completely disjoint, we need to treat messages on the two protocols completely separately and should not let rejections on one protocol affect how we treat messages on the other.
[g175] multi: small G175 preparations
Use a blank identifier when values are intentionally unused.
two constructor funcs that create and return a pointer to an AnnounceSignatures1. `NewAnnSigFromSignature` takes `nodeSig` and `bitcoinSig` as pointers to `*ecdsa.Signature`. `NewAnnSigFromWireECDSA` takes those arguments in the raw 64-byte format we expect.
We change the discovery gossiper to send a signature announcement in response to receiving a signature announcement, but only if the full proof is available. Previously the behavior was to send the channel announcement.
This change aligns our behavior with latest protocol guidelines. That is, when we receive a signature announcement when we already have the full proof we reply with our signature announcement once per (re)connection. see: lightning/bolts#1256
f0dc8d3 to
2e601d8
Compare
|
I think I addressed all comments. Ready for a new round of code review. |
ellemouton
left a comment
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.
looks good! i think just some commit restructuring needed. Other than that, logic LGTM!
discovery/gossiper.go
Outdated
| chanInfo.AuthProof, chanInfo, e1, e2, | ||
| chanAP := chanInfo.AuthProof | ||
| var remoteNSB []byte | ||
| var remoteBSB []byte |
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 think this was resolved without a reply? 😊
discovery/gossiper.go
Outdated
| remoteNSB, | ||
| remoteBSB, 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.
still
| if peerIsFirstNode { | ||
| localNSB = chanAP.NodeSig2Bytes | ||
| localBSB = chanAP.BitcoinSig2Bytes | ||
| } else { | ||
| remoteNSB = chanAP.NodeSig1Bytes | ||
| remoteBSB = chanAP.BitcoinSig1Bytes | ||
| localNSB = chanAP.NodeSig1Bytes | ||
| localBSB = chanAP.BitcoinSig1Bytes |
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.
ah, ok yeah, for sake of review, rather make these changes in the commit where the variables are introduced
496c5e3 to
8eb29f1
Compare
57eb251 to
6fcdbbb
Compare
706b22a to
95b84a8
Compare
This PR aligns our behavior with latest protocol guidelines. That
is, when we receive a signature announcement when we already have the
full proof we reply with our signature announcement once per
(re)connection.
see: lightning/bolts#1256
fixes: #9843