mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-19 12:01:27 +02:00
peer: abstract out ping payload generation from the pingHandler
This change makes the generation of the ping payload a no-arg closure parameter, relieving the pingHandler of having to directly monitor the chain state. This makes use of the BestBlockView that was introduced in earlier commits.
This commit is contained in:
@@ -649,7 +649,35 @@ func (p *Brontide) Start() error {
|
||||
go p.writeHandler()
|
||||
go p.readHandler()
|
||||
go p.channelManager()
|
||||
go p.pingHandler()
|
||||
|
||||
var (
|
||||
lastBlockHeader *wire.BlockHeader
|
||||
lastSerializedBlockHeader [wire.MaxBlockHeaderPayload]byte
|
||||
)
|
||||
newPingPayload := func() []byte {
|
||||
// We query the BestBlockHeader from our BestBlockView each time
|
||||
// this is called, and update our serialized block header if
|
||||
// they differ. Over time, we'll use this to disseminate the
|
||||
// latest block header 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.
|
||||
header, err := p.cfg.BestBlockView.BestBlockHeader()
|
||||
if err == nil && header != lastBlockHeader {
|
||||
buf := bytes.NewBuffer(lastSerializedBlockHeader[0:0])
|
||||
err := header.Serialize(buf)
|
||||
if err == nil {
|
||||
lastBlockHeader = header
|
||||
} else {
|
||||
p.log.Warn("unable to serialize current block" +
|
||||
"header for ping payload generation." +
|
||||
"This should be impossible and means" +
|
||||
"there is an implementation bug.")
|
||||
}
|
||||
}
|
||||
|
||||
return lastSerializedBlockHeader[:]
|
||||
}
|
||||
go p.pingHandler(newPingPayload)
|
||||
|
||||
// Signal to any external processes that the peer is now active.
|
||||
close(p.activeSignal)
|
||||
@@ -2257,7 +2285,7 @@ func (p *Brontide) queueHandler() {
|
||||
// connection is still active.
|
||||
//
|
||||
// NOTE: This method MUST be run as a goroutine.
|
||||
func (p *Brontide) pingHandler() {
|
||||
func (p *Brontide) pingHandler(newPayload func() []byte) {
|
||||
defer p.wg.Done()
|
||||
|
||||
pingTicker := time.NewTicker(pingInterval)
|
||||
@@ -2266,47 +2294,14 @@ func (p *Brontide) pingHandler() {
|
||||
// TODO(roasbeef): make dynamic in order to create fake cover traffic
|
||||
const numPongBytes = 16
|
||||
|
||||
blockEpochs, err := p.cfg.ChainNotifier.RegisterBlockEpochNtfn(nil)
|
||||
if err != nil {
|
||||
p.log.Errorf("unable to establish block epoch "+
|
||||
"subscription: %v", err)
|
||||
return
|
||||
}
|
||||
defer blockEpochs.Cancel()
|
||||
|
||||
var (
|
||||
pingPayload [wire.MaxBlockHeaderPayload]byte
|
||||
blockHeader *wire.BlockHeader
|
||||
)
|
||||
out:
|
||||
for {
|
||||
select {
|
||||
// Each time a new block comes in, we'll copy the raw header
|
||||
// contents over to our ping payload declared above. Over time,
|
||||
// we'll use this to disseminate the latest block header
|
||||
// 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, ok := <-blockEpochs.Epochs:
|
||||
if !ok {
|
||||
p.log.Debugf("block notifications " +
|
||||
"canceled")
|
||||
return
|
||||
}
|
||||
|
||||
blockHeader = epoch.BlockHeader
|
||||
headerBuf := bytes.NewBuffer(pingPayload[0:0])
|
||||
err := blockHeader.Serialize(headerBuf)
|
||||
if err != nil {
|
||||
p.log.Errorf("unable to encode header: %v",
|
||||
err)
|
||||
}
|
||||
|
||||
case <-pingTicker.C:
|
||||
|
||||
pingMsg := &lnwire.Ping{
|
||||
NumPongBytes: numPongBytes,
|
||||
PaddingBytes: pingPayload[:],
|
||||
PaddingBytes: newPayload(),
|
||||
}
|
||||
|
||||
p.queueMsg(pingMsg, nil)
|
||||
|
Reference in New Issue
Block a user