peer: fix bug in handshake wherein RevokeAndAck would be sent first

This commit fixes a bug in the opening handshake between to peers. The
bug would arise when on or many channels were active between a node
establishing a new connection. The htlcManager goroutines will
immediately attempt to extend the revocation window once they’re
active. However, at this time, the init message may not yet have been
sent as the two executions are in distinct goroutines.

We fix this bug by manually writing the init message directly to the
socket, rather than traveling through the queueHandler goroutine. With
this, we ensure that the init message is _always_ sent first.
This commit is contained in:
Olaoluwa Osuntokun 2017-03-16 19:45:10 -07:00
parent ec52c49b6c
commit ac83b8ae06
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
1 changed files with 11 additions and 13 deletions

24
peer.go
View File

@ -287,18 +287,15 @@ func (p *peer) Start() error {
peerLog.Tracef("peer %v starting", p)
p.wg.Add(2)
go p.queueHandler()
go p.writeHandler()
// Exchange local and global features, the init message should be
// very first between two nodes.
// Exchange local and global features, the init message should be very
// first between two nodes.
if err := p.sendInitMsg(); err != nil {
return err
}
// Should wait for peers to compare their feature vectors
// and only then start message exchanges.
// Before we launch any of the helper goroutines off the peer struct,
// we'll first ensure proper adherance to the p2p protocl. The init
// message MUST be sent before any other message.
msg, _, err := p.readNextMessage()
if err != nil {
return err
@ -313,7 +310,9 @@ func (p *peer) Start() error {
"must be init message")
}
p.wg.Add(3)
p.wg.Add(5)
go p.queueHandler()
go p.writeHandler()
go p.readHandler()
go p.channelManager()
go p.pingHandler()
@ -1236,16 +1235,15 @@ func (p *peer) handleInitMsg(msg *lnwire.Init) error {
return nil
}
// sendInitMsg sends init message to remote peer which represent our
// features local and global vectors.
// sendInitMsg sends init message to remote peer which contains our currently
// supported local and global features.
func (p *peer) sendInitMsg() error {
msg := lnwire.NewInitMessage(
p.server.globalFeatures,
p.server.localFeatures,
)
p.queueMsg(msg, nil)
return nil
return p.writeMessage(msg)
}
// handleDownStreamPkt processes an HTLC packet sent from the downstream HTLC