diff --git a/peer/brontide.go b/peer/brontide.go index 2d77f3479..8d71fffe6 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -347,6 +347,13 @@ type Brontide struct { // our last ping message. To be used atomically. pingLastSend int64 + // lastPingPayload stores an unsafe pointer wrapped as an atomic + // variable which points to the last payload the remote party sent us + // as their ping. + // + // MUST be used atomically. + lastPingPayload atomic.Value + cfg Config // activeSignal when closed signals that the peer is now active and @@ -1368,8 +1375,14 @@ out: atomic.StoreInt64(&p.pingTime, delay) case *lnwire.Ping: - // TODO(roasbeef): get from buffer pool somewhere? ends - // up w/ lots of small allocations + // First, we'll store their latest ping payload within + // the relevant atomic variable. + p.lastPingPayload.Store(msg.PaddingBytes[:]) + + // Next, we'll send over the amount of specified pong + // bytes. + // + // TODO(roasbeef): read out from pong scratch instead? pongBytes := make([]byte, msg.NumPongBytes) p.queueMsg(lnwire.NewPong(pongBytes), nil) @@ -2004,7 +2017,13 @@ out: // between all our peers, which can later be used to // cross-check our own view of the network to mitigate various // types of eclipse attacks. - case epoch := <-blockEpochs.Epochs: + case epoch, ok := <-blockEpochs.Epochs: + if !ok { + peerLog.Debugf("block notifications " + + "canceled") + return + } + blockHeader = epoch.BlockHeader headerBuf := bytes.NewBuffer(pingPayload[0:0]) err := blockHeader.Serialize(headerBuf) @@ -3157,3 +3176,19 @@ func (p *Brontide) BytesReceived() uint64 { func (p *Brontide) BytesSent() uint64 { return atomic.LoadUint64(&p.bytesSent) } + +// LastRemotePingPayload returns the last payload the remote party sent as part +// of their ping. +func (p *Brontide) LastRemotePingPayload() []byte { + pingPayload := p.lastPingPayload.Load() + if pingPayload == nil { + return []byte{} + } + + pingBytes, ok := pingPayload.(lnwire.PingPayload) + if !ok { + return nil + } + + return pingBytes +}