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

fundingmanager: send messages directly to peers #1505

Merged

Conversation

wpaulino
Copy link
Contributor

@wpaulino wpaulino commented Jul 6, 2018

In this PR, we introduce a similar optimization to the one done in #1345. Currently, each call to server.SendToPeer acquires the server's mutex to obtain the active peer. We work around this by passing the peer struct itself within the internal fundingManager messages.

Fixes #1495.

@wpaulino wpaulino force-pushed the fundingmanager-send-peer-directly branch from f97bf6e to 08ea215 Compare July 6, 2018 19:27
@@ -2399,11 +2399,11 @@ func (d *AuthenticatedGossiper) sendAnnSigReliably(
"to peer(%x): %v. Will retry when online.",
remotePeer.SerializeCompressed(), err)

connected := make(chan struct{})
d.cfg.NotifyWhenOnline(remotePeer, connected)
peerChan := make(chan lnpeer.Peer)
Copy link
Contributor

Choose a reason for hiding this comment

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

buffer this as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

f.cfg.NotifyWhenOnline = func(peer *btcec.PublicKey,
connectedChan chan<- lnpeer.Peer) {

go func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

will these tests pass w/o the goroutine now that we're buffering?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep! Fixed.

peer.go Outdated

// AddNewChannel adds a new channel to the peer. The channel should fail to be
// added if the fundingQuit channel is closed.
func (p *peer) AddNewChannel(channel *lnwallet.LightningChannel,
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@@ -107,7 +107,7 @@ type Config struct {
// NotifyWhenOnline is a function that allows the gossiper to be
// notified when a certain peer comes online, allowing it to
// retry sending a peer message.
NotifyWhenOnline func(peer *btcec.PublicKey, connectedChan chan<- struct{})
NotifyWhenOnline func(peer *btcec.PublicKey, peerChan chan<- lnpeer.Peer)
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps make a note in the godoc that peerChan MUST be buffered

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@wpaulino wpaulino force-pushed the fundingmanager-send-peer-directly branch from 08ea215 to 4a7b000 Compare July 7, 2018 01:23
Copy link
Contributor

@cfromknecht cfromknecht left a comment

Choose a reason for hiding this comment

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

Awesome! Fairly familiar with this PR as spent a good amount of time working through it w/ @wpaulino. LGTM, but would appreciate feedback from others.

@Roasbeef Roasbeef requested a review from halseth July 7, 2018 02:48
@Roasbeef Roasbeef added P2 should be fixed if one has time needs review PR needs review by regular contributors needs testing PR hasn't yet been actively tested on testnet/mainnet first pass review done PR has had first pass of review, needs more tho labels Jul 11, 2018
Copy link
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

Did a first pass, and like what I see! I dig the commit format you have been using lately (small, independent commits), makes reviewing a joy!

Main request I have is to try to simplify the logic sending to the peer when it might not be online, avoiding the nil parameter.

peer.go Outdated
p.server.fundingMgr.processFundingError(msg, p.addr)
case p.server.fundingMgr.IsPendingChannel(
msg.ChanID, p.addr.IdentityKey,
):
Copy link
Contributor

Choose a reason for hiding this comment

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

hm, weird format? Maybe just do key := addr.IdentityKey to keep on one line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

lnpeer.Peer

// AddNewChannel adds a new channel to the peer. The channel should fail
// to be added if the fundingQuit channel is closed.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think cancel would be a better name for the chan.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

peer.go Outdated
@@ -223,6 +223,9 @@ func newPeer(conn net.Conn, connReq *connmgr.ConnReq, server *server,
return p, nil
}

// A compile-time check to ensure that peer satisfies the FundingPeer interface.
var _ FundingPeer = (*peer)(nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, this has the unfortunate effect of keeping the dependency cycle peer<->fundingmanager. Why not make AddNewChannel part of the regular Peer interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@@ -630,7 +633,9 @@ func (f *fundingManager) Start() error {
go func(dbChan *channeldb.OpenChannel) {
defer f.wg.Done()

err := f.handleFundingConfirmation(dbChan, shortChanID)
err := f.handleFundingConfirmation(
nil, dbChan, shortChanID,
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if passing nil here is the best option, can make it easy to make errors down the line. Instead, can you fetch the peer (NotifyWhenOnline ) right before it is used, or make sure that it will never be passed in as nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed it so that we fetch the peer before handleFundingConfirmation.

@@ -337,7 +337,7 @@ type fundingConfig struct {
// the channel to the ChainArbitrator so it can watch for any on-chain
// events related to the channel. We also provide the address of the
// node we're establishing a channel with for reconnection purposes.
WatchNewChannel func(*channeldb.OpenChannel, *lnwire.NetAddress) error
WatchNewChannel func(*channeldb.OpenChannel, *btcec.PublicKey) error
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: update comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@@ -9,7 +9,7 @@ import (
"sync/atomic"
"time"

"github.com/coreos/bbolt"
bolt "github.com/coreos/bbolt"
Copy link
Contributor

Choose a reason for hiding this comment

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

why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Had to add it because it wouldn't compile otherwise. Although it no longer seems to be a problem...

fndgLog.Warnf("Unable to send fundingLocked "+
"to peer %x: %v",
peerKey.SerializeCompressed(), err)
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can peer be nil here? If not, this can be written

err = sendMessage(..)
if err == nil {
    break
}
print(err)
... go on ...

EDIT: see other comment about nil peer

@wpaulino wpaulino force-pushed the fundingmanager-send-peer-directly branch from 4a7b000 to a8a9e26 Compare July 12, 2018 01:53
@Roasbeef Roasbeef added funding Related to the opening of new channels with funding transactions on the blockchain server and removed needs review PR needs review by regular contributors labels Jul 13, 2018
peer.go Outdated
// before we close the channel barrier corresponding to the channel.
select {
case <-newChanDone:
case <-cancel:
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if cancelling at this point will actually stop the channel from being added to the peer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, not much we can do after the request has already been sent. Just ended up removing this instead as this wasn't being handled previously anyway.

peer.go Outdated
// handle the error.
case p.server.fundingMgr.IsPendingChannel(msg.ChanID, p.addr):
p.server.fundingMgr.processFundingError(msg, p.addr)
// If the channel ID for the error message corresponds
Copy link
Contributor

Choose a reason for hiding this comment

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

formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

f.cfg.NotifyWhenOnline(ch.IdentityPub, peerChan)

select {
case peer := <-peerChan:
Copy link
Contributor

Choose a reason for hiding this comment

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

Can do

var peer lnpeer.Peer
select {
case peer = <-peerChan:
case <-f.quit:
    return
}
err := f.handleFundingConfirmation ....

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

f.cfg.NotifyWhenOnline(dbChan.IdentityPub, peerChan)

select {
case peer := <-peerChan:
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

return
case <-newChanDone: // Fallthrough if we're not quitting.
}
fmsg.peer.AddNewChannel(channel, f.quit)
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to let this return an error that we can log here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

// sender. Since the fundingManager now has a reference to peers itself,
// alice.sendMessage will be triggered when Bob's funding manager
// attempts to send a message to Alice and vice versa.
alice.remotePeer = bob
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@wpaulino wpaulino force-pushed the fundingmanager-send-peer-directly branch from a8a9e26 to 6f618f0 Compare July 16, 2018 21:20
@Roasbeef Roasbeef added this to the 0.5 milestone Jul 17, 2018
@cfromknecht
Copy link
Contributor

needs rebase

In this commit, we modify the existing message sending functionality
within the fundingmanager. Due to each mesage send requiring to hold the
server's lock to retrieve the peer, we might run into a case where the
lock is held for a larger than usual amount of time and would therefore
block on sending the message within the fundingmanager. We remedy this
by taking a similar approach to some recent changes within the gossiper.
We now keep track of each peer within the internal fundingmanager
messages and send messages directly to them.
callbacks

The FindPeer and SendToPeer callbacks are no longer needed within the
fundingManager due to the previous commit allowing us to send messages
to peers directly.
@wpaulino wpaulino force-pushed the fundingmanager-send-peer-directly branch from 6f618f0 to d54d41e Compare July 19, 2018 19:34
@wpaulino
Copy link
Contributor Author

Rebased.

Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

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

LGTM 🏌🏾

Really dig the incremental step towards removing all references to *peer within the main package all together!

@Roasbeef Roasbeef merged commit 271db7d into lightningnetwork:master Jul 21, 2018
@wpaulino wpaulino deleted the fundingmanager-send-peer-directly branch July 21, 2018 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
first pass review done PR has had first pass of review, needs more tho funding Related to the opening of new channels with funding transactions on the blockchain needs testing PR hasn't yet been actively tested on testnet/mainnet P2 should be fixed if one has time server
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants